Skip to content

Add EffectfulExprSyntax syntax trait #2572

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ public let EXPR_NODES: [Node] = [
kind: .awaitExpr,
base: .expr,
nameForDiagnostics: "'await' expression",
traits: [
"EffectfulExpr"
],
children: [
Child(
name: "awaitKeyword",
Expand Down Expand Up @@ -1914,6 +1917,9 @@ public let EXPR_NODES: [Node] = [
try! foo()
```
""",
traits: [
"EffectfulExpr"
],
children: [
Child(
name: "tryKeyword",
Expand Down
12 changes: 12 additions & 0 deletions CodeGeneration/Sources/SyntaxSupport/Traits.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,18 @@ public let TRAITS: [Trait] = [
Child(name: "memberBlock", kind: .node(kind: .memberBlock)),
]
),
Trait(
traitName: "EffectfulExpr",
documentation: "Syntax trait for effectful expressions, such as `try` and `await`.",
children: [
Child(name: "expression", kind: .node(kind: .expr)),
Child(
name: "keyword",
kind: .token(choices: [.keyword(.try), .keyword(.await)]),
documentation: "The token that represents the specific keyword of the effectful expression."
),
]
),
Trait(
traitName: "EffectSpecifiers",
children: [
Expand Down
25 changes: 25 additions & 0 deletions Release Notes/610.md
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ahoppen, please let me know if you want to land this PR in version 600. I will then move this release note to the 600.md file.

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Swift Syntax 610 Release Notes

## New APIs

- `EffectfulExprSyntax`
- Description: A protocol for unified handling of `try` and `await` expressions, with a `keyword` property to identify the expression's specific keyword.
- Issue: https://github.com/apple/swift-syntax/issues/2549
- Pull Request: https://github.com/apple/swift-syntax/pull/2572

## API Behavior Changes

## Deprecations

## API-Incompatible Changes

## Template

- *Affected API or two word description*
- Description: *A 1-2 sentence description of the new/modified API*
- Issue: *If an issue exists for this change, a link to the issue*
- Pull Request: *Link to the pull request(s) that introduces this change*
- Migration steps: Steps that adopters of swift-syntax should take to move to the new API (required for deprecations and API-incompatible changes).
- Notes: *In case of deprecations or API-incompatible changes, the reason why this change was made and the suggested alternative*

*Insert entries in chronological order, with newer entries at the bottom*
22 changes: 22 additions & 0 deletions Sources/SwiftSyntax/CustomTraits.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@ extension ActorDeclSyntax {
}
}

extension AwaitExprSyntax {
public var keyword: TokenSyntax {
get {
return awaitKeyword
}
set {
awaitKeyword = newValue
}
}
}

extension ClassDeclSyntax {
public var introducer: TokenSyntax {
get {
Expand Down Expand Up @@ -76,6 +87,17 @@ extension StructDeclSyntax {
}
}

extension TryExprSyntax {
public var keyword: TokenSyntax {
get {
return tryKeyword
}
set {
tryKeyword = newValue
}
}
}

//==========================================================================//
// IMPORTANT: If you are tempted to add an extension here, please insert //
// it in alphabetical order above //
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ These articles are intended for developers wishing to contribute to SwiftSyntax

- <doc:SwiftSyntax/BracedSyntax>
- <doc:SwiftSyntax/DeclGroupSyntax>
- <doc:SwiftSyntax/EffectfulExprSyntax>
- <doc:SwiftSyntax/EffectSpecifiersSyntax>
- <doc:SwiftSyntax/FreestandingMacroExpansionSyntax>
- <doc:SwiftSyntax/NamedDeclSyntax>
Expand Down
53 changes: 53 additions & 0 deletions Sources/SwiftSyntax/generated/SyntaxTraits.swift
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,55 @@ public extension SyntaxProtocol {
}
}

// MARK: - EffectfulExprSyntax

/// Syntax trait for effectful expressions, such as `try` and `await`.
public protocol EffectfulExprSyntax: SyntaxProtocol {
var expression: ExprSyntax {
get
set
}

/// The token that represents the specific keyword of the effectful expression.
///
/// ### Tokens
///
/// For syntax trees generated by the parser, this is guaranteed to be one of the following kinds:
/// - `try`
/// - `await`
var keyword: TokenSyntax {
get
set
}
}

public extension EffectfulExprSyntax {
/// Without this function, the `with` function defined on `SyntaxProtocol`
/// does not work on existentials of this protocol type.
@_disfavoredOverload
func with<T>(_ keyPath: WritableKeyPath<EffectfulExprSyntax, T>, _ newChild: T) -> EffectfulExprSyntax {
var copy: EffectfulExprSyntax = self
copy[keyPath: keyPath] = newChild
return copy
}
}

public extension SyntaxProtocol {
/// Check whether the non-type erased version of this syntax node conforms to
/// `EffectfulExprSyntax`.
/// Note that this will incur an existential conversion.
func isProtocol(_: EffectfulExprSyntax.Protocol) -> Bool {
return self.asProtocol(EffectfulExprSyntax.self) != nil
}

/// Return the non-type erased version of this syntax node if it conforms to
/// `EffectfulExprSyntax`. Otherwise return `nil`.
/// Note that this will incur an existential conversion.
func asProtocol(_: EffectfulExprSyntax.Protocol) -> EffectfulExprSyntax? {
return Syntax(self).asProtocol(SyntaxProtocol.self) as? EffectfulExprSyntax
}
}

// MARK: - EffectSpecifiersSyntax

public protocol EffectSpecifiersSyntax: SyntaxProtocol {
Expand Down Expand Up @@ -689,6 +738,8 @@ extension AttributedTypeSyntax: WithAttributesSyntax {}

extension AvailabilityArgumentSyntax: WithTrailingCommaSyntax {}

extension AwaitExprSyntax: EffectfulExprSyntax {}

extension CatchClauseSyntax: WithCodeBlockSyntax {}

extension CatchItemSyntax: WithTrailingCommaSyntax {}
Expand Down Expand Up @@ -831,6 +882,8 @@ extension SwitchCaseSyntax: WithStatementsSyntax {}

extension SwitchExprSyntax: BracedSyntax {}

extension TryExprSyntax: EffectfulExprSyntax {}

extension TupleExprSyntax: ParenthesizedSyntax {}

extension TuplePatternElementSyntax: WithTrailingCommaSyntax {}
Expand Down