Skip to content

Commit 95ae192

Browse files
committed
[CodeCompletion] Do not include decl in own (string interp) initializer
Strings are a single token, so the previous check would treat completions inside string interpolations as being outside of the initializer. Grab the end of the token from the Lexer, but wrap in a context check to avoid performing that for every declaration found in the lookup. Resolves rdar://70833348
1 parent c36a302 commit 95ae192

File tree

5 files changed

+32
-11
lines changed

5 files changed

+32
-11
lines changed

include/swift/AST/NameLookup.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -418,13 +418,14 @@ class AccessFilteringDeclConsumer final : public VisibleDeclConsumer {
418418
/// a decl inside its own initializer or a non-type decl before its definition.
419419
class UsableFilteringDeclConsumer final : public VisibleDeclConsumer {
420420
const SourceManager &SM;
421+
const DeclContext *DC;
421422
SourceLoc Loc;
422423
VisibleDeclConsumer &ChainedConsumer;
423424

424425
public:
425-
UsableFilteringDeclConsumer(const SourceManager &SM, SourceLoc loc,
426-
VisibleDeclConsumer &consumer)
427-
: SM(SM), Loc(loc), ChainedConsumer(consumer) {}
426+
UsableFilteringDeclConsumer(const SourceManager &SM, const DeclContext *DC,
427+
SourceLoc loc, VisibleDeclConsumer &consumer)
428+
: SM(SM), DC(DC), Loc(loc), ChainedConsumer(consumer) {}
428429

429430
void foundDecl(ValueDecl *D, DeclVisibilityKind reason,
430431
DynamicLookupInfo dynamicLookupInfo) override;

lib/AST/NameLookup.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
//
1515
//===----------------------------------------------------------------------===//
1616

17-
#include "clang/AST/DeclObjC.h"
1817
#include "swift/AST/NameLookup.h"
1918
#include "swift/AST/ASTContext.h"
2019
#include "swift/AST/ASTVisitor.h"
@@ -31,9 +30,11 @@
3130
#include "swift/AST/ParameterList.h"
3231
#include "swift/AST/SourceFile.h"
3332
#include "swift/Basic/Debug.h"
33+
#include "swift/Basic/STLExtras.h"
3434
#include "swift/Basic/SourceManager.h"
3535
#include "swift/Basic/Statistic.h"
36-
#include "swift/Basic/STLExtras.h"
36+
#include "swift/Parse/Lexer.h"
37+
#include "clang/AST/DeclObjC.h"
3738
#include "llvm/ADT/DenseMap.h"
3839
#include "llvm/ADT/TinyPtrVector.h"
3940
#include "llvm/Support/Debug.h"
@@ -148,10 +149,16 @@ void UsableFilteringDeclConsumer::foundDecl(ValueDecl *D,
148149
DeclVisibilityKind reason, DynamicLookupInfo dynamicLookupInfo) {
149150
// Skip when Loc is within the decl's own initializer
150151
if (auto *VD = dyn_cast<VarDecl>(D)) {
152+
// Only check if the VarDecl has the same (or parent) context to avoid
153+
// grabbing the end location for every decl
151154
if (auto *init = VD->getParentInitializer()) {
152-
auto initRange = init->getSourceRange();
153-
if (initRange.isValid() && SM.rangeContainsTokenLoc(initRange, Loc))
154-
return;
155+
auto *varContext = VD->getDeclContext();
156+
if (DC == varContext || DC->isChildContextOf(varContext)) {
157+
auto initRange = Lexer::getCharSourceRangeFromSourceRange(
158+
SM, init->getSourceRange());
159+
if (initRange.isValid() && initRange.contains(Loc))
160+
return;
161+
}
155162
}
156163
}
157164

lib/IDE/CodeCompletion.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4652,8 +4652,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
46524652
: LookupKind::ValueInDeclContext;
46534653
NeedLeadingDot = false;
46544654

4655-
UsableFilteringDeclConsumer UsableFilteringConsumer(Ctx.SourceMgr,
4656-
Ctx.SourceMgr.getCodeCompletionLoc(), *this);
4655+
UsableFilteringDeclConsumer UsableFilteringConsumer(
4656+
Ctx.SourceMgr, CurrDeclContext, Ctx.SourceMgr.getCodeCompletionLoc(),
4657+
*this);
46574658
AccessFilteringDeclConsumer AccessFilteringConsumer(
46584659
CurrDeclContext, UsableFilteringConsumer);
46594660

lib/Sema/LookupVisibleDecls.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1303,7 +1303,7 @@ void swift::lookupVisibleDecls(VisibleDeclConsumer &Consumer,
13031303
return;
13041304
}
13051305
UsableFilteringDeclConsumer FilteringConsumer(DC->getASTContext().SourceMgr,
1306-
Loc, Consumer);
1306+
DC, Loc, Consumer);
13071307
lookupVisibleDeclsImpl(FilteringConsumer, DC, IncludeTopLevel, Loc);
13081308
}
13091309

test/IDE/complete_expr_postfix_begin.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@
8282
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OWN_INIT_5 | %FileCheck %s -check-prefix=OWN_INIT_5
8383
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OWN_INIT_6 | %FileCheck %s -check-prefix=OWN_INIT_6
8484
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OWN_INIT_7 | %FileCheck %s -check-prefix=OWN_INIT_7
85+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OWN_INIT_8 | %FileCheck %s -check-prefix=OWN_INIT_8
86+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OWN_INIT_9 | %FileCheck %s -check-prefix=OWN_INIT_9
87+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OWN_INIT_10 | %FileCheck %s -check-prefix=OWN_INIT_10
8588

8689
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OWN_ACCESSOR_1 | %FileCheck %s -check-prefix=OWN_ACCESSOR_1
8790
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OWN_ACCESSOR_2 | %FileCheck %s -check-prefix=OWN_ACCESSOR_2
@@ -584,13 +587,19 @@ func sync() {}
584587
var ownInit2: () -> Void = { #^OWN_INIT_2^# }
585588
// OWN_INIT_2: Begin completions
586589
// OWN_INIT_2-NOT: ownInit2
590+
var ownInit8: Int = "\(#^OWN_INIT_8^#)"
591+
// OWN_INIT_8: Begin completions
592+
// OWN_INIT_8-NOT: ownInit8
587593
struct OwnInitTester {
588594
var ownInit3: Int = #^OWN_INIT_3^#
589595
// OWN_INIT_3: Begin completions
590596
// OWN_INIT_3-NOT: ownInit3
591597
var ownInit4: () -> Void = { #^OWN_INIT_4^# }
592598
// OWN_INIT_4: Begin completions
593599
// OWN_INIT_4-NOT: ownInit4
600+
var ownInit9: String = "\(#^OWN_INIT_9^#)"
601+
// OWN_INIT_9: Begin completions
602+
// OWN_INIT_9-NOT: ownInit9
594603
}
595604
func ownInitTesting() {
596605
var ownInit5: Int = #^OWN_INIT_5^#
@@ -599,6 +608,9 @@ func ownInitTesting() {
599608
var ownInit6: () -> Void = { #^OWN_INIT_6^# }
600609
// OWN_INIT_6: Begin completions
601610
// OWN_INIT_6-NOT: ownInit6
611+
var ownInit10: String = "\(#^OWN_INIT_10^#)"
612+
// OWN_INIT_10: Begin completions
613+
// OWN_INIT_10-NOT: ownInit10
602614
}
603615
func ownInitTestingShadow(ownInit7: Int) {
604616
var ownInit7: Int = #^OWN_INIT_7^#

0 commit comments

Comments
 (0)