@@ -2406,6 +2406,53 @@ LazyStoragePropertyRequest::evaluate(Evaluator &evaluator,
2406
2406
return Storage;
2407
2407
}
2408
2408
2409
+ // / Synthesize a computed property representing the wrapped value for a
2410
+ // / parameter with an attached property wrapper.
2411
+ static VarDecl *synthesizeLocalWrappedValueVar (VarDecl *var) {
2412
+ if (!var->hasAttachedPropertyWrapper () || !isa<ParamDecl>(var))
2413
+ return nullptr ;
2414
+
2415
+ auto dc = var->getDeclContext ();
2416
+ auto &ctx = var->getASTContext ();
2417
+
2418
+ SmallString<64 > nameBuf;
2419
+ if (var->getName ().hasDollarPrefix ()) {
2420
+ nameBuf = var->getName ().str ().drop_front ();
2421
+ } else {
2422
+ nameBuf = var->getName ().str ();
2423
+ }
2424
+ Identifier name = ctx.getIdentifier (nameBuf);
2425
+
2426
+ VarDecl *localVar = new (ctx) VarDecl (/* IsStatic=*/ false ,
2427
+ VarDecl::Introducer::Var,
2428
+ var->getLoc (), name, dc);
2429
+ if (!var->hasImplicitPropertyWrapper ())
2430
+ localVar->setInterfaceType (var->getInterfaceType ());
2431
+ localVar->setImplicit ();
2432
+ localVar->getAttrs () = var->getAttrs ();
2433
+ localVar->overwriteAccess (var->getFormalAccess ());
2434
+
2435
+ if (var->hasImplicitPropertyWrapper ()) {
2436
+ // FIXME: This can have a setter, but we need a resolved wrapper type
2437
+ // to figure it out.
2438
+ localVar->setImplInfo (StorageImplInfo::getImmutableComputed ());
2439
+ } else {
2440
+ auto mutability = *var->getPropertyWrapperMutability ();
2441
+ if (mutability.Getter == PropertyWrapperMutability::Mutating) {
2442
+ ctx.Diags .diagnose (var->getLoc (), diag::property_wrapper_param_mutating);
2443
+ return nullptr ;
2444
+ }
2445
+
2446
+ if (mutability.Setter == PropertyWrapperMutability::Nonmutating) {
2447
+ localVar->setImplInfo (StorageImplInfo::getMutableComputed ());
2448
+ } else {
2449
+ localVar->setImplInfo (StorageImplInfo::getImmutableComputed ());
2450
+ }
2451
+ }
2452
+
2453
+ return localVar;
2454
+ }
2455
+
2409
2456
// / Synthesize a computed property `$foo` for a property with an attached
2410
2457
// / wrapper that has a `projectedValue` property.
2411
2458
static VarDecl *synthesizePropertyWrapperProjectionVar (
@@ -2710,6 +2757,7 @@ PropertyWrapperAuxiliaryVariablesRequest::evaluate(Evaluator &evaluator,
2710
2757
auto dc = var->getDeclContext ();
2711
2758
VarDecl *backingVar = nullptr ;
2712
2759
VarDecl *projectionVar = nullptr ;
2760
+ VarDecl *wrappedValueVar = nullptr ;
2713
2761
2714
2762
if (auto *param = dyn_cast<ParamDecl>(var)) {
2715
2763
backingVar = ParamDecl::cloneWithoutType (ctx, param);
@@ -2768,7 +2816,14 @@ PropertyWrapperAuxiliaryVariablesRequest::evaluate(Evaluator &evaluator,
2768
2816
ctx, var, wrapperType, wrapperInfo.projectedValueVar );
2769
2817
}
2770
2818
2771
- return PropertyWrapperAuxiliaryVariables (backingVar, projectionVar);
2819
+ if ((wrappedValueVar = synthesizeLocalWrappedValueVar (var))) {
2820
+ // Record the backing storage for the local wrapped value var, which
2821
+ // is needed for synthesizing its accessors.
2822
+ evaluator.cacheOutput (PropertyWrapperAuxiliaryVariablesRequest{wrappedValueVar},
2823
+ PropertyWrapperAuxiliaryVariables (backingVar, projectionVar));
2824
+ }
2825
+
2826
+ return PropertyWrapperAuxiliaryVariables (backingVar, projectionVar, wrappedValueVar);
2772
2827
}
2773
2828
2774
2829
PropertyWrapperInitializerInfo
@@ -2888,56 +2943,6 @@ PropertyWrapperInitializerInfoRequest::evaluate(Evaluator &evaluator,
2888
2943
return PropertyWrapperInitializerInfo (wrappedValueInit, projectedValueInit);
2889
2944
}
2890
2945
2891
- VarDecl *
2892
- PropertyWrapperWrappedValueVarRequest::evaluate (Evaluator &evaluator,
2893
- VarDecl *var) const {
2894
- auto wrapperInfo = var->getPropertyWrapperAuxiliaryVariables ();
2895
- if (!wrapperInfo || !isa<ParamDecl>(var))
2896
- return nullptr ;
2897
-
2898
- auto dc = var->getDeclContext ();
2899
- auto &ctx = var->getASTContext ();
2900
-
2901
- SmallString<64 > nameBuf;
2902
- if (var->getName ().hasDollarPrefix ()) {
2903
- nameBuf = var->getName ().str ().drop_front ();
2904
- } else {
2905
- nameBuf = var->getName ().str ();
2906
- }
2907
- Identifier name = ctx.getIdentifier (nameBuf);
2908
-
2909
- VarDecl *localVar = new (ctx) VarDecl (/* IsStatic=*/ false ,
2910
- VarDecl::Introducer::Var,
2911
- var->getLoc (), name, dc);
2912
- if (!var->hasImplicitPropertyWrapper ())
2913
- localVar->setInterfaceType (var->getInterfaceType ());
2914
- localVar->setImplicit ();
2915
- localVar->getAttrs () = var->getAttrs ();
2916
- localVar->overwriteAccess (var->getFormalAccess ());
2917
-
2918
- if (var->hasImplicitPropertyWrapper ()) {
2919
- // FIXME: This can have a setter, but we need a resolved wrapper type
2920
- // to figure it out.
2921
- localVar->setImplInfo (StorageImplInfo::getImmutableComputed ());
2922
- } else {
2923
- auto mutability = *var->getPropertyWrapperMutability ();
2924
- if (mutability.Getter == PropertyWrapperMutability::Mutating) {
2925
- ctx.Diags .diagnose (var->getLoc (), diag::property_wrapper_param_mutating);
2926
- return nullptr ;
2927
- }
2928
-
2929
- if (mutability.Setter == PropertyWrapperMutability::Nonmutating) {
2930
- localVar->setImplInfo (StorageImplInfo::getMutableComputed ());
2931
- } else {
2932
- localVar->setImplInfo (StorageImplInfo::getImmutableComputed ());
2933
- }
2934
- }
2935
-
2936
- evaluator.cacheOutput (PropertyWrapperAuxiliaryVariablesRequest{localVar},
2937
- std::move (wrapperInfo));
2938
- return localVar;
2939
- }
2940
-
2941
2946
// / Given a storage declaration in a protocol, set it up with the right
2942
2947
// / StorageImpl and add the right set of opaque accessors.
2943
2948
static void finishProtocolStorageImplInfo (AbstractStorageDecl *storage,
0 commit comments