Skip to content

Commit d871c9a

Browse files
committed
[CodeCompletion] Split code completion operator kind out
...into separate prefix, postfix and infix operators. Also incidentally make the whitespace around operators special so we can decide when to skip over it. Tested in SourceKit. Swift SVN r32468
1 parent c7c9846 commit d871c9a

9 files changed

+108
-57
lines changed

include/swift/IDE/CodeCompletion.h

+18-1
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ class CodeCompletionString {
107107
ExclamationMark,
108108
QuestionMark,
109109
Ampersand,
110+
Whitespace,
110111

111112
/// The first chunk of a substring that describes the parameter for a
112113
/// generic type.
@@ -195,6 +196,7 @@ class CodeCompletionString {
195196
Kind == ChunkKind::ExclamationMark ||
196197
Kind == ChunkKind::QuestionMark ||
197198
Kind == ChunkKind::Ampersand ||
199+
Kind == ChunkKind::Whitespace ||
198200
Kind == ChunkKind::CallParameterName ||
199201
Kind == ChunkKind::CallParameterInternalName ||
200202
Kind == ChunkKind::CallParameterColon ||
@@ -392,7 +394,9 @@ enum class CodeCompletionDeclKind {
392394
Subscript,
393395
StaticMethod,
394396
InstanceMethod,
395-
OperatorFunction,
397+
PrefixOperatorFunction,
398+
PostfixOperatorFunction,
399+
InfixOperatorFunction,
396400
FreeFunction,
397401
StaticVar,
398402
InstanceVar,
@@ -537,6 +541,19 @@ class CodeCompletionResult {
537541
return static_cast<CodeCompletionDeclKind>(AssociatedDeclKind);
538542
}
539543

544+
bool isOperator() const {
545+
if (getKind() != Declaration)
546+
return false;
547+
switch (getAssociatedDeclKind()) {
548+
case CodeCompletionDeclKind::PrefixOperatorFunction:
549+
case CodeCompletionDeclKind::PostfixOperatorFunction:
550+
case CodeCompletionDeclKind::InfixOperatorFunction:
551+
return true;
552+
default:
553+
return false;
554+
}
555+
}
556+
540557
ExpectedTypeRelation getExpectedTypeRelation() const {
541558
assert(getKind() == Declaration);
542559
return static_cast<ExpectedTypeRelation>(TypeDistance);

lib/IDE/CodeCompletion.cpp

+34-8
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ void CodeCompletionString::print(raw_ostream &OS) const {
158158
case Chunk::ChunkKind::ExclamationMark:
159159
case Chunk::ChunkKind::QuestionMark:
160160
case Chunk::ChunkKind::Ampersand:
161+
case Chunk::ChunkKind::Whitespace:
161162
AnnotatedTextChunk = C.isAnnotation();
162163
SWIFT_FALLTHROUGH;
163164
case Chunk::ChunkKind::CallParameterName:
@@ -264,14 +265,30 @@ CodeCompletionResult::getCodeCompletionDeclKind(const Decl *D) {
264265
return CodeCompletionDeclKind::StaticMethod;
265266
return CodeCompletionDeclKind::InstanceMethod;
266267
}
267-
if (FD->isOperator())
268-
return CodeCompletionDeclKind::OperatorFunction;
268+
if (FD->isOperator()) {
269+
if (auto op = FD->getOperatorDecl()) {
270+
switch (op->getKind()) {
271+
case DeclKind::PrefixOperator:
272+
return CodeCompletionDeclKind::PrefixOperatorFunction;
273+
case DeclKind::PostfixOperator:
274+
return CodeCompletionDeclKind::PostfixOperatorFunction;
275+
case DeclKind::InfixOperator:
276+
return CodeCompletionDeclKind::InfixOperatorFunction;
277+
default:
278+
llvm_unreachable("unexpected operator kind");
279+
}
280+
} else {
281+
return CodeCompletionDeclKind::InfixOperatorFunction;
282+
}
283+
}
269284
return CodeCompletionDeclKind::FreeFunction;
270285
}
271286
case DeclKind::InfixOperator:
287+
return CodeCompletionDeclKind::InfixOperatorFunction;
272288
case DeclKind::PrefixOperator:
289+
return CodeCompletionDeclKind::PrefixOperatorFunction;
273290
case DeclKind::PostfixOperator:
274-
return CodeCompletionDeclKind::OperatorFunction;
291+
return CodeCompletionDeclKind::PostfixOperatorFunction;
275292
case DeclKind::EnumElement:
276293
return CodeCompletionDeclKind::EnumElement;
277294
case DeclKind::Subscript:
@@ -322,8 +339,14 @@ void CodeCompletionResult::print(raw_ostream &OS) const {
322339
case CodeCompletionDeclKind::InstanceMethod:
323340
Prefix.append("[InstanceMethod]");
324341
break;
325-
case CodeCompletionDeclKind::OperatorFunction:
326-
Prefix.append("[OperatorFunction]");
342+
case CodeCompletionDeclKind::PrefixOperatorFunction:
343+
Prefix.append("[PrefixOperatorFunction]");
344+
break;
345+
case CodeCompletionDeclKind::PostfixOperatorFunction:
346+
Prefix.append("[PostfixOperatorFunction]");
347+
break;
348+
case CodeCompletionDeclKind::InfixOperatorFunction:
349+
Prefix.append("[InfixOperatorFunction]");
327350
break;
328351
case CodeCompletionDeclKind::FreeFunction:
329352
Prefix.append("[FreeFunction]");
@@ -640,6 +663,7 @@ Optional<unsigned> CodeCompletionString::getFirstTextChunkIndex(
640663
case CodeCompletionString::Chunk::ChunkKind::Ellipsis:
641664
case CodeCompletionString::Chunk::ChunkKind::Comma:
642665
case CodeCompletionString::Chunk::ChunkKind::Ampersand:
666+
case CodeCompletionString::Chunk::ChunkKind::Whitespace:
643667
case CodeCompletionString::Chunk::ChunkKind::AccessControlKeyword:
644668
case CodeCompletionString::Chunk::ChunkKind::OverrideKeyword:
645669
case CodeCompletionString::Chunk::ChunkKind::ThrowsKeyword:
@@ -2396,9 +2420,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
23962420
{});
23972421
builder.setAssociatedDecl(op);
23982422
// FIXME: detect whether we need space on the LHS.
2399-
builder.addTextChunk(" ");
2423+
builder.addWhitespace(" ");
24002424
builder.addTextChunk(op->getName().str());
2401-
builder.addTextChunk(" ");
2425+
builder.addWhitespace(" ");
24022426
if (RHSType)
24032427
builder.addCallParameter(Identifier(), Identifier(), RHSType, false);
24042428
if (resultType)
@@ -3985,7 +4009,9 @@ void swift::ide::copyCodeCompletionResults(CodeCompletionResultSink &targetSink,
39854009
case CodeCompletionDeclKind::Subscript:
39864010
case CodeCompletionDeclKind::StaticMethod:
39874011
case CodeCompletionDeclKind::InstanceMethod:
3988-
case CodeCompletionDeclKind::OperatorFunction:
4012+
case CodeCompletionDeclKind::PrefixOperatorFunction:
4013+
case CodeCompletionDeclKind::PostfixOperatorFunction:
4014+
case CodeCompletionDeclKind::InfixOperatorFunction:
39894015
case CodeCompletionDeclKind::FreeFunction:
39904016
case CodeCompletionDeclKind::StaticVar:
39914017
case CodeCompletionDeclKind::InstanceVar:

lib/IDE/CodeCompletionResultBuilder.h

+5
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,11 @@ class CodeCompletionResultBuilder {
349349
addChunkWithTextNoCopy(
350350
CodeCompletionString::Chunk::ChunkKind::BraceStmtWithCursor, " {}");
351351
}
352+
353+
void addWhitespace(StringRef space) {
354+
addChunkWithText(
355+
CodeCompletionString::Chunk::ChunkKind::Whitespace, space);
356+
}
352357
};
353358

354359
} // namespace ide

lib/IDE/REPLCodeCompletion.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ static std::string toInsertableString(CodeCompletionResult *Result) {
5454
case CodeCompletionString::Chunk::ChunkKind::ExclamationMark:
5555
case CodeCompletionString::Chunk::ChunkKind::QuestionMark:
5656
case CodeCompletionString::Chunk::ChunkKind::Ampersand:
57+
case CodeCompletionString::Chunk::ChunkKind::Whitespace:
5758
case CodeCompletionString::Chunk::ChunkKind::DynamicLookupMethodCallTail:
5859
case CodeCompletionString::Chunk::ChunkKind::OptionalMethodCallTail:
5960
if (!C.isAnnotation())
@@ -118,7 +119,9 @@ static void toDisplayString(CodeCompletionResult *Result,
118119
case CodeCompletionDeclKind::Subscript:
119120
case CodeCompletionDeclKind::StaticMethod:
120121
case CodeCompletionDeclKind::InstanceMethod:
121-
case CodeCompletionDeclKind::OperatorFunction:
122+
case CodeCompletionDeclKind::PrefixOperatorFunction:
123+
case CodeCompletionDeclKind::PostfixOperatorFunction:
124+
case CodeCompletionDeclKind::InfixOperatorFunction:
122125
case CodeCompletionDeclKind::FreeFunction:
123126
OS << " -> ";
124127
break;

test/IDE/complete_enum_elements.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ enum BazEnum<T> {
201201
// BAZ_T_ENUM_NO_DOT-NEXT: Decl[StaticVar]/CurrNominal: .staticVar[#Int#]{{; name=.+$}}
202202
// BAZ_T_ENUM_NO_DOT-NEXT: Decl[StaticVar]/CurrNominal: .staticVarT[#T#]{{; name=.+$}}
203203
// BAZ_T_ENUM_NO_DOT-NEXT: Decl[StaticMethod]/CurrNominal: .bazStaticFunc()[#Void#]{{; name=.+$}}
204-
// BAZ_T_ENUM_NO_DOT-NEXT: Decl[OperatorFunction]/OtherModule[Swift]: != {#Any.Type?#}[#Bool#]
204+
// BAZ_T_ENUM_NO_DOT-NEXT: Decl[InfixOperatorFunction]/OtherModule[Swift]: != {#Any.Type?#}[#Bool#]
205205
// BAZ_T_ENUM_NO_DOT-NEXT: End completions
206206

207207
// BAZ_INT_ENUM_DOT: Begin completions, 6 items

test/IDE/complete_from_stdlib.swift

+18-18
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,8 @@ func testPostfixOperator1(x: Int) {
225225
func testPostfixOperator2(var x: Int) {
226226
x#^POSTFIX_INT_2^#
227227
}
228-
// POSTFIX_LVALUE_INT: Decl[OperatorFunction]/OtherModule[Swift]: ++[#Int#]; name=
229-
// POSTFIX_LVALUE_INT: Decl[OperatorFunction]/OtherModule[Swift]: --[#Int#]; name=
228+
// POSTFIX_LVALUE_INT: Decl[PostfixOperatorFunction]/OtherModule[Swift]: ++[#Int#]; name=
229+
// POSTFIX_LVALUE_INT: Decl[PostfixOperatorFunction]/OtherModule[Swift]: --[#Int#]; name=
230230

231231
func testPostfixOperator3(x: MyInt??) {
232232
x#^POSTFIX_OPTIONAL_1^#
@@ -237,36 +237,36 @@ func testInfixOperator1(x: Int) {
237237
x#^INFIX_INT_1^#
238238
}
239239
// INFIX_INT: Begin completions
240-
// INFIX_INT-DAG: Decl[OperatorFunction]/OtherModule[Swift]: ... {#Int#}[#Range<Int>#]
241-
// INFIX_INT-DAG: Decl[OperatorFunction]/OtherModule[Swift]: &+ {#Int#}[#Int#]
242-
// INFIX_INT-DAG: Decl[OperatorFunction]/OtherModule[Swift]: + {#Int#}[#Int#]
243-
// INFIX_INT-DAG: Decl[OperatorFunction]/OtherModule[Swift]: << {#Int#}[#Int#]
244-
// INFIX_INT-DAG: Decl[OperatorFunction]/OtherModule[Swift]: < {#Int#}[#Bool#]
245-
// INFIX_INT-DAG: Decl[OperatorFunction]/OtherModule[Swift]: == {#Int#}[#Bool#]
240+
// INFIX_INT-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: ... {#Int#}[#Range<Int>#]
241+
// INFIX_INT-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: &+ {#Int#}[#Int#]
242+
// INFIX_INT-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: + {#Int#}[#Int#]
243+
// INFIX_INT-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: << {#Int#}[#Int#]
244+
// INFIX_INT-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: < {#Int#}[#Bool#]
245+
// INFIX_INT-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: == {#Int#}[#Bool#]
246246
// INFIX_INT-DAG-NOT: &&
247247
// INFIX_INT-DAG-NOT: +=
248248
// INFIX_INT: End completions
249249
func testInfixOperator2(var x: Int) {
250250
x#^INFIX_INT_2^#
251251
}
252252
// INFIX_LVALUE_INT: Begin completions
253-
// INFIX_LVALUE_INT-DAG: Decl[OperatorFunction]/OtherModule[Swift]: ... {#Int#}[#Range<Int>#]
254-
// INFIX_LVALUE_INT-DAG: Decl[OperatorFunction]/OtherModule[Swift]: &+ {#Int#}[#Int#]
255-
// INFIX_LVALUE_INT-DAG: Decl[OperatorFunction]/OtherModule[Swift]: + {#Int#}[#Int#]
256-
// INFIX_LVALUE_INT-DAG: Decl[OperatorFunction]/OtherModule[Swift]: << {#Int#}[#Int#]
257-
// INFIX_LVALUE_INT-DAG: Decl[OperatorFunction]/OtherModule[Swift]: < {#Int#}[#Bool#]
258-
// INFIX_LVALUE_INT-DAG: Decl[OperatorFunction]/OtherModule[Swift]: == {#Int#}[#Bool#]
259-
// INFIX_LVALUE_INT-DAG: Decl[OperatorFunction]/OtherModule[Swift]: += {#Int#}[#Void#]
253+
// INFIX_LVALUE_INT-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: ... {#Int#}[#Range<Int>#]
254+
// INFIX_LVALUE_INT-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: &+ {#Int#}[#Int#]
255+
// INFIX_LVALUE_INT-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: + {#Int#}[#Int#]
256+
// INFIX_LVALUE_INT-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: << {#Int#}[#Int#]
257+
// INFIX_LVALUE_INT-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: < {#Int#}[#Bool#]
258+
// INFIX_LVALUE_INT-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: == {#Int#}[#Bool#]
259+
// INFIX_LVALUE_INT-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: += {#Int#}[#Void#]
260260
// INFIX_LVALUE_INT-NOT: &&
261261
// INFIX_LVALUE_INT: End completions
262262

263263
func testInfixOperator3(x: String) {
264264
x#^INFIX_STRING_1^#
265265
}
266266
// INFIX_STRING: Begin completions
267-
// INFIX_STRING-DAG: Decl[OperatorFunction]/OtherModule[Swift]: + {#String#}[#String#]
268-
// INFIX_STRING-DAG: Decl[OperatorFunction]/OtherModule[Swift]: == {#String#}[#Bool#]
269-
// INFIX_STRING-DAG: Decl[OperatorFunction]/OtherModule[Swift]: < {#String#}[#Bool#]
267+
// INFIX_STRING-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: + {#String#}[#String#]
268+
// INFIX_STRING-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: == {#String#}[#Bool#]
269+
// INFIX_STRING-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: < {#String#}[#Bool#]
270270
// INFIX_STRING-NOT: +=
271271
// INFIX_STRING-NOT: <<
272272
// INFIX_STRING: End completions

test/IDE/complete_from_swift_module.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func testCompleteModuleQualified3() {
6464
// MODULE_QUALIFIED_3-NEXT: Decl[Constructor]/CurrNominal: ({#t: T#})[#BarGenericSwiftStruct1<T>#]
6565
// MODULE_QUALIFIED_3-NEXT: Decl[InstanceMethod]/CurrNominal: .bar1InstanceFunc({#self: BarGenericSwiftStruct1<T>#})[#() -> Void#]{{; name=.+$}}
6666
// FIXME: recovery is treating the reference to BarGenericSwiftStruct1<t_0_0> as Int.
67-
// MODULE_QUALIFIED_3: Decl[OperatorFunction]/OtherModule[foo_swift_module]: =>[#Int#]
67+
// MODULE_QUALIFIED_3: Decl[PostfixOperatorFunction]/OtherModule[foo_swift_module]: =>[#Int#]
6868
// MODULE_QUALIFIED_3: End completions
6969

7070
func testCompleteModuleQualified4() {
@@ -74,7 +74,7 @@ func testCompleteModuleQualified4() {
7474
// MODULE_QUALIFIED_4-NEXT: Decl[Constructor]/CurrNominal: ({#t: T#}, {#u: U#})[#BarGenericSwiftStruct2<T, U>#]
7575
// MODULE_QUALIFIED_4-NEXT: Decl[InstanceMethod]/CurrNominal: .bar2InstanceFunc({#self: BarGenericSwiftStruct2<T, U>#})[#() -> Void#]
7676
// FIXME: recovery is treating the reference to BarGenericSwiftStruct1<t_0_0> as Int.
77-
// MODULE_QUALIFIED_4: Decl[OperatorFunction]/OtherModule[foo_swift_module]: =>[#Int#]
77+
// MODULE_QUALIFIED_4: Decl[PostfixOperatorFunction]/OtherModule[foo_swift_module]: =>[#Int#]
7878
// MODULE_QUALIFIED_4-NEXT: End completions
7979

8080
func testCompleteModuleQualified5() {
@@ -86,8 +86,8 @@ func testPostfixOperator1(x: Int) {
8686
}
8787

8888
// POSTFIX_OPERATOR_1: Begin completions
89-
// POSTFIX_OPERATOR_1-DAG: Decl[OperatorFunction]/OtherModule[foo_swift_module]: =>[#Int#]
90-
// POSTFIX_OPERATOR_1-DAG: Decl[OperatorFunction]/OtherModule[foo_swift_module]: %%% {#Int#}[#Int#]
89+
// POSTFIX_OPERATOR_1-DAG: Decl[PostfixOperatorFunction]/OtherModule[foo_swift_module]: =>[#Int#]
90+
// POSTFIX_OPERATOR_1-DAG: Decl[InfixOperatorFunction]/OtherModule[foo_swift_module]: %%% {#Int#}[#Int#]
9191
// POSTFIX_OPERATOR_1-DAG-NOT: =->
9292
// POSTFIX_OPERATOR_1: End completions
9393

0 commit comments

Comments
 (0)