|
26 | 26 |
|
27 | 27 | using namespace swift; |
28 | 28 |
|
| 29 | +/// Check whether given declaration comes from the .swiftinterface file. |
| 30 | +static bool inSwiftInterfaceContext(NominalTypeDecl *typeDecl) { |
| 31 | + auto *SF = typeDecl->getDeclContext()->getParentSourceFile(); |
| 32 | + return SF && SF->Kind == SourceFileKind::Interface; |
| 33 | +} |
| 34 | + |
| 35 | +static ValueDecl *findMember(NominalTypeDecl *typeDecl, Identifier memberName) { |
| 36 | + auto members = typeDecl->lookupDirect(memberName); |
| 37 | + return members.size() == 1 ? members.front() : nullptr; |
| 38 | +} |
| 39 | + |
29 | 40 | static PatternBindingDecl *injectVariable(DeclContext *DC, Identifier name, |
30 | 41 | Type type, |
31 | 42 | VarDecl::Introducer introducer, |
@@ -119,9 +130,19 @@ static void getTypeWrappers(NominalTypeDecl *decl, |
119 | 130 | continue; |
120 | 131 |
|
121 | 132 | auto *typeWrapper = nominal->getAttrs().getAttribute<TypeWrapperAttr>(); |
122 | | - if (typeWrapper && typeWrapper->isValid()) |
| 133 | + if (typeWrapper && typeWrapper->isValid()) { |
| 134 | + auto attrType = evaluateOrDefault( |
| 135 | + ctx.evaluator, |
| 136 | + CustomAttrTypeRequest{mutableAttr, decl, |
| 137 | + CustomAttrTypeKind::TypeWrapper}, |
| 138 | + Type()); |
| 139 | + |
| 140 | + if (!attrType || attrType->hasError()) |
| 141 | + continue; |
| 142 | + |
123 | 143 | typeWrappers.push_back( |
124 | | - {mutableAttr, nominal, decl, /*isInferred=*/false}); |
| 144 | + {mutableAttr, attrType, nominal, decl, /*isInferred=*/false}); |
| 145 | + } |
125 | 146 | } |
126 | 147 |
|
127 | 148 | // Do not allow transitive protocol inference between protocols. |
@@ -184,24 +205,6 @@ GetTypeWrapper::evaluate(Evaluator &evaluator, NominalTypeDecl *decl) const { |
184 | 205 | return typeWrappers.front(); |
185 | 206 | } |
186 | 207 |
|
187 | | -Type GetTypeWrapperType::evaluate(Evaluator &evaluator, |
188 | | - NominalTypeDecl *decl) const { |
189 | | - auto typeWrapperInfo = decl->getTypeWrapper(); |
190 | | - if (!typeWrapperInfo) |
191 | | - return Type(); |
192 | | - |
193 | | - auto type = evaluateOrDefault( |
194 | | - evaluator, |
195 | | - CustomAttrTypeRequest{typeWrapperInfo->Attr, decl->getDeclContext(), |
196 | | - CustomAttrTypeKind::TypeWrapper}, |
197 | | - Type()); |
198 | | - |
199 | | - if (!type || type->hasError()) { |
200 | | - return ErrorType::get(decl->getASTContext()); |
201 | | - } |
202 | | - return type; |
203 | | -} |
204 | | - |
205 | 208 | VarDecl *NominalTypeDecl::getTypeWrapperProperty() const { |
206 | 209 | auto *mutableSelf = const_cast<NominalTypeDecl *>(this); |
207 | 210 | return evaluateOrDefault(getASTContext().evaluator, |
@@ -284,6 +287,15 @@ TypeDecl *GetTypeWrapperStorage::evaluate(Evaluator &evaluator, |
284 | 287 |
|
285 | 288 | auto &ctx = parent->getASTContext(); |
286 | 289 |
|
| 290 | + // .swiftinterfaces have both attribute and a synthesized member |
| 291 | + // (if it's public), so in this case we need use existing declaration |
| 292 | + // if available. |
| 293 | + if (inSwiftInterfaceContext(parent)) { |
| 294 | + if (auto *storage = dyn_cast_or_null<TypeDecl>( |
| 295 | + findMember(parent, ctx.Id_TypeWrapperStorage))) |
| 296 | + return storage; |
| 297 | + } |
| 298 | + |
287 | 299 | TypeDecl *storage = nullptr; |
288 | 300 | if (isa<ProtocolDecl>(parent)) { |
289 | 301 | // If type wrapper is associated with a protocol, we need to |
@@ -320,13 +332,19 @@ GetTypeWrapperProperty::evaluate(Evaluator &evaluator, |
320 | 332 | if (!typeWrapper) |
321 | 333 | return nullptr; |
322 | 334 |
|
| 335 | + // .swiftinterfaces have both attribute and a synthesized member |
| 336 | + // (if it's public), so in this case we need use existing declaration |
| 337 | + // if available. |
| 338 | + if (inSwiftInterfaceContext(parent)) { |
| 339 | + if (auto *storage = dyn_cast_or_null<VarDecl>( |
| 340 | + findMember(parent, ctx.Id_TypeWrapperProperty))) |
| 341 | + return storage; |
| 342 | + } |
| 343 | + |
323 | 344 | auto *storage = parent->getTypeWrapperStorageDecl(); |
324 | 345 | assert(storage); |
325 | 346 |
|
326 | | - auto *typeWrapperType = |
327 | | - evaluateOrDefault(ctx.evaluator, GetTypeWrapperType{parent}, Type()) |
328 | | - ->castTo<AnyGenericType>(); |
329 | | - assert(typeWrapperType); |
| 347 | + auto *typeWrapperType = typeWrapper->AttrType->castTo<AnyGenericType>(); |
330 | 348 |
|
331 | 349 | // $storage: Wrapper<<ParentType>, <ParentType>.$Storage> |
332 | 350 | auto propertyTy = BoundGenericType::get( |
|
0 commit comments