Skip to content

Commit 907bb90

Browse files
authored
Merge pull request #74906 from hamishknight/body-attr-6.0
[6.0] [Completion] Handle body macro attribute completion
2 parents 8a2173c + d562dcf commit 907bb90

File tree

6 files changed

+91
-46
lines changed

6 files changed

+91
-46
lines changed

include/swift/AST/Decl.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7821,9 +7821,14 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
78217821
/// declaration, given that it is @objc and 'async'.
78227822
std::optional<ForeignAsyncConvention> getForeignAsyncConvention() const;
78237823

7824+
/// Whether the given DeclKind is for an AbstractFunctionDecl.
7825+
static bool isKind(DeclKind kind) {
7826+
return kind >= DeclKind::First_AbstractFunctionDecl &&
7827+
kind <= DeclKind::Last_AbstractFunctionDecl;
7828+
}
7829+
78247830
static bool classof(const Decl *D) {
7825-
return D->getKind() >= DeclKind::First_AbstractFunctionDecl &&
7826-
D->getKind() <= DeclKind::Last_AbstractFunctionDecl;
7831+
return isKind(D->getKind());
78277832
}
78287833

78297834
static bool classof(const DeclContext *DC) {

include/swift/IDE/CodeCompletionResult.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ enum class CodeCompletionMacroRole : uint8_t {
323323
AttachedVar = 1 << 3,
324324
AttachedContext = 1 << 4,
325325
AttachedDecl = 1 << 5,
326+
AttachedFunction = 1 << 6,
326327
};
327328
using CodeCompletionMacroRoles = OptionSet<CodeCompletionMacroRole>;
328329

@@ -337,6 +338,7 @@ enum class CodeCompletionFilterFlag : uint16_t {
337338
AttachedVarMacro = 1 << 7,
338339
AttachedContextMacro = 1 << 8,
339340
AttachedDeclMacro = 1 << 9,
341+
AttachedFunctionMacro = 1 << 10,
340342
};
341343
using CodeCompletionFilter = OptionSet<CodeCompletionFilterFlag>;
342344

include/swift/IDE/CodeCompletionResultType.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ enum class CustomAttributeKind : uint8_t {
3434
ContextMacro = 1 << 4,
3535
/// A macro that can be used on any declaration.
3636
DeclMacro = 1 << 5,
37+
/// A macro that can by used on any function.
38+
FunctionMacro = 1 << 6,
3739
};
3840

3941
/// The expected contextual type(s) for code-completion.

lib/IDE/CodeCompletion.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1843,6 +1843,8 @@ void CodeCompletionCallbacksImpl::doneParsing(SourceFile *SrcFile) {
18431843
if (*AttTargetDK != DeclKind::Param) {
18441844
ExpectedCustomAttributeKinds |= CustomAttributeKind::DeclMacro;
18451845
}
1846+
if (AbstractFunctionDecl::isKind(*AttTargetDK))
1847+
ExpectedCustomAttributeKinds |= CustomAttributeKind::FunctionMacro;
18461848
} else {
18471849
// If we don't know on which decl kind we are completing, suggest all
18481850
// attribute kinds.
@@ -1852,6 +1854,7 @@ void CodeCompletionCallbacksImpl::doneParsing(SourceFile *SrcFile) {
18521854
ExpectedCustomAttributeKinds |= CustomAttributeKind::VarMacro;
18531855
ExpectedCustomAttributeKinds |= CustomAttributeKind::ContextMacro;
18541856
ExpectedCustomAttributeKinds |= CustomAttributeKind::DeclMacro;
1857+
ExpectedCustomAttributeKinds |= CustomAttributeKind::FunctionMacro;
18551858
}
18561859

18571860
Lookup.setExpectedTypes(/*Types=*/{}, /*isImpliedResult=*/false,

lib/IDE/CodeCompletionResult.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ CodeCompletionMacroRoles swift::ide::getCompletionMacroRoles(const Decl *D) {
4848
if (macroRoles.contains(MacroRole::Peer)) {
4949
roles |= CodeCompletionMacroRole::AttachedDecl;
5050
}
51+
if (macroRoles.contains(MacroRole::Body) ||
52+
macroRoles.contains(MacroRole::Preamble)) {
53+
roles |= CodeCompletionMacroRole::AttachedFunction;
54+
}
5155

5256
return roles;
5357
}
@@ -64,6 +68,9 @@ swift::ide::getCompletionMacroRoles(OptionSet<CustomAttributeKind> kinds) {
6468
if (kinds.contains(CustomAttributeKind::DeclMacro)) {
6569
roles |= CodeCompletionMacroRole::AttachedDecl;
6670
}
71+
if (kinds.contains(CustomAttributeKind::FunctionMacro)) {
72+
roles |= CodeCompletionMacroRole::AttachedFunction;
73+
}
6774
return roles;
6875
}
6976

@@ -88,6 +95,9 @@ swift::ide::getCompletionMacroRoles(CodeCompletionFilter filter) {
8895
if (filter.contains(CodeCompletionFilterFlag::AttachedDeclMacro)) {
8996
roles |= CodeCompletionMacroRole::AttachedDecl;
9097
}
98+
if (filter.contains(CodeCompletionFilterFlag::AttachedFunctionMacro)) {
99+
roles |= CodeCompletionMacroRole::AttachedFunction;
100+
}
91101
return roles;
92102
}
93103

@@ -112,6 +122,9 @@ swift::ide::getCompletionFilter(CodeCompletionMacroRoles roles) {
112122
if (roles.contains(CodeCompletionMacroRole::AttachedDecl)) {
113123
filter |= CodeCompletionFilterFlag::AttachedDeclMacro;
114124
}
125+
if (roles.contains(CodeCompletionMacroRole::AttachedFunction)) {
126+
filter |= CodeCompletionFilterFlag::AttachedFunctionMacro;
127+
}
115128
return filter;
116129
}
117130

test/IDE/complete_macros.swift

Lines changed: 64 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ public macro AttachedPeerMacro()
5555
@attached(extension)
5656
public macro AttachedConformanceMacro()
5757

58+
@attached(body)
59+
public macro BodyMacro()
60+
5861
@freestanding(expression)
5962
@freestanding(declaration)
6063
@attached(accessor)
@@ -69,59 +72,68 @@ public macro EverythingMacro()
6972
import MacroDefinitions
7073
#endif
7174

72-
@#^CLASS_ATTR?check=NOMINAL_ATTR^# class C {}
73-
@#^EXTRA_FILTER?check=NOMINAL_ATTR^#IB class C2 {}
74-
@#^ENUM_ATTR?check=NOMINAL_ATTR^# enum E {}
75-
@#^STRUCT_ATTR?check=NOMINAL_ATTR^# struct S{}
76-
// NOMINAL_ATTR-NOT: freestanding
77-
// NOMINAL_ATTR-NOT: AttachedAccessorMacro
75+
@#^CLASS_ATTR?check=NOMINAL_ATTR;check=NOMINAL_ATTR_NOT^# class C {}
76+
@#^EXTRA_FILTER?check=NOMINAL_ATTR;check=NOMINAL_ATTR_NOT^#IB class C2 {}
77+
@#^ENUM_ATTR?check=NOMINAL_ATTR;check=NOMINAL_ATTR_NOT^# enum E {}
78+
@#^STRUCT_ATTR?check=NOMINAL_ATTR;check=NOMINAL_ATTR_NOT^# struct S{}
7879
// NOMINAL_ATTR-DAG: Decl[Macro]/{{.*}}/TypeRelation[Convertible]: AttachedMemberMacro[#Member Macro#]; name=AttachedMemberMacro
7980
// NOMINAL_ATTR-DAG: Decl[Macro]/{{.*}}/TypeRelation[Convertible]: AttachedMemberMacroWithArgs({#arg1: Int#})[#Member Macro#]; name=AttachedMemberMacroWithArgs
8081
// NOMINAL_ATTR-DAG: Decl[Macro]/{{.*}}/TypeRelation[Convertible]: AttachedMemberAttributeMacro[#Member Attribute Macro#]; name=AttachedMemberAttributeMacro
8182
// NOMINAL_ATTR-DAG: Decl[Macro]/{{.*}}/TypeRelation[Convertible]: AttachedPeerMacro[#Peer Macro#]; name=AttachedPeerMacro
8283
// NOMINAL_ATTR-DAG: Decl[Macro]/{{.*}}/TypeRelation[Convertible]: AttachedConformanceMacro[#Extension Macro#]; name=AttachedConformanceMacro
8384
// NOMINAL_ATTR-DAG: Decl[Macro]/{{.*}}/TypeRelation[Convertible]: EverythingMacro[#Expression Macro, Declaration Macro, Accessor Macro, Member Attribute Macro, Member Macro, Peer Macro, Extension Macro#]; name=EverythingMacro
85+
//
86+
// NOMINAL_ATTR_NOT-NOT: freestanding
87+
// NOMINAL_ATTR_NOT-NOT: AttachedAccessorMacro
88+
// NOMINAL_ATTR_NOT-NOT: BodyMacro
8489

85-
@#^FUNC_ATTR?check=DECL_ATTR^# func method() {}
90+
@#^FUNC_ATTR?check=FUNC_ATTR;check=FUNC_ATTR_NOT^# func method() {}
8691
struct MethodAttrs {
87-
@#^INIT_ATTR?check=DECL_ATTR^# init() {}
88-
@#^DEINIT_ATTR?check=DECL_ATTR^# deinit{}
89-
@#^METHOD_ATTR?check=DECL_ATTR^# func method() {}
92+
var x: Int {
93+
@#^ACCESSOR_ATTR?check=FUNC_ATTR;check=FUNC_ATTR_NOT^# get { 0 }
94+
}
95+
@#^INIT_ATTR?check=FUNC_ATTR;check=FUNC_ATTR_NOT^# init() {}
96+
@#^DEINIT_ATTR?check=FUNC_ATTR;check=FUNC_ATTR_NOT^# deinit{}
97+
@#^METHOD_ATTR?check=FUNC_ATTR;check=FUNC_ATTR_NOT^# func method() {}
9098
}
91-
// DECL_ATTR-NOT: freestanding
92-
// DECL_ATTR-NOT: AttachedAccessorMacro
93-
// DECL_ATTR-NOT: AttachedMemberMacro
94-
// DECL_ATTR-NOT: AttachedMemberMacroWithArgs
95-
// DECL_ATTR-NOT: AttachedConformanceMacro
96-
// DECL_ATTR-DAG: Decl[Macro]/{{.*}}/TypeRelation[Convertible]: AttachedPeerMacro[#Peer Macro#]; name=AttachedPeerMacro
97-
// DECL_ATTR-DAG: Decl[Macro]/{{.*}}/TypeRelation[Convertible]: EverythingMacro[#Expression Macro, Declaration Macro, Accessor Macro, Member Attribute Macro, Member Macro, Peer Macro, Extension Macro#]; name=EverythingMacro
98-
99-
@#^GLOBAL_ATTR?check=VAR_ATTR^# var globalVar
99+
// FUNC_ATTR-DAG: Decl[Macro]/{{.*}}/TypeRelation[Convertible]: AttachedPeerMacro[#Peer Macro#]; name=AttachedPeerMacro
100+
// FUNC_ATTR-DAG: Decl[Macro]/{{.*}}/TypeRelation[Convertible]: BodyMacro[#Body Macro#]; name=BodyMacro
101+
// FUNC_ATTR-DAG: Decl[Macro]/{{.*}}/TypeRelation[Convertible]: EverythingMacro[#Expression Macro, Declaration Macro, Accessor Macro, Member Attribute Macro, Member Macro, Peer Macro, Extension Macro#]; name=EverythingMacro
102+
//
103+
// FUNC_ATTR_NOT-NOT: freestanding
104+
// FUNC_ATTR_NOT-NOT: AttachedAccessorMacro
105+
// FUNC_ATTR_NOT-NOT: AttachedMemberMacro
106+
// FUNC_ATTR_NOT-NOT: AttachedMemberMacroWithArgs
107+
// FUNC_ATTR_NOT-NOT: AttachedConformanceMacro
108+
109+
@#^GLOBAL_ATTR?check=VAR_ATTR;check=VAR_ATTR_NOT^# var globalVar
100110
struct PropAttr {
101-
@#^PROP_ATTR?check=VAR_ATTR^# var propVar
111+
@#^PROP_ATTR?check=VAR_ATTR;check=VAR_ATTR_NOT^# var propVar
102112
func localAttr() {
103-
@#^LOCAL_ATTR?check=VAR_ATTR^# var localVar
113+
@#^LOCAL_ATTR?check=VAR_ATTR;check=VAR_ATTR_NOT^# var localVar
104114
}
105115
}
106-
// VAR_ATTR-NOT: freestanding
107-
// VAR_ATTR-NOT: AttachedMemberMacro
108-
// VAR_ATTR-NOT: AttachedMemberMacroWithArgs
109-
// VAR_ATTR-NOT: AttachedMemberAttributeMacro
110-
// VAR_ATTR-NOT: AttachedConformanceMacro
111116
// VAR_ATTR-DAG: Decl[Macro]/{{.*}}/TypeRelation[Convertible]: AttachedAccessorMacro[#Accessor Macro#]; name=AttachedAccessorMacro
112117
// VAR_ATTR-DAG: Decl[Macro]/{{.*}}/TypeRelation[Convertible]: AttachedPeerMacro[#Peer Macro#]; name=AttachedPeerMacro
113118
// VAR_ATTR-DAG: Decl[Macro]/{{.*}}/TypeRelation[Convertible]: EverythingMacro[#Expression Macro, Declaration Macro, Accessor Macro, Member Attribute Macro, Member Macro, Peer Macro, Extension Macro#]; name=EverythingMacro
119+
//
120+
// VAR_ATTR_NOT-NOT: freestanding
121+
// VAR_ATTR_NOT-NOT: AttachedMemberMacro
122+
// VAR_ATTR_NOT-NOT: AttachedMemberMacroWithArgs
123+
// VAR_ATTR_NOT-NOT: AttachedMemberAttributeMacro
124+
// VAR_ATTR_NOT-NOT: AttachedConformanceMacro
125+
// VAR_ATTR_NOT-NOT: BodyMacro
114126

115127
func paramAttr(@#^PARAM_ATTR?check=PARAM_ATTR^#) {}
116128
func paramAttr2(@#^PARAM2_ATTR?check=PARAM_ATTR^# arg: Int) {}
117129
// TODO: These should both be PARAM_ATTR
118130
func takeNoArgClosure(_: (Int) -> Void) {
119-
takeClosure { @#^NO_ARG_CLOSURE_ATTR?check=INDEPENDENT_ATTR^# in
131+
takeClosure { @#^NO_ARG_CLOSURE_ATTR?check=INDEPENDENT_ATTR;check=INDEPENDENT_ATTR_NOT^# in
120132
print("x")
121133
}
122134
}
123135
func takeNoArgClosure(_: () -> Void) {
124-
takeClosure { @#^CLOSURE_ATTR?check=INDEPENDENT_ATTR^# in
136+
takeClosure { @#^CLOSURE_ATTR?check=INDEPENDENT_ATTR;check=INDEPENDENT_ATTR_NOT^# in
125137
print("x")
126138
}
127139
}
@@ -132,41 +144,47 @@ func takeNoArgClosure(_: () -> Void) {
132144
// PARAM_ATTR-NOT: AttachedMemberAttributeMacro
133145
// PARAM_ATTR-NOT: AttachedPeerMacro
134146
// PARAM_ATTR-NOT: AttachedConformanceMacro
147+
// PARAM_ATTR-NOT: BodyMacro
135148
// PARAM_ATTR-NOT: EverythingMacro
136149

137-
##^TOP_LEVEL_FREESTANDING?check=ALL_FREESTANDING^#
150+
##^TOP_LEVEL_FREESTANDING?check=ALL_FREESTANDING;check=ALL_FREESTANDING_NOT^#
138151
func nestedFreestanding() {
139-
##^TOP_NESTED_FREESTANDING?check=ALL_FREESTANDING^#
152+
##^TOP_NESTED_FREESTANDING?check=ALL_FREESTANDING;check=ALL_FREESTANDING_NOT^#
140153
}
141-
// ALL_FREESTANDING-NOT: Attached
142154
// ALL_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingDeclMacro[#Declaration Macro#]; name=freestandingDeclMacro
143155
// ALL_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingCodeItemMacro[#Code Item Macro#]; name=freestandingCodeItemMacro
144156
// ALL_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingExprIntMacro[#Int#]; name=freestandingExprIntMacro
145157
// ALL_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingExprStringMacro[#String#]; name=freestandingExprStringMacro
146158
// ALL_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingExprTMacro({#(value): T#})[#T#]; name=freestandingExprTMacro(:)
147159
// ALL_FREESTANDING-DAG: Decl[Macro]/{{.*}}: EverythingMacro[#Expression Macro, Declaration Macro, Accessor Macro, Member Attribute Macro, Member Macro, Peer Macro, Extension Macro#]; name=EverythingMacro
160+
//
161+
// ALL_FREESTANDING_NOT-NOT: Attached
162+
// ALL_FREESTANDING_NOT-NOT: BodyMacro
148163

149164
func exprFreestanding(arg: Int) {
150-
_ = arg + ##^EXPR_FREESTANDING^#
165+
_ = arg + ##^EXPR_FREESTANDING?check=EXPR_FREESTANDING;check=EXPR_FREESTANDING_NOT^#
151166
}
152-
// EXPR_FREESTANDING-NOT: freestandingDeclMacro
153-
// EXPR_FREESTANDING-NOT: freestandingCodeItemMacro
154-
// EXPR_FREESTANDING-NOT: Attached
155167
// EXPR_FREESTANDING-DAG: Decl[Macro]/{{.*}}/TypeRelation[Convertible]: freestandingExprIntMacro[#Int#]; name=freestandingExprIntMacro
156168
// EXPR_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingExprStringMacro[#String#]; name=freestandingExprStringMacro
157169
// EXPR_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingExprTMacro({#(value): T#})[#T#]; name=freestandingExprTMacro(:)
158170
// TODO: This should be invalid in both same module and across modules
159171
// EXPR_FREESTANDING-DAG: Decl[Macro]/{{.*}}: EverythingMacro[#Expression Macro, Declaration Macro, Accessor Macro, Member Attribute Macro, Member Macro, Peer Macro, Extension Macro#]; name=EverythingMacro
172+
//
173+
// EXPR_FREESTANDING_NOT-NOT: freestandingDeclMacro
174+
// EXPR_FREESTANDING_NOT-NOT: freestandingCodeItemMacro
175+
// EXPR_FREESTANDING_NOT-NOT: Attached
176+
// EXPR_FREESTANDING_NOT-NOT: BodyMacro
160177

161178
struct NestedFreestanding {
162-
##^TYPE_NESTED_FREESTANDING?check=ITEM_FREESTANDING^#
179+
##^TYPE_NESTED_FREESTANDING?check=ITEM_FREESTANDING;check=ITEM_FREESTANDING_NOT^#
163180
}
164-
// ITEM_FREESTANDING-NOT: Attached
165-
// ITEM_FREESTANDING-NOT: freestandingExpr
166-
// ITEM_FREESTANDING-NOT: freestandingCodeItemMacro
167181
// ITEM_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingDeclMacro[#Declaration Macro#]; name=freestandingDeclMacro
168182
// ITEM_FREESTANDING-DAG: Decl[Macro]/{{.*}}: EverythingMacro[#Expression Macro, Declaration Macro, Accessor Macro, Member Attribute Macro, Member Macro, Peer Macro, Extension Macro#]; name=EverythingMacro
169-
183+
//
184+
// ITEM_FREESTANDING_NOT-NOT: Attached
185+
// ITEM_FREESTANDING_NOT-NOT: freestandingExpr
186+
// ITEM_FREESTANDING_NOT-NOT: freestandingCodeItemMacro
187+
// ITEM_FREESTANDING_NOT-NOT: BodyMacro
170188

171189
@AttachedMemberMacroWithEnumArgs(.#^ATTACHED_MACRO_ARG^#)
172190
struct AttachedMacroArg {}
@@ -181,15 +199,17 @@ struct AttachedMacroSecondArgLabel {}
181199

182200

183201
struct LastMember {
184-
@#^LAST_MEMBER_ATTR?check=INDEPENDENT_ATTR^#
202+
@#^LAST_MEMBER_ATTR?check=INDEPENDENT_ATTR;check=INDEPENDENT_ATTR_NOT^#
185203
}
186-
@#^INDEPENDENT?check=INDEPENDENT_ATTR^#
187-
// INDEPENDENT_ATTR-NOT: freestandingExprMacro
188-
// INDEPENDENT_ATTR-NOT: freestandingDeclMacro
204+
@#^INDEPENDENT?check=INDEPENDENT_ATTR;check=INDEPENDENT_ATTR_NOT^#
189205
// INDEPENDENT_ATTR-DAG: Decl[Macro]/{{.*}}/TypeRelation[Convertible]: AttachedAccessorMacro[#Accessor Macro#]; name=AttachedAccessorMacro
190206
// INDEPENDENT_ATTR-DAG: Decl[Macro]/{{.*}}/TypeRelation[Convertible]: AttachedMemberMacro[#Member Macro#]; name=AttachedMemberMacro
191207
// INDEPENDENT_ATTR-DAG: Decl[Macro]/{{.*}}/TypeRelation[Convertible]: AttachedMemberMacroWithArgs({#arg1: Int#})[#Member Macro#]; name=AttachedMemberMacroWithArgs
192208
// INDEPENDENT_ATTR-DAG: Decl[Macro]/{{.*}}/TypeRelation[Convertible]: AttachedMemberAttributeMacro[#Member Attribute Macro#]; name=AttachedMemberAttributeMacro
193209
// INDEPENDENT_ATTR-DAG: Decl[Macro]/{{.*}}/TypeRelation[Convertible]: AttachedPeerMacro[#Peer Macro#]; name=AttachedPeerMacro
194210
// INDEPENDENT_ATTR-DAG: Decl[Macro]/{{.*}}/TypeRelation[Convertible]: AttachedConformanceMacro[#Extension Macro#]; name=AttachedConformanceMacro
211+
// INDEPENDENT_ATTR-DAG: Decl[Macro]/{{.*}}/TypeRelation[Convertible]: BodyMacro[#Body Macro#]; name=BodyMacro
195212
// INDEPENDENT_ATTR-DAG: Decl[Macro]/{{.*}}/TypeRelation[Convertible]: EverythingMacro[#Expression Macro, Declaration Macro, Accessor Macro, Member Attribute Macro, Member Macro, Peer Macro, Extension Macro#]; name=EverythingMacro
213+
//
214+
// INDEPENDENT_ATTR_NOT-NOT: freestandingExprMacro
215+
// INDEPENDENT_ATTR_NOT-NOT: freestandingDeclMacro

0 commit comments

Comments
 (0)