Skip to content

Commit b5d86b9

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 5f9ac48 commit b5d86b9

File tree

3 files changed

+43
-12
lines changed

3 files changed

+43
-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: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,15 @@ 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->castTo<AnyFunctionType>();
114+
ParameterListInfo paramInfo(funcType->getParams(), VD,
115+
/*skipCurriedSelf*/ VD->hasCurriedSelf());
113116

114117
if (paramInfo.size() - paramInfo.numNonDefaultedParameters() == 1) {
115118
auto param = funcType->getParams().back();
@@ -1947,19 +1950,21 @@ static StringRef getTypeAnnotationString(const MacroDecl *MD,
19471950
}
19481951

19491952
void CompletionLookup::addMacroCallArguments(const MacroDecl *MD,
1950-
DeclVisibilityKind Reason) {
1953+
DeclVisibilityKind Reason,
1954+
bool forTrivialTrailingClosure) {
19511955
CodeCompletionResultBuilder Builder =
19521956
makeResultBuilder(CodeCompletionResultKind::Declaration,
19531957
getSemanticContext(MD, Reason, DynamicLookupInfo()));
19541958
Builder.setAssociatedDecl(MD);
19551959

19561960
addValueBaseName(Builder, MD->getBaseIdentifier());
19571961

1958-
Type macroType = MD->getInterfaceType();
1959-
if (MD->parameterList && MD->parameterList->size() > 0) {
1962+
if (forTrivialTrailingClosure) {
1963+
Builder.addBraceStmtWithCursor(" { code }");
1964+
} else if (MD->parameterList && MD->parameterList->size() > 0) {
1965+
auto *macroTy = MD->getInterfaceType()->castTo<AnyFunctionType>();
19601966
Builder.addLeftParen();
1961-
addCallArgumentPatterns(Builder, macroType->castTo<AnyFunctionType>(),
1962-
MD->parameterList,
1967+
addCallArgumentPatterns(Builder, macroTy, MD->parameterList,
19631968
MD->getGenericSignature());
19641969
Builder.addRightParen();
19651970
}
@@ -1990,6 +1995,9 @@ void CompletionLookup::addMacroExpansion(const MacroDecl *MD,
19901995
return;
19911996
}
19921997

1998+
if (hasTrivialTrailingClosure(MD, MD->getInterfaceType()))
1999+
addMacroCallArguments(MD, Reason, /*forTrivialTrailingClosure*/ true);
2000+
19932001
addMacroCallArguments(MD, Reason);
19942002
}
19952003

test/IDE/complete_macros.swift

Lines changed: 22 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^#

0 commit comments

Comments
 (0)