-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[SE-0279] Add support for an unbraced syntax for multiple trailing closures #31052
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@swift-ci Please smoke test. |
@swift-ci Please test. |
Build failed |
Build failed |
swiftlang/swift-syntax#212 |
Build failed |
swiftlang/swift-syntax#212 |
Build failed |
Build failed |
@swift-ci Please test |
Build failed |
Build failed |
swiftlang/swift-syntax#212 |
swiftlang/swift-syntax#212 |
1 similar comment
swiftlang/swift-syntax#212 |
if (!returnsVoid) | ||
OS << " -> " << AFT->getResult()->getString(PO); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@benlangmuir If the return type is unresolved type, could you stop emitting -> _
?
In such cases, the return type probably inferred by the body, so we should not emit the return type signature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a suggestion for a test case? Everything I've tried either gives a name or it fails entirely to provide argument completions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a generic param type or a archetype type. Sorry I don't have this branch in my hand, but does this suggests y: { () -> A in <#code#> }
?
func foo<A>(x: () -> Void, y: () -> A) {}
foo() {} #^COMPLETE^#
If so, I think we should not suggest the signature in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yep it gives y: { () -> A in <#code#> }
. This is consistent with how completing the whole "foo" call behaves though (if you complete foo and then expand the placeholder the result is identical), so if we're going to change it I think it should be a separate PR.
In general, we might want to drop the return type in most cases even if it is resolved - it seems to be more common style to omit the types unless they are required. We could also drop the parens around the parameters in that case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be a separate PR
Agreed!
Build failed |
Build failed |
f1fff73
to
f884f33
Compare
swiftlang/swift-syntax#212 |
1 similar comment
swiftlang/swift-syntax#212 |
swiftlang/swift-syntax#212 |
Build failed |
Build failed |
swiftlang/swift-syntax#212 |
Build failed |
At an earlier point, we were doing this check after parsing the labeled closures, but that never made much sense, since it's a good diagnostic regardless.
…or of parsing `default:` labels.
TODO: Postfix completion after trailing closures
So that SourceKit can expand them to closure literals.
…ple trailing closures.
Instead of getting all edits up front using the same source code, apply each replacement before calculating the next. Placeholder expansion is sensitive the surrounding code, so expanding multiple closures separately can give different results from doing so in order. To allow testing that, add a magic placeholder identifier __skip__ to skip expansion during testing. This is also required for handling multiple trailing closures.
Since placeholder expansion works with a single placeholder, which is somewhat at odds with multiple-trailing closures, we eagerly attempt to expand all consecutive placeholders of closure type. That is, if the API has multiple closure parameters at the end, expanding any one of them will transform all of them to the new syntax. Example ``` foo(a: <#T##()->()#>, b: <#T##()->()#>) ``` expanding *either* parameter will produce the following: ``` foo { <#code#> } b: { <#code#> } ``` (caveat: the indentation is not part of placeholder expansion, but it's added here for clarity) At least for now we do not attempt to corral an existing closure into the new syntax, so for ``` foo(a: { bar() }, b: <#T##()->()#>) ``` The exansion will be ``` foo(a: { bar() }) { <#code#> } ``` as it was before. rdar://59688632
When completing a single argument for a trailing closure, pre-expand the closure expression syntax instead of using a placeholder. It's not valid to pass a non-closure anyway. rdar://62189182
f884f33
to
37b98af
Compare
swiftlang/swift-syntax#212 |
Build failed |
Build failed |
@rjmccall I changed swift-syntax PR to swiftlang/swift-syntax#216 because the CI somehow didn't picked up the updated hash of it. |
swiftlang/swift-syntax#216 |
@rjmccall I have updated the PR description to reflect that what's implemented is in fact the proposed syntax and not an alternative to it, for future readers who may be confused. |
This PR implements the syntax proposed in SE-0279, allowing an initial unlabeled trailing closure to be followed by an arbitrary number of labeled-closure postfixes.
swift-syntax: swiftlang/swift-syntax#212