[CodeCompletion] Refactor how code completion results are returned to support cancellation

This refactors a bunch of code-completion methods around `performOperation` to return their results via a callback only instead of the current mixed approach  of indicating failure via a return value, returning an error string as an inout parameter and success results via a callback. The new guarantee should be that the callback is always called exactly once on control flow graph.

Other than a support for passing the (currently unused) cancelled state through the different instance, there should be no functionality change.
This commit is contained in:
Alex Hoppen
2021-10-07 18:03:29 +02:00
parent c209f52b9c
commit 2fcb24e716
13 changed files with 691 additions and 184 deletions

View File

@@ -1000,12 +1000,12 @@ SwiftLangSupport::getFileSystem(const Optional<VFSOptions> &vfsOptions,
return llvm::vfs::getRealFileSystem();
}
bool SwiftLangSupport::performCompletionLikeOperation(
void SwiftLangSupport::performCompletionLikeOperation(
llvm::MemoryBuffer *UnresolvedInputFile, unsigned Offset,
ArrayRef<const char *> Args,
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,
std::string &Error,
llvm::function_ref<void(CompilerInstance &, bool)> Callback) {
llvm::function_ref<void(CancellableResult<CompletionInstanceResult>)>
Callback) {
assert(FileSystem);
// Resolve symlinks for the input file; we resolve them for the input files
@@ -1045,22 +1045,26 @@ bool SwiftLangSupport::performCompletionLikeOperation(
ForwardingDiagnosticConsumer CIDiags(Diags);
CompilerInvocation Invocation;
bool Failed = getASTManager()->initCompilerInvocation(
std::string CompilerInvocationError;
bool CreatingInvocationFailed = getASTManager()->initCompilerInvocation(
Invocation, Args, Diags, newBuffer->getBufferIdentifier(), FileSystem,
Error);
if (Failed)
return false;
CompilerInvocationError);
if (CreatingInvocationFailed) {
Callback(CancellableResult<CompletionInstanceResult>::failure(
CompilerInvocationError));
return;
}
if (!Invocation.getFrontendOptions().InputsAndOutputs.hasInputs()) {
Error = "no input filenames specified";
return false;
Callback(CancellableResult<CompletionInstanceResult>::failure(
"no input filenames specified"));
return;
}
// Pin completion instance.
auto CompletionInst = getCompletionInstance();
return CompletionInst->performOperation(Invocation, Args, FileSystem,
newBuffer.get(), Offset,
Error, &CIDiags, Callback);
CompletionInst->performOperation(Invocation, Args, FileSystem,
newBuffer.get(), Offset, &CIDiags, Callback);
}
CloseClangModuleFiles::~CloseClangModuleFiles() {