Skip to content

Commit b0d3234

Browse files
authored
Merge pull request #67806 from rintaro/ide-completion-fakeannotation-rdar109062582
[CodeCompletion] Add fake type annotation to custom attributes
2 parents 8b97d43 + fcaae5c commit b0d3234

4 files changed

+148
-66
lines changed

lib/IDE/CompletionLookup.cpp

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1669,6 +1669,27 @@ void CompletionLookup::addSubscriptCall(const SubscriptDecl *SD,
16691669
addTypeAnnotation(Builder, resultTy, SD->getGenericSignatureOfContext());
16701670
}
16711671

1672+
static StringRef getTypeAnnotationString(const NominalTypeDecl *NTD,
1673+
SmallVectorImpl<char> &stash) {
1674+
SmallVector<StringRef, 1> attrRoleStrs;
1675+
if (NTD->getAttrs().hasAttribute<PropertyWrapperAttr>())
1676+
attrRoleStrs.push_back("Property Wrapper");
1677+
if (NTD->getAttrs().hasAttribute<ResultBuilderAttr>())
1678+
attrRoleStrs.push_back("Result Builder");
1679+
if (NTD->isGlobalActor())
1680+
attrRoleStrs.push_back("Global Actor");
1681+
1682+
if (attrRoleStrs.empty())
1683+
return StringRef();
1684+
if (attrRoleStrs.size() == 1)
1685+
return attrRoleStrs[0];
1686+
1687+
assert(stash.empty());
1688+
llvm::raw_svector_ostream OS(stash);
1689+
llvm::interleave(attrRoleStrs, OS, ", ");
1690+
return {stash.data(), stash.size()};
1691+
}
1692+
16721693
void CompletionLookup::addNominalTypeRef(const NominalTypeDecl *NTD,
16731694
DeclVisibilityKind Reason,
16741695
DynamicLookupInfo dynamicLookupInfo) {
@@ -1679,7 +1700,14 @@ void CompletionLookup::addNominalTypeRef(const NominalTypeDecl *NTD,
16791700
addLeadingDot(Builder);
16801701
Builder.addBaseName(NTD->getName().str());
16811702

1682-
addTypeAnnotation(Builder, NTD->getDeclaredType());
1703+
// "Fake" annotation for custom attribute types.
1704+
SmallVector<char, 0> stash;
1705+
StringRef customAttributeAnnotation = getTypeAnnotationString(NTD, stash);
1706+
if (!customAttributeAnnotation.empty()) {
1707+
Builder.addTypeAnnotation(customAttributeAnnotation);
1708+
} else {
1709+
addTypeAnnotation(Builder, NTD->getDeclaredType());
1710+
}
16831711

16841712
// Override the type relation for NominalTypes. Use the better relation
16851713
// for the metatypes and the instance type. For example,
@@ -1790,6 +1818,56 @@ void CompletionLookup::addEnumElementRef(const EnumElementDecl *EED,
17901818
Builder.addFlair(CodeCompletionFlairBit::ExpressionSpecific);
17911819
}
17921820

1821+
static StringRef getTypeAnnotationString(const MacroDecl *MD,
1822+
SmallVectorImpl<char> &stash) {
1823+
auto roles = MD->getMacroRoles();
1824+
SmallVector<StringRef, 1> roleStrs;
1825+
for (auto role : getAllMacroRoles()) {
1826+
if (!roles.contains(role))
1827+
continue;
1828+
1829+
switch (role) {
1830+
case MacroRole::Accessor:
1831+
roleStrs.push_back("Accessor Macro");
1832+
break;
1833+
case MacroRole::CodeItem:
1834+
roleStrs.push_back("Code Item Macro");
1835+
break;
1836+
case MacroRole::Conformance:
1837+
roleStrs.push_back("Conformance Macro");
1838+
break;
1839+
case MacroRole::Declaration:
1840+
roleStrs.push_back("Declaration Macro");
1841+
break;
1842+
case MacroRole::Expression:
1843+
roleStrs.push_back("Expression Macro");
1844+
break;
1845+
case MacroRole::Extension:
1846+
roleStrs.push_back("Extension Macro");
1847+
break;
1848+
case MacroRole::Member:
1849+
roleStrs.push_back("Member Macro");
1850+
break;
1851+
case MacroRole::MemberAttribute:
1852+
roleStrs.push_back("Member Attribute Macro");
1853+
break;
1854+
case MacroRole::Peer:
1855+
roleStrs.push_back("Peer Macro");
1856+
break;
1857+
}
1858+
}
1859+
1860+
if (roleStrs.empty())
1861+
return "Macro";
1862+
if (roleStrs.size() == 1)
1863+
return roleStrs[0];
1864+
1865+
assert(stash.empty());
1866+
llvm::raw_svector_ostream OS(stash);
1867+
llvm::interleave(roleStrs, OS, ", ");
1868+
return {stash.data(), stash.size()};
1869+
}
1870+
17931871
void CompletionLookup::addMacroExpansion(const MacroDecl *MD,
17941872
DeclVisibilityKind Reason) {
17951873
if (!MD->hasName() || !MD->isAccessibleFrom(CurrDeclContext) ||
@@ -1822,9 +1900,13 @@ void CompletionLookup::addMacroExpansion(const MacroDecl *MD,
18221900
Builder.addRightParen();
18231901
}
18241902

1825-
if (!MD->getResultInterfaceType()->isVoid()) {
1903+
auto roles = MD->getMacroRoles();
1904+
if (roles.containsOnly(MacroRole::Expression)) {
18261905
addTypeAnnotation(Builder, MD->getResultInterfaceType(),
18271906
MD->getGenericSignature());
1907+
} else {
1908+
llvm::SmallVector<char, 0> stash;
1909+
Builder.addTypeAnnotation(getTypeAnnotationString(MD, stash));
18281910
}
18291911
}
18301912

test/IDE/complete_decl_attribute.swift

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,9 @@ actor MyGenericGlobalActor<T> {
111111
// KEYWORD2-NEXT: Keyword/None: backDeployed[#Func Attribute#]; name=backDeployed
112112
// KEYWORD2-NOT: Keyword
113113
// KEYWORD2-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
114-
// KEYWORD2-DAG: Decl[Struct]/CurrModule: MyPropertyWrapper[#MyPropertyWrapper#]; name=MyPropertyWrapper
115-
// KEYWORD2-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyResultBuilder[#MyResultBuilder#]; name=MyResultBuilder
116-
// KEYWORD2-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGlobalActor[#MyGlobalActor#]; name=MyGlobalActor
114+
// KEYWORD2-DAG: Decl[Struct]/CurrModule: MyPropertyWrapper[#Property Wrapper#]; name=MyPropertyWrapper
115+
// KEYWORD2-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyResultBuilder[#Result Builder#]; name=MyResultBuilder
116+
// KEYWORD2-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGlobalActor[#Global Actor#]; name=MyGlobalActor
117117

118118
@#^KEYWORD3^# class C {}
119119

@@ -183,12 +183,12 @@ actor MyGenericGlobalActor<T> {
183183
// ON_GLOBALVAR-DAG: Keyword/None: backDeployed[#Var Attribute#]; name=backDeployed
184184
// ON_GLOBALVAR-NOT: Keyword
185185
// ON_GLOBALVAR-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
186-
// ON_GLOBALVAR-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyPropertyWrapper[#MyPropertyWrapper#]; name=MyPropertyWrapper
187-
// ON_GLOBALVAR-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyGenericPropertyWrapper[#MyGenericPropertyWrapper#]; name=MyGenericPropertyWrapper
188-
// ON_GLOBALVAR-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyResultBuilder[#MyResultBuilder#]; name=MyResultBuilder
189-
// ON_GLOBALVAR-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyGenericResultBuilder[#MyGenericResultBuilder#]; name=MyGenericResultBuilder
190-
// ON_GLOBALVAR-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGlobalActor[#MyGlobalActor#]; name=MyGlobalActor
191-
// ON_GLOBALVAR-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGenericGlobalActor[#MyGenericGlobalActor#]; name=MyGenericGlobalActor
186+
// ON_GLOBALVAR-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyPropertyWrapper[#Property Wrapper#]; name=MyPropertyWrapper
187+
// ON_GLOBALVAR-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyGenericPropertyWrapper[#Property Wrapper#]; name=MyGenericPropertyWrapper
188+
// ON_GLOBALVAR-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyResultBuilder[#Result Builder#]; name=MyResultBuilder
189+
// ON_GLOBALVAR-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyGenericResultBuilder[#Result Builder#]; name=MyGenericResultBuilder
190+
// ON_GLOBALVAR-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGlobalActor[#Global Actor#]; name=MyGlobalActor
191+
// ON_GLOBALVAR-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGenericGlobalActor[#Global Actor#]; name=MyGenericGlobalActor
192192

193193
struct _S {
194194
@#^ON_INIT^# init()
@@ -220,12 +220,12 @@ struct _S {
220220
// ON_PROPERTY-DAG: Keyword/None: backDeployed[#Var Attribute#]; name=backDeployed
221221
// ON_PROPERTY-NOT: Keyword
222222
// ON_PROPERTY-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
223-
// ON_PROPERTY-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyPropertyWrapper[#MyPropertyWrapper#]; name=MyPropertyWrapper
224-
// ON_PROPERTY-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyGenericPropertyWrapper[#MyGenericPropertyWrapper#]; name=MyGenericPropertyWrapper
225-
// ON_PROPERTY-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyResultBuilder[#MyResultBuilder#]; name=MyResultBuilder
226-
// ON_PROPERTY-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyGenericResultBuilder[#MyGenericResultBuilder#]; name=MyGenericResultBuilder
227-
// ON_PROPERTY-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGlobalActor[#MyGlobalActor#]; name=MyGlobalActor
228-
// ON_PROPERTY-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGenericGlobalActor[#MyGenericGlobalActor#]; name=MyGenericGlobalActor
223+
// ON_PROPERTY-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyPropertyWrapper[#Property Wrapper#]; name=MyPropertyWrapper
224+
// ON_PROPERTY-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyGenericPropertyWrapper[#Property Wrapper#]; name=MyGenericPropertyWrapper
225+
// ON_PROPERTY-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyResultBuilder[#Result Builder#]; name=MyResultBuilder
226+
// ON_PROPERTY-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyGenericResultBuilder[#Result Builder#]; name=MyGenericResultBuilder
227+
// ON_PROPERTY-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGlobalActor[#Global Actor#]; name=MyGlobalActor
228+
// ON_PROPERTY-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGenericGlobalActor[#Global Actor#]; name=MyGenericGlobalActor
229229
// ON_PROPERTY-NOT: Decl[PrecedenceGroup]
230230

231231
@#^ON_METHOD^# private
@@ -250,21 +250,21 @@ struct _S {
250250
// ON_METHOD-DAG: Keyword/None: backDeployed[#Func Attribute#]; name=backDeployed
251251
// ON_METHOD-NOT: Keyword
252252
// ON_METHOD-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
253-
// ON_METHOD-DAG: Decl[Struct]/CurrModule: MyPropertyWrapper[#MyPropertyWrapper#]; name=MyPropertyWrapper
254-
// ON_METHOD-DAG: Decl[Struct]/CurrModule: MyGenericPropertyWrapper[#MyGenericPropertyWrapper#]; name=MyGenericPropertyWrapper
255-
// ON_METHOD-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyResultBuilder[#MyResultBuilder#]; name=MyResultBuilder
256-
// ON_METHOD-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyGenericResultBuilder[#MyGenericResultBuilder#]; name=MyGenericResultBuilder
257-
// ON_METHOD-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGlobalActor[#MyGlobalActor#]; name=MyGlobalActor
258-
// ON_METHOD-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGenericGlobalActor[#MyGenericGlobalActor#]; name=MyGenericGlobalActor
253+
// ON_METHOD-DAG: Decl[Struct]/CurrModule: MyPropertyWrapper[#Property Wrapper#]; name=MyPropertyWrapper
254+
// ON_METHOD-DAG: Decl[Struct]/CurrModule: MyGenericPropertyWrapper[#Property Wrapper#]; name=MyGenericPropertyWrapper
255+
// ON_METHOD-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyResultBuilder[#Result Builder#]; name=MyResultBuilder
256+
// ON_METHOD-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyGenericResultBuilder[#Result Builder#]; name=MyGenericResultBuilder
257+
// ON_METHOD-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGlobalActor[#Global Actor#]; name=MyGlobalActor
258+
// ON_METHOD-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGenericGlobalActor[#Global Actor#]; name=MyGenericGlobalActor
259259

260260

261261

262262
func bar(@#^ON_PARAM_1^#)
263263
// ON_PARAM-NOT: Keyword
264264
// ON_PARAM-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
265-
// ON_PARAM-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyPropertyWrapper[#MyPropertyWrapper#]; name=MyPropertyWrapper
266-
// ON_PARAM-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyResultBuilder[#MyResultBuilder#]; name=MyResultBuilder
267-
// ON_PARAM-DAG: Decl[Actor]/CurrModule: MyGlobalActor[#MyGlobalActor#]; name=MyGlobalActor
265+
// ON_PARAM-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyPropertyWrapper[#Property Wrapper#]; name=MyPropertyWrapper
266+
// ON_PARAM-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyResultBuilder[#Result Builder#]; name=MyResultBuilder
267+
// ON_PARAM-DAG: Decl[Actor]/CurrModule: MyGlobalActor[#Global Actor#]; name=MyGlobalActor
268268
// ON_PARAM-NOT: Keyword
269269

270270
func bar(
@@ -323,12 +323,12 @@ struct _S {
323323
// ON_MEMBER_LAST-DAG: Keyword/None: storageRestrictions[#Declaration Attribute#]; name=storageRestrictions
324324
// ON_MEMBER_LAST-NOT: Keyword
325325
// ON_MEMBER_LAST-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
326-
// ON_MEMBER_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyPropertyWrapper[#MyPropertyWrapper#]; name=MyPropertyWrapper
327-
// ON_MEMBER_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyGenericPropertyWrapper[#MyGenericPropertyWrapper#]; name=MyGenericPropertyWrapper
328-
// ON_MEMBER_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyResultBuilder[#MyResultBuilder#]; name=MyResultBuilder
329-
// ON_MEMBER_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyGenericResultBuilder[#MyGenericResultBuilder#]; name=MyGenericResultBuilder
330-
// ON_MEMBER_LAST-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGlobalActor[#MyGlobalActor#]; name=MyGlobalActor
331-
// ON_MEMBER_LAST-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGenericGlobalActor[#MyGenericGlobalActor#]; name=MyGenericGlobalActor
326+
// ON_MEMBER_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyPropertyWrapper[#Property Wrapper#]; name=MyPropertyWrapper
327+
// ON_MEMBER_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyGenericPropertyWrapper[#Property Wrapper#]; name=MyGenericPropertyWrapper
328+
// ON_MEMBER_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyResultBuilder[#Result Builder#]; name=MyResultBuilder
329+
// ON_MEMBER_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyGenericResultBuilder[#Result Builder#]; name=MyGenericResultBuilder
330+
// ON_MEMBER_LAST-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGlobalActor[#Global Actor#]; name=MyGlobalActor
331+
// ON_MEMBER_LAST-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGenericGlobalActor[#Global Actor#]; name=MyGenericGlobalActor
332332
// ON_MEMBER_LAST-NOT: Decl[PrecedenceGroup]
333333
}
334334

@@ -339,9 +339,9 @@ func takeClosure(_: () -> Void) {
339339
}
340340
// FIXME: We should mark MyPropertyWrapper and MyResultBuilder as Unrelated
341341
// IN_CLOSURE-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
342-
// IN_CLOSURE-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyPropertyWrapper[#MyPropertyWrapper#]; name=MyPropertyWrapper
343-
// IN_CLOSURE-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyResultBuilder[#MyResultBuilder#]; name=MyResultBuilder
344-
// IN_CLOSURE-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGlobalActor[#MyGlobalActor#]; name=MyGlobalActor
342+
// IN_CLOSURE-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyPropertyWrapper[#Property Wrapper#]; name=MyPropertyWrapper
343+
// IN_CLOSURE-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyResultBuilder[#Result Builder#]; name=MyResultBuilder
344+
// IN_CLOSURE-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGlobalActor[#Global Actor#]; name=MyGlobalActor
345345

346346

347347
@#^KEYWORD_INDEPENDENT_1^#
@@ -394,9 +394,9 @@ func dummy2() {}
394394
// KEYWORD_LAST-DAG: Keyword/None: storageRestrictions[#Declaration Attribute#]; name=storageRestrictions
395395
// KEYWORD_LAST-NOT: Keyword
396396
// KEYWORD_LAST-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
397-
// KEYWORD_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyGenericPropertyWrapper[#MyGenericPropertyWrapper#]; name=MyGenericPropertyWrapper
398-
// KEYWORD_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyPropertyWrapper[#MyPropertyWrapper#]; name=MyPropertyWrapper
399-
// KEYWORD_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyGenericResultBuilder[#MyGenericResultBuilder#]; name=MyGenericResultBuilder
400-
// KEYWORD_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyResultBuilder[#MyResultBuilder#]; name=MyResultBuilder
401-
// KEYWORD_LAST-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGenericGlobalActor[#MyGenericGlobalActor#]; name=MyGenericGlobalActor
402-
// KEYWORD_LAST-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGlobalActor[#MyGlobalActor#]; name=MyGlobalActor
397+
// KEYWORD_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyGenericPropertyWrapper[#Property Wrapper#]; name=MyGenericPropertyWrapper
398+
// KEYWORD_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyPropertyWrapper[#Property Wrapper#]; name=MyPropertyWrapper
399+
// KEYWORD_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyGenericResultBuilder[#Result Builder#]; name=MyGenericResultBuilder
400+
// KEYWORD_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyResultBuilder[#Result Builder#]; name=MyResultBuilder
401+
// KEYWORD_LAST-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGenericGlobalActor[#Global Actor#]; name=MyGenericGlobalActor
402+
// KEYWORD_LAST-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGlobalActor[#Global Actor#]; name=MyGlobalActor

0 commit comments

Comments
 (0)