@@ -22,11 +22,32 @@ using namespace swift;
2222using namespace ide ;
2323using TypeRelation = CodeCompletionResultTypeRelation;
2424
25+ // MARK: - Utilities
26+
27+ // / Returns the kind of attributes \c Ty can be used as.
28+ static OptionSet<CustomAttributeKind> getCustomAttributeKinds (Type Ty) {
29+ OptionSet<CustomAttributeKind> Result;
30+ if (auto NominalTy = Ty->getAs <NominalType>()) {
31+ auto NominalDecl = NominalTy->getDecl ();
32+ if (NominalDecl->getAttrs ().hasAttribute <PropertyWrapperAttr>()) {
33+ Result |= CustomAttributeKind::PropertyWrapper;
34+ }
35+ if (NominalDecl->getAttrs ().hasAttribute <ResultBuilderAttr>()) {
36+ Result |= CustomAttributeKind::ResultBuilder;
37+ }
38+ if (NominalDecl->isGlobalActor ()) {
39+ Result |= CustomAttributeKind::GlobalActor;
40+ }
41+ }
42+ return Result;
43+ }
44+
2545// MARK: - USRBasedTypeContext
2646
2747USRBasedTypeContext::USRBasedTypeContext (const ExpectedTypeContext *TypeContext,
2848 USRBasedTypeArena &Arena)
29- : Arena(Arena) {
49+ : Arena(Arena), ExpectedCustomAttributeKinds(
50+ TypeContext->getExpectedCustomAttributeKinds ()) {
3051
3152 for (auto possibleTy : TypeContext->getPossibleTypes ()) {
3253 ContextualTypes.emplace_back (USRBasedType::fromType (possibleTy, Arena));
@@ -63,6 +84,11 @@ USRBasedTypeContext::USRBasedTypeContext(const ExpectedTypeContext *TypeContext,
6384
6485TypeRelation
6586USRBasedTypeContext::typeRelation (const USRBasedType *ResultType) const {
87+ if (ExpectedCustomAttributeKinds) {
88+ return ResultType->getCustomAttributeKinds () & ExpectedCustomAttributeKinds
89+ ? TypeRelation::Convertible
90+ : TypeRelation::Unrelated;
91+ }
6692 const USRBasedType *VoidType = Arena.getVoidType ();
6793 if (ResultType == VoidType) {
6894 // Void is not convertible to anything and we don't report Void <-> Void
@@ -85,7 +111,7 @@ USRBasedTypeContext::typeRelation(const USRBasedType *ResultType) const {
85111
86112USRBasedTypeArena::USRBasedTypeArena () {
87113 // '$sytD' is the USR of the Void type.
88- VoidType = USRBasedType::fromUSR (" $sytD" , {}, *this );
114+ VoidType = USRBasedType::fromUSR (" $sytD" , {}, {}, *this );
89115}
90116
91117const USRBasedType *USRBasedTypeArena::getVoidType () const { return VoidType; }
@@ -125,11 +151,12 @@ TypeRelation USRBasedType::typeRelationImpl(
125151}
126152
127153const USRBasedType *USRBasedType::null (USRBasedTypeArena &Arena) {
128- return USRBasedType::fromUSR (/* USR=*/ " " , /* Supertypes=*/ {}, Arena);
154+ return USRBasedType::fromUSR (/* USR=*/ " " , /* Supertypes=*/ {}, {}, Arena);
129155}
130156
131157const USRBasedType *
132158USRBasedType::fromUSR (StringRef USR, ArrayRef<const USRBasedType *> Supertypes,
159+ OptionSet<CustomAttributeKind> CustomAttributeKinds,
133160 USRBasedTypeArena &Arena) {
134161 auto ExistingTypeIt = Arena.CanonicalTypes .find (USR);
135162 if (ExistingTypeIt != Arena.CanonicalTypes .end ()) {
@@ -142,7 +169,7 @@ USRBasedType::fromUSR(StringRef USR, ArrayRef<const USRBasedType *> Supertypes,
142169 Supertypes = Supertypes.copy (Arena.Allocator );
143170
144171 const USRBasedType *Result =
145- new (Arena.Allocator ) USRBasedType (USR, Supertypes);
172+ new (Arena.Allocator ) USRBasedType (USR, Supertypes, CustomAttributeKinds );
146173 Arena.CanonicalTypes [USR] = Result;
147174 return Result;
148175}
@@ -223,7 +250,8 @@ const USRBasedType *USRBasedType::fromType(Type Ty, USRBasedTypeArena &Arena) {
223250 return ImpliedSupertypes.contains (Ty);
224251 });
225252
226- return USRBasedType::fromUSR (USR, Supertypes, Arena);
253+ return USRBasedType::fromUSR (USR, Supertypes, ::getCustomAttributeKinds (Ty),
254+ Arena);
227255}
228256
229257TypeRelation USRBasedType::typeRelation (const USRBasedType *ResultType,
@@ -281,6 +309,12 @@ calculateMaxTypeRelation(Type Ty, const ExpectedTypeContext &typeContext,
281309 const DeclContext &DC) {
282310 if (Ty->isVoid () && typeContext.requiresNonVoid ())
283311 return TypeRelation::Invalid;
312+ if (typeContext.getExpectedCustomAttributeKinds ()) {
313+ return (getCustomAttributeKinds (Ty) &
314+ typeContext.getExpectedCustomAttributeKinds ())
315+ ? TypeRelation::Convertible
316+ : TypeRelation::Unrelated;
317+ }
284318 if (typeContext.empty ())
285319 return TypeRelation::Unknown;
286320
0 commit comments