Skip to content

Commit 8c2a7d8

Browse files
committed
[CodeCompletion] Inherit options when parsing new buffer
for fast completions. Options may affect the parsing result. Also, don't collect interface hash tokens inside inactive blocks. (cherry picked from commit ec0c948)
1 parent de3a67a commit 8c2a7d8

File tree

3 files changed

+55
-7
lines changed

3 files changed

+55
-7
lines changed

lib/IDE/CompletionInstance.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -315,10 +315,10 @@ bool CompletionInstance::performCachedOperationIfPossible(
315315
auto tmpBufferID = tmpSM.addMemBufferCopy(completionBuffer);
316316
tmpSM.setCodeCompletionPoint(tmpBufferID, Offset);
317317

318-
LangOptions langOpts;
318+
LangOptions langOpts = CI.getASTContext().LangOpts;
319319
langOpts.DisableParserLookup = true;
320-
TypeCheckerOptions typeckOpts;
321-
SearchPathOptions searchPathOpts;
320+
TypeCheckerOptions typeckOpts = CI.getASTContext().TypeCheckerOpts;
321+
SearchPathOptions searchPathOpts = CI.getASTContext().SearchPathOpts;
322322
DiagnosticEngine tmpDiags(tmpSM);
323323
std::unique_ptr<ASTContext> tmpCtx(
324324
ASTContext::get(langOpts, typeckOpts, searchPathOpts, tmpSM, tmpDiags));
@@ -327,15 +327,22 @@ bool CompletionInstance::performCachedOperationIfPossible(
327327
registerTypeCheckerRequestFunctions(tmpCtx->evaluator);
328328
registerSILGenRequestFunctions(tmpCtx->evaluator);
329329
ModuleDecl *tmpM = ModuleDecl::create(Identifier(), *tmpCtx);
330-
SourceFile *tmpSF =
331-
new (*tmpCtx) SourceFile(*tmpM, oldSF->Kind, tmpBufferID,
332-
SourceFile::ImplicitModuleImportKind::None);
330+
SourceFile *tmpSF = new (*tmpCtx)
331+
SourceFile(*tmpM, oldSF->Kind, tmpBufferID,
332+
SourceFile::ImplicitModuleImportKind::None,
333+
/*KeepParsedTokens=*/false, /*BuildSyntaxTree=*/false,
334+
oldSF->getParsingOptions());
333335
tmpSF->enableInterfaceHash();
334336
// Ensure all non-function-body tokens are hashed into the interface hash
335337
tmpCtx->LangOpts.EnableTypeFingerprints = false;
336338

337-
// Couldn't find any completion token?
339+
// FIXME: Since we don't setup module loaders on the temporary AST context,
340+
// 'canImport()' conditional compilation directive always fails. That causes
341+
// interface hash change and prevents fast-completion.
342+
343+
// Parse and get the completion context.
338344
auto *newState = tmpSF->getDelayedParserState();
345+
// Couldn't find any completion token?
339346
if (!newState->hasCodeCompletionDelayedDeclState())
340347
return false;
341348

lib/Parse/ParseIfConfig.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,10 @@ ParserResult<IfConfigDecl> Parser::parseIfConfig(
676676
SmallVector<ASTNode, 16> Elements;
677677
llvm::SaveAndRestore<bool> S(InInactiveClauseEnvironment,
678678
InInactiveClauseEnvironment || !isActive);
679+
// Disable updating the interface hash inside inactive blocks.
680+
llvm::SaveAndRestore<NullablePtr<llvm::MD5>> T(
681+
CurrentTokenHash, isActive ? CurrentTokenHash : nullptr);
682+
679683
if (isActive || !isVersionCondition) {
680684
parseElements(Elements, isActive);
681685
} else if (SyntaxContext->isEnabled()) {
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
struct MyStruct { func foo() {} }
2+
3+
#if DEBUG
4+
import Swift
5+
#endif
6+
7+
#if arch(x86_64)
8+
operator ++++++
9+
#endif
10+
11+
#if !targetEnvironment(simulator)
12+
precedencegroup MyPrecedence
13+
#endif
14+
15+
func foo(value: MyStruct) {
16+
value.
17+
}
18+
19+
// Ensure that compilation directives are equally evaluated and doesn't affect the fast completions.
20+
21+
// RUN: %sourcekitd-test \
22+
// RUN: -req=complete -pos=16:9 -repeat-request=2 %s -- %s -target %target-triple \
23+
// RUN: | %FileCheck %s
24+
25+
// CHECK-LABEL: key.results: [
26+
// CHECK-NOT: ]
27+
// CHECK-DAG: key.description: "foo()",
28+
// CHECK-DAG: key.description: "self",
29+
// CHECK: ]
30+
// CHECK-NOT: key.reusingastcontext
31+
32+
// CHECK-LABEL: key.results: [
33+
// CHECK-NOT: ]
34+
// CHECK-DAG: key.description: "foo()",
35+
// CHECK-DAG: key.description: "self",
36+
// CHECK: ],
37+
// CHECK: key.reusingastcontext: 1

0 commit comments

Comments
 (0)