Skip to content

Commit fb2f49c

Browse files
authored
Merge pull request #72887 from rintaro/ide-completion-rdar124667867
[CodeCompletion] Always print argument ':' in filterName
2 parents 15973e3 + 46cc32e commit fb2f49c

File tree

5 files changed

+63
-54
lines changed

5 files changed

+63
-54
lines changed

lib/IDE/CodeCompletionResultBuilder.cpp

Lines changed: 36 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -234,60 +234,58 @@ void CodeCompletionResultBuilder::setAssociatedDecl(const Decl *D) {
234234
void CodeCompletionResultBuilder::addCallArgument(
235235
Identifier Name, Identifier LocalName, Type Ty, Type ContextTy,
236236
bool IsVarArg, bool IsInOut, bool IsIUO, bool IsAutoClosure,
237-
bool UseUnderscoreLabel, bool IsLabeledTrailingClosure, bool HasDefault) {
237+
bool IsLabeledTrailingClosure, bool IsForOperator, bool HasDefault) {
238238
++CurrentNestingLevel;
239239
using ChunkKind = CodeCompletionString::Chunk::ChunkKind;
240240

241241
addSimpleChunk(ChunkKind::CallArgumentBegin);
242242

243243
if (shouldAnnotateResults()) {
244-
if (!Name.empty() || !LocalName.empty()) {
245-
llvm::SmallString<16> EscapedKeyword;
246-
247-
if (!Name.empty()) {
248-
addChunkWithText(
249-
CodeCompletionString::Chunk::ChunkKind::CallArgumentName,
250-
escapeKeyword(Name.str(), false, EscapedKeyword));
251-
252-
if (!LocalName.empty() && Name != LocalName) {
253-
addChunkWithTextNoCopy(ChunkKind::Text, " ");
254-
getLastChunk().setIsAnnotation();
255-
addChunkWithText(
256-
ChunkKind::CallArgumentInternalName,
257-
escapeKeyword(LocalName.str(), false, EscapedKeyword));
258-
getLastChunk().setIsAnnotation();
259-
}
260-
} else {
261-
assert(!LocalName.empty());
262-
addChunkWithTextNoCopy(ChunkKind::CallArgumentName, "_");
263-
getLastChunk().setIsAnnotation();
244+
llvm::SmallString<16> EscapedKeyword;
245+
if (!Name.empty()) {
246+
addChunkWithText(ChunkKind::CallArgumentName,
247+
escapeKeyword(Name.str(), false, EscapedKeyword));
248+
if (!LocalName.empty() && Name != LocalName) {
264249
addChunkWithTextNoCopy(ChunkKind::Text, " ");
265250
getLastChunk().setIsAnnotation();
266251
addChunkWithText(ChunkKind::CallArgumentInternalName,
267252
escapeKeyword(LocalName.str(), false, EscapedKeyword));
253+
getLastChunk().setIsAnnotation();
268254
}
269255
addChunkWithTextNoCopy(ChunkKind::CallArgumentColon, ": ");
256+
} else if (!LocalName.empty()) {
257+
addChunkWithTextNoCopy(ChunkKind::CallArgumentName, "_");
258+
getLastChunk().setIsAnnotation();
259+
addChunkWithTextNoCopy(ChunkKind::Text, " ");
260+
getLastChunk().setIsAnnotation();
261+
addChunkWithText(ChunkKind::CallArgumentInternalName,
262+
escapeKeyword(LocalName.str(), false, EscapedKeyword));
263+
addChunkWithTextNoCopy(ChunkKind::CallArgumentColon, ": ");
264+
} else if (!IsForOperator) {
265+
addChunkWithTextNoCopy(ChunkKind::CallArgumentName, "_");
266+
if (!IsLabeledTrailingClosure)
267+
getLastChunk().setIsAnnotation();
268+
addChunkWithTextNoCopy(ChunkKind::CallArgumentColon, ": ");
269+
if (!IsLabeledTrailingClosure)
270+
getLastChunk().setIsAnnotation();
270271
}
271272
} else {
273+
llvm::SmallString<16> stash;
274+
ChunkKind nameKind;
275+
StringRef nameStr;
272276
if (!Name.empty()) {
273-
llvm::SmallString<16> EscapedKeyword;
274-
addChunkWithText(CodeCompletionString::Chunk::ChunkKind::CallArgumentName,
275-
escapeKeyword(Name.str(), false, EscapedKeyword));
276-
addChunkWithTextNoCopy(
277-
CodeCompletionString::Chunk::ChunkKind::CallArgumentColon, ": ");
278-
} else if (UseUnderscoreLabel) {
279-
addChunkWithTextNoCopy(
280-
CodeCompletionString::Chunk::ChunkKind::CallArgumentName, "_");
281-
addChunkWithTextNoCopy(
282-
CodeCompletionString::Chunk::ChunkKind::CallArgumentColon, ": ");
277+
nameKind = ChunkKind::CallArgumentName;
278+
nameStr = escapeKeyword(Name.str(), false, stash);
279+
} else if (IsLabeledTrailingClosure) {
280+
nameKind = ChunkKind::CallArgumentName;
281+
nameStr = "_";
283282
} else if (!LocalName.empty()) {
284-
// Use local (non-API) parameter name if we have nothing else.
285-
llvm::SmallString<16> EscapedKeyword;
286-
addChunkWithText(
287-
CodeCompletionString::Chunk::ChunkKind::CallArgumentInternalName,
288-
escapeKeyword(LocalName.str(), false, EscapedKeyword));
289-
addChunkWithTextNoCopy(
290-
CodeCompletionString::Chunk::ChunkKind::CallArgumentColon, ": ");
283+
nameKind = ChunkKind::CallArgumentInternalName;
284+
nameStr = escapeKeyword(LocalName.str(), false, stash);
285+
}
286+
if (!nameStr.empty()) {
287+
addChunkWithText(nameKind, nameStr);
288+
addChunkWithTextNoCopy(ChunkKind::CallArgumentColon, ": ");
291289
}
292290
}
293291

lib/IDE/CodeCompletionResultBuilder.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -425,14 +425,16 @@ class CodeCompletionResultBuilder {
425425

426426
void addCallArgument(Identifier Name, Identifier LocalName, Type Ty,
427427
Type ContextTy, bool IsVarArg, bool IsInOut, bool IsIUO,
428-
bool IsAutoClosure, bool UseUnderscoreLabel,
429-
bool IsLabeledTrailingClosure, bool HasDefault);
428+
bool IsAutoClosure, bool IsLabeledTrailingClosure,
429+
bool IsForOperator, bool HasDefault);
430430

431-
void addCallArgument(Identifier Name, Type Ty, Type ContextTy = Type()) {
431+
void addCallArgument(Identifier Name, Type Ty, Type ContextTy = Type(),
432+
bool IsForOperator = false) {
432433
addCallArgument(Name, Identifier(), Ty, ContextTy,
433434
/*IsVarArg=*/false, /*IsInOut=*/false, /*IsIUO=*/false,
434-
/*IsAutoClosure=*/false, /*UseUnderscoreLabel=*/false,
435-
/*IsLabeledTrailingClosure=*/false, /*HasDefault=*/false);
435+
/*IsAutoClosure=*/false,
436+
/*IsLabeledTrailingClosure=*/false, IsForOperator,
437+
/*HasDefault=*/false);
436438
}
437439

438440
void addGenericParameter(StringRef Name) {

lib/IDE/CodeCompletionResultPrinter.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -516,8 +516,7 @@ static void printCodeCompletionResultFilterName(
516516
case ChunkKind::CallArgumentColon:
517517
case ChunkKind::ParameterDeclColon:
518518
// Since we don't add the type, also don't add the space after ':'.
519-
if (shouldPrint)
520-
OS << ":";
519+
OS << ":";
521520
++i;
522521
continue;
523522
case ChunkKind::Text:

lib/IDE/CompletionLookup.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,8 +1073,8 @@ bool CompletionLookup::addCallArgumentPatterns(
10731073
Builder.addCallArgument(argName, bodyName,
10741074
eraseArchetypes(paramTy, genericSig), contextTy,
10751075
isVariadic, isInOut, isIUO, isAutoclosure,
1076-
/*UseUnderscoreLabel=*/false,
1077-
/*IsLabeledTrailingClosure=*/false, hasDefault);
1076+
/*IsLabeledTrailingClosure=*/false,
1077+
/*IsForOperator=*/false, hasDefault);
10781078

10791079
modifiedBuilder = true;
10801080
needComma = true;
@@ -2560,7 +2560,8 @@ void CompletionLookup::addAssignmentOperator(Type RHSType) {
25602560
Type contextTy;
25612561
if (auto typeContext = CurrDeclContext->getInnermostTypeContext())
25622562
contextTy = typeContext->getDeclaredTypeInContext();
2563-
builder.addCallArgument(Identifier(), RHSType, contextTy);
2563+
builder.addCallArgument(Identifier(), RHSType, contextTy,
2564+
/*IsForOperator=*/true);
25642565
}
25652566

25662567
void CompletionLookup::addInfixOperatorCompletion(OperatorDecl *op,
@@ -2584,7 +2585,8 @@ void CompletionLookup::addInfixOperatorCompletion(OperatorDecl *op,
25842585
Type contextTy;
25852586
if (auto typeContext = CurrDeclContext->getInnermostTypeContext())
25862587
contextTy = typeContext->getDeclaredTypeInContext();
2587-
builder.addCallArgument(Identifier(), RHSType, contextTy);
2588+
builder.addCallArgument(Identifier(), RHSType, contextTy,
2589+
/*IsForOperator=*/true);
25882590
}
25892591
if (resultType)
25902592
addTypeAnnotation(builder, resultType);
@@ -2913,8 +2915,9 @@ void CompletionLookup::addCallArgumentCompletionResults(
29132915
Builder.addCallArgument(Arg->getLabel(), Identifier(), Arg->getPlainType(),
29142916
ContextType, Arg->isVariadic(), Arg->isInOut(),
29152917
/*IsIUO=*/false, Arg->isAutoClosure(),
2916-
/*UseUnderscoreLabel=*/true,
2917-
isLabeledTrailingClosure, /*HasDefault=*/false);
2918+
isLabeledTrailingClosure,
2919+
/*IsForOperator=*/false,
2920+
/*HasDefault=*/false);
29182921
Builder.addFlair(CodeCompletionFlairBit::ArgumentLabels);
29192922
auto Ty = Arg->getPlainType();
29202923
if (Arg->isInOut()) {

test/IDE/complete_annotation.swift

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
struct MyStruct {
44
init(x: Int) {}
5+
init<T, U>(_: T.Type, _: U.Type, value: Int = 1) {}
56
var propNormal: Int { fatalError() }
67
var propFunction: () -> MyStruct { fatalError() }
78
func labelNameParamName(label param: (inout Int) throws -> MyStruct) rethrows {}
89
func labelName(label: (@autoclosure () -> Int) -> Int) {}
910
func sameName(label label: inout Int) {}
1011
func paramName(_ param: Int) {}
12+
func emptyName<T>(_: T.Type) {}
1113
subscript(param: Int) -> Int { 1 }
1214
subscript(label param: Int) -> Int { 1 }
1315

@@ -54,19 +56,20 @@ func testType(value: #^GLOBAL_TYPE^#) {}
5456
func testMember(value: MyStruct) {
5557
value.#^EXPR_MEMBER^#
5658
}
57-
// EXPR_MEMBER: Begin completions, 7 items
59+
// EXPR_MEMBER: Begin completions, 8 items
5860
// EXPR_MEMBER-DAG: Keyword[self]/CurrNominal: <keyword>self</keyword>; typename=<typeid.user>MyStruct</typeid.user>;
5961
// EXPR_MEMBER-DAG: Decl[InstanceVar]/CurrNominal: <name>propNormal</name>; typename=<typeid.sys>Int</typeid.sys>;
6062
// EXPR_MEMBER-DAG: Decl[InstanceVar]/CurrNominal: <name>propFunction</name>; typename=() -&gt; <typeid.user>MyStruct</typeid.user>;
6163
// EXPR_MEMBER-DAG: Decl[InstanceMethod]/CurrNominal: <name>labelNameParamName</name>(<callarg><callarg.label>label</callarg.label> <callarg.param>param</callarg.param>: <callarg.type>(<keyword>inout</keyword> <typeid.sys>Int</typeid.sys>) <keyword>throws</keyword> -&gt; <typeid.user>MyStruct</typeid.user></callarg.type></callarg>) <keyword>rethrows</keyword>; typename=<typeid.sys>Void</typeid.sys>;
6264
// EXPR_MEMBER-DAG: Decl[InstanceMethod]/CurrNominal: <name>labelName</name>(<callarg><callarg.label>label</callarg.label>: <callarg.type>(<attribute>@autoclosure</attribute> () -&gt; <typeid.sys>Int</typeid.sys>) -&gt; <typeid.sys>Int</typeid.sys></callarg.type></callarg>); typename=<typeid.sys>Void</typeid.sys>;
6365
// EXPR_MEMBER-DAG: Decl[InstanceMethod]/CurrNominal: <name>sameName</name>(<callarg><callarg.label>label</callarg.label>: &amp;<callarg.type><typeid.sys>Int</typeid.sys></callarg.type></callarg>); typename=<typeid.sys>Void</typeid.sys>;
6466
// EXPR_MEMBER-DAG: Decl[InstanceMethod]/CurrNominal: <name>paramName</name>(<callarg><callarg.label>_</callarg.label> <callarg.param>param</callarg.param>: <callarg.type><typeid.sys>Int</typeid.sys></callarg.type></callarg>); typename=<typeid.sys>Void</typeid.sys>;
67+
// EXPR_MEMBER-DAG: Decl[InstanceMethod]/CurrNominal: <name>emptyName</name>(<callarg><callarg.label>_</callarg.label>: <callarg.type><typeid.user>T</typeid.user>.Type</callarg.type></callarg>); typename=<typeid.sys>Void</typeid.sys>; name=emptyName(:); sourcetext=emptyName(<#T##T.Type#>)
6568

6669
func testPostfix(value: MyStruct) {
6770
value #^EXPR_POSTFIX^#
6871
}
69-
// EXPR_POSTFIX: Begin completions, 10 items
72+
// EXPR_POSTFIX: Begin completions, 11 items
7073
// EXPR_POSTFIX-DAG: Decl[InstanceVar]/CurrNominal: <name>propNormal</name>; typename=<typeid.sys>Int</typeid.sys>;
7174
// EXPR_POSTFIX-DAG: Decl[InstanceVar]/CurrNominal: <name>propFunction</name>; typename=() -&gt; <typeid.user>MyStruct</typeid.user>;
7275
// EXPR_POSTFIX-DAG: Decl[InstanceMethod]/CurrNominal: <name>labelNameParamName</name>(<callarg><callarg.label>label</callarg.label> <callarg.param>param</callarg.param>: <callarg.type>(<keyword>inout</keyword> <typeid.sys>Int</typeid.sys>) <keyword>throws</keyword> -&gt; <typeid.user>MyStruct</typeid.user></callarg.type></callarg>) <keyword>rethrows</keyword>; typename=<typeid.sys>Void</typeid.sys>;
@@ -77,17 +80,21 @@ func testPostfix(value: MyStruct) {
7780
// EXPR_POSTFIX-DAG: Decl[Subscript]/CurrNominal: [<callarg><callarg.label>label</callarg.label> <callarg.param>param</callarg.param>: <callarg.type><typeid.sys>Int</typeid.sys></callarg.type></callarg>]; typename=<typeid.sys>Int</typeid.sys>;
7881
// EXPR_POSTFIX-DAG: Keyword[self]/CurrNominal: <keyword>self</keyword>; typename=<typeid.user>MyStruct</typeid.user>;
7982
// EXPR_POSTFIX-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]/IsSystem: <name>+</name>; typename=<typeid.user>MyStruct</typeid.user>;
83+
// EXPR_POSTFIX-DAG: Decl[InstanceMethod]/CurrNominal: <name>emptyName</name>(<callarg><callarg.label>_</callarg.label>: <callarg.type><typeid.user>T</typeid.user>.Type</callarg.type></callarg>); typename=<typeid.sys>Void</typeid.sys>; name=emptyName(:); sourcetext=.emptyName(<#T##T.Type#>)
8084

8185
func testImplicitMember() -> MyStruct {
8286
return .#^EXPR_IMPLICITMEMBER^#
8387
}
84-
// EXPR_IMPLICITMEMBER: Begin completions, 7 items
88+
// EXPR_IMPLICITMEMBER: Begin completions, 10 items
8589
// EXPR_IMPLICITMEMBER-DAG: Decl[Constructor]/CurrNominal/TypeRelation[Convertible]: <name>init</name>(<callarg><callarg.label>x</callarg.label>: <callarg.type><typeid.sys>Int</typeid.sys></callarg.type></callarg>); typename=<typeid.user>MyStruct</typeid.user>;
90+
// EXPR_IMPLICITMEMBER-DAG: Decl[Constructor]/CurrNominal/TypeRelation[Convertible]: <name>init</name>(<callarg><callarg.label>_</callarg.label>: <callarg.type><typeid.user>T</typeid.user>.Type</callarg.type></callarg>, <callarg><callarg.label>_</callarg.label>: <callarg.type><typeid.user>U</typeid.user>.Type</callarg.type></callarg>); typename=<typeid.user>MyStruct</typeid.user>; name=init(::); sourcetext=init(<#T##T.Type#>, <#T##U.Type#>)
91+
// EXPR_IMPLICITMEMBER-DAG: Decl[Constructor]/CurrNominal/TypeRelation[Convertible]: <name>init</name>(<callarg><callarg.label>_</callarg.label>: <callarg.type><typeid.user>T</typeid.user>.Type</callarg.type></callarg>, <callarg><callarg.label>_</callarg.label>: <callarg.type><typeid.user>U</typeid.user>.Type</callarg.type></callarg>, <callarg><callarg.label>value</callarg.label>: <callarg.type><typeid.sys>Int</typeid.sys></callarg.type><callarg.default/></callarg>); typename=<typeid.user>MyStruct</typeid.user>; name=init(::value:); sourcetext=init(<#T##T.Type#>, <#T##U.Type#>, value: <#T##Int#>)
8692
// EXPR_IMPLICITMEMBER-DAG: Decl[StaticVar]/CurrNominal/Flair[ExprSpecific]/TypeRelation[Convertible]: <name>instance</name>; typename=<typeid.user>MyStruct</typeid.user>;
8793
// EXPR_IMPLICITMEMBER-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Invalid]: <name>labelNameParamName</name>(<callarg><callarg.label>_</callarg.label> <callarg.param>self</callarg.param>: <callarg.type><typeid.user>MyStruct</typeid.user></callarg.type></callarg>); typename=(label: (<keyword>inout</keyword> <typeid.sys>Int</typeid.sys>) <keyword>throws</keyword> -&gt; <typeid.user>MyStruct</typeid.user>) -&gt; <typeid.sys>Void</typeid.sys>;
8894
// EXPR_IMPLICITMEMBER-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Invalid]: <name>labelName</name>(<callarg><callarg.label>_</callarg.label> <callarg.param>self</callarg.param>: <callarg.type><typeid.user>MyStruct</typeid.user></callarg.type></callarg>); typename=(label: (<attribute>@autoclosure</attribute> () -&gt; <typeid.sys>Int</typeid.sys>) -&gt; <typeid.sys>Int</typeid.sys>) -&gt; <typeid.sys>Void</typeid.sys>;
8995
// EXPR_IMPLICITMEMBER-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Invalid]: <name>sameName</name>(<callarg><callarg.label>_</callarg.label> <callarg.param>self</callarg.param>: <callarg.type><typeid.user>MyStruct</typeid.user></callarg.type></callarg>); typename=(label: <keyword>inout</keyword> <typeid.sys>Int</typeid.sys>) -&gt; <typeid.sys>Void</typeid.sys>;
9096
// EXPR_IMPLICITMEMBER-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Invalid]: <name>paramName</name>(<callarg><callarg.label>_</callarg.label> <callarg.param>self</callarg.param>: <callarg.type><typeid.user>MyStruct</typeid.user></callarg.type></callarg>); typename=(<typeid.sys>Int</typeid.sys>) -&gt; <typeid.sys>Void</typeid.sys>;
97+
// EXPR_IMPLICITMEMBER-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Invalid]: <name>emptyName</name>(<callarg><callarg.label>_</callarg.label> <callarg.param>self</callarg.param>: <callarg.type><typeid.user>MyStruct</typeid.user></callarg.type></callarg>); typename=(<typeid.user>T</typeid.user>.Type) -&gt; <typeid.sys>Void</typeid.sys>; name=emptyName(:); sourcetext=emptyName(<#T##self: MyStruct##MyStruct#>)
9198
// EXPR_IMPLICITMEMBER-DAG: Decl[StaticMethod]/CurrNominal/Flair[ExprSpecific]/TypeRelation[Convertible]: <name>create</name>(<callarg><callarg.label>x</callarg.label>: <callarg.type><typeid.sys>Int</typeid.sys></callarg.type></callarg>); typename=<typeid.user>MyStruct</typeid.user>;
9299

93100
func testArgument() -> MyStruct {

0 commit comments

Comments
 (0)