Skip to content

Commit 52d8b36

Browse files
committed
[Completion] Suggest trivial trailing closures for macros
Follow the same logic as function decl completion and suggest a trailing closure for trivial cases. rdar://150550747
1 parent 352caa4 commit 52d8b36

File tree

3 files changed

+49
-12
lines changed

3 files changed

+49
-12
lines changed

include/swift/IDE/CompletionLookup.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
458458
void addEnumElementRef(const EnumElementDecl *EED, DeclVisibilityKind Reason,
459459
DynamicLookupInfo dynamicLookupInfo,
460460
bool HasTypeContext);
461-
void addMacroCallArguments(const MacroDecl *MD, DeclVisibilityKind Reason);
461+
void addMacroCallArguments(const MacroDecl *MD, DeclVisibilityKind Reason,
462+
bool forTrivialTrailingClosure = false);
462463
void addMacroExpansion(const MacroDecl *MD, DeclVisibilityKind Reason);
463464

464465
void addKeyword(

lib/IDE/CompletionLookup.cpp

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,18 @@ static Type defaultTypeLiteralKind(CodeCompletionLiteralKind kind,
104104
llvm_unreachable("Unhandled CodeCompletionLiteralKind in switch.");
105105
}
106106

107-
/// Whether funcType has a single argument (not including defaulted arguments)
108-
/// that is of type () -> ().
109-
static bool hasTrivialTrailingClosure(const FuncDecl *FD,
110-
AnyFunctionType *funcType) {
111-
ParameterListInfo paramInfo(funcType->getParams(), FD,
112-
/*skipCurriedSelf*/ FD->hasCurriedSelf());
107+
/// Whether the provided type has a single argument (not including defaulted
108+
/// arguments) that is of type () -> ().
109+
static bool hasTrivialTrailingClosure(const ValueDecl *VD, Type type) {
110+
if (!VD->hasParameterList())
111+
return false;
112+
113+
auto *funcType = type->getAs<AnyFunctionType>();
114+
if (!funcType)
115+
return false;
116+
117+
ParameterListInfo paramInfo(funcType->getParams(), VD,
118+
/*skipCurriedSelf*/ VD->hasCurriedSelf());
113119

114120
if (paramInfo.size() - paramInfo.numNonDefaultedParameters() == 1) {
115121
auto param = funcType->getParams().back();
@@ -1947,19 +1953,21 @@ static StringRef getTypeAnnotationString(const MacroDecl *MD,
19471953
}
19481954

19491955
void CompletionLookup::addMacroCallArguments(const MacroDecl *MD,
1950-
DeclVisibilityKind Reason) {
1956+
DeclVisibilityKind Reason,
1957+
bool forTrivialTrailingClosure) {
19511958
CodeCompletionResultBuilder Builder =
19521959
makeResultBuilder(CodeCompletionResultKind::Declaration,
19531960
getSemanticContext(MD, Reason, DynamicLookupInfo()));
19541961
Builder.setAssociatedDecl(MD);
19551962

19561963
addValueBaseName(Builder, MD->getBaseIdentifier());
19571964

1958-
Type macroType = MD->getInterfaceType();
1959-
if (MD->parameterList && MD->parameterList->size() > 0) {
1965+
if (forTrivialTrailingClosure) {
1966+
Builder.addBraceStmtWithCursor(" { code }");
1967+
} else if (MD->parameterList && MD->parameterList->size() > 0) {
1968+
auto *macroTy = MD->getInterfaceType()->castTo<AnyFunctionType>();
19601969
Builder.addLeftParen();
1961-
addCallArgumentPatterns(Builder, macroType->castTo<AnyFunctionType>(),
1962-
MD->parameterList,
1970+
addCallArgumentPatterns(Builder, macroTy, MD->parameterList,
19631971
MD->getGenericSignature());
19641972
Builder.addRightParen();
19651973
}
@@ -1990,6 +1998,9 @@ void CompletionLookup::addMacroExpansion(const MacroDecl *MD,
19901998
return;
19911999
}
19922000

2001+
if (hasTrivialTrailingClosure(MD, MD->getInterfaceType()))
2002+
addMacroCallArguments(MD, Reason, /*forTrivialTrailingClosure*/ true);
2003+
19932004
addMacroCallArguments(MD, Reason);
19942005
}
19952006

test/IDE/complete_macros.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ public macro freestandingExprStringMacro() -> String
2121
@freestanding(expression)
2222
public macro freestandingExprTMacro<T>(_ value: T) -> T
2323

24+
@freestanding(expression)
25+
public macro freestandingExprVoidClosureMacro(fn: () -> Void)
26+
27+
@freestanding(expression)
28+
public macro freestandingExprIntClosureMacro(fn: () -> Int)
29+
30+
@freestanding(declaration)
31+
public macro freestandingDeclVoidClosureMacro(fn: () -> Void)
32+
2433
@freestanding(declaration)
2534
public macro freestandingDeclMacro()
2635

@@ -158,8 +167,21 @@ func nestedFreestanding() {
158167
// ALL_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingExprTMacro({#(value): T#})[#T#]; name=freestandingExprTMacro(:)
159168
// ALL_FREESTANDING-DAG: Decl[Macro]/{{.*}}: EverythingMacro[#Expression Macro, Declaration Macro, Accessor Macro, Member Attribute Macro, Member Macro, Peer Macro, Extension Macro#]; name=EverythingMacro
160169
//
170+
// We offer a trailing closure completion for the Void case, but not the
171+
// Int case currently. Placeholder expansion will turn the latter into the
172+
// former though.
173+
//
174+
// ALL_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingExprVoidClosureMacro {|}[#Void#]; name=freestandingExprVoidClosureMacro
175+
// ALL_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingExprVoidClosureMacro({#fn: () -> Void##() -> Void#})[#Void#]; name=freestandingExprVoidClosureMacro(fn:)
176+
//
177+
// ALL_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingExprIntClosureMacro({#fn: () -> Int##() -> Int#})[#Void#]; name=freestandingExprIntClosureMacro(fn:)
178+
//
179+
// ALL_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingDeclVoidClosureMacro {|}[#Declaration Macro#]; name=freestandingDeclVoidClosureMacro
180+
// ALL_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingDeclVoidClosureMacro({#fn: () -> Void##() -> Void#})[#Declaration Macro#]; name=freestandingDeclVoidClosureMacro(fn:)
181+
//
161182
// ALL_FREESTANDING_NOT-NOT: Attached
162183
// ALL_FREESTANDING_NOT-NOT: BodyMacro
184+
// ALL_FREESTANDING_NOT-NOT: freestandingExprIntClosureMacro {|}
163185

164186
func exprFreestanding(arg: Int) {
165187
_ = arg + ##^EXPR_FREESTANDING?check=EXPR_FREESTANDING;check=EXPR_FREESTANDING_NOT^#
@@ -181,6 +203,9 @@ struct NestedFreestanding {
181203
// ITEM_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingDeclMacro[#Declaration Macro#]; name=freestandingDeclMacro
182204
// ITEM_FREESTANDING-DAG: Decl[Macro]/{{.*}}: EverythingMacro[#Expression Macro, Declaration Macro, Accessor Macro, Member Attribute Macro, Member Macro, Peer Macro, Extension Macro#]; name=EverythingMacro
183205
//
206+
// ITEM_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingDeclVoidClosureMacro {|}[#Declaration Macro#]; name=freestandingDeclVoidClosureMacro
207+
// ITEM_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingDeclVoidClosureMacro({#fn: () -> Void##() -> Void#})[#Declaration Macro#]; name=freestandingDeclVoidClosureMacro(fn:)
208+
//
184209
// ITEM_FREESTANDING_NOT-NOT: Attached
185210
// ITEM_FREESTANDING_NOT-NOT: freestandingExpr
186211
// ITEM_FREESTANDING_NOT-NOT: freestandingCodeItemMacro

0 commit comments

Comments
 (0)