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,
|
void addEnumElementRef(const EnumElementDecl *EED, DeclVisibilityKind Reason,
|
||||||
DynamicLookupInfo dynamicLookupInfo,
|
DynamicLookupInfo dynamicLookupInfo,
|
||||||
bool HasTypeContext);
|
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 addMacroExpansion(const MacroDecl *MD, DeclVisibilityKind Reason);
|
||||||
|
|
||||||
void addKeyword(
|
void addKeyword(
|
||||||
|
|||||||
@@ -104,12 +104,18 @@ static Type defaultTypeLiteralKind(CodeCompletionLiteralKind kind,
|
|||||||
llvm_unreachable("Unhandled CodeCompletionLiteralKind in switch.");
|
llvm_unreachable("Unhandled CodeCompletionLiteralKind in switch.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether funcType has a single argument (not including defaulted arguments)
|
/// Whether the provided type has a single argument (not including defaulted
|
||||||
/// that is of type () -> ().
|
/// arguments) that is of type () -> ().
|
||||||
static bool hasTrivialTrailingClosure(const FuncDecl *FD,
|
static bool hasTrivialTrailingClosure(const ValueDecl *VD, Type type) {
|
||||||
AnyFunctionType *funcType) {
|
if (!VD->hasParameterList())
|
||||||
ParameterListInfo paramInfo(funcType->getParams(), FD,
|
return false;
|
||||||
/*skipCurriedSelf*/ FD->hasCurriedSelf());
|
|
||||||
|
auto *funcType = type->getAs<AnyFunctionType>();
|
||||||
|
if (!funcType)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ParameterListInfo paramInfo(funcType->getParams(), VD,
|
||||||
|
/*skipCurriedSelf*/ VD->hasCurriedSelf());
|
||||||
|
|
||||||
if (paramInfo.size() - paramInfo.numNonDefaultedParameters() == 1) {
|
if (paramInfo.size() - paramInfo.numNonDefaultedParameters() == 1) {
|
||||||
auto param = funcType->getParams().back();
|
auto param = funcType->getParams().back();
|
||||||
@@ -1947,7 +1953,8 @@ static StringRef getTypeAnnotationString(const MacroDecl *MD,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CompletionLookup::addMacroCallArguments(const MacroDecl *MD,
|
void CompletionLookup::addMacroCallArguments(const MacroDecl *MD,
|
||||||
DeclVisibilityKind Reason) {
|
DeclVisibilityKind Reason,
|
||||||
|
bool forTrivialTrailingClosure) {
|
||||||
CodeCompletionResultBuilder Builder =
|
CodeCompletionResultBuilder Builder =
|
||||||
makeResultBuilder(CodeCompletionResultKind::Declaration,
|
makeResultBuilder(CodeCompletionResultKind::Declaration,
|
||||||
getSemanticContext(MD, Reason, DynamicLookupInfo()));
|
getSemanticContext(MD, Reason, DynamicLookupInfo()));
|
||||||
@@ -1955,11 +1962,12 @@ void CompletionLookup::addMacroCallArguments(const MacroDecl *MD,
|
|||||||
|
|
||||||
addValueBaseName(Builder, MD->getBaseIdentifier());
|
addValueBaseName(Builder, MD->getBaseIdentifier());
|
||||||
|
|
||||||
Type macroType = MD->getInterfaceType();
|
if (forTrivialTrailingClosure) {
|
||||||
if (MD->parameterList && MD->parameterList->size() > 0) {
|
Builder.addBraceStmtWithCursor(" { code }");
|
||||||
|
} else if (MD->parameterList && MD->parameterList->size() > 0) {
|
||||||
|
auto *macroTy = MD->getInterfaceType()->castTo<AnyFunctionType>();
|
||||||
Builder.addLeftParen();
|
Builder.addLeftParen();
|
||||||
addCallArgumentPatterns(Builder, macroType->castTo<AnyFunctionType>(),
|
addCallArgumentPatterns(Builder, macroTy, MD->parameterList,
|
||||||
MD->parameterList,
|
|
||||||
MD->getGenericSignature());
|
MD->getGenericSignature());
|
||||||
Builder.addRightParen();
|
Builder.addRightParen();
|
||||||
}
|
}
|
||||||
@@ -1990,6 +1998,9 @@ void CompletionLookup::addMacroExpansion(const MacroDecl *MD,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasTrivialTrailingClosure(MD, MD->getInterfaceType()))
|
||||||
|
addMacroCallArguments(MD, Reason, /*forTrivialTrailingClosure*/ true);
|
||||||
|
|
||||||
addMacroCallArguments(MD, Reason);
|
addMacroCallArguments(MD, Reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,15 @@ public macro freestandingExprStringMacro() -> String
|
|||||||
@freestanding(expression)
|
@freestanding(expression)
|
||||||
public macro freestandingExprTMacro<T>(_ value: T) -> T
|
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)
|
@freestanding(declaration)
|
||||||
public macro freestandingDeclMacro()
|
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]/{{.*}}: 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
|
// 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: Attached
|
||||||
// ALL_FREESTANDING_NOT-NOT: BodyMacro
|
// ALL_FREESTANDING_NOT-NOT: BodyMacro
|
||||||
|
// ALL_FREESTANDING_NOT-NOT: freestandingExprIntClosureMacro {|}
|
||||||
|
|
||||||
func exprFreestanding(arg: Int) {
|
func exprFreestanding(arg: Int) {
|
||||||
_ = arg + ##^EXPR_FREESTANDING?check=EXPR_FREESTANDING;check=EXPR_FREESTANDING_NOT^#
|
_ = 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]/{{.*}}: 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]/{{.*}}: 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: Attached
|
||||||
// ITEM_FREESTANDING_NOT-NOT: freestandingExpr
|
// ITEM_FREESTANDING_NOT-NOT: freestandingExpr
|
||||||
// ITEM_FREESTANDING_NOT-NOT: freestandingCodeItemMacro
|
// ITEM_FREESTANDING_NOT-NOT: freestandingCodeItemMacro
|
||||||
|
|||||||
Reference in New Issue
Block a user