Skip to content

Commit 679aaca

Browse files
authored
Merge pull request #33601 from LucianoPAlmeida/SR-13426-code-completion-keypath-optional
[CodeCompletion] Do not offer completion Wrapped members for optional key path root type
2 parents b7d5ea8 + ecc5b90 commit 679aaca

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

lib/IDE/CodeCompletion.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3725,8 +3725,12 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
37253725
llvm::SaveAndRestore<bool> ChangeNeedOptionalUnwrap(NeedOptionalUnwrap,
37263726
true);
37273727
if (DotLoc.isValid()) {
3728+
// Let's not erase the dot if the completion is after a swift key path
3729+
// root because \A?.?.member is the correct way to access wrapped type
3730+
// member from an optional key path root.
3731+
auto loc = IsAfterSwiftKeyPathRoot ? DotLoc.getAdvancedLoc(1) : DotLoc;
37283732
NumBytesToEraseForOptionalUnwrap = Ctx.SourceMgr.getByteDistance(
3729-
DotLoc, Ctx.SourceMgr.getCodeCompletionLoc());
3733+
loc, Ctx.SourceMgr.getCodeCompletionLoc());
37303734
} else {
37313735
NumBytesToEraseForOptionalUnwrap = 0;
37323736
}
@@ -5934,7 +5938,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
59345938
if (!OnRoot && KPE->getComponents().back().getKind() ==
59355939
KeyPathExpr::Component::Kind::OptionalWrap) {
59365940
// KeyPath expr with '?' (e.g. '\Ty.[0].prop?.another').
5937-
// Althogh expected type is optional, we should unwrap it because it's
5941+
// Although expected type is optional, we should unwrap it because it's
59385942
// unwrapped.
59395943
baseType = baseType->getOptionalObjectType();
59405944
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TYPE_INFER_DOT_OPTIONAL | %FileCheck %s -check-prefix=PERSONTYPE-INFER-DOT-OPT
2+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TYPE_DOT_OPTIONAL | %FileCheck %s -check-prefix=PERSONTYPE-DOT-OPT
3+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TYPE_DOT_OPTIONAL_SPACE | %FileCheck %s -check-prefix=PERSONTYPE-DOT-OPT-SPACE
4+
5+
class Person {
6+
var name: String
7+
var friends: [Person] = []
8+
var bestFriend: Person? = nil
9+
var itself: Person { return self }
10+
init(name: String) {
11+
self.name = name
12+
}
13+
func getName() -> String { return name }
14+
subscript(_ index: Int) -> Int { get { return 1} }
15+
}
16+
17+
extension Optional {
18+
var optMember: String { "member" }
19+
}
20+
21+
let _ : KeyPath<Person?, String> = \.#^TYPE_INFER_DOT_OPTIONAL^#
22+
// PERSONTYPE-INFER-DOT-OPT: Begin completions, 9 items
23+
// PERSONTYPE-INFER-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal: ?.name[#String#]; name=name
24+
// PERSONTYPE-INFER-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal: ?.friends[#[Person]#]; name=friends
25+
// PERSONTYPE-INFER-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal: ?.bestFriend[#Person?#]; name=bestFriend
26+
// PERSONTYPE-INFER-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal: ?.itself[#Person#]; name=itself
27+
// PERSONTYPE-INFER-DOT-OPT-NEXT: Decl[Subscript]/CurrNominal: ?[{#(index): Int#}][#Int#]; name=[index: Int]
28+
// PERSONTYPE-INFER-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal/IsSystem: unsafelyUnwrapped[#Person#]; name=unsafelyUnwrapped
29+
// PERSONTYPE-INFER-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal: optMember[#String#]; name=optMember
30+
// PERSONTYPE-INFER-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal/IsSystem: debugDescription[#String#]; name=debugDescription
31+
// PERSONTYPE-INFER-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal/IsSystem: customMirror[#Mirror#]; name=customMirror
32+
33+
let _ : KeyPath<Person?, String> = \Person?.#^TYPE_DOT_OPTIONAL^#
34+
// PERSONTYPE-DOT-OPT: Begin completions, 9 items
35+
// PERSONTYPE-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal: ?.name[#String#]; name=name
36+
// PERSONTYPE-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal: ?.friends[#[Person]#]; name=friends
37+
// PERSONTYPE-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal: ?.bestFriend[#Person?#]; name=bestFriend
38+
// PERSONTYPE-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal: ?.itself[#Person#]; name=itself
39+
// PERSONTYPE-DOT-OPT-NEXT: Decl[Subscript]/CurrNominal: ?[{#(index): Int#}][#Int#]; name=[index: Int]
40+
// PERSONTYPE-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal/IsSystem: unsafelyUnwrapped[#Person#]; name=unsafelyUnwrapped
41+
// PERSONTYPE-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal: optMember[#String#]; name=optMember
42+
// PERSONTYPE-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal/IsSystem: debugDescription[#String#]; name=debugDescription
43+
// PERSONTYPE-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal/IsSystem: customMirror[#Mirror#]; name=customMirror
44+
45+
let _ : KeyPath<Person?, String> = \Person?. #^TYPE_DOT_OPTIONAL_SPACE^#
46+
// PERSONTYPE-DOT-OPT-SPACE: Begin completions, 9 items
47+
// PERSONTYPE-DOT-OPT-SPACE-NEXT: Decl[InstanceVar]/CurrNominal/Erase[1]: ?.name[#String#]; name=name
48+
// PERSONTYPE-DOT-OPT-SPACE-NEXT: Decl[InstanceVar]/CurrNominal/Erase[1]: ?.friends[#[Person]#]; name=friends
49+
// PERSONTYPE-DOT-OPT-SPACE-NEXT: Decl[InstanceVar]/CurrNominal/Erase[1]: ?.bestFriend[#Person?#]; name=bestFriend
50+
// PERSONTYPE-DOT-OPT-SPACE-NEXT: Decl[InstanceVar]/CurrNominal/Erase[1]: ?.itself[#Person#]; name=itself
51+
// PERSONTYPE-DOT-OPT-SPACE-NEXT: Decl[Subscript]/CurrNominal/Erase[1]: ?[{#(index): Int#}][#Int#]; name=[index: Int]
52+
// PERSONTYPE-DOT-OPT-SPACE-NEXT: Decl[InstanceVar]/CurrNominal/IsSystem: unsafelyUnwrapped[#Person#]; name=unsafelyUnwrapped
53+
// PERSONTYPE-DOT-OPT-SPACE-NEXT: Decl[InstanceVar]/CurrNominal: optMember[#String#]; name=optMember
54+
// PERSONTYPE-DOT-OPT-SPACE-NEXT: Decl[InstanceVar]/CurrNominal/IsSystem: debugDescription[#String#]; name=debugDescription
55+
// PERSONTYPE-DOT-OPT-SPACE-NEXT: Decl[InstanceVar]/CurrNominal/IsSystem: customMirror[#Mirror#]; name=customMirror

0 commit comments

Comments
 (0)