From 478c5d8c3038f700d63beb9f775ab7f5c9eddc51 Mon Sep 17 00:00:00 2001 From: Michael Gottesman Date: Wed, 17 May 2023 14:10:57 -0700 Subject: [PATCH 1/6] Rename AwaitTryMove -> ExpressionModifierKeyword at @ahoppen's request. (cherry picked from commit 628a64c5f9eea0627665bcdc902a767e2f7dcc5e) --- Sources/SwiftParser/Expressions.swift | 2 +- Sources/SwiftParser/TokenSpecSet.swift | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Sources/SwiftParser/Expressions.swift b/Sources/SwiftParser/Expressions.swift index 37fa05a8d39..638eb61932a 100644 --- a/Sources/SwiftParser/Expressions.swift +++ b/Sources/SwiftParser/Expressions.swift @@ -411,7 +411,7 @@ extension Parser { } } - switch self.at(anyIn: AwaitTryMove.self) { + switch self.at(anyIn: ExpressionModifierKeyword.self) { case (.awaitKeyword, let handle)?: let awaitTok = self.eat(handle) let sub = self.parseSequenceExpressionElement( diff --git a/Sources/SwiftParser/TokenSpecSet.swift b/Sources/SwiftParser/TokenSpecSet.swift index a3d8cfb73aa..c74de9fb2d0 100644 --- a/Sources/SwiftParser/TokenSpecSet.swift +++ b/Sources/SwiftParser/TokenSpecSet.swift @@ -452,7 +452,7 @@ public enum TypeSpecifier: TokenSpecSet { // MARK: Expression start -enum AwaitTryMove: TokenSpecSet { +enum ExpressionModifierKeyword: TokenSpecSet { case awaitKeyword case _moveKeyword case _borrowKeyword @@ -668,13 +668,13 @@ enum PrimaryExpressionStart: TokenSpecSet { /// - `MatchingPatternStart` /// - `PrimaryExpressionStart` enum ExpressionStart: TokenSpecSet { - case awaitTryMove(AwaitTryMove) + case awaitTryMove(ExpressionModifierKeyword) case expressionPrefixOperator(ExpressionPrefixOperator) case primaryExpressionStart(PrimaryExpressionStart) case ifOrSwitch(IfOrSwitch) init?(lexeme: Lexer.Lexeme) { - if let subset = AwaitTryMove(lexeme: lexeme) { + if let subset = ExpressionModifierKeyword(lexeme: lexeme) { self = .awaitTryMove(subset) } else if let subset = ExpressionPrefixOperator(lexeme: lexeme) { self = .expressionPrefixOperator(subset) @@ -688,7 +688,7 @@ enum ExpressionStart: TokenSpecSet { } static var allCases: [ExpressionStart] { - return AwaitTryMove.allCases.map(Self.awaitTryMove) + return ExpressionModifierKeyword.allCases.map(Self.awaitTryMove) + ExpressionPrefixOperator.allCases.map(Self.expressionPrefixOperator) + PrimaryExpressionStart.allCases.map(Self.primaryExpressionStart) + IfOrSwitch.allCases.map(Self.ifOrSwitch) From 13c31416692ff61082962e50f97b1dce712dddbc Mon Sep 17 00:00:00 2001 From: Michael Gottesman Date: Mon, 15 May 2023 17:41:18 -0700 Subject: [PATCH 2/6] [copy-operator] Add parsing support for copy operator. I followed the same model that we used for consume, namely we need an identifier to copy. This ensures that if we have a function called copy or a variable called copy, we do not break source stability. rdar://101862423 (cherry picked from commit 895977a5ea2e4e851f0205ca4fdc850ff5c9be6b) --- .../Sources/SyntaxSupport/ExprNodes.swift | 16 ++ .../Sources/SyntaxSupport/KeywordSpec.swift | 1 + Sources/SwiftParser/Expressions.swift | 37 +++- Sources/SwiftParser/TokenSpecSet.swift | 3 + .../translated/CopyExprTests.swift | 182 ++++++++++++++++++ 5 files changed, 235 insertions(+), 4 deletions(-) create mode 100644 Tests/SwiftParserTest/translated/CopyExprTests.swift diff --git a/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift b/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift index f45bd5f2254..e15a34200df 100644 --- a/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift @@ -1140,6 +1140,22 @@ public let EXPR_NODES: [Node] = [ ] ), + Node( + name: "CopyExpr", + nameForDiagnostics: "'copy' expression", + kind: "Expr", + children: [ + Child( + name: "CopyKeyword", + kind: .token(choices: [.keyword(text: "copy")]) + ), + Child( + name: "Expression", + kind: .node(kind: "Expr") + ), + ] + ), + Node( name: "MultipleTrailingClosureElementList", nameForDiagnostics: nil, diff --git a/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift b/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift index 65c85aa18dd..046979b549e 100644 --- a/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift +++ b/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift @@ -106,6 +106,7 @@ public let KEYWORDS: [KeywordSpec] = [ KeywordSpec("catch", isLexerClassified: true, requiresLeadingSpace: true), KeywordSpec("class", isLexerClassified: true, requiresTrailingSpace: true), KeywordSpec("consume"), + KeywordSpec("copy"), KeywordSpec("consuming"), KeywordSpec("continue", isLexerClassified: true, requiresTrailingSpace: true), KeywordSpec("convenience"), diff --git a/Sources/SwiftParser/Expressions.swift b/Sources/SwiftParser/Expressions.swift index 638eb61932a..38367d98481 100644 --- a/Sources/SwiftParser/Expressions.swift +++ b/Sources/SwiftParser/Expressions.swift @@ -411,7 +411,7 @@ extension Parser { } } - switch self.at(anyIn: ExpressionModifierKeyword.self) { + EXPR_PREFIX: switch self.at(anyIn: ExpressionModifierKeyword.self) { case (.awaitKeyword, let handle)?: let awaitTok = self.eat(handle) let sub = self.parseSequenceExpressionElement( @@ -472,18 +472,46 @@ extension Parser { ) ) + case (.copyKeyword, let handle)?: + // `copy` is only contextually a keyword, if it's followed by an + // identifier or keyword on the same line. We do this to ensure that we do + // not break any copy functions defined by users. This is following with + // what we have done for the consume keyword. + switch self.peek() { + case TokenSpec(.identifier, allowAtStartOfLine: false), + TokenSpec(.dollarIdentifier, allowAtStartOfLine: false), + TokenSpec(.self, allowAtStartOfLine: false): + break + default: + break EXPR_PREFIX // Break out of `outer switch` on failure. + } + + let copyTok = self.eat(handle) + let sub = self.parseSequenceExpressionElement( + flavor, + forDirective: forDirective, + pattern: pattern + ) + return RawExprSyntax( + RawCopyExprSyntax( + copyKeyword: copyTok, + expression: sub, + arena: self.arena + ) + ) + case (.consumeKeyword, let handle)?: // `consume` is only contextually a keyword, if it's followed by an // identifier or keyword on the same line. let next = peek() if next.isAtStartOfLine { - fallthrough + break } if next.rawTokenKind != .identifier, next.rawTokenKind != .dollarIdentifier, next.rawTokenKind != .keyword { - fallthrough + break } let consumeTok = self.eat(handle) @@ -500,8 +528,9 @@ extension Parser { ) ) case nil: - return self.parseUnaryExpression(flavor, forDirective: forDirective, pattern: pattern) + break } + return self.parseUnaryExpression(flavor, forDirective: forDirective, pattern: pattern) } /// Parse an optional prefix operator followed by an expression. diff --git a/Sources/SwiftParser/TokenSpecSet.swift b/Sources/SwiftParser/TokenSpecSet.swift index c74de9fb2d0..c364585711e 100644 --- a/Sources/SwiftParser/TokenSpecSet.swift +++ b/Sources/SwiftParser/TokenSpecSet.swift @@ -458,6 +458,7 @@ enum ExpressionModifierKeyword: TokenSpecSet { case _borrowKeyword case tryKeyword case consumeKeyword + case copyKeyword init?(lexeme: Lexer.Lexeme) { switch PrepareForKeywordMatch(lexeme) { @@ -466,6 +467,7 @@ enum ExpressionModifierKeyword: TokenSpecSet { case TokenSpec(._borrow): self = ._borrowKeyword case TokenSpec(.try): self = .tryKeyword case TokenSpec(.consume): self = .consumeKeyword + case TokenSpec(.copy): self = .copyKeyword default: return nil } } @@ -476,6 +478,7 @@ enum ExpressionModifierKeyword: TokenSpecSet { case ._moveKeyword: return .keyword(._move) case ._borrowKeyword: return .keyword(._borrow) case .consumeKeyword: return .keyword(.consume) + case .copyKeyword: return .keyword(.copy) case .tryKeyword: return .keyword(.try) } } diff --git a/Tests/SwiftParserTest/translated/CopyExprTests.swift b/Tests/SwiftParserTest/translated/CopyExprTests.swift new file mode 100644 index 00000000000..dbee930eebf --- /dev/null +++ b/Tests/SwiftParserTest/translated/CopyExprTests.swift @@ -0,0 +1,182 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +// This test file has been translated from swift/test/Parse/copy_expr.swift + +import XCTest + +final class CopyExprTests: XCTestCase { + func testGlobal() { + assertParse( + """ + var global: Int = 5 + func testGlobal() { + let _ = copy global + } + """ + ) + } + + func testLet() { + assertParse( + """ + func testLet() { + let t = String() + let _ = copy t + } + """ + ) + } + + func testVar() { + assertParse( + """ + func testVar() { + var t = String() + t = String() + let _ = copy t + } + """ + ) + } + + func testStillAbleToCallFunctionCalledCopy() { + assertParse( + """ + func copy() {} + func copy(_: String) {} + func copy(_: String, _: Int) {} + func copy(x: String, y: Int) {} + + func useCopyFunc() { + var s = String() + var i = global + + copy() + copy(s) + copy(i) // expected-error{{cannot convert value of type 'Int' to expected argument type 'String'}} + copy(s, i) + copy(i, s) // expected-error{{unnamed argument #2 must precede unnamed argument #1}} + copy(x: s, y: i) + copy(y: i, x: s) // expected-error{{argument 'x' must precede argument 'y'}} + } + """ + ) + } + + // Ensure we can still parse a variable named copy. + func testUseCopyVariable() { + assertParse( + """ + func useCopyVar(copy: inout String) { + let s = copy + copy = s + + // We can copy from a variable named `copy` + let t = copy copy + copy = t + + // We can do member access and subscript a variable named `copy` + let i = copy.startIndex + let _ = copy[i] + } + """ + ) + } + + func testPropertyWrapperWithCopy() { + assertParse( + """ + @propertyWrapper + struct FooWrapper { + var value: T + + init(wrappedValue: T) { value = wrappedValue } + + var wrappedValue: T { + get { value } + nonmutating set {} + } + var projectedValue: T { + get { value } + nonmutating set {} + } + } + + struct Foo { + @FooWrapper var wrapperTest: String + + func copySelf() { + _ = copy self + } + + func copyPropertyWrapper() { + // should still parse, even if it doesn't semantically work out + _ = copy wrapperTest // expected-error{{can only be applied to lvalues}} + _ = copy _wrapperTest // expected-error{{can only be applied to lvalues}} + _ = copy $wrapperTest // expected-error{{can only be applied to lvalues}} + } + } + """ + ) + } + + func testAsCaseStmt() { + assertParse( + """ + class ParentKlass {} + class SubKlass : ParentKlass {} + + func test(_ s: SubKlass) { + switch s { + case let copy as ParentKlass: + fallthrough + } + } + """ + ) + } + + func testParseCanCopyClosureDollarIdentifier() { + assertParse( + """ + class Klass {} + let f: (Klass) -> () = { + let _ = copy $0 + } + """ + ) + } + + func testForLoop() { + assertParse( + """ + func test() { + for copy in 1..<1024 { + } + } + """ + ) + } + + func testCopySelf() { + assertParse( + """ + class Klass { + func test() { + let _ = copy self + } + } + """ + ) + } +} From 2749ca40d0edeb45e503aed8c97a5b30c5368526 Mon Sep 17 00:00:00 2001 From: Michael Gottesman Date: Wed, 17 May 2023 13:37:21 -0700 Subject: [PATCH 3/6] [consume-operator] Fix diagnostics so we say consume operator instead of move operator and add consume tests. rdar://109413392 (cherry picked from commit 4e2633d38028ca210e1f4a7349afe9af23e47c4a) --- .../Sources/SyntaxSupport/ExprNodes.swift | 2 +- .../translated/MoveExprTests.swift | 36 ++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift b/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift index e15a34200df..1a7f8424cea 100644 --- a/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift @@ -1126,7 +1126,7 @@ public let EXPR_NODES: [Node] = [ // The move expr Node( name: "MoveExpr", - nameForDiagnostics: "'_move' expression", + nameForDiagnostics: "'consume' expression", kind: "Expr", children: [ Child( diff --git a/Tests/SwiftParserTest/translated/MoveExprTests.swift b/Tests/SwiftParserTest/translated/MoveExprTests.swift index 081a970ff1b..cd011e4fefb 100644 --- a/Tests/SwiftParserTest/translated/MoveExprTests.swift +++ b/Tests/SwiftParserTest/translated/MoveExprTests.swift @@ -49,4 +49,38 @@ final class MoveExprTests: XCTestCase { ) } -} + func testConsumeExpr1() { + assertParse( + """ + var global: Int = 5 + func testGlobal() { + let _ = consume global + } + """ + ) + } + + func testConsumeExpr2() { + assertParse( + """ + func testLet() { + let t = String() + let _ = consume t + } + """ + ) + } + + func testConsumeExpr3() { + assertParse( + """ + func testVar() { + var t = String() + t = String() + let _ = consume t + } + """ + ) + } +}} + From bba497a47b1786d6288916038d928292fe317b6c Mon Sep 17 00:00:00 2001 From: Michael Gottesman Date: Wed, 17 May 2023 14:18:33 -0700 Subject: [PATCH 4/6] [consume] Change how we parse consume to match copy so we properly handle consume used as a name in case stmt as pattern match. rdar://109413278 (cherry picked from commit bc84e48c957a43af73051ec20ed25bccfb4f3765) --- Sources/SwiftParser/Expressions.swift | 18 +++++++++--------- .../translated/MoveExprTests.swift | 17 ++++++++++++++++- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/Sources/SwiftParser/Expressions.swift b/Sources/SwiftParser/Expressions.swift index 38367d98481..82fea5d1440 100644 --- a/Sources/SwiftParser/Expressions.swift +++ b/Sources/SwiftParser/Expressions.swift @@ -502,16 +502,16 @@ extension Parser { case (.consumeKeyword, let handle)?: // `consume` is only contextually a keyword, if it's followed by an - // identifier or keyword on the same line. - let next = peek() - if next.isAtStartOfLine { - break - } - if next.rawTokenKind != .identifier, - next.rawTokenKind != .dollarIdentifier, - next.rawTokenKind != .keyword - { + // identifier or keyword on the same line. We do this to ensure that we do + // not break any copy functions defined by users. This is following with + // what we have done for the consume keyword. + switch self.peek() { + case TokenSpec(.identifier, allowAtStartOfLine: false), + TokenSpec(.dollarIdentifier, allowAtStartOfLine: false), + TokenSpec(.self, allowAtStartOfLine: false): break + default: + break EXPR_PREFIX // break out of the outer `switch` } let consumeTok = self.eat(handle) diff --git a/Tests/SwiftParserTest/translated/MoveExprTests.swift b/Tests/SwiftParserTest/translated/MoveExprTests.swift index cd011e4fefb..c7da48df34b 100644 --- a/Tests/SwiftParserTest/translated/MoveExprTests.swift +++ b/Tests/SwiftParserTest/translated/MoveExprTests.swift @@ -82,5 +82,20 @@ final class MoveExprTests: XCTestCase { """ ) } -}} + + func testConsumeVariableNameInCast() { + assertParse( + """ + class ParentKlass {} + class SubKlass : ParentKlass {} + + func test(_ x: SubKlass) { + switch x { + case let consume as ParentKlass: + fallthrough + } + } + """) + } +} From 38e3a4d6fa185af35af2d0e5d79aab13ffb7b0c7 Mon Sep 17 00:00:00 2001 From: Michael Gottesman Date: Thu, 18 May 2023 00:22:10 -0700 Subject: [PATCH 5/6] Fix swift-format errors. (cherry picked from commit b3d38fddb357511085eced00b6a7cd285bd32349) --- Sources/SwiftParser/Expressions.swift | 14 ++++++++------ .../SwiftParserTest/translated/MoveExprTests.swift | 4 ++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Sources/SwiftParser/Expressions.swift b/Sources/SwiftParser/Expressions.swift index 82fea5d1440..c7c10c82b64 100644 --- a/Sources/SwiftParser/Expressions.swift +++ b/Sources/SwiftParser/Expressions.swift @@ -479,11 +479,12 @@ extension Parser { // what we have done for the consume keyword. switch self.peek() { case TokenSpec(.identifier, allowAtStartOfLine: false), - TokenSpec(.dollarIdentifier, allowAtStartOfLine: false), - TokenSpec(.self, allowAtStartOfLine: false): + TokenSpec(.dollarIdentifier, allowAtStartOfLine: false), + TokenSpec(.self, allowAtStartOfLine: false): break default: - break EXPR_PREFIX // Break out of `outer switch` on failure. + // Break out of `outer switch` on failure. + break EXPR_PREFIX } let copyTok = self.eat(handle) @@ -507,11 +508,12 @@ extension Parser { // what we have done for the consume keyword. switch self.peek() { case TokenSpec(.identifier, allowAtStartOfLine: false), - TokenSpec(.dollarIdentifier, allowAtStartOfLine: false), - TokenSpec(.self, allowAtStartOfLine: false): + TokenSpec(.dollarIdentifier, allowAtStartOfLine: false), + TokenSpec(.self, allowAtStartOfLine: false): break default: - break EXPR_PREFIX // break out of the outer `switch` + // Break out of the outer `switch`. + break EXPR_PREFIX } let consumeTok = self.eat(handle) diff --git a/Tests/SwiftParserTest/translated/MoveExprTests.swift b/Tests/SwiftParserTest/translated/MoveExprTests.swift index c7da48df34b..5a3a8a60a54 100644 --- a/Tests/SwiftParserTest/translated/MoveExprTests.swift +++ b/Tests/SwiftParserTest/translated/MoveExprTests.swift @@ -95,7 +95,7 @@ final class MoveExprTests: XCTestCase { fallthrough } } - """) + """ + ) } } - From 0ed075971f5b405642cd0eae3a8d6a59277d0f0f Mon Sep 17 00:00:00 2001 From: Michael Gottesman Date: Fri, 19 May 2023 15:14:44 -0700 Subject: [PATCH 6/6] Regenerate generated sources for 5.9 --- .../SyntaxKindNameForDiagnostics.swift | 4 +- .../generated/SwiftSyntax.md | 1 + .../generated/ChildNameForKeyPath.swift | 10 ++ Sources/SwiftSyntax/generated/Keyword.swift | 4 + .../generated/SyntaxAnyVisitor.swift | 8 ++ .../generated/SyntaxBaseNodes.swift | 6 +- .../SwiftSyntax/generated/SyntaxEnum.swift | 3 + .../SwiftSyntax/generated/SyntaxKind.swift | 3 + .../generated/SyntaxRewriter.swift | 25 ++++ .../generated/SyntaxTransform.swift | 14 +++ .../SwiftSyntax/generated/SyntaxVisitor.swift | 25 ++++ .../generated/raw/RawSyntaxNodes.swift | 72 ++++++++++- .../generated/raw/RawSyntaxValidation.swift | 7 ++ .../syntaxNodes/SyntaxExprNodes.swift | 116 ++++++++++++++++++ 14 files changed, 294 insertions(+), 4 deletions(-) diff --git a/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift b/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift index 589b580dfca..90fad2d34b8 100644 --- a/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift +++ b/Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift @@ -107,6 +107,8 @@ extension SyntaxKind { return "@convention(...) arguments" case .conventionWitnessMethodAttributeArguments: return "@convention(...) arguments for witness methods" + case .copyExpr: + return "'copy' expression" case .declModifier: return "modifier" case .declName: @@ -270,7 +272,7 @@ extension SyntaxKind { case .missingType: return "type" case .moveExpr: - return "'_move' expression" + return "'consume' expression" case .multipleTrailingClosureElement: return "trailing closure" case .namedOpaqueReturnType: diff --git a/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md b/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md index 75198a232b9..d1e7454744b 100644 --- a/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md +++ b/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md @@ -94,6 +94,7 @@ allows Swift tools to parse, inspect, generate, and transform Swift source code. - - - +- - - - diff --git a/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift b/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift index 1f72b8870ba..c359198e33f 100644 --- a/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift +++ b/Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift @@ -757,6 +757,16 @@ public func childName(_ keyPath: AnyKeyPath) -> String? { return "protocolName" case \ConventionWitnessMethodAttributeArgumentsSyntax.unexpectedAfterProtocolName: return "unexpectedAfterProtocolName" + case \CopyExprSyntax.unexpectedBeforeCopyKeyword: + return "unexpectedBeforeCopyKeyword" + case \CopyExprSyntax.copyKeyword: + return "copyKeyword" + case \CopyExprSyntax.unexpectedBetweenCopyKeywordAndExpression: + return "unexpectedBetweenCopyKeywordAndExpression" + case \CopyExprSyntax.expression: + return "expression" + case \CopyExprSyntax.unexpectedAfterExpression: + return "unexpectedAfterExpression" case \DeclModifierDetailSyntax.unexpectedBeforeLeftParen: return "unexpectedBeforeLeftParen" case \DeclModifierDetailSyntax.leftParen: diff --git a/Sources/SwiftSyntax/generated/Keyword.swift b/Sources/SwiftSyntax/generated/Keyword.swift index 80dc9ec8866..3df330e8d63 100644 --- a/Sources/SwiftSyntax/generated/Keyword.swift +++ b/Sources/SwiftSyntax/generated/Keyword.swift @@ -83,6 +83,7 @@ public enum Keyword: UInt8, Hashable { case `catch` case `class` case consume + case copy case consuming case `continue` case convenience @@ -265,6 +266,8 @@ public enum Keyword: UInt8, Hashable { self = ._spi case "case": self = .`case` + case "copy": + self = .copy case "each": self = .each case "else": @@ -806,6 +809,7 @@ public enum Keyword: UInt8, Hashable { "catch", "class", "consume", + "copy", "consuming", "continue", "convenience", diff --git a/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift b/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift index d36c377d3b5..bb6349157b9 100644 --- a/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift +++ b/Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift @@ -573,6 +573,14 @@ open class SyntaxAnyVisitor: SyntaxVisitor { visitAnyPost(node._syntaxNode) } + override open func visit(_ node: CopyExprSyntax) -> SyntaxVisitorContinueKind { + return visitAny(node._syntaxNode) + } + + override open func visitPost(_ node: CopyExprSyntax) { + visitAnyPost(node._syntaxNode) + } + override open func visit(_ node: DeclModifierDetailSyntax) -> SyntaxVisitorContinueKind { return visitAny(node._syntaxNode) } diff --git a/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift b/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift index d0b8a554a54..9966ca18331 100644 --- a/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift +++ b/Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift @@ -206,7 +206,7 @@ public struct ExprSyntax: ExprSyntaxProtocol, SyntaxHashable { public init?(_ node: S) { switch node.raw.kind { - case .arrayExpr, .arrowExpr, .asExpr, .assignmentExpr, .awaitExpr, .binaryOperatorExpr, .booleanLiteralExpr, .borrowExpr, .closureExpr, .dictionaryExpr, .discardAssignmentExpr, .editorPlaceholderExpr, .floatLiteralExpr, .forcedValueExpr, .functionCallExpr, .identifierExpr, .ifExpr, .inOutExpr, .infixOperatorExpr, .integerLiteralExpr, .isExpr, .keyPathExpr, .macroExpansionExpr, .memberAccessExpr, .missingExpr, .moveExpr, .nilLiteralExpr, .optionalChainingExpr, .packElementExpr, .packExpansionExpr, .postfixIfConfigExpr, .postfixUnaryExpr, .prefixOperatorExpr, .regexLiteralExpr, .sequenceExpr, .specializeExpr, .stringLiteralExpr, .subscriptExpr, .superRefExpr, .switchExpr, .ternaryExpr, .tryExpr, .tupleExpr, .typeExpr, .unresolvedAsExpr, .unresolvedIsExpr, .unresolvedPatternExpr, .unresolvedTernaryExpr: + case .arrayExpr, .arrowExpr, .asExpr, .assignmentExpr, .awaitExpr, .binaryOperatorExpr, .booleanLiteralExpr, .borrowExpr, .closureExpr, .copyExpr, .dictionaryExpr, .discardAssignmentExpr, .editorPlaceholderExpr, .floatLiteralExpr, .forcedValueExpr, .functionCallExpr, .identifierExpr, .ifExpr, .inOutExpr, .infixOperatorExpr, .integerLiteralExpr, .isExpr, .keyPathExpr, .macroExpansionExpr, .memberAccessExpr, .missingExpr, .moveExpr, .nilLiteralExpr, .optionalChainingExpr, .packElementExpr, .packExpansionExpr, .postfixIfConfigExpr, .postfixUnaryExpr, .prefixOperatorExpr, .regexLiteralExpr, .sequenceExpr, .specializeExpr, .stringLiteralExpr, .subscriptExpr, .superRefExpr, .switchExpr, .ternaryExpr, .tryExpr, .tupleExpr, .typeExpr, .unresolvedAsExpr, .unresolvedIsExpr, .unresolvedPatternExpr, .unresolvedTernaryExpr: self._syntaxNode = node._syntaxNode default: return nil @@ -218,7 +218,7 @@ public struct ExprSyntax: ExprSyntaxProtocol, SyntaxHashable { /// is undefined. internal init(_ data: SyntaxData) { switch data.raw.kind { - case .arrayExpr, .arrowExpr, .asExpr, .assignmentExpr, .awaitExpr, .binaryOperatorExpr, .booleanLiteralExpr, .borrowExpr, .closureExpr, .dictionaryExpr, .discardAssignmentExpr, .editorPlaceholderExpr, .floatLiteralExpr, .forcedValueExpr, .functionCallExpr, .identifierExpr, .ifExpr, .inOutExpr, .infixOperatorExpr, .integerLiteralExpr, .isExpr, .keyPathExpr, .macroExpansionExpr, .memberAccessExpr, .missingExpr, .moveExpr, .nilLiteralExpr, .optionalChainingExpr, .packElementExpr, .packExpansionExpr, .postfixIfConfigExpr, .postfixUnaryExpr, .prefixOperatorExpr, .regexLiteralExpr, .sequenceExpr, .specializeExpr, .stringLiteralExpr, .subscriptExpr, .superRefExpr, .switchExpr, .ternaryExpr, .tryExpr, .tupleExpr, .typeExpr, .unresolvedAsExpr, .unresolvedIsExpr, .unresolvedPatternExpr, .unresolvedTernaryExpr: + case .arrayExpr, .arrowExpr, .asExpr, .assignmentExpr, .awaitExpr, .binaryOperatorExpr, .booleanLiteralExpr, .borrowExpr, .closureExpr, .copyExpr, .dictionaryExpr, .discardAssignmentExpr, .editorPlaceholderExpr, .floatLiteralExpr, .forcedValueExpr, .functionCallExpr, .identifierExpr, .ifExpr, .inOutExpr, .infixOperatorExpr, .integerLiteralExpr, .isExpr, .keyPathExpr, .macroExpansionExpr, .memberAccessExpr, .missingExpr, .moveExpr, .nilLiteralExpr, .optionalChainingExpr, .packElementExpr, .packExpansionExpr, .postfixIfConfigExpr, .postfixUnaryExpr, .prefixOperatorExpr, .regexLiteralExpr, .sequenceExpr, .specializeExpr, .stringLiteralExpr, .subscriptExpr, .superRefExpr, .switchExpr, .ternaryExpr, .tryExpr, .tupleExpr, .typeExpr, .unresolvedAsExpr, .unresolvedIsExpr, .unresolvedPatternExpr, .unresolvedTernaryExpr: break default: preconditionFailure("Unable to create ExprSyntax from \(data.raw.kind)") @@ -263,6 +263,7 @@ public struct ExprSyntax: ExprSyntaxProtocol, SyntaxHashable { .node(BooleanLiteralExprSyntax.self), .node(BorrowExprSyntax.self), .node(ClosureExprSyntax.self), + .node(CopyExprSyntax.self), .node(DictionaryExprSyntax.self), .node(DiscardAssignmentExprSyntax.self), .node(EditorPlaceholderExprSyntax.self), @@ -749,6 +750,7 @@ extension Syntax { .node(ContinueStmtSyntax.self), .node(ConventionAttributeArgumentsSyntax.self), .node(ConventionWitnessMethodAttributeArgumentsSyntax.self), + .node(CopyExprSyntax.self), .node(DeclModifierDetailSyntax.self), .node(DeclModifierSyntax.self), .node(DeclNameArgumentListSyntax.self), diff --git a/Sources/SwiftSyntax/generated/SyntaxEnum.swift b/Sources/SwiftSyntax/generated/SyntaxEnum.swift index 65db0aef584..a0b602504d4 100644 --- a/Sources/SwiftSyntax/generated/SyntaxEnum.swift +++ b/Sources/SwiftSyntax/generated/SyntaxEnum.swift @@ -81,6 +81,7 @@ public enum SyntaxEnum { case continueStmt(ContinueStmtSyntax) case conventionAttributeArguments(ConventionAttributeArgumentsSyntax) case conventionWitnessMethodAttributeArguments(ConventionWitnessMethodAttributeArgumentsSyntax) + case copyExpr(CopyExprSyntax) case declModifierDetail(DeclModifierDetailSyntax) case declModifier(DeclModifierSyntax) case declNameArgumentList(DeclNameArgumentListSyntax) @@ -423,6 +424,8 @@ public extension Syntax { return .conventionAttributeArguments(ConventionAttributeArgumentsSyntax(self)!) case .conventionWitnessMethodAttributeArguments: return .conventionWitnessMethodAttributeArguments(ConventionWitnessMethodAttributeArgumentsSyntax(self)!) + case .copyExpr: + return .copyExpr(CopyExprSyntax(self)!) case .declModifierDetail: return .declModifierDetail(DeclModifierDetailSyntax(self)!) case .declModifier: diff --git a/Sources/SwiftSyntax/generated/SyntaxKind.swift b/Sources/SwiftSyntax/generated/SyntaxKind.swift index bce69632b0f..0fdb7493b5d 100644 --- a/Sources/SwiftSyntax/generated/SyntaxKind.swift +++ b/Sources/SwiftSyntax/generated/SyntaxKind.swift @@ -81,6 +81,7 @@ public enum SyntaxKind { case continueStmt case conventionAttributeArguments case conventionWitnessMethodAttributeArguments + case copyExpr case declModifierDetail case declModifier case declNameArgumentList @@ -538,6 +539,8 @@ public enum SyntaxKind { return ConventionAttributeArgumentsSyntax.self case .conventionWitnessMethodAttributeArguments: return ConventionWitnessMethodAttributeArgumentsSyntax.self + case .copyExpr: + return CopyExprSyntax.self case .declModifierDetail: return DeclModifierDetailSyntax.self case .declModifier: diff --git a/Sources/SwiftSyntax/generated/SyntaxRewriter.swift b/Sources/SwiftSyntax/generated/SyntaxRewriter.swift index 9d3ad35273d..4b3376f7d60 100644 --- a/Sources/SwiftSyntax/generated/SyntaxRewriter.swift +++ b/Sources/SwiftSyntax/generated/SyntaxRewriter.swift @@ -480,6 +480,13 @@ open class SyntaxRewriter { return Syntax(visitChildren(node)).cast(ConventionWitnessMethodAttributeArgumentsSyntax.self) } + /// Visit a `CopyExprSyntax`. + /// - Parameter node: the node that is being visited + /// - Returns: the rewritten node + open func visit(_ node: CopyExprSyntax) -> ExprSyntax { + return ExprSyntax(visitChildren(node)) + } + /// Visit a `DeclModifierDetailSyntax`. /// - Parameter node: the node that is being visited /// - Returns: the rewritten node @@ -2892,6 +2899,20 @@ open class SyntaxRewriter { return Syntax(visit(node)) } + /// Implementation detail of visit(_:). Do not call directly. + private func visitImplCopyExprSyntax(_ data: SyntaxData) -> Syntax { + let node = CopyExprSyntax(data) + // Accessing _syntaxNode directly is faster than calling Syntax(node) + visitPre(node._syntaxNode) + defer { + visitPost(node._syntaxNode) + } + if let newNode = visitAny(node._syntaxNode) { + return newNode + } + return Syntax(visit(node)) + } + /// Implementation detail of visit(_:). Do not call directly. private func visitImplDeclModifierDetailSyntax(_ data: SyntaxData) -> Syntax { let node = DeclModifierDetailSyntax(data) @@ -5920,6 +5941,8 @@ open class SyntaxRewriter { return visitImplConventionAttributeArgumentsSyntax case .conventionWitnessMethodAttributeArguments: return visitImplConventionWitnessMethodAttributeArgumentsSyntax + case .copyExpr: + return visitImplCopyExprSyntax case .declModifierDetail: return visitImplDeclModifierDetailSyntax case .declModifier: @@ -6468,6 +6491,8 @@ open class SyntaxRewriter { return visitImplConventionAttributeArgumentsSyntax(data) case .conventionWitnessMethodAttributeArguments: return visitImplConventionWitnessMethodAttributeArgumentsSyntax(data) + case .copyExpr: + return visitImplCopyExprSyntax(data) case .declModifierDetail: return visitImplDeclModifierDetailSyntax(data) case .declModifier: diff --git a/Sources/SwiftSyntax/generated/SyntaxTransform.swift b/Sources/SwiftSyntax/generated/SyntaxTransform.swift index dc1f62452fc..205a7e2cdab 100644 --- a/Sources/SwiftSyntax/generated/SyntaxTransform.swift +++ b/Sources/SwiftSyntax/generated/SyntaxTransform.swift @@ -344,6 +344,11 @@ public protocol SyntaxTransformVisitor { /// - Returns: the sum of whatever the child visitors return. func visit(_ node: ConventionWitnessMethodAttributeArgumentsSyntax) -> ResultType + /// Visiting `CopyExprSyntax` specifically. + /// - Parameter node: the node we are visiting. + /// - Returns: the sum of whatever the child visitors return. + func visit(_ node: CopyExprSyntax) -> ResultType + /// Visiting `DeclModifierDetailSyntax` specifically. /// - Parameter node: the node we are visiting. /// - Returns: the sum of whatever the child visitors return. @@ -1825,6 +1830,13 @@ extension SyntaxTransformVisitor { visitAny(Syntax(node)) } + /// Visiting `CopyExprSyntax` specifically. + /// - Parameter node: the node we are visiting. + /// - Returns: nil by default. + public func visit(_ node: CopyExprSyntax) -> ResultType { + visitAny(Syntax(node)) + } + /// Visiting `DeclModifierDetailSyntax` specifically. /// - Parameter node: the node we are visiting. /// - Returns: nil by default. @@ -3387,6 +3399,8 @@ extension SyntaxTransformVisitor { return visit(derived) case .conventionWitnessMethodAttributeArguments(let derived): return visit(derived) + case .copyExpr(let derived): + return visit(derived) case .declModifierDetail(let derived): return visit(derived) case .declModifier(let derived): diff --git a/Sources/SwiftSyntax/generated/SyntaxVisitor.swift b/Sources/SwiftSyntax/generated/SyntaxVisitor.swift index bbd78532b26..1b90c4ef2fa 100644 --- a/Sources/SwiftSyntax/generated/SyntaxVisitor.swift +++ b/Sources/SwiftSyntax/generated/SyntaxVisitor.swift @@ -814,6 +814,18 @@ open class SyntaxVisitor { open func visitPost(_ node: ConventionWitnessMethodAttributeArgumentsSyntax) { } + /// Visiting `CopyExprSyntax` specifically. + /// - Parameter node: the node we are visiting. + /// - Returns: how should we continue visiting. + open func visit(_ node: CopyExprSyntax) -> SyntaxVisitorContinueKind { + return .visitChildren + } + + /// The function called after visiting `CopyExprSyntax` and its descendents. + /// - node: the node we just finished visiting. + open func visitPost(_ node: CopyExprSyntax) { + } + /// Visiting `DeclModifierDetailSyntax` specifically. /// - Parameter node: the node we are visiting. /// - Returns: how should we continue visiting. @@ -3989,6 +4001,17 @@ open class SyntaxVisitor { visitPost(node) } + /// Implementation detail of doVisit(_:_:). Do not call directly. + private func visitImplCopyExprSyntax(_ data: SyntaxData) { + let node = CopyExprSyntax(data) + let needsChildren = (visit(node) == .visitChildren) + // Avoid calling into visitChildren if possible. + if needsChildren && !node.raw.layoutView!.children.isEmpty { + visitChildren(node) + } + visitPost(node) + } + /// Implementation detail of doVisit(_:_:). Do not call directly. private func visitImplDeclModifierDetailSyntax(_ data: SyntaxData) { let node = DeclModifierDetailSyntax(data) @@ -6370,6 +6393,8 @@ open class SyntaxVisitor { visitImplConventionAttributeArgumentsSyntax(data) case .conventionWitnessMethodAttributeArguments: visitImplConventionWitnessMethodAttributeArgumentsSyntax(data) + case .copyExpr: + visitImplCopyExprSyntax(data) case .declModifierDetail: visitImplDeclModifierDetailSyntax(data) case .declModifier: diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodes.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodes.swift index a925190867a..e7dbd2e67d0 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxNodes.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxNodes.swift @@ -5368,6 +5368,76 @@ public struct RawConventionWitnessMethodAttributeArgumentsSyntax: RawSyntaxNodeP } } +@_spi(RawSyntax) +public struct RawCopyExprSyntax: RawExprSyntaxNodeProtocol { + @_spi(RawSyntax) + public var layoutView: RawSyntaxLayoutView { + return raw.layoutView! + } + + public static func isKindOf(_ raw: RawSyntax) -> Bool { + return raw.kind == .copyExpr + } + + public var raw: RawSyntax + + init(raw: RawSyntax) { + precondition(Self.isKindOf(raw)) + self.raw = raw + } + + private init(unchecked raw: RawSyntax) { + self.raw = raw + } + + public init?(_ other: Node) { + guard Self.isKindOf(other.raw) else { + return nil + } + self.init(unchecked: other.raw) + } + + public init( + _ unexpectedBeforeCopyKeyword: RawUnexpectedNodesSyntax? = nil, + copyKeyword: RawTokenSyntax, + _ unexpectedBetweenCopyKeywordAndExpression: RawUnexpectedNodesSyntax? = nil, + expression: RawExprSyntax, + _ unexpectedAfterExpression: RawUnexpectedNodesSyntax? = nil, + arena: __shared SyntaxArena + ) { + let raw = RawSyntax.makeLayout( + kind: .copyExpr, uninitializedCount: 5, arena: arena) { layout in + layout.initialize(repeating: nil) + layout[0] = unexpectedBeforeCopyKeyword?.raw + layout[1] = copyKeyword.raw + layout[2] = unexpectedBetweenCopyKeywordAndExpression?.raw + layout[3] = expression.raw + layout[4] = unexpectedAfterExpression?.raw + } + self.init(unchecked: raw) + } + + public var unexpectedBeforeCopyKeyword: RawUnexpectedNodesSyntax? { + layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:)) + } + + public var copyKeyword: RawTokenSyntax { + layoutView.children[1].map(RawTokenSyntax.init(raw:))! + } + + public var unexpectedBetweenCopyKeywordAndExpression: RawUnexpectedNodesSyntax? { + layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:)) + } + + public var expression: RawExprSyntax { + layoutView.children[3].map(RawExprSyntax.init(raw:))! + } + + public var unexpectedAfterExpression: RawUnexpectedNodesSyntax? { + layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:)) + } +} + @_spi(RawSyntax) public struct RawDeclModifierDetailSyntax: RawSyntaxNodeProtocol { @_spi(RawSyntax) @@ -8445,7 +8515,7 @@ public struct RawExprSyntax: RawExprSyntaxNodeProtocol { public static func isKindOf(_ raw: RawSyntax) -> Bool { switch raw.kind { - case .arrayExpr, .arrowExpr, .asExpr, .assignmentExpr, .awaitExpr, .binaryOperatorExpr, .booleanLiteralExpr, .borrowExpr, .closureExpr, .dictionaryExpr, .discardAssignmentExpr, .editorPlaceholderExpr, .floatLiteralExpr, .forcedValueExpr, .functionCallExpr, .identifierExpr, .ifExpr, .inOutExpr, .infixOperatorExpr, .integerLiteralExpr, .isExpr, .keyPathExpr, .macroExpansionExpr, .memberAccessExpr, .missingExpr, .moveExpr, .nilLiteralExpr, .optionalChainingExpr, .packElementExpr, .packExpansionExpr, .postfixIfConfigExpr, .postfixUnaryExpr, .prefixOperatorExpr, .regexLiteralExpr, .sequenceExpr, .specializeExpr, .stringLiteralExpr, .subscriptExpr, .superRefExpr, .switchExpr, .ternaryExpr, .tryExpr, .tupleExpr, .typeExpr, .unresolvedAsExpr, .unresolvedIsExpr, .unresolvedPatternExpr, .unresolvedTernaryExpr: + case .arrayExpr, .arrowExpr, .asExpr, .assignmentExpr, .awaitExpr, .binaryOperatorExpr, .booleanLiteralExpr, .borrowExpr, .closureExpr, .copyExpr, .dictionaryExpr, .discardAssignmentExpr, .editorPlaceholderExpr, .floatLiteralExpr, .forcedValueExpr, .functionCallExpr, .identifierExpr, .ifExpr, .inOutExpr, .infixOperatorExpr, .integerLiteralExpr, .isExpr, .keyPathExpr, .macroExpansionExpr, .memberAccessExpr, .missingExpr, .moveExpr, .nilLiteralExpr, .optionalChainingExpr, .packElementExpr, .packExpansionExpr, .postfixIfConfigExpr, .postfixUnaryExpr, .prefixOperatorExpr, .regexLiteralExpr, .sequenceExpr, .specializeExpr, .stringLiteralExpr, .subscriptExpr, .superRefExpr, .switchExpr, .ternaryExpr, .tryExpr, .tupleExpr, .typeExpr, .unresolvedAsExpr, .unresolvedIsExpr, .unresolvedPatternExpr, .unresolvedTernaryExpr: return true default: return false diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift index 20b88db0c0c..6c6a4ced5aa 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift @@ -775,6 +775,13 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) assertNoError(kind, 5, verify(layout[5], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.identifier)])) assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self)) + case .copyExpr: + assert(layout.count == 5) + assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [.keyword("copy")])) + assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) + assertNoError(kind, 3, verify(layout[3], as: RawExprSyntax.self)) + assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) case .declModifierDetail: assert(layout.count == 7) assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) diff --git a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxExprNodes.swift b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxExprNodes.swift index 98dd79a1c38..1d6f1618a9a 100644 --- a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxExprNodes.swift +++ b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxExprNodes.swift @@ -1110,6 +1110,122 @@ public struct ClosureExprSyntax: ExprSyntaxProtocol, SyntaxHashable { } } +// MARK: - CopyExprSyntax + + +public struct CopyExprSyntax: ExprSyntaxProtocol, SyntaxHashable { + public let _syntaxNode: Syntax + + public init?(_ node: S) { + guard node.raw.kind == .copyExpr else { + return nil + } + self._syntaxNode = node._syntaxNode + } + + /// Creates a `CopyExprSyntax` node from the given `SyntaxData`. This assumes + /// that the `SyntaxData` is of the correct kind. If it is not, the behaviour + /// is undefined. + internal init(_ data: SyntaxData) { + precondition(data.raw.kind == .copyExpr) + self._syntaxNode = Syntax(data) + } + + public init( + leadingTrivia: Trivia? = nil, + _ unexpectedBeforeCopyKeyword: UnexpectedNodesSyntax? = nil, + copyKeyword: TokenSyntax = .keyword(.copy), + _ unexpectedBetweenCopyKeywordAndExpression: UnexpectedNodesSyntax? = nil, + expression: E, + _ unexpectedAfterExpression: UnexpectedNodesSyntax? = nil, + trailingTrivia: Trivia? = nil + + ) { + // Extend the lifetime of all parameters so their arenas don't get destroyed + // before they can be added as children of the new arena. + let data: SyntaxData = withExtendedLifetime((SyntaxArena(), ( + unexpectedBeforeCopyKeyword, + copyKeyword, + unexpectedBetweenCopyKeywordAndExpression, + expression, + unexpectedAfterExpression + ))) {(arena, _) in + let layout: [RawSyntax?] = [ + unexpectedBeforeCopyKeyword?.raw, + copyKeyword.raw, + unexpectedBetweenCopyKeywordAndExpression?.raw, + expression.raw, + unexpectedAfterExpression?.raw + ] + let raw = RawSyntax.makeLayout( + kind: SyntaxKind.copyExpr, + from: layout, + arena: arena, + leadingTrivia: leadingTrivia, + trailingTrivia: trailingTrivia + + ) + return SyntaxData.forRoot(raw) + } + self.init(data) + } + + public var unexpectedBeforeCopyKeyword: UnexpectedNodesSyntax? { + get { + return data.child(at: 0, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) + } + set(value) { + self = CopyExprSyntax(data.replacingChild(at: 0, with: value?.raw, arena: SyntaxArena())) + } + } + + public var copyKeyword: TokenSyntax { + get { + return TokenSyntax(data.child(at: 1, parent: Syntax(self))!) + } + set(value) { + self = CopyExprSyntax(data.replacingChild(at: 1, with: value.raw, arena: SyntaxArena())) + } + } + + public var unexpectedBetweenCopyKeywordAndExpression: UnexpectedNodesSyntax? { + get { + return data.child(at: 2, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) + } + set(value) { + self = CopyExprSyntax(data.replacingChild(at: 2, with: value?.raw, arena: SyntaxArena())) + } + } + + public var expression: ExprSyntax { + get { + return ExprSyntax(data.child(at: 3, parent: Syntax(self))!) + } + set(value) { + self = CopyExprSyntax(data.replacingChild(at: 3, with: value.raw, arena: SyntaxArena())) + } + } + + public var unexpectedAfterExpression: UnexpectedNodesSyntax? { + get { + return data.child(at: 4, parent: Syntax(self)).map(UnexpectedNodesSyntax.init) + } + set(value) { + self = CopyExprSyntax(data.replacingChild(at: 4, with: value?.raw, arena: SyntaxArena())) + } + } + + public static var structure: SyntaxNodeStructure { + return .layout([ + \Self.unexpectedBeforeCopyKeyword, + \Self.copyKeyword, + \Self.unexpectedBetweenCopyKeywordAndExpression, + \Self.expression, + \Self.unexpectedAfterExpression + ]) + } +} + // MARK: - DictionaryExprSyntax