[SourceKit] Reuse compiler instance between multiple completion

- Introduce ide::CompletionInstance to manage CompilerInstance
- `CompletionInstance` vends the cached CompilerInstance when:
-- The compiler arguments (i.e. CompilerInvocation) has has not changed
-- The primary file is the same
-- The completion happens inside function bodies in both previous and
   current completion
-- The interface hash of the primary file has not changed
- Otherwise, it vends a fresh CompilerInstance and cache it for the next
  completion

rdar://problem/20787086
This commit is contained in:
Rintaro Ishizaki
2019-11-18 18:02:41 +09:00
parent ff97c06e8d
commit 62c44126b6
23 changed files with 589 additions and 318 deletions

View File

@@ -25,6 +25,7 @@
#include "swift/Config.h"
#include "swift/IDE/CodeCompletion.h"
#include "swift/IDE/CodeCompletionCache.h"
#include "swift/IDE/CompletionInstance.h"
#include "swift/IDE/SyntaxModel.h"
#include "swift/IDE/Utils.h"
@@ -266,6 +267,9 @@ SwiftLangSupport::SwiftLangSupport(SourceKit::Context &SKCtx)
ASTMgr = std::make_shared<SwiftASTManager>(EditorDocuments,
SKCtx.getGlobalConfiguration(),
Stats, RuntimeResourcePath);
CompletionInst = std::make_unique<CompletionInstance>();
// By default, just use the in-memory cache.
CCCache->inMemory = llvm::make_unique<ide::CodeCompletionCache>();
@@ -276,26 +280,6 @@ SwiftLangSupport::SwiftLangSupport(SourceKit::Context &SKCtx)
SwiftLangSupport::~SwiftLangSupport() {
}
std::unique_ptr<llvm::MemoryBuffer>
SwiftLangSupport::makeCodeCompletionMemoryBuffer(
const llvm::MemoryBuffer *origBuf, unsigned &Offset,
const std::string bufferIdentifier) {
auto origBuffSize = origBuf->getBufferSize();
if (Offset > origBuffSize)
Offset = origBuffSize;
auto newBuffer = llvm::WritableMemoryBuffer::getNewUninitMemBuffer(
origBuffSize + 1, bufferIdentifier);
auto *pos = origBuf->getBufferStart() + Offset;
auto *newPos =
std::copy(origBuf->getBufferStart(), pos, newBuffer->getBufferStart());
*newPos = '\0';
std::copy(pos, origBuf->getBufferEnd(), newPos + 1);
return std::unique_ptr<llvm::MemoryBuffer>(newBuffer.release());
}
UIdent SwiftLangSupport::getUIDForDecl(const Decl *D, bool IsRef) {
return UIdentVisitor(IsRef).visit(const_cast<Decl*>(D));
}