Skip to content

Commit 0976e39

Browse files
authored
Merge pull request #29763 from rintaro/ide-unqualifiedlookup-rdar58881999
[CodeCompletion] Workaround fast-completion issue in UnqualifiedLookup
2 parents 8d32ee3 + ff2ccd4 commit 0976e39

File tree

3 files changed

+73
-4
lines changed

3 files changed

+73
-4
lines changed

include/swift/Basic/SourceManager.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ class SourceManager {
7676
CodeCompletionOffset = Offset;
7777
}
7878

79+
bool hasCodeCompletionBuffer() const {
80+
return CodeCompletionBufferID != 0U;
81+
}
82+
7983
unsigned getCodeCompletionBufferID() const {
8084
return CodeCompletionBufferID;
8185
}

lib/AST/UnqualifiedLookup.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,19 +58,34 @@ namespace {
5858
// lookup.
5959
if (loc.isInvalid() || decl->getBraces().isInvalid())
6060
return true;
61-
61+
62+
SourceManager &SM = decl->getASTContext().SourceMgr;
63+
64+
// If a code completion happens inside a function body, some lookups may
65+
// happen from the 'loc' that is in a different buffer from the 'decl'.
66+
// In such cases, look for members of the 'decl' because we know 'loc' is
67+
// inside a function body in the 'decl'.
68+
if (SM.hasCodeCompletionBuffer()) {
69+
auto completionBufferID = SM.getCodeCompletionBufferID();
70+
if (SM.getRangeForBuffer(completionBufferID).contains(loc)) {
71+
auto declBufferID =
72+
decl->getDeclContext()->getParentSourceFile()->getBufferID();
73+
if (completionBufferID != declBufferID)
74+
return true;
75+
}
76+
}
77+
6278
// Within the braces, always look for members.
63-
auto &ctx = decl->getASTContext();
6479
auto braces = decl->getBraces();
6580
if (braces.Start != braces.End &&
66-
ctx.SourceMgr.rangeContainsTokenLoc(braces, loc))
81+
SM.rangeContainsTokenLoc(braces, loc))
6782
return true;
6883

6984
// Within 'where' clause, we can also look for members.
7085
if (auto *whereClause = decl->getTrailingWhereClause()) {
7186
SourceRange whereClauseRange = whereClause->getSourceRange();
7287
if (whereClauseRange.isValid() &&
73-
ctx.SourceMgr.rangeContainsTokenLoc(whereClauseRange, loc)) {
88+
SM.rangeContainsTokenLoc(whereClauseRange, loc)) {
7489
return true;
7590
}
7691
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
struct Outer {
2+
enum Inner {
3+
case east, west
4+
static func staticMethod() {}
5+
func instanceMethod() {}
6+
7+
func test() {
8+
Inner.
9+
}
10+
}
11+
12+
func test() {
13+
Inner.
14+
}
15+
}
16+
17+
// RUN: %sourcekitd-test \
18+
// RUN: -req=track-compiles == \
19+
// RUN: -req=complete -req-opts=reuseastcontext=1 -pos=8:13 %s -- %s == \
20+
// RUN: -req=complete -req-opts=reuseastcontext=1 -pos=8:13 %s -- %s == \
21+
// RUN: -req=complete -req-opts=reuseastcontext=1 -pos=13:11 %s -- %s \
22+
// RUN: > %t.response
23+
// RUN: %FileCheck --check-prefix=RESULT %s < %t.response
24+
// RUN: %FileCheck --check-prefix=TRACE %s < %t.response
25+
26+
// RESULT-LABEL: key.results: [
27+
// RESULT-DAG: key.description: "east"
28+
// RESULT-DAG: key.description: "west"
29+
// RESULT-DAG: key.description: "staticMethod()"
30+
// RESULT-DAG: key.description: "instanceMethod(self: Outer.Inner)"
31+
// RESULT: ]
32+
// RESULT-LABEL: key.results: [
33+
// RESULT-DAG: key.description: "east"
34+
// RESULT-DAG: key.description: "west"
35+
// RESULT-DAG: key.description: "staticMethod()"
36+
// RESULT-DAG: key.description: "instanceMethod(self: Outer.Inner)"
37+
// RESULT: ]
38+
// RESULT-LABEL: key.results: [
39+
// RESULT-DAG: key.description: "east"
40+
// RESULT-DAG: key.description: "west"
41+
// RESULT-DAG: key.description: "staticMethod()"
42+
// RESULT-DAG: key.description: "instanceMethod(self: Inner)"
43+
// RESULT: ]
44+
45+
// TRACE-LABEL: key.notification: source.notification.compile-did-finish,
46+
// TRACE-NOT: key.description: "completion reusing previous ASTContext (benign diagnostic)"
47+
// TRACE-LABEL: key.notification: source.notification.compile-did-finish,
48+
// TRACE: key.description: "completion reusing previous ASTContext (benign diagnostic)"
49+
// TRACE-LABEL: key.notification: source.notification.compile-did-finish,
50+
// TRACE: key.description: "completion reusing previous ASTContext (benign diagnostic)"

0 commit comments

Comments
 (0)