@@ -701,9 +701,65 @@ void swift::ide::CompletionInstance::typeContextInfo(
701
701
*Result.CI .getCodeCompletionFile (), *callbacksFactory);
702
702
if (!Consumer.HandleResultsCalled ) {
703
703
// If we didn't receive a handleResult call from the second
704
- // pass, we didn't receive any results. To make sure
705
- // DeliverTransformed gets called exactly once, call it with
706
- // no results here.
704
+ // pass, we didn't receive any results. To make sure Callback
705
+ // gets called exactly once, call it manually with no results
706
+ // here.
707
+ DeliverTransformed (
708
+ ResultType::success ({/* Results=*/ {}, Result.DidReuseAST }));
709
+ }
710
+ },
711
+ Callback);
712
+ });
713
+ }
714
+
715
+ void swift::ide::CompletionInstance::conformingMethodList (
716
+ swift::CompilerInvocation &Invocation, llvm::ArrayRef<const char *> Args,
717
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,
718
+ llvm::MemoryBuffer *completionBuffer, unsigned int Offset,
719
+ DiagnosticConsumer *DiagC, ArrayRef<const char *> ExpectedTypeNames,
720
+ llvm::function_ref<void (CancellableResult<ConformingMethodListResults>)>
721
+ Callback) {
722
+ using ResultType = CancellableResult<ConformingMethodListResults>;
723
+
724
+ struct ConsumerToCallbackAdapter
725
+ : public swift::ide::ConformingMethodListConsumer {
726
+ bool ReusingASTContext;
727
+ llvm::function_ref<void (ResultType)> Callback;
728
+ bool HandleResultsCalled = false ;
729
+
730
+ ConsumerToCallbackAdapter (bool ReusingASTContext,
731
+ llvm::function_ref<void (ResultType)> Callback)
732
+ : ReusingASTContext(ReusingASTContext), Callback(Callback) {}
733
+
734
+ void handleResult (const ide::ConformingMethodListResult &result) override {
735
+ HandleResultsCalled = true ;
736
+ Callback (ResultType::success ({&result, ReusingASTContext}));
737
+ }
738
+ };
739
+
740
+ performOperation (
741
+ Invocation, Args, FileSystem, completionBuffer, Offset, DiagC,
742
+ [&](CancellableResult<CompletionInstanceResult> CIResult) {
743
+ CIResult.mapAsync <ConformingMethodListResults>(
744
+ [&ExpectedTypeNames](auto &Result, auto DeliverTransformed) {
745
+ ConsumerToCallbackAdapter Consumer (Result.DidReuseAST ,
746
+ DeliverTransformed);
747
+ std::unique_ptr<CodeCompletionCallbacksFactory> callbacksFactory (
748
+ ide::makeConformingMethodListCallbacksFactory (
749
+ ExpectedTypeNames, Consumer));
750
+
751
+ if (!Result.DidFindCodeCompletionToken ) {
752
+ DeliverTransformed (
753
+ ResultType::success ({/* Results=*/ {}, Result.DidReuseAST }));
754
+ }
755
+
756
+ performCodeCompletionSecondPass (
757
+ *Result.CI .getCodeCompletionFile (), *callbacksFactory);
758
+ if (!Consumer.HandleResultsCalled ) {
759
+ // If we didn't receive a handleResult call from the second
760
+ // pass, we didn't receive any results. To make sure Callback
761
+ // gets called exactly once, call it manually with no results
762
+ // here.
707
763
DeliverTransformed (
708
764
ResultType::success ({/* Results=*/ {}, Result.DidReuseAST }));
709
765
}
0 commit comments