mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[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
This commit is contained in:
@@ -458,7 +458,8 @@ public:
|
||||
void addEnumElementRef(const EnumElementDecl *EED, DeclVisibilityKind Reason,
|
||||
DynamicLookupInfo dynamicLookupInfo,
|
||||
bool HasTypeContext);
|
||||
void addMacroCallArguments(const MacroDecl *MD, DeclVisibilityKind Reason);
|
||||
void addMacroCallArguments(const MacroDecl *MD, DeclVisibilityKind Reason,
|
||||
bool forTrivialTrailingClosure = false);
|
||||
void addMacroExpansion(const MacroDecl *MD, DeclVisibilityKind Reason);
|
||||
|
||||
void addKeyword(
|
||||
|
||||
@@ -104,12 +104,18 @@ static Type defaultTypeLiteralKind(CodeCompletionLiteralKind kind,
|
||||
llvm_unreachable("Unhandled CodeCompletionLiteralKind in switch.");
|
||||
}
|
||||
|
||||
/// Whether funcType has a single argument (not including defaulted arguments)
|
||||
/// that is of type () -> ().
|
||||
static bool hasTrivialTrailingClosure(const FuncDecl *FD,
|
||||
AnyFunctionType *funcType) {
|
||||
ParameterListInfo paramInfo(funcType->getParams(), FD,
|
||||
/*skipCurriedSelf*/ FD->hasCurriedSelf());
|
||||
/// Whether the provided type has a single argument (not including defaulted
|
||||
/// arguments) that is of type () -> ().
|
||||
static bool hasTrivialTrailingClosure(const ValueDecl *VD, Type type) {
|
||||
if (!VD->hasParameterList())
|
||||
return false;
|
||||
|
||||
auto *funcType = type->getAs<AnyFunctionType>();
|
||||
if (!funcType)
|
||||
return false;
|
||||
|
||||
ParameterListInfo paramInfo(funcType->getParams(), VD,
|
||||
/*skipCurriedSelf*/ VD->hasCurriedSelf());
|
||||
|
||||
if (paramInfo.size() - paramInfo.numNonDefaultedParameters() == 1) {
|
||||
auto param = funcType->getParams().back();
|
||||
@@ -1947,7 +1953,8 @@ static StringRef getTypeAnnotationString(const MacroDecl *MD,
|
||||
}
|
||||
|
||||
void CompletionLookup::addMacroCallArguments(const MacroDecl *MD,
|
||||
DeclVisibilityKind Reason) {
|
||||
DeclVisibilityKind Reason,
|
||||
bool forTrivialTrailingClosure) {
|
||||
CodeCompletionResultBuilder Builder =
|
||||
makeResultBuilder(CodeCompletionResultKind::Declaration,
|
||||
getSemanticContext(MD, Reason, DynamicLookupInfo()));
|
||||
@@ -1955,11 +1962,12 @@ void CompletionLookup::addMacroCallArguments(const MacroDecl *MD,
|
||||
|
||||
addValueBaseName(Builder, MD->getBaseIdentifier());
|
||||
|
||||
Type macroType = MD->getInterfaceType();
|
||||
if (MD->parameterList && MD->parameterList->size() > 0) {
|
||||
if (forTrivialTrailingClosure) {
|
||||
Builder.addBraceStmtWithCursor(" { code }");
|
||||
} else if (MD->parameterList && MD->parameterList->size() > 0) {
|
||||
auto *macroTy = MD->getInterfaceType()->castTo<AnyFunctionType>();
|
||||
Builder.addLeftParen();
|
||||
addCallArgumentPatterns(Builder, macroType->castTo<AnyFunctionType>(),
|
||||
MD->parameterList,
|
||||
addCallArgumentPatterns(Builder, macroTy, MD->parameterList,
|
||||
MD->getGenericSignature());
|
||||
Builder.addRightParen();
|
||||
}
|
||||
@@ -1990,6 +1998,9 @@ void CompletionLookup::addMacroExpansion(const MacroDecl *MD,
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasTrivialTrailingClosure(MD, MD->getInterfaceType()))
|
||||
addMacroCallArguments(MD, Reason, /*forTrivialTrailingClosure*/ true);
|
||||
|
||||
addMacroCallArguments(MD, Reason);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,15 @@ public macro freestandingExprStringMacro() -> String
|
||||
@freestanding(expression)
|
||||
public macro freestandingExprTMacro<T>(_ value: T) -> T
|
||||
|
||||
@freestanding(expression)
|
||||
public macro freestandingExprVoidClosureMacro(fn: () -> Void)
|
||||
|
||||
@freestanding(expression)
|
||||
public macro freestandingExprIntClosureMacro(fn: () -> Int)
|
||||
|
||||
@freestanding(declaration)
|
||||
public macro freestandingDeclVoidClosureMacro(fn: () -> Void)
|
||||
|
||||
@freestanding(declaration)
|
||||
public macro freestandingDeclMacro()
|
||||
|
||||
@@ -158,8 +167,21 @@ func nestedFreestanding() {
|
||||
// ALL_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingExprTMacro({#(value): T#})[#T#]; name=freestandingExprTMacro(:)
|
||||
// ALL_FREESTANDING-DAG: Decl[Macro]/{{.*}}: EverythingMacro[#Expression Macro, Declaration Macro, Accessor Macro, Member Attribute Macro, Member Macro, Peer Macro, Extension Macro#]; name=EverythingMacro
|
||||
//
|
||||
// We offer a trailing closure completion for the Void case, but not the
|
||||
// Int case currently. Placeholder expansion will turn the latter into the
|
||||
// former though.
|
||||
//
|
||||
// ALL_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingExprVoidClosureMacro {|}[#Void#]; name=freestandingExprVoidClosureMacro
|
||||
// ALL_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingExprVoidClosureMacro({#fn: () -> Void##() -> Void#})[#Void#]; name=freestandingExprVoidClosureMacro(fn:)
|
||||
//
|
||||
// ALL_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingExprIntClosureMacro({#fn: () -> Int##() -> Int#})[#Void#]; name=freestandingExprIntClosureMacro(fn:)
|
||||
//
|
||||
// ALL_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingDeclVoidClosureMacro {|}[#Declaration Macro#]; name=freestandingDeclVoidClosureMacro
|
||||
// ALL_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingDeclVoidClosureMacro({#fn: () -> Void##() -> Void#})[#Declaration Macro#]; name=freestandingDeclVoidClosureMacro(fn:)
|
||||
//
|
||||
// ALL_FREESTANDING_NOT-NOT: Attached
|
||||
// ALL_FREESTANDING_NOT-NOT: BodyMacro
|
||||
// ALL_FREESTANDING_NOT-NOT: freestandingExprIntClosureMacro {|}
|
||||
|
||||
func exprFreestanding(arg: Int) {
|
||||
_ = arg + ##^EXPR_FREESTANDING?check=EXPR_FREESTANDING;check=EXPR_FREESTANDING_NOT^#
|
||||
@@ -181,6 +203,9 @@ struct NestedFreestanding {
|
||||
// ITEM_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingDeclMacro[#Declaration Macro#]; name=freestandingDeclMacro
|
||||
// ITEM_FREESTANDING-DAG: Decl[Macro]/{{.*}}: EverythingMacro[#Expression Macro, Declaration Macro, Accessor Macro, Member Attribute Macro, Member Macro, Peer Macro, Extension Macro#]; name=EverythingMacro
|
||||
//
|
||||
// ITEM_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingDeclVoidClosureMacro {|}[#Declaration Macro#]; name=freestandingDeclVoidClosureMacro
|
||||
// ITEM_FREESTANDING-DAG: Decl[Macro]/{{.*}}: freestandingDeclVoidClosureMacro({#fn: () -> Void##() -> Void#})[#Declaration Macro#]; name=freestandingDeclVoidClosureMacro(fn:)
|
||||
//
|
||||
// ITEM_FREESTANDING_NOT-NOT: Attached
|
||||
// ITEM_FREESTANDING_NOT-NOT: freestandingExpr
|
||||
// ITEM_FREESTANDING_NOT-NOT: freestandingCodeItemMacro
|
||||
|
||||
Reference in New Issue
Block a user