Skip to content

Commit 163ccf9

Browse files
committed
[SourceKit] Move invocation of code completion second pass for code completion from SoruceKit to CompletionInstance
1 parent 367c981 commit 163ccf9

File tree

5 files changed

+193
-219
lines changed

5 files changed

+193
-219
lines changed

include/swift/IDE/CodeCompletion.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "swift/Basic/Debug.h"
1818
#include "swift/Basic/LLVM.h"
1919
#include "swift/Basic/OptionSet.h"
20+
#include "swift/Frontend/Frontend.h"
2021
#include "llvm/ADT/ArrayRef.h"
2122
#include "llvm/ADT/StringMap.h"
2223
#include "llvm/ADT/StringRef.h"
@@ -1062,6 +1063,12 @@ class CodeCompletionContext {
10621063
}
10631064
};
10641065

1066+
struct SwiftCompletionInfo {
1067+
swift::ASTContext *swiftASTContext = nullptr;
1068+
const swift::CompilerInvocation *invocation = nullptr;
1069+
CodeCompletionContext *completionContext = nullptr;
1070+
};
1071+
10651072
/// An abstract base class for consumers of code completion results.
10661073
/// \see \c SimpleCachingCodeCompletionConsumer.
10671074
class CodeCompletionConsumer {

include/swift/IDE/CompletionInstance.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "swift/Frontend/Frontend.h"
1717
#include "swift/IDE/CancellableResult.h"
18+
#include "swift/IDE/CodeCompletion.h"
1819
#include "swift/IDE/ConformingMethodList.h"
1920
#include "swift/IDE/TypeContextInfo.h"
2021
#include "llvm/ADT/Hashing.h"
@@ -50,6 +51,12 @@ struct CompletionInstanceResult {
5051
bool DidFindCodeCompletionToken;
5152
};
5253

54+
/// The results returned from \c CompletionInstance::codeComplete.
55+
struct CodeCompleteResult {
56+
MutableArrayRef<CodeCompletionResult *> Results;
57+
SwiftCompletionInfo &Info;
58+
};
59+
5360
/// The results returned from \c CompletionInstance::typeContextInfo.
5461
struct TypeContextInfoResult {
5562
/// The actual results. If empty, no results were found.
@@ -143,6 +150,13 @@ class CompletionInstance {
143150
llvm::function_ref<void(CancellableResult<CompletionInstanceResult>)>
144151
Callback);
145152

153+
void codeComplete(
154+
swift::CompilerInvocation &Invocation, llvm::ArrayRef<const char *> Args,
155+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,
156+
llvm::MemoryBuffer *completionBuffer, unsigned int Offset,
157+
DiagnosticConsumer *DiagC, ide::CodeCompletionContext &&CompletionContext,
158+
llvm::function_ref<void(CancellableResult<CodeCompleteResult>)> Callback);
159+
146160
void typeContextInfo(
147161
swift::CompilerInvocation &Invocation, llvm::ArrayRef<const char *> Args,
148162
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,

lib/IDE/CompletionInstance.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "swift/ClangImporter/ClangModule.h"
2626
#include "swift/Driver/FrontendUtil.h"
2727
#include "swift/Frontend/Frontend.h"
28+
#include "swift/IDE/CodeCompletion.h"
2829
#include "swift/Parse/Lexer.h"
2930
#include "swift/Parse/PersistentParserState.h"
3031
#include "swift/Serialization/SerializedModuleLoader.h"
@@ -656,6 +657,81 @@ void swift::ide::CompletionInstance::performOperation(
656657
Offset, DiagC, Callback);
657658
}
658659

660+
void swift::ide::CompletionInstance::codeComplete(
661+
swift::CompilerInvocation &Invocation, llvm::ArrayRef<const char *> Args,
662+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,
663+
llvm::MemoryBuffer *completionBuffer, unsigned int Offset,
664+
DiagnosticConsumer *DiagC, ide::CodeCompletionContext &&CompletionContext,
665+
llvm::function_ref<void(CancellableResult<CodeCompleteResult>)> Callback) {
666+
using ResultType = CancellableResult<CodeCompleteResult>;
667+
668+
struct ConsumerToCallbackAdapter
669+
: public SimpleCachingCodeCompletionConsumer {
670+
SwiftCompletionInfo SwiftContext;
671+
llvm::function_ref<void(ResultType)> Callback;
672+
bool HandleResultsCalled = false;
673+
674+
ConsumerToCallbackAdapter(llvm::function_ref<void(ResultType)> Callback)
675+
: Callback(Callback) {}
676+
677+
void setContext(swift::ASTContext *context,
678+
const swift::CompilerInvocation *invocation,
679+
swift::ide::CodeCompletionContext *completionContext) {
680+
SwiftContext.swiftASTContext = context;
681+
SwiftContext.invocation = invocation;
682+
SwiftContext.completionContext = completionContext;
683+
}
684+
void clearContext() { SwiftContext = SwiftCompletionInfo(); }
685+
686+
void handleResults(CodeCompletionContext &context) override {
687+
HandleResultsCalled = true;
688+
MutableArrayRef<CodeCompletionResult *> Results = context.takeResults();
689+
assert(SwiftContext.swiftASTContext);
690+
Callback(ResultType::success({Results, SwiftContext}));
691+
}
692+
};
693+
694+
performOperation(
695+
Invocation, Args, FileSystem, completionBuffer, Offset, DiagC,
696+
[&](CancellableResult<CompletionInstanceResult> CIResult) {
697+
CIResult.mapAsync<CodeCompleteResult>(
698+
[&CompletionContext](auto &Result, auto DeliverTransformed) {
699+
CompletionContext.ReusingASTContext = Result.DidReuseAST;
700+
CompilerInstance &CI = Result.CI;
701+
ConsumerToCallbackAdapter Consumer(DeliverTransformed);
702+
703+
std::unique_ptr<CodeCompletionCallbacksFactory> callbacksFactory(
704+
ide::makeCodeCompletionCallbacksFactory(CompletionContext,
705+
Consumer));
706+
707+
if (!Result.DidFindCodeCompletionToken) {
708+
SwiftCompletionInfo Info{&CI.getASTContext(),
709+
&CI.getInvocation(),
710+
&CompletionContext};
711+
DeliverTransformed(ResultType::success({/*Results=*/{}, Info}));
712+
return;
713+
}
714+
715+
Consumer.setContext(&CI.getASTContext(), &CI.getInvocation(),
716+
&CompletionContext);
717+
performCodeCompletionSecondPass(*CI.getCodeCompletionFile(),
718+
*callbacksFactory);
719+
Consumer.clearContext();
720+
if (!Consumer.HandleResultsCalled) {
721+
// If we didn't receive a handleResult call from the second
722+
// pass, we didn't receive any results. To make sure Callback
723+
// gets called exactly once, call it manually with no results
724+
// here.
725+
SwiftCompletionInfo Info{&CI.getASTContext(),
726+
&CI.getInvocation(),
727+
&CompletionContext};
728+
DeliverTransformed(ResultType::success({/*Results=*/{}, Info}));
729+
}
730+
},
731+
Callback);
732+
});
733+
}
734+
659735
void swift::ide::CompletionInstance::typeContextInfo(
660736
swift::CompilerInvocation &Invocation, llvm::ArrayRef<const char *> Args,
661737
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,

tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "CodeCompletion.h"
1717
#include "SourceKit/Core/LangSupport.h"
18+
#include "swift/IDE/CodeCompletion.h"
1819
#include "llvm/ADT/StringMap.h"
1920

2021
namespace swift {
@@ -53,17 +54,11 @@ struct Options {
5354
unsigned popularityBonus = 2;
5455
};
5556

56-
struct SwiftCompletionInfo {
57-
swift::ASTContext *swiftASTContext = nullptr;
58-
const swift::CompilerInvocation *invocation = nullptr;
59-
swift::ide::CodeCompletionContext *completionContext = nullptr;
60-
};
61-
6257
typedef llvm::StringMap<PopularityFactor> NameToPopularityMap;
6358

6459
std::vector<Completion *>
6560
extendCompletions(ArrayRef<SwiftResult *> swiftResults, CompletionSink &sink,
66-
SwiftCompletionInfo &info,
61+
swift::ide::SwiftCompletionInfo &info,
6762
const NameToPopularityMap *nameToPopularity,
6863
const Options &options, Completion *prefix = nullptr,
6964
bool clearFlair = false);

0 commit comments

Comments
 (0)