diff --git a/include/swift/Parse/CodeCompletionCallbacks.h b/include/swift/Parse/CodeCompletionCallbacks.h index b8c5fe151fe83..eeee748a4b904 100644 --- a/include/swift/Parse/CodeCompletionCallbacks.h +++ b/include/swift/Parse/CodeCompletionCallbacks.h @@ -198,6 +198,10 @@ class CodeCompletionCallbacks { virtual void completeCallArg(CodeCompletionExpr *E, bool isFirst) {}; + virtual bool canPerformCompleteLabeledTrailingClosure() const { + return false; + } + virtual void completeLabeledTrailingClosure(CodeCompletionExpr *E, bool isAtStartOfLine) {}; diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp index f05c3c8ffe83a..99a42527e03ba 100644 --- a/lib/IDE/CodeCompletion.cpp +++ b/lib/IDE/CodeCompletion.cpp @@ -1687,6 +1687,10 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks { void completeLabeledTrailingClosure(CodeCompletionExpr *E, bool isAtStartOfLine) override; + bool canPerformCompleteLabeledTrailingClosure() const override { + return true; + } + void completeReturnStmt(CodeCompletionExpr *E) override; void completeYieldStmt(CodeCompletionExpr *E, Optional yieldIndex) override; diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 3922c9e2d1569..d35321bbced2e 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -3213,6 +3213,13 @@ Parser::parseTrailingClosures(bool isExprBasic, SourceRange calleeRange, if (!Tok.is(tok::code_complete)) break; + // If the current completion mode doesn't support trailing closure + // completion, leave the token here and let "postfix completion" to + // handle it. + if (CodeCompletion && + !CodeCompletion->canPerformCompleteLabeledTrailingClosure()) + break; + // foo() {} auto CCExpr = new (Context) CodeCompletionExpr(Tok.getLoc()); if (CodeCompletion) diff --git a/test/IDE/conforming-methods-afterclosure.swift b/test/IDE/conforming-methods-afterclosure.swift new file mode 100644 index 0000000000000..faa168b12761d --- /dev/null +++ b/test/IDE/conforming-methods-afterclosure.swift @@ -0,0 +1,27 @@ +// RUN: %target-swift-ide-test -conforming-methods -source-filename %s -code-completion-token=AFTER_TRAILINGCLOSURE -module-name MyModule -conforming-methods-expected-types 's:8MyModule7TargetPP' | %FileCheck %s -check-prefix=AFTER_TRAILINGCLOSURE + +public protocol TargetP {} +struct ConcreteP: TargetP {} + +public struct MyStruct { + init(arg1: Int = 0, fn: () -> Int) {} + + public func returnSomeP -> some TargetP { ConcreteP() } + public func returnConcreteP -> ConcreteP { ConcreteP() } + public func reutrnInt -> Int { 1 } +} + +func test() { + MyStruct { + 1 + } #^AFTER_TRAILINGCLOSURE^# +} + +//AFTER_TRAILINGCLOSURE: -----BEGIN CONFORMING METHOD LIST----- +//AFTER_TRAILINGCLOSURE-NEXT: - TypeName: MyStruct +//AFTER_TRAILINGCLOSURE-NEXT: - Members: +//AFTER_TRAILINGCLOSURE-NEXT: - Name: returnSomeP() +//AFTER_TRAILINGCLOSURE-NEXT: TypeName: some TargetP +//AFTER_TRAILINGCLOSURE-NEXT: - Name: returnConcreteP() +//AFTER_TRAILINGCLOSURE-NEXT: TypeName: ConcreteP +//AFTER_TRAILINGCLOSURE-NEXT: -----END CONFORMING METHOD LIST-----