Skip to content

Commit 1150e70

Browse files
committed
[CodeComplete] Store the compiler instace as a shared pointer in CompletionInstance
1 parent dec3267 commit 1150e70

File tree

5 files changed

+48
-56
lines changed

5 files changed

+48
-56
lines changed

include/swift/IDE/CompletionInstance.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ makeCodeCompletionMemoryBuffer(const llvm::MemoryBuffer *origBuf,
4646
/// The result returned via the callback from the perform*Operation methods.
4747
struct CompletionInstanceResult {
4848
/// The compiler instance that is prepared for the second pass.
49-
CompilerInstance &CI;
49+
std::shared_ptr<CompilerInstance> CI;
5050
/// Whether an AST was reused.
5151
bool DidReuseAST;
5252
/// Whether the CompletionInstance found a code completion token in the source
@@ -87,14 +87,14 @@ class CompletionInstance {
8787

8888
std::mutex mtx;
8989

90-
std::unique_ptr<CompilerInstance> CachedCI;
90+
std::shared_ptr<CompilerInstance> CachedCI;
9191
llvm::hash_code CachedArgHash;
9292
llvm::sys::TimePoint<> DependencyCheckedTimestamp;
9393
llvm::StringMap<llvm::hash_code> InMemoryDependencyHash;
9494
unsigned CachedReuseCount = 0;
9595
std::atomic<bool> CachedCIShouldBeInvalidated;
9696

97-
void cacheCompilerInstance(std::unique_ptr<CompilerInstance> CI,
97+
void cacheCompilerInstance(std::shared_ptr<CompilerInstance> CI,
9898
llvm::hash_code ArgsHash);
9999

100100
bool shouldCheckDependencies() const;

include/swift/IDE/SwiftCompletionInfo.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ namespace swift {
2020
namespace ide {
2121

2222
struct SwiftCompletionInfo {
23-
swift::ASTContext *swiftASTContext = nullptr;
24-
const swift::CompilerInvocation *invocation = nullptr;
23+
std::shared_ptr<CompilerInstance> compilerInstance = nullptr;
2524
CodeCompletionContext *completionContext = nullptr;
2625
};
2726

lib/IDE/CompletionInstance.cpp

Lines changed: 37 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -197,15 +197,14 @@ bool CompletionInstance::performCachedOperationIfPossible(
197197
if (CachedArgHash != ArgsHash)
198198
return false;
199199

200-
auto &CI = *CachedCI;
201-
auto *oldSF = CI.getCodeCompletionFile();
200+
auto *oldSF = CachedCI->getCodeCompletionFile();
202201
assert(oldSF->getBufferID());
203202

204203
auto *oldState = oldSF->getDelayedParserState();
205204
assert(oldState->hasCodeCompletionDelayedDeclState());
206205
auto &oldInfo = oldState->getCodeCompletionDelayedDeclState();
207206

208-
auto &SM = CI.getSourceMgr();
207+
auto &SM = CachedCI->getSourceMgr();
209208
auto bufferName = completionBuffer->getBufferIdentifier();
210209
if (SM.getIdentifierForBuffer(*oldSF->getBufferID()) != bufferName)
211210
return false;
@@ -222,7 +221,7 @@ bool CompletionInstance::performCachedOperationIfPossible(
222221
}
223222

224223
if (areAnyDependentFilesInvalidated(
225-
CI, *FileSystem, *oldSF->getBufferID(),
224+
*CachedCI, *FileSystem, *oldSF->getBufferID(),
226225
DependencyCheckedTimestamp, InMemoryDependencyHash))
227226
return false;
228227
DependencyCheckedTimestamp = std::chrono::system_clock::now();
@@ -233,10 +232,10 @@ bool CompletionInstance::performCachedOperationIfPossible(
233232
auto tmpBufferID = tmpSM.addMemBufferCopy(completionBuffer);
234233
tmpSM.setCodeCompletionPoint(tmpBufferID, Offset);
235234

236-
LangOptions langOpts = CI.getASTContext().LangOpts;
237-
TypeCheckerOptions typeckOpts = CI.getASTContext().TypeCheckerOpts;
238-
SILOptions silOpts = CI.getASTContext().SILOpts;
239-
SearchPathOptions searchPathOpts = CI.getASTContext().SearchPathOpts;
235+
LangOptions langOpts = CachedCI->getASTContext().LangOpts;
236+
TypeCheckerOptions typeckOpts = CachedCI->getASTContext().TypeCheckerOpts;
237+
SILOptions silOpts = CachedCI->getASTContext().SILOpts;
238+
SearchPathOptions searchPathOpts = CachedCI->getASTContext().SearchPathOpts;
240239
DiagnosticEngine tmpDiags(tmpSM);
241240
ClangImporterOptions clangOpts;
242241
symbolgraphgen::SymbolGraphOptions symbolOpts;
@@ -382,7 +381,7 @@ bool CompletionInstance::performCachedOperationIfPossible(
382381
newM->addFile(*newSF);
383382

384383
// Tell the compiler instance we've replaced the main module.
385-
CI.setMainModule(newM);
384+
CachedCI->setMainModule(newM);
386385

387386
// Re-process the whole file (parsing will be lazily triggered). Still
388387
// re-use imported modules.
@@ -407,22 +406,22 @@ bool CompletionInstance::performCachedOperationIfPossible(
407406

408407
// The diagnostic engine is keeping track of state which might modify
409408
// parsing and type checking behaviour. Clear the flags.
410-
CI.getDiags().resetHadAnyError();
411-
CI.getASTContext().CancellationFlag = CancellationFlag;
409+
CachedCI->getDiags().resetHadAnyError();
410+
CachedCI->getASTContext().CancellationFlag = CancellationFlag;
412411

413412
if (DiagC)
414-
CI.addDiagnosticConsumer(DiagC);
413+
CachedCI->addDiagnosticConsumer(DiagC);
415414

416415
if (CancellationFlag && CancellationFlag->load(std::memory_order_relaxed)) {
417416
Callback(CancellableResult<CompletionInstanceResult>::cancelled());
418417
} else {
419418
Callback(CancellableResult<CompletionInstanceResult>::success(
420-
{CI, /*reusingASTContext=*/true,
419+
{CachedCI, /*reusingASTContext=*/true,
421420
/*DidFindCodeCompletionToken=*/true}));
422421
}
423422

424423
if (DiagC)
425-
CI.removeDiagnosticConsumer(DiagC);
424+
CachedCI->removeDiagnosticConsumer(DiagC);
426425
}
427426

428427
CachedReuseCount += 1;
@@ -443,45 +442,44 @@ void CompletionInstance::performNewOperation(
443442
// If ArgsHash is None we shouldn't cache the compiler instance.
444443
bool ShouldCacheCompilerInstance = ArgsHash.hasValue();
445444

446-
auto TheInstance = std::make_unique<CompilerInstance>();
445+
auto CI = std::make_shared<CompilerInstance>();
447446

448447
// Track non-system dependencies in fast-completion mode to invalidate the
449448
// compiler instance if any dependent files are modified.
450449
Invocation.getFrontendOptions().IntermoduleDependencyTracking =
451450
IntermoduleDepTrackingMode::ExcludeSystem;
452451

453452
{
454-
auto &CI = *TheInstance;
455453
if (DiagC)
456-
CI.addDiagnosticConsumer(DiagC);
454+
CI->addDiagnosticConsumer(DiagC);
457455

458456
SWIFT_DEFER {
459457
if (DiagC)
460-
CI.removeDiagnosticConsumer(DiagC);
458+
CI->removeDiagnosticConsumer(DiagC);
461459
};
462460

463461
if (FileSystem != llvm::vfs::getRealFileSystem())
464-
CI.getSourceMgr().setFileSystem(FileSystem);
462+
CI->getSourceMgr().setFileSystem(FileSystem);
465463

466464
Invocation.setCodeCompletionPoint(completionBuffer, Offset);
467465

468466
std::string InstanceSetupError;
469-
if (CI.setup(Invocation, InstanceSetupError)) {
467+
if (CI->setup(Invocation, InstanceSetupError)) {
470468
Callback(CancellableResult<CompletionInstanceResult>::failure(
471469
InstanceSetupError));
472470
return;
473471
}
474-
CI.getASTContext().CancellationFlag = CancellationFlag;
475-
registerIDERequestFunctions(CI.getASTContext().evaluator);
472+
CI->getASTContext().CancellationFlag = CancellationFlag;
473+
registerIDERequestFunctions(CI->getASTContext().evaluator);
476474

477-
CI.performParseAndResolveImportsOnly();
475+
CI->performParseAndResolveImportsOnly();
478476

479-
bool DidFindCodeCompletionToken = CI.getCodeCompletionFile()
477+
bool DidFindCodeCompletionToken = CI->getCodeCompletionFile()
480478
->getDelayedParserState()
481479
->hasCodeCompletionDelayedDeclState();
482480
ShouldCacheCompilerInstance &= DidFindCodeCompletionToken;
483481

484-
auto CancellationFlag = CI.getASTContext().CancellationFlag;
482+
auto CancellationFlag = CI->getASTContext().CancellationFlag;
485483
if (CancellationFlag && CancellationFlag->load(std::memory_order_relaxed)) {
486484
Callback(CancellableResult<CompletionInstanceResult>::cancelled());
487485
// The completion instance may be in an invalid state when it's been
@@ -502,11 +500,11 @@ void CompletionInstance::performNewOperation(
502500
// because performCachedOperationIfPossible wouldn't have an old code
503501
// completion state to compare the new one to.
504502
if (ShouldCacheCompilerInstance)
505-
cacheCompilerInstance(std::move(TheInstance), *ArgsHash);
503+
cacheCompilerInstance(std::move(CI), *ArgsHash);
506504
}
507505

508506
void CompletionInstance::cacheCompilerInstance(
509-
std::unique_ptr<CompilerInstance> CI, llvm::hash_code ArgsHash) {
507+
std::shared_ptr<CompilerInstance> CI, llvm::hash_code ArgsHash) {
510508
CachedCI = std::move(CI);
511509
CachedArgHash = ArgsHash;
512510
auto now = std::chrono::system_clock::now();
@@ -602,11 +600,9 @@ void swift::ide::CompletionInstance::codeComplete(
602600
: ImportDep(ImportDep), CancellationFlag(CancellationFlag),
603601
Callback(Callback) {}
604602

605-
void setContext(swift::ASTContext *context,
606-
const swift::CompilerInvocation *invocation,
603+
void setContext(std::shared_ptr<CompilerInstance> compilerInstance,
607604
swift::ide::CodeCompletionContext *completionContext) {
608-
SwiftContext.swiftASTContext = context;
609-
SwiftContext.invocation = invocation;
605+
SwiftContext.compilerInstance = std::move(compilerInstance);
610606
SwiftContext.completionContext = completionContext;
611607
}
612608
void clearContext() { SwiftContext = SwiftCompletionInfo(); }
@@ -617,7 +613,7 @@ void swift::ide::CompletionInstance::codeComplete(
617613
CancellationFlag->load(std::memory_order_relaxed)) {
618614
Callback(ResultType::cancelled());
619615
} else {
620-
assert(SwiftContext.swiftASTContext);
616+
assert(SwiftContext.compilerInstance);
621617
Callback(ResultType::success({context.getResultSink(), SwiftContext, ImportDep}));
622618
}
623619
}
@@ -631,9 +627,9 @@ void swift::ide::CompletionInstance::codeComplete(
631627
[&CompletionContext, &CancellationFlag](auto &Result,
632628
auto DeliverTransformed) {
633629
CompletionContext.ReusingASTContext = Result.DidReuseAST;
634-
CompilerInstance &CI = Result.CI;
635-
ImportDepth ImportDep{CI.getASTContext(),
636-
CI.getInvocation().getFrontendOptions()};
630+
std::shared_ptr<CompilerInstance> CI = Result.CI;
631+
ImportDepth ImportDep{CI->getASTContext(),
632+
CI->getInvocation().getFrontendOptions()};
637633
ConsumerToCallbackAdapter Consumer(ImportDep, CancellationFlag,
638634
DeliverTransformed);
639635

@@ -642,27 +638,22 @@ void swift::ide::CompletionInstance::codeComplete(
642638
Consumer));
643639

644640
if (!Result.DidFindCodeCompletionToken) {
645-
SwiftCompletionInfo Info{&CI.getASTContext(),
646-
&CI.getInvocation(),
647-
&CompletionContext};
641+
SwiftCompletionInfo Info{CI, &CompletionContext};
648642
CodeCompletionResultSink ResultSink;
649643
DeliverTransformed(ResultType::success({ResultSink, Info, ImportDep}));
650644
return;
651645
}
652646

653-
Consumer.setContext(&CI.getASTContext(), &CI.getInvocation(),
654-
&CompletionContext);
655-
performCodeCompletionSecondPass(*CI.getCodeCompletionFile(),
647+
Consumer.setContext(CI, &CompletionContext);
648+
performCodeCompletionSecondPass(*CI->getCodeCompletionFile(),
656649
*callbacksFactory);
657650
Consumer.clearContext();
658651
if (!Consumer.HandleResultsCalled) {
659652
// If we didn't receive a handleResult call from the second
660653
// pass, we didn't receive any results. To make sure Callback
661654
// gets called exactly once, call it manually with no results
662655
// here.
663-
SwiftCompletionInfo Info{&CI.getASTContext(),
664-
&CI.getInvocation(),
665-
&CompletionContext};
656+
SwiftCompletionInfo Info{CI, &CompletionContext};
666657
CodeCompletionResultSink ResultSink;
667658
DeliverTransformed(ResultType::success({ResultSink, Info, ImportDep}));
668659
}
@@ -724,7 +715,7 @@ void swift::ide::CompletionInstance::typeContextInfo(
724715
}
725716

726717
performCodeCompletionSecondPass(
727-
*Result.CI.getCodeCompletionFile(), *callbacksFactory);
718+
*Result.CI->getCodeCompletionFile(), *callbacksFactory);
728719
if (!Consumer.HandleResultsCalled) {
729720
// If we didn't receive a handleResult call from the second
730721
// pass, we didn't receive any results. To make sure Callback
@@ -792,7 +783,7 @@ void swift::ide::CompletionInstance::conformingMethodList(
792783
}
793784

794785
performCodeCompletionSecondPass(
795-
*Result.CI.getCodeCompletionFile(), *callbacksFactory);
786+
*Result.CI->getCodeCompletionFile(), *callbacksFactory);
796787
if (!Consumer.HandleResultsCalled) {
797788
// If we didn't receive a handleResult call from the second
798789
// pass, we didn't receive any results. To make sure Callback

tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,11 @@ std::vector<Completion *> SourceKit::CodeCompletion::extendCompletions(
7676
const Options &options, Completion *prefix, bool clearFlair) {
7777

7878
ImportDepth depth;
79-
if (info.swiftASTContext) {
79+
if (info.compilerInstance) {
8080
// Build import depth map.
81-
depth = ImportDepth(*info.swiftASTContext,
82-
info.invocation->getFrontendOptions());
81+
depth = ImportDepth(
82+
info.compilerInstance->getASTContext(),
83+
info.compilerInstance->getInvocation().getFrontendOptions());
8384
}
8485

8586
if (info.completionContext)

tools/swift-ide-test/swift-ide-test.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,7 +1168,7 @@ static int printCodeCompletionResults(
11681168
printCodeCompletionResultsImpl(
11691169
Result.ResultSink.Results, llvm::outs(), IncludeKeywords,
11701170
IncludeComments, IncludeSourceText, PrintAnnotatedDescription,
1171-
*Result.Info.swiftASTContext);
1171+
Result.Info.compilerInstance->getASTContext());
11721172
return 0;
11731173
});
11741174
}
@@ -1547,7 +1547,8 @@ static int doBatchCodeCompletion(const CompilerInvocation &InitInvok,
15471547
printCodeCompletionResultsImpl(
15481548
Result->ResultSink.Results, OS, IncludeKeywords,
15491549
IncludeComments, IncludeSourceText,
1550-
CodeCompletionAnnotateResults, *Result->Info.swiftASTContext);
1550+
CodeCompletionAnnotateResults,
1551+
Result->Info.compilerInstance->getASTContext());
15511552
break;
15521553
}
15531554
case CancellableResultKind::Failure:

0 commit comments

Comments
 (0)