|
25 | 25 | #include "swift/ClangImporter/ClangModule.h"
|
26 | 26 | #include "swift/Driver/FrontendUtil.h"
|
27 | 27 | #include "swift/Frontend/Frontend.h"
|
| 28 | +#include "swift/IDE/CodeCompletion.h" |
28 | 29 | #include "swift/Parse/Lexer.h"
|
29 | 30 | #include "swift/Parse/PersistentParserState.h"
|
30 | 31 | #include "swift/Serialization/SerializedModuleLoader.h"
|
@@ -656,6 +657,81 @@ void swift::ide::CompletionInstance::performOperation(
|
656 | 657 | Offset, DiagC, Callback);
|
657 | 658 | }
|
658 | 659 |
|
| 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 | + |
659 | 735 | void swift::ide::CompletionInstance::typeContextInfo(
|
660 | 736 | swift::CompilerInvocation &Invocation, llvm::ArrayRef<const char *> Args,
|
661 | 737 | llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,
|
|
0 commit comments