diff --git a/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift b/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift index c642bf81efb..1d75123631e 100644 --- a/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift @@ -341,13 +341,19 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "name", - kind: .token(choices: [.token(.identifier), .keyword(.self)]) + kind: .token(choices: [.token(.identifier)]), + isOptional: true ), Child( - name: "initializer", - kind: .node(kind: .initializerClause), + name: "equal", + deprecatedName: "assignToken", + kind: .token(choices: [.token(.equal)]), isOptional: true ), + Child( + name: "expression", + kind: .node(kind: .expr) + ), Child( name: "trailingComma", kind: .token(choices: [.token(.comma)]), diff --git a/CodeGeneration/Tests/ValidateSyntaxNodes/ValidateSyntaxNodes.swift b/CodeGeneration/Tests/ValidateSyntaxNodes/ValidateSyntaxNodes.swift index 4a1612b07e2..93046782bf3 100644 --- a/CodeGeneration/Tests/ValidateSyntaxNodes/ValidateSyntaxNodes.swift +++ b/CodeGeneration/Tests/ValidateSyntaxNodes/ValidateSyntaxNodes.swift @@ -482,22 +482,22 @@ class ValidateSyntaxNodes: XCTestCase { ValidationFailure( node: .enumCaseElement, message: - "child 'rawValue' is named inconsistently with 'ClosureCaptureSyntax.initializer', which has the same type ('InitializerClauseSyntax')" + "child 'rawValue' is named inconsistently with 'MatchingPatternConditionSyntax.initializer', which has the same type ('InitializerClauseSyntax')" ), ValidationFailure( node: .enumCaseParameter, message: - "child 'defaultValue' is named inconsistently with 'ClosureCaptureSyntax.initializer', which has the same type ('InitializerClauseSyntax')" + "child 'defaultValue' is named inconsistently with 'MatchingPatternConditionSyntax.initializer', which has the same type ('InitializerClauseSyntax')" ), ValidationFailure( node: .functionParameter, message: - "child 'defaultValue' is named inconsistently with 'ClosureCaptureSyntax.initializer', which has the same type ('InitializerClauseSyntax')" + "child 'defaultValue' is named inconsistently with 'MatchingPatternConditionSyntax.initializer', which has the same type ('InitializerClauseSyntax')" ), ValidationFailure( node: .macroDecl, message: - "child 'definition' is named inconsistently with 'ClosureCaptureSyntax.initializer', which has the same type ('InitializerClauseSyntax')" + "child 'definition' is named inconsistently with 'MatchingPatternConditionSyntax.initializer', which has the same type ('InitializerClauseSyntax')" ), // MARK: Miscellaneous ValidationFailure( diff --git a/Release Notes/601.md b/Release Notes/601.md index e608a19fdda..0aa91b991d7 100644 --- a/Release Notes/601.md +++ b/Release Notes/601.md @@ -31,10 +31,6 @@ - Description: `IncrementalEdit` is being dropped for `SourceEdit`. `SourceEdit` has deprecated compatibility layers to make it API-compatible with `IncrementalEdit` - Issue: https://github.com/apple/swift-syntax/issues/2532 - Pull request: https://github.com/apple/swift-syntax/pull/2604 - -- `ClosureCaptureSyntax.init(leadingTrivia:specifier:name:equal:expression:trailingComma:trailingTrivia:)` deprecated in favor of a new `ClosureCaptureSyntax.init(leadingTrivia:_:specifier:_:name:_:initializer:_:trailingComma:_:trailingTrivia:)` initializer. - - Description: `ClosureCaptureSyntax` now has an `initializer` property instead of `equal` and `expression`. Additionally, the `name` property is no longer optional. - - Pull request: https://github.com/swiftlang/swift-syntax/pull/2763 ## API-Incompatible Changes @@ -42,17 +38,13 @@ - Description: Allows retrieving the radix value from the `literal.text`. - Issue: https://github.com/apple/swift-syntax/issues/405 - Pull Request: https://github.com/apple/swift-syntax/pull/2605 - + - `FixIt.Change` gained a new case `replaceChild(data:)`. - Description: The new case covers the replacement of a child node with another node. - Issue: https://github.com/swiftlang/swift-syntax/issues/2205 - Pull Request: https://github.com/swiftlang/swift-syntax/pull/2758 - Migration steps: In exhaustive switches over `FixIt.Change`, cover the new case. -- `ClosureCaptureSyntax.name` is no longer optional. - - Description: Due to the new `ClosureCaptureSyntax` node structure, `name` property is non-optional. - - Pull request: https://github.com/swiftlang/swift-syntax/pull/2763 - ## Template - *Affected API or two word description* diff --git a/Sources/SwiftLexicalLookup/IdentifiableSyntax.swift b/Sources/SwiftLexicalLookup/IdentifiableSyntax.swift index 893ccc3e914..033dad3244b 100644 --- a/Sources/SwiftLexicalLookup/IdentifiableSyntax.swift +++ b/Sources/SwiftLexicalLookup/IdentifiableSyntax.swift @@ -33,7 +33,12 @@ import SwiftSyntax @_spi(Experimental) extension ClosureCaptureSyntax: IdentifiableSyntax { @_spi(Experimental) public var identifier: TokenSyntax { - name + /* Doesn't work with closures like: + _ = { [y=1+2] in + print(y) + } + */ + expression.as(DeclReferenceExprSyntax.self)!.baseName } } diff --git a/Sources/SwiftParser/Expressions.swift b/Sources/SwiftParser/Expressions.swift index 2b99d46d536..6bdc159dcaf 100644 --- a/Sources/SwiftParser/Expressions.swift +++ b/Sources/SwiftParser/Expressions.swift @@ -1615,7 +1615,7 @@ extension Parser { } extension Parser { - mutating func parseInitializerClause() -> RawInitializerClauseSyntax { + mutating func parseDefaultArgument() -> RawInitializerClauseSyntax { let unexpectedBeforeEq: RawUnexpectedNodesSyntax? let eq: RawTokenSyntax if let comparison = self.consumeIfContextualPunctuator("==") { @@ -1704,22 +1704,29 @@ extension Parser { let specifier = self.parseClosureCaptureSpecifiers() // The thing being capture specified is an identifier, or as an identifier - // followed by an initializer clause. - let (unexpectedBeforeName, name) = self.expect( - .identifier, - TokenSpec(.self), - default: .identifier - ) - - let initializer: RawInitializerClauseSyntax? - if self.at(.equal) { - // The name is a new declaration with - // initializer clause. - initializer = self.parseInitializerClause() + // followed by an expression. + let unexpectedBeforeName: RawUnexpectedNodesSyntax? + let name: RawTokenSyntax? + let unexpectedBeforeEqual: RawUnexpectedNodesSyntax? + let equal: RawTokenSyntax? + let expression: RawExprSyntax + if self.peek(isAt: .equal) { + // The name is a new declaration. + (unexpectedBeforeName, name) = self.expect( + .identifier, + TokenSpec(.self, remapping: .identifier), + default: .identifier + ) + (unexpectedBeforeEqual, equal) = self.expect(.equal) + expression = self.parseExpression(flavor: .basic, pattern: .none) } else { - // This is the simple case - the identifier is the name and - // the initializer clause is empty. - initializer = nil + // This is the simple case - the identifier is both the name and + // the expression to capture. + unexpectedBeforeName = nil + name = nil + unexpectedBeforeEqual = nil + equal = nil + expression = RawExprSyntax(self.parseIdentifierExpression(flavor: .basic)) } keepGoing = self.consume(if: .comma) @@ -1728,9 +1735,11 @@ extension Parser { specifier: specifier, unexpectedBeforeName, name: name, - initializer: initializer, + unexpectedBeforeEqual, + equal: equal, + expression: expression, trailingComma: keepGoing, - arena: arena + arena: self.arena ) ) } while keepGoing != nil && self.hasProgressed(&loopProgress) diff --git a/Sources/SwiftParser/Parameters.swift b/Sources/SwiftParser/Parameters.swift index c5380e7d6b0..6cf2d8a1152 100644 --- a/Sources/SwiftParser/Parameters.swift +++ b/Sources/SwiftParser/Parameters.swift @@ -129,7 +129,7 @@ extension Parser { let defaultValue: RawInitializerClauseSyntax? if self.at(.equal) || self.atContextualPunctuator("==") { - defaultValue = self.parseInitializerClause() + defaultValue = self.parseDefaultArgument() } else { defaultValue = nil } @@ -234,7 +234,7 @@ extension Parser { let defaultValue: RawInitializerClauseSyntax? if self.at(.equal) || self.atContextualPunctuator("==") { - defaultValue = self.parseInitializerClause() + defaultValue = self.parseDefaultArgument() } else { defaultValue = nil } diff --git a/Sources/SwiftParser/generated/Parser+TokenSpecSet.swift b/Sources/SwiftParser/generated/Parser+TokenSpecSet.swift index 1f83e88bf73..d26de02a349 100644 --- a/Sources/SwiftParser/generated/Parser+TokenSpecSet.swift +++ b/Sources/SwiftParser/generated/Parser+TokenSpecSet.swift @@ -560,58 +560,6 @@ extension ClosureCaptureSpecifierSyntax { } } -extension ClosureCaptureSyntax { - @_spi(Diagnostics) - public enum NameOptions: TokenSpecSet { - case identifier - case `self` - - init?(lexeme: Lexer.Lexeme, experimentalFeatures: Parser.ExperimentalFeatures) { - switch PrepareForKeywordMatch(lexeme) { - case TokenSpec(.identifier): - self = .identifier - case TokenSpec(.self): - self = .self - default: - return nil - } - } - - public init?(token: TokenSyntax) { - switch token { - case TokenSpec(.identifier): - self = .identifier - case TokenSpec(.self): - self = .self - default: - return nil - } - } - - var spec: TokenSpec { - switch self { - case .identifier: - return .identifier - case .self: - return .keyword(.self) - } - } - - /// Returns a token that satisfies the `TokenSpec` of this case. - /// - /// If the token kind of this spec has variable text, e.g. for an identifier, this returns a token with empty text. - @_spi(Diagnostics) - public var tokenSyntax: TokenSyntax { - switch self { - case .identifier: - return .identifier("") - case .self: - return .keyword(.self) - } - } - } -} - extension ClosureParameterSyntax { @_spi(Diagnostics) public enum FirstNameOptions: TokenSpecSet { diff --git a/Sources/SwiftSyntax/Convenience.swift b/Sources/SwiftSyntax/Convenience.swift index 36b2e11e9ac..3c0c51bad5c 100644 --- a/Sources/SwiftSyntax/Convenience.swift +++ b/Sources/SwiftSyntax/Convenience.swift @@ -10,6 +10,33 @@ // //===----------------------------------------------------------------------===// +extension ClosureCaptureSyntax { + + /// Creates a ``ClosureCaptureSyntax`` with a `name`, and automatically adds an `equal` token to it since the name is non-optional. + /// + /// - SeeAlso: ``ClosureCaptureSyntax/init(leadingTrivia:_:specifier:_:name:_:equal:_:expression:_:trailingComma:_:trailingTrivia:)``. + /// + public init( + leadingTrivia: Trivia? = nil, + specifier: ClosureCaptureSpecifierSyntax? = nil, + name: TokenSyntax, + equal: TokenSyntax = TokenSyntax.equalToken(), + expression: some ExprSyntaxProtocol, + trailingComma: TokenSyntax? = nil, + trailingTrivia: Trivia? = nil + ) { + self.init( + leadingTrivia: leadingTrivia, + specifier: specifier, + name: name as TokenSyntax?, + equal: equal, + expression: expression, + trailingComma: trailingComma, + trailingTrivia: trailingTrivia + ) + } +} + extension EnumCaseParameterSyntax { /// Creates an ``EnumCaseParameterSyntax`` with a `firstName`, and automatically adds a `colon` to it. diff --git a/Sources/SwiftSyntax/SwiftSyntaxCompatibility.swift b/Sources/SwiftSyntax/SwiftSyntaxCompatibility.swift index 0c4f5131a16..a46a784af09 100644 --- a/Sources/SwiftSyntax/SwiftSyntaxCompatibility.swift +++ b/Sources/SwiftSyntax/SwiftSyntaxCompatibility.swift @@ -144,197 +144,6 @@ extension DeclGroupSyntax { } } -extension ClosureCaptureSyntax { - @available(*, deprecated, renamed: "unexpectedBetweenNameAndInitializer") - public var unexpectedBetweenNameAndAssignToken: UnexpectedNodesSyntax? { - get { - return unexpectedBetweenNameAndInitializer - } - set { - unexpectedBetweenNameAndInitializer = newValue - } - } - - @available(*, deprecated, renamed: "initializer.equal") - public var assignToken: TokenSyntax? { - get { - return initializer?.equal - } - set { - initializer?.equal = newValue ?? .equalToken(presence: .missing) - } - } - - @available(*, deprecated, renamed: "initializer.unexpectedBetweenEqualAndValue") - public var unexpectedBetweenAssignTokenAndExpression: UnexpectedNodesSyntax? { - get { - return initializer?.unexpectedBetweenEqualAndValue - } - set { - initializer?.unexpectedBetweenEqualAndValue = newValue - } - } - - @available( - *, - deprecated, - renamed: "ClosureCaptureSyntax(leadingTrivia:_:specifier:_:name:_:initializer:_:trailingComma:_:trailingTrivia:)" - ) - @_disfavoredOverload - public init( - leadingTrivia: Trivia? = nil, - _ unexpectedBeforeSpecifier: UnexpectedNodesSyntax? = nil, - specifier: ClosureCaptureSpecifierSyntax? = nil, - _ unexpectedBetweenSpecifierAndName: UnexpectedNodesSyntax? = nil, - name: TokenSyntax? = nil, - _ unexpectedBetweenNameAndAssignToken: UnexpectedNodesSyntax? = nil, - assignToken: TokenSyntax? = nil, - _ unexpectedBetweenAssignTokenAndExpression: UnexpectedNodesSyntax? = nil, - expression: some ExprSyntaxProtocol, - _ unexpectedBetweenExpressionAndTrailingComma: UnexpectedNodesSyntax? = nil, - trailingComma: TokenSyntax? = nil, - _ unexpectedAfterTrailingComma: UnexpectedNodesSyntax? = nil, - trailingTrivia: Trivia? = nil - - ) { - self.init( - leadingTrivia: leadingTrivia, - unexpectedBeforeSpecifier, - specifier: specifier, - unexpectedBetweenSpecifierAndName, - name: name ?? .identifier("", presence: .missing), - unexpectedBetweenNameAndAssignToken, - initializer: InitializerClauseSyntax( - equal: assignToken ?? .equalToken(presence: .missing), - unexpectedBetweenAssignTokenAndExpression, - value: expression - ), - unexpectedBetweenExpressionAndTrailingComma, - trailingComma: trailingComma, - unexpectedAfterTrailingComma, - trailingTrivia: trailingTrivia - ) - } - - /// Creates a ``ClosureCaptureSyntax`` with a `name`, and automatically adds an `equal` token to it since the name is non-optional. - /// - /// - SeeAlso: ``ClosureCaptureSyntax/init(leadingTrivia:_:specifier:_:name:_:initializer:_:trailingComma:_:trailingTrivia:)``. - /// - @available( - *, - deprecated, - message: "Use 'init(leadingTrivia:_:specifier:_:name:_:initializer:_:trailingComma:_:trailingTrivia:)' instead" - ) - public init( - leadingTrivia: Trivia? = nil, - specifier: ClosureCaptureSpecifierSyntax? = nil, - name: TokenSyntax, - equal: TokenSyntax = TokenSyntax.equalToken(), - expression: some ExprSyntaxProtocol, - trailingComma: TokenSyntax? = nil, - trailingTrivia: Trivia? = nil - ) { - self.init( - leadingTrivia: leadingTrivia, - specifier: specifier, - name: name, - initializer: InitializerClauseSyntax(equal: equal, value: expression), - trailingComma: trailingComma, - trailingTrivia: trailingTrivia - ) - } - - @available(*, deprecated, renamed: "unexpectedBetweenNameAndInitializer") - public var unexpectedBetweenNameAndEqual: UnexpectedNodesSyntax? { - get { - return unexpectedBetweenNameAndInitializer - } - set { - unexpectedBetweenNameAndInitializer = newValue - } - } - - @available(*, deprecated, renamed: "initializer.equal") - public var equal: TokenSyntax? { - get { - return initializer?.equal - } - set { - initializer?.equal = newValue ?? .equalToken(presence: .missing) - } - } - - @available(*, deprecated, renamed: "initializer.unexpectedBetweenEqualAndValue") - public var unexpectedBetweenEqualAndExpression: UnexpectedNodesSyntax? { - get { - return initializer?.unexpectedBetweenEqualAndValue - } - set { - initializer?.unexpectedBetweenEqualAndValue = newValue - } - } - - @available(*, deprecated, renamed: "initializer.value") - public var expression: ExprSyntax { - get { - return initializer?.value ?? ExprSyntax(MissingExprSyntax()) - } - set(value) { - initializer?.value = value - } - } - - @available(*, deprecated, renamed: "unexpectedBetweenInitializerAndTrailingComma") - public var unexpectedBetweenExpressionAndTrailingComma: UnexpectedNodesSyntax? { - get { - return unexpectedBetweenInitializerAndTrailingComma - } - set(value) { - unexpectedBetweenInitializerAndTrailingComma = value - } - } - - @available( - *, - deprecated, - renamed: "ClosureCaptureSyntax(leadingTrivia:_:specifier:_:name:_:initializer:_:trailingComma:_:trailingTrivia:)" - ) - @_disfavoredOverload - public init( - leadingTrivia: Trivia? = nil, - _ unexpectedBeforeSpecifier: UnexpectedNodesSyntax? = nil, - specifier: ClosureCaptureSpecifierSyntax? = nil, - _ unexpectedBetweenSpecifierAndName: UnexpectedNodesSyntax? = nil, - name: TokenSyntax? = nil, - _ unexpectedBetweenNameAndEqual: UnexpectedNodesSyntax? = nil, - equal: TokenSyntax? = nil, - _ unexpectedBetweenEqualAndExpression: UnexpectedNodesSyntax? = nil, - expression: some ExprSyntaxProtocol, - _ unexpectedBetweenExpressionAndTrailingComma: UnexpectedNodesSyntax? = nil, - trailingComma: TokenSyntax? = nil, - _ unexpectedAfterTrailingComma: UnexpectedNodesSyntax? = nil, - trailingTrivia: Trivia? = nil - ) { - self.init( - leadingTrivia: leadingTrivia, - unexpectedBeforeSpecifier, - specifier: specifier, - unexpectedBetweenSpecifierAndName, - name: name ?? .identifier("", presence: .missing), - unexpectedBetweenNameAndEqual, - initializer: InitializerClauseSyntax( - equal: equal ?? .equalToken(presence: .missing), - unexpectedBetweenEqualAndExpression, - value: expression - ), - unexpectedBetweenExpressionAndTrailingComma, - trailingComma: trailingComma, - unexpectedAfterTrailingComma, - trailingTrivia: trailingTrivia - ) - } -} - extension EffectSpecifiersSyntax { @available(*, deprecated, renamed: "unexpectedBetweenAsyncSpecifierAndThrowsClause") public var unexpectedBetweenAsyncSpecifierAndThrowsSpecifier: UnexpectedNodesSyntax? { diff --git a/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift b/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift index 0779415c327..b328be7cf7d 100644 --- a/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift +++ b/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift @@ -499,12 +499,16 @@ public func childName(_ keyPath: AnyKeyPath) -> String? { return "unexpectedBetweenSpecifierAndName" case \ClosureCaptureSyntax.name: return "name" - case \ClosureCaptureSyntax.unexpectedBetweenNameAndInitializer: - return "unexpectedBetweenNameAndInitializer" - case \ClosureCaptureSyntax.initializer: - return "initializer" - case \ClosureCaptureSyntax.unexpectedBetweenInitializerAndTrailingComma: - return "unexpectedBetweenInitializerAndTrailingComma" + case \ClosureCaptureSyntax.unexpectedBetweenNameAndEqual: + return "unexpectedBetweenNameAndEqual" + case \ClosureCaptureSyntax.equal: + return "equal" + case \ClosureCaptureSyntax.unexpectedBetweenEqualAndExpression: + return "unexpectedBetweenEqualAndExpression" + case \ClosureCaptureSyntax.expression: + return "expression" + case \ClosureCaptureSyntax.unexpectedBetweenExpressionAndTrailingComma: + return "unexpectedBetweenExpressionAndTrailingComma" case \ClosureCaptureSyntax.trailingComma: return "trailingComma" case \ClosureCaptureSyntax.unexpectedAfterTrailingComma: diff --git a/Sources/SwiftSyntax/generated/RenamedChildrenCompatibility.swift b/Sources/SwiftSyntax/generated/RenamedChildrenCompatibility.swift index a1b26254cbf..c798061a9e6 100644 --- a/Sources/SwiftSyntax/generated/RenamedChildrenCompatibility.swift +++ b/Sources/SwiftSyntax/generated/RenamedChildrenCompatibility.swift @@ -1167,6 +1167,73 @@ extension ClassDeclSyntax { } } +extension ClosureCaptureSyntax { + @available(*, deprecated, renamed: "unexpectedBetweenNameAndEqual") + public var unexpectedBetweenNameAndAssignToken: UnexpectedNodesSyntax? { + get { + return unexpectedBetweenNameAndEqual + } + set { + unexpectedBetweenNameAndEqual = newValue + } + } + + @available(*, deprecated, renamed: "equal") + public var assignToken: TokenSyntax? { + get { + return equal + } + set { + equal = newValue + } + } + + @available(*, deprecated, renamed: "unexpectedBetweenEqualAndExpression") + public var unexpectedBetweenAssignTokenAndExpression: UnexpectedNodesSyntax? { + get { + return unexpectedBetweenEqualAndExpression + } + set { + unexpectedBetweenEqualAndExpression = newValue + } + } + + @available(*, deprecated, renamed: "ClosureCaptureSyntax(leadingTrivia:_:specifier:_:name:_:equal:_:expression:_:trailingComma:_:trailingTrivia:)") + @_disfavoredOverload + public init( + leadingTrivia: Trivia? = nil, + _ unexpectedBeforeSpecifier: UnexpectedNodesSyntax? = nil, + specifier: ClosureCaptureSpecifierSyntax? = nil, + _ unexpectedBetweenSpecifierAndName: UnexpectedNodesSyntax? = nil, + name: TokenSyntax? = nil, + _ unexpectedBetweenNameAndAssignToken: UnexpectedNodesSyntax? = nil, + assignToken: TokenSyntax? = nil, + _ unexpectedBetweenAssignTokenAndExpression: UnexpectedNodesSyntax? = nil, + expression: some ExprSyntaxProtocol, + _ unexpectedBetweenExpressionAndTrailingComma: UnexpectedNodesSyntax? = nil, + trailingComma: TokenSyntax? = nil, + _ unexpectedAfterTrailingComma: UnexpectedNodesSyntax? = nil, + trailingTrivia: Trivia? = nil + + ) { + self.init( + leadingTrivia: leadingTrivia, + unexpectedBeforeSpecifier, + specifier: specifier, + unexpectedBetweenSpecifierAndName, + name: name, + unexpectedBetweenNameAndAssignToken, + equal: assignToken, + unexpectedBetweenAssignTokenAndExpression, + expression: expression, + unexpectedBetweenExpressionAndTrailingComma, + trailingComma: trailingComma, + unexpectedAfterTrailingComma, + trailingTrivia: trailingTrivia + ) + } +} + extension ClosureParameterClauseSyntax { @available(*, deprecated, renamed: "unexpectedBetweenLeftParenAndParameters") public var unexpectedBetweenLeftParenAndParameterList: UnexpectedNodesSyntax? { diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesC.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesC.swift index 79c158bf4b5..ba466a6adff 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesC.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodesC.swift @@ -935,26 +935,30 @@ public struct RawClosureCaptureSyntax: RawSyntaxNodeProtocol { _ unexpectedBeforeSpecifier: RawUnexpectedNodesSyntax? = nil, specifier: RawClosureCaptureSpecifierSyntax?, _ unexpectedBetweenSpecifierAndName: RawUnexpectedNodesSyntax? = nil, - name: RawTokenSyntax, - _ unexpectedBetweenNameAndInitializer: RawUnexpectedNodesSyntax? = nil, - initializer: RawInitializerClauseSyntax?, - _ unexpectedBetweenInitializerAndTrailingComma: RawUnexpectedNodesSyntax? = nil, + name: RawTokenSyntax?, + _ unexpectedBetweenNameAndEqual: RawUnexpectedNodesSyntax? = nil, + equal: RawTokenSyntax?, + _ unexpectedBetweenEqualAndExpression: RawUnexpectedNodesSyntax? = nil, + expression: RawExprSyntax, + _ unexpectedBetweenExpressionAndTrailingComma: RawUnexpectedNodesSyntax? = nil, trailingComma: RawTokenSyntax?, _ unexpectedAfterTrailingComma: RawUnexpectedNodesSyntax? = nil, arena: __shared SyntaxArena ) { let raw = RawSyntax.makeLayout( - kind: .closureCapture, uninitializedCount: 9, arena: arena) { layout in + kind: .closureCapture, uninitializedCount: 11, arena: arena) { layout in layout.initialize(repeating: nil) layout[0] = unexpectedBeforeSpecifier?.raw layout[1] = specifier?.raw layout[2] = unexpectedBetweenSpecifierAndName?.raw - layout[3] = name.raw - layout[4] = unexpectedBetweenNameAndInitializer?.raw - layout[5] = initializer?.raw - layout[6] = unexpectedBetweenInitializerAndTrailingComma?.raw - layout[7] = trailingComma?.raw - layout[8] = unexpectedAfterTrailingComma?.raw + layout[3] = name?.raw + layout[4] = unexpectedBetweenNameAndEqual?.raw + layout[5] = equal?.raw + layout[6] = unexpectedBetweenEqualAndExpression?.raw + layout[7] = expression.raw + layout[8] = unexpectedBetweenExpressionAndTrailingComma?.raw + layout[9] = trailingComma?.raw + layout[10] = unexpectedAfterTrailingComma?.raw } self.init(unchecked: raw) } @@ -971,28 +975,36 @@ public struct RawClosureCaptureSyntax: RawSyntaxNodeProtocol { layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:)) } - public var name: RawTokenSyntax { - layoutView.children[3].map(RawTokenSyntax.init(raw:))! + public var name: RawTokenSyntax? { + layoutView.children[3].map(RawTokenSyntax.init(raw:)) } - public var unexpectedBetweenNameAndInitializer: RawUnexpectedNodesSyntax? { + public var unexpectedBetweenNameAndEqual: RawUnexpectedNodesSyntax? { layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:)) } - public var initializer: RawInitializerClauseSyntax? { - layoutView.children[5].map(RawInitializerClauseSyntax.init(raw:)) + public var equal: RawTokenSyntax? { + layoutView.children[5].map(RawTokenSyntax.init(raw:)) } - public var unexpectedBetweenInitializerAndTrailingComma: RawUnexpectedNodesSyntax? { + public var unexpectedBetweenEqualAndExpression: RawUnexpectedNodesSyntax? { layoutView.children[6].map(RawUnexpectedNodesSyntax.init(raw:)) } + public var expression: RawExprSyntax { + layoutView.children[7].map(RawExprSyntax.init(raw:))! + } + + public var unexpectedBetweenExpressionAndTrailingComma: RawUnexpectedNodesSyntax? { + layoutView.children[8].map(RawUnexpectedNodesSyntax.init(raw:)) + } + public var trailingComma: RawTokenSyntax? { - layoutView.children[7].map(RawTokenSyntax.init(raw:)) + layoutView.children[9].map(RawTokenSyntax.init(raw:)) } public var unexpectedAfterTrailingComma: RawUnexpectedNodesSyntax? { - layoutView.children[8].map(RawUnexpectedNodesSyntax.init(raw:)) + layoutView.children[10].map(RawUnexpectedNodesSyntax.init(raw:)) } } diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift index ae36578f97b..9896d11e81d 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift @@ -563,16 +563,18 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { assertNoError(kind, 7, verify(layout[7], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.rightParen)])) assertNoError(kind, 8, verify(layout[8], as: RawUnexpectedNodesSyntax?.self)) case .closureCapture: - assert(layout.count == 9) + assert(layout.count == 11) assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) assertNoError(kind, 1, verify(layout[1], as: RawClosureCaptureSpecifierSyntax?.self)) assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.identifier), .keyword("self")])) + assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.identifier)])) assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 5, verify(layout[5], as: RawInitializerClauseSyntax?.self)) + assertNoError(kind, 5, verify(layout[5], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.equal)])) assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 7, verify(layout[7], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.comma)])) + assertNoError(kind, 7, verify(layout[7], as: RawExprSyntax.self)) assertNoError(kind, 8, verify(layout[8], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 9, verify(layout[9], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.comma)])) + assertNoError(kind, 10, verify(layout[10], as: RawUnexpectedNodesSyntax?.self)) case .closureExpr: assert(layout.count == 9) assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) diff --git a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesC.swift b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesC.swift index 4b830a51aa5..bfdce0dd3ce 100644 --- a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesC.swift +++ b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesC.swift @@ -1528,8 +1528,9 @@ public struct ClosureCaptureSpecifierSyntax: SyntaxProtocol, SyntaxHashable, _Le /// ### Children /// /// - `specifier`: ``ClosureCaptureSpecifierSyntax``? -/// - `name`: (`` | `self`) -/// - `initializer`: ``InitializerClauseSyntax``? +/// - `name`: ``? +/// - `equal`: `=`? +/// - `expression`: ``ExprSyntax`` /// - `trailingComma`: `,`? /// /// ### Contained in @@ -1553,10 +1554,12 @@ public struct ClosureCaptureSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxN _ unexpectedBeforeSpecifier: UnexpectedNodesSyntax? = nil, specifier: ClosureCaptureSpecifierSyntax? = nil, _ unexpectedBetweenSpecifierAndName: UnexpectedNodesSyntax? = nil, - name: TokenSyntax, - _ unexpectedBetweenNameAndInitializer: UnexpectedNodesSyntax? = nil, - initializer: InitializerClauseSyntax? = nil, - _ unexpectedBetweenInitializerAndTrailingComma: UnexpectedNodesSyntax? = nil, + name: TokenSyntax? = nil, + _ unexpectedBetweenNameAndEqual: UnexpectedNodesSyntax? = nil, + equal: TokenSyntax? = nil, + _ unexpectedBetweenEqualAndExpression: UnexpectedNodesSyntax? = nil, + expression: some ExprSyntaxProtocol, + _ unexpectedBetweenExpressionAndTrailingComma: UnexpectedNodesSyntax? = nil, trailingComma: TokenSyntax? = nil, _ unexpectedAfterTrailingComma: UnexpectedNodesSyntax? = nil, trailingTrivia: Trivia? = nil @@ -1569,9 +1572,11 @@ public struct ClosureCaptureSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxN specifier, unexpectedBetweenSpecifierAndName, name, - unexpectedBetweenNameAndInitializer, - initializer, - unexpectedBetweenInitializerAndTrailingComma, + unexpectedBetweenNameAndEqual, + equal, + unexpectedBetweenEqualAndExpression, + expression, + unexpectedBetweenExpressionAndTrailingComma, trailingComma, unexpectedAfterTrailingComma ))) { (arena, _) in @@ -1579,10 +1584,12 @@ public struct ClosureCaptureSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxN unexpectedBeforeSpecifier?.raw, specifier?.raw, unexpectedBetweenSpecifierAndName?.raw, - name.raw, - unexpectedBetweenNameAndInitializer?.raw, - initializer?.raw, - unexpectedBetweenInitializerAndTrailingComma?.raw, + name?.raw, + unexpectedBetweenNameAndEqual?.raw, + equal?.raw, + unexpectedBetweenEqualAndExpression?.raw, + expression.raw, + unexpectedBetweenExpressionAndTrailingComma?.raw, trailingComma?.raw, unexpectedAfterTrailingComma?.raw ] @@ -1627,19 +1634,17 @@ public struct ClosureCaptureSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxN /// ### Tokens /// - /// For syntax trees generated by the parser, this is guaranteed to be one of the following kinds: - /// - `` - /// - `self` - public var name: TokenSyntax { + /// For syntax trees generated by the parser, this is guaranteed to be ``. + public var name: TokenSyntax? { get { - return Syntax(self).child(at: 3)!.cast(TokenSyntax.self) + return Syntax(self).child(at: 3)?.cast(TokenSyntax.self) } set(value) { self = Syntax(self).replacingChild(at: 3, with: Syntax(value), arena: SyntaxArena()).cast(ClosureCaptureSyntax.self) } } - public var unexpectedBetweenNameAndInitializer: UnexpectedNodesSyntax? { + public var unexpectedBetweenNameAndEqual: UnexpectedNodesSyntax? { get { return Syntax(self).child(at: 4)?.cast(UnexpectedNodesSyntax.self) } @@ -1648,16 +1653,19 @@ public struct ClosureCaptureSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxN } } - public var initializer: InitializerClauseSyntax? { + /// ### Tokens + /// + /// For syntax trees generated by the parser, this is guaranteed to be `=`. + public var equal: TokenSyntax? { get { - return Syntax(self).child(at: 5)?.cast(InitializerClauseSyntax.self) + return Syntax(self).child(at: 5)?.cast(TokenSyntax.self) } set(value) { self = Syntax(self).replacingChild(at: 5, with: Syntax(value), arena: SyntaxArena()).cast(ClosureCaptureSyntax.self) } } - public var unexpectedBetweenInitializerAndTrailingComma: UnexpectedNodesSyntax? { + public var unexpectedBetweenEqualAndExpression: UnexpectedNodesSyntax? { get { return Syntax(self).child(at: 6)?.cast(UnexpectedNodesSyntax.self) } @@ -1666,24 +1674,42 @@ public struct ClosureCaptureSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxN } } + public var expression: ExprSyntax { + get { + return Syntax(self).child(at: 7)!.cast(ExprSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 7, with: Syntax(value), arena: SyntaxArena()).cast(ClosureCaptureSyntax.self) + } + } + + public var unexpectedBetweenExpressionAndTrailingComma: UnexpectedNodesSyntax? { + get { + return Syntax(self).child(at: 8)?.cast(UnexpectedNodesSyntax.self) + } + set(value) { + self = Syntax(self).replacingChild(at: 8, with: Syntax(value), arena: SyntaxArena()).cast(ClosureCaptureSyntax.self) + } + } + /// ### Tokens /// /// For syntax trees generated by the parser, this is guaranteed to be `,`. public var trailingComma: TokenSyntax? { get { - return Syntax(self).child(at: 7)?.cast(TokenSyntax.self) + return Syntax(self).child(at: 9)?.cast(TokenSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 7, with: Syntax(value), arena: SyntaxArena()).cast(ClosureCaptureSyntax.self) + self = Syntax(self).replacingChild(at: 9, with: Syntax(value), arena: SyntaxArena()).cast(ClosureCaptureSyntax.self) } } public var unexpectedAfterTrailingComma: UnexpectedNodesSyntax? { get { - return Syntax(self).child(at: 8)?.cast(UnexpectedNodesSyntax.self) + return Syntax(self).child(at: 10)?.cast(UnexpectedNodesSyntax.self) } set(value) { - self = Syntax(self).replacingChild(at: 8, with: Syntax(value), arena: SyntaxArena()).cast(ClosureCaptureSyntax.self) + self = Syntax(self).replacingChild(at: 10, with: Syntax(value), arena: SyntaxArena()).cast(ClosureCaptureSyntax.self) } } @@ -1692,9 +1718,11 @@ public struct ClosureCaptureSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxN \Self.specifier, \Self.unexpectedBetweenSpecifierAndName, \Self.name, - \Self.unexpectedBetweenNameAndInitializer, - \Self.initializer, - \Self.unexpectedBetweenInitializerAndTrailingComma, + \Self.unexpectedBetweenNameAndEqual, + \Self.equal, + \Self.unexpectedBetweenEqualAndExpression, + \Self.expression, + \Self.unexpectedBetweenExpressionAndTrailingComma, \Self.trailingComma, \Self.unexpectedAfterTrailingComma ]) diff --git a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift index c72423c0f2e..2a4290515da 100644 --- a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift +++ b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesGHI.swift @@ -3746,7 +3746,6 @@ public struct InheritedTypeSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxNo /// /// ### Contained in /// -/// - ``ClosureCaptureSyntax``.``ClosureCaptureSyntax/initializer`` /// - ``EnumCaseElementSyntax``.``EnumCaseElementSyntax/rawValue`` /// - ``EnumCaseParameterSyntax``.``EnumCaseParameterSyntax/defaultValue`` /// - ``FunctionParameterSyntax``.``FunctionParameterSyntax/defaultValue`` diff --git a/Tests/SwiftParserTest/TypeTests.swift b/Tests/SwiftParserTest/TypeTests.swift index 0e8bd40d38f..496b65264a0 100644 --- a/Tests/SwiftParserTest/TypeTests.swift +++ b/Tests/SwiftParserTest/TypeTests.swift @@ -94,8 +94,8 @@ final class TypeTests: ParserTestCase { diagnostics: [ DiagnosticSpec( locationMarker: "1️⃣", - message: "expected closure capture in closure capture clause", - fixIts: ["insert closure capture"] + message: "expected identifier in closure capture", + fixIts: ["insert identifier"] ), DiagnosticSpec( locationMarker: "1️⃣", diff --git a/Tests/SwiftSyntaxTest/SyntaxTests.swift b/Tests/SwiftSyntaxTest/SyntaxTests.swift index 42e569153cb..a07a5265c19 100644 --- a/Tests/SwiftSyntaxTest/SyntaxTests.swift +++ b/Tests/SwiftSyntaxTest/SyntaxTests.swift @@ -139,6 +139,14 @@ class SyntaxTests: XCTestCase { XCTAssertEqual(node.formatted().description, "label: MyType") } + public func testClosureCaptureSyntaxConvenienceInitWithEqual() { + let noNameClosureCapture = ClosureCaptureSyntax(expression: ExprSyntax("123")) + XCTAssertEqual(noNameClosureCapture.formatted().description, "123") + + let node = ClosureCaptureSyntax(name: "test", expression: ExprSyntax("123")) + XCTAssertEqual(node.formatted().description, "test = 123") + } + func testShareSyntaxIndexInTreeBetweenTrees() throws { let source = "func foo() {}"