@@ -1388,10 +1388,9 @@ bool PatternBindingEntry::isInitialized() const {
1388
1388
1389
1389
// Initialized via a property wrapper.
1390
1390
if (auto var = getPattern ()->getSingleVar ()) {
1391
- if (auto customAttr = var->getAttachedPropertyWrapper ()) {
1392
- if (customAttr->getArg () != nullptr )
1393
- return true ;
1394
- }
1391
+ auto customAttrs = var->getAttachedPropertyWrappers ();
1392
+ if (customAttrs.size () > 0 && customAttrs[0 ]->getArg () != nullptr )
1393
+ return true ;
1395
1394
}
1396
1395
1397
1396
return false ;
@@ -1581,10 +1580,10 @@ bool PatternBindingDecl::isDefaultInitializable(unsigned i) const {
1581
1580
if (entry.isInitialized ())
1582
1581
return true ;
1583
1582
1584
- // If it has an attached property wrapper that vends an `init()`, use that
1583
+ // If the outermost attached property wrapper vends an `init()`, use that
1585
1584
// for default initialization.
1586
1585
if (auto singleVar = getSingleVar ()) {
1587
- if (auto wrapperInfo = singleVar->getAttachedPropertyWrapperTypeInfo ()) {
1586
+ if (auto wrapperInfo = singleVar->getAttachedPropertyWrapperTypeInfo (0 )) {
1588
1587
if (wrapperInfo.defaultInit )
1589
1588
return true ;
1590
1589
}
@@ -5328,12 +5327,12 @@ static bool isBackingStorageForDeclaredProperty(const VarDecl *var) {
5328
5327
return name.str ().startswith (" $__lazy_storage_$_" );
5329
5328
}
5330
5329
5331
- // / Whether the given variable
5330
+ // / Whether the given variable is a delcared property that has separate backing storage.
5332
5331
static bool isDeclaredPropertyWithBackingStorage (const VarDecl *var) {
5333
5332
if (var->getAttrs ().hasAttribute <LazyAttr>())
5334
5333
return true ;
5335
5334
5336
- if (var->getAttachedPropertyWrapper ())
5335
+ if (var->hasAttachedPropertyWrapper ())
5337
5336
return true ;
5338
5337
5339
5338
return false ;
@@ -5374,7 +5373,7 @@ bool VarDecl::isMemberwiseInitialized(bool preferDeclaredProperties) const {
5374
5373
if (auto origWrapped = getOriginalWrappedProperty ())
5375
5374
origVar = origWrapped;
5376
5375
if (origVar->getFormalAccess () < AccessLevel::Internal &&
5377
- origVar->getAttachedPropertyWrapper () &&
5376
+ origVar->hasAttachedPropertyWrapper () &&
5378
5377
(origVar->isParentInitialized () ||
5379
5378
(origVar->getParentPatternBinding () &&
5380
5379
origVar->getParentPatternBinding ()->isDefaultInitializable ())))
@@ -5416,22 +5415,39 @@ StaticSpellingKind AbstractStorageDecl::getCorrectStaticSpelling() const {
5416
5415
return getCorrectStaticSpellingForDecl (this );
5417
5416
}
5418
5417
5419
- CustomAttr *VarDecl::getAttachedPropertyWrapper () const {
5418
+ llvm::TinyPtrVector< CustomAttr *> VarDecl::getAttachedPropertyWrappers () const {
5420
5419
auto &ctx = getASTContext ();
5421
5420
if (!ctx.getLazyResolver ())
5422
- return nullptr ;
5421
+ return { } ;
5423
5422
5424
5423
auto mutableThis = const_cast <VarDecl *>(this );
5425
5424
return evaluateOrDefault (ctx.evaluator ,
5426
- AttachedPropertyWrapperRequest {mutableThis},
5427
- nullptr );
5425
+ AttachedPropertyWrappersRequest {mutableThis},
5426
+ { } );
5428
5427
}
5429
5428
5430
- PropertyWrapperTypeInfo VarDecl::getAttachedPropertyWrapperTypeInfo () const {
5431
- auto attr = getAttachedPropertyWrapper ();
5432
- if (!attr)
5433
- return PropertyWrapperTypeInfo ();
5429
+ // / Whether this property has any attached property wrappers.
5430
+ bool VarDecl::hasAttachedPropertyWrapper () const {
5431
+ return !getAttachedPropertyWrappers ().empty ();
5432
+ }
5433
+
5434
+ // / Whether all of the attached property wrappers have an init(initialValue:) initializer.
5435
+ bool VarDecl::allAttachedPropertyWrappersHaveInitialValueInit () const {
5436
+ for (unsigned i : indices (getAttachedPropertyWrappers ())) {
5437
+ if (!getAttachedPropertyWrapperTypeInfo (i).initialValueInit )
5438
+ return false ;
5439
+ }
5440
+
5441
+ return true ;
5442
+ }
5434
5443
5444
+ PropertyWrapperTypeInfo
5445
+ VarDecl::getAttachedPropertyWrapperTypeInfo (unsigned i) const {
5446
+ auto attrs = getAttachedPropertyWrappers ();
5447
+ if (i >= attrs.size ())
5448
+ return PropertyWrapperTypeInfo ();
5449
+
5450
+ auto attr = attrs[i];
5435
5451
auto dc = getDeclContext ();
5436
5452
ASTContext &ctx = getASTContext ();
5437
5453
auto nominal = evaluateOrDefault (
@@ -5442,12 +5458,13 @@ PropertyWrapperTypeInfo VarDecl::getAttachedPropertyWrapperTypeInfo() const {
5442
5458
return nominal->getPropertyWrapperTypeInfo ();
5443
5459
}
5444
5460
5445
- Type VarDecl::getAttachedPropertyWrapperType () const {
5461
+ Type VarDecl::getAttachedPropertyWrapperType (unsigned index ) const {
5446
5462
auto &ctx = getASTContext ();
5447
5463
auto mutableThis = const_cast <VarDecl *>(this );
5448
- return evaluateOrDefault (ctx.evaluator ,
5449
- AttachedPropertyWrapperTypeRequest{mutableThis},
5450
- Type ());
5464
+ return evaluateOrDefault (
5465
+ ctx.evaluator ,
5466
+ AttachedPropertyWrapperTypeRequest{mutableThis, index },
5467
+ Type ());
5451
5468
}
5452
5469
5453
5470
Type VarDecl::getPropertyWrapperBackingPropertyType () const {
@@ -5473,8 +5490,8 @@ VarDecl *VarDecl::getPropertyWrapperBackingProperty() const {
5473
5490
}
5474
5491
5475
5492
bool VarDecl::isPropertyWrapperInitializedWithInitialValue () const {
5476
- auto customAttr = getAttachedPropertyWrapper ();
5477
- if (!customAttr )
5493
+ auto customAttrs = getAttachedPropertyWrappers ();
5494
+ if (customAttrs. empty () )
5478
5495
return false ;
5479
5496
5480
5497
auto *PBD = getParentPatternBinding ();
@@ -5486,24 +5503,23 @@ bool VarDecl::isPropertyWrapperInitializedWithInitialValue() const {
5486
5503
if (PBD->getPatternList ()[0 ].getEqualLoc ().isValid ())
5487
5504
return true ;
5488
5505
5489
- // If there was an initializer on the attribute itself , initialize
5506
+ // If there was an initializer on the outermost wrapper , initialize
5490
5507
// via the full wrapper.
5491
- if (customAttr ->getArg () != nullptr )
5508
+ if (customAttrs[ 0 ] ->getArg () != nullptr )
5492
5509
return false ;
5493
5510
5494
5511
// Default initialization does not use a value.
5495
- auto wrapperTypeInfo = getAttachedPropertyWrapperTypeInfo ();
5496
- if (wrapperTypeInfo.defaultInit )
5512
+ if (getAttachedPropertyWrapperTypeInfo (0 ).defaultInit )
5497
5513
return false ;
5498
5514
5499
- // There is no initializer, so the initialization form depends on
5500
- // whether the property wrapper type has an init(initialValue:) .
5501
- return wrapperTypeInfo. initialValueInit != nullptr ;
5515
+ // If all property wrappers have an initialValue initializer, the property
5516
+ // wrapper will be initialized that way .
5517
+ return allAttachedPropertyWrappersHaveInitialValueInit () ;
5502
5518
}
5503
5519
5504
5520
bool VarDecl::isPropertyMemberwiseInitializedWithWrappedType () const {
5505
- auto customAttr = getAttachedPropertyWrapper ();
5506
- if (!customAttr )
5521
+ auto customAttrs = getAttachedPropertyWrappers ();
5522
+ if (customAttrs. empty () )
5507
5523
return false ;
5508
5524
5509
5525
auto *PBD = getParentPatternBinding ();
@@ -5515,15 +5531,14 @@ bool VarDecl::isPropertyMemberwiseInitializedWithWrappedType() const {
5515
5531
if (PBD->getPatternList ()[0 ].getEqualLoc ().isValid ())
5516
5532
return true ;
5517
5533
5518
- // If there was an initializer on the attribute itself , initialize
5534
+ // If there was an initializer on the outermost wrapper , initialize
5519
5535
// via the full wrapper.
5520
- if (customAttr ->getArg () != nullptr )
5536
+ if (customAttrs[ 0 ] ->getArg () != nullptr )
5521
5537
return false ;
5522
5538
5523
- // There is no initializer, so the initialization form depends on
5524
- // whether the property wrapper type has an init(initialValue:).
5525
- auto wrapperTypeInfo = getAttachedPropertyWrapperTypeInfo ();
5526
- return wrapperTypeInfo.initialValueInit != nullptr ;
5539
+ // If all property wrappers have an initialValue initializer, the property
5540
+ // wrapper will be initialized that way.
5541
+ return allAttachedPropertyWrappersHaveInitialValueInit ();
5527
5542
}
5528
5543
5529
5544
Identifier VarDecl::getObjCPropertyName () const {
@@ -5790,9 +5805,8 @@ void ParamDecl::setDefaultArgumentInitContext(Initializer *initContext) {
5790
5805
}
5791
5806
5792
5807
Expr *swift::findOriginalPropertyWrapperInitialValue (VarDecl *var,
5793
- Expr *init) {
5794
- auto attr = var->getAttachedPropertyWrapper ();
5795
- assert (attr && " No attached property wrapper?" );
5808
+ Expr *init) {
5809
+ auto attr = var->getAttachedPropertyWrappers ().front ();
5796
5810
5797
5811
// Direct initialization implies no original initial value.
5798
5812
if (attr->getArg ())
@@ -5846,7 +5860,9 @@ ParamDecl::getDefaultValueStringRepresentation(
5846
5860
auto var = getStoredProperty ();
5847
5861
5848
5862
if (auto original = var->getOriginalWrappedProperty ()) {
5849
- if (auto attr = original->getAttachedPropertyWrapper ()) {
5863
+ auto wrapperAttrs = original->getAttachedPropertyWrappers ();
5864
+ if (wrapperAttrs.size () > 0 ) {
5865
+ auto attr = wrapperAttrs.front ();
5850
5866
if (auto arg = attr->getArg ()) {
5851
5867
SourceRange fullRange (attr->getTypeLoc ().getSourceRange ().Start ,
5852
5868
arg->getEndLoc ());
0 commit comments