diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 35ac46e..48ca012 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -14,10 +14,11 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: '0' - - name: Install swift + - name: Install swift + if: matrix.os == 'macos-latest' || matrix.os == 'windows-latest' uses: SwiftyLab/setup-swift@latest with: - swift-version: "5.9" + check-latest: true - name: Run Linux Build if: matrix.os == 'ubuntu-20.04' run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cab7c6b..3340988 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,10 +21,11 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: '0' - - name: Install swift + - name: Install swift + if: matrix.os == 'macos-latest' || matrix.os == 'windows-latest' uses: SwiftyLab/setup-swift@latest with: - swift-version: "5.9" + check-latest: true - name: Run Linux Build if: matrix.os == 'ubuntu-20.04' run: | diff --git a/Package.resolved b/Package.resolved index 7a10cb7..96793ae 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,4 +1,5 @@ { + "originHash" : "f0bdad18f08b8438e54c541e12efce628281aa84df2fdc05c794ae30b579c24c", "pins" : [ { "identity" : "swift-argument-parser", @@ -14,10 +15,10 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-syntax.git", "state" : { - "revision" : "74203046135342e4a4a627476dd6caf8b28fe11b", - "version" : "509.0.0" + "revision" : "fa8f95c2d536d6620cc2f504ebe8a6167c9fc2dd", + "version" : "510.0.1" } } ], - "version" : 2 + "version" : 3 } \ No newline at end of file diff --git a/Package.swift b/Package.swift index bd1b837..33a9e02 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version: 5.9 +// swift-tools-version: 5.10 import PackageDescription @@ -12,7 +12,7 @@ let package = Package( ], dependencies: [ .package(url: "https://github.com/apple/swift-argument-parser", from: "1.2.0"), - .package(url: "https://github.com/apple/swift-syntax", from: "509.0.0"), + .package(url: "https://github.com/apple/swift-syntax", from: "510.0.1"), ], targets: [ .target( @@ -22,6 +22,9 @@ let package = Package( .product(name: "SwiftParser", package: "swift-syntax"), .product(name: "SwiftOperators", package: "swift-syntax"), "CodeGeneration", + ], + swiftSettings: [ + .unsafeFlags(["-warnings-as-errors"]) ] ), .target( diff --git a/Sources/CodeGeneration/SyntaxSupport/AttributeNodes.swift b/Sources/CodeGeneration/SyntaxSupport/AttributeNodes.swift index b52e80f..9cdec68 100644 --- a/Sources/CodeGeneration/SyntaxSupport/AttributeNodes.swift +++ b/Sources/CodeGeneration/SyntaxSupport/AttributeNodes.swift @@ -180,9 +180,7 @@ public let ATTRIBUTE_NODES: [Node] = [ Child( name: "availabilityArguments", deprecatedName: "availabilityList", - kind: .collection( - kind: .availabilityArgumentList, collectionElementName: "AvailabilityArgument", - deprecatedCollectionElementName: "Availability") + kind: .collection(kind: .availabilityArgumentList, collectionElementName: "AvailabilityArgument", deprecatedCollectionElementName: "Availability") ), Child( name: "semicolon", @@ -238,9 +236,7 @@ public let ATTRIBUTE_NODES: [Node] = [ Child( name: "platforms", deprecatedName: "versionList", - kind: .collection( - kind: .platformVersionItemList, collectionElementName: "Platform", - deprecatedCollectionElementName: "Availability"), + kind: .collection(kind: .platformVersionItemList, collectionElementName: "Platform", deprecatedCollectionElementName: "Availability"), documentation: "The list of OS versions in which the declaration became ABI stable." ), ] @@ -361,8 +357,7 @@ public let ATTRIBUTE_NODES: [Node] = [ kind: .differentiabilityArgument, base: .syntax, nameForDiagnostics: "differentiability argument", - documentation: - "A differentiability argument: either the \"self\" identifier, a function parameter name, or a function parameter index.", + documentation: "A differentiability argument: either the \"self\" identifier, a function parameter name, or a function parameter index.", traits: [ "WithTrailingComma" ], @@ -476,8 +471,7 @@ public let ATTRIBUTE_NODES: [Node] = [ name: "genericWhereClause", deprecatedName: "whereClause", kind: .node(kind: .genericWhereClause), - documentation: - "A `where` clause that places additional constraints on generic parameters like `where T: Differentiable`.", + documentation: "A `where` clause that places additional constraints on generic parameters like `where T: Differentiable`.", isOptional: true ), ] @@ -563,8 +557,7 @@ public let ATTRIBUTE_NODES: [Node] = [ kind: .effectsAttributeArgumentList, base: .syntaxCollection, nameForDiagnostics: "@_effects arguments", - documentation: - "The arguments of the '@_effects' attribute. These will be parsed during the SIL stage.", + documentation: "The arguments of the '@_effects' attribute. These will be parsed during the SIL stage.", elementChoices: [.token] ), @@ -595,8 +588,7 @@ public let ATTRIBUTE_NODES: [Node] = [ kind: .implementsAttributeArguments, base: .syntax, nameForDiagnostics: "@_implements arguemnts", - documentation: - "The arguments for the `@_implements` attribute of the form `Type, methodName(arg1Label:arg2Label:)`", + documentation: "The arguments for the `@_implements` attribute of the form `Type, methodName(arg1Label:arg2Label:)`", children: [ Child( name: "type", @@ -637,7 +629,6 @@ public let ATTRIBUTE_NODES: [Node] = [ .keyword(.kind), .keyword(.spi), .keyword(.spiModule), - .keyword(.available), ]), nameForDiagnostics: "label", documentation: "The label of the argument" @@ -708,8 +699,7 @@ public let ATTRIBUTE_NODES: [Node] = [ Child( name: "ordinal", kind: .token(choices: [.token(.integerLiteral)]), - documentation: - "The ordinal corresponding to the 'some' keyword that introduced this opaque type." + documentation: "The ordinal corresponding to the 'some' keyword that introduced this opaque type." ), ] ), @@ -748,18 +738,14 @@ public let ATTRIBUTE_NODES: [Node] = [ base: .syntaxCollection, nameForDiagnostics: "argument to '@_specialize", documentation: "A collection of arguments for the `@_specialize` attribute", - elementChoices: [ - .labeledSpecializeArgument, .specializeAvailabilityArgument, - .specializeTargetFunctionArgument, .genericWhereClause, - ] + elementChoices: [.labeledSpecializeArgument, .specializeAvailabilityArgument, .specializeTargetFunctionArgument, .genericWhereClause] ), Node( kind: .specializeTargetFunctionArgument, base: .syntax, nameForDiagnostics: "attribute argument", - documentation: - "A labeled argument for the `@_specialize` attribute with a function decl value like `target: myFunc(_:)`", + documentation: "A labeled argument for the `@_specialize` attribute with a function decl value like `target: myFunc(_:)`", traits: [ "WithTrailingComma" ], diff --git a/Sources/CodeGeneration/SyntaxSupport/AvailabilityNodes.swift b/Sources/CodeGeneration/SyntaxSupport/AvailabilityNodes.swift index 980e8b1..be317e4 100644 --- a/Sources/CodeGeneration/SyntaxSupport/AvailabilityNodes.swift +++ b/Sources/CodeGeneration/SyntaxSupport/AvailabilityNodes.swift @@ -15,8 +15,7 @@ public let AVAILABILITY_NODES: [Node] = [ kind: .availabilityArgument, base: .syntax, nameForDiagnostics: "availability argument", - documentation: - "A single argument to an `@available` argument like `*`, `iOS 10.1`, or `message: \"This has been deprecated\"`.", + documentation: "A single argument to an `@available` argument like `*`, `iOS 10.1`, or `message: \"This has been deprecated\"`.", traits: ["WithTrailingComma"], children: [ Child( @@ -55,8 +54,7 @@ public let AVAILABILITY_NODES: [Node] = [ kind: .availabilityLabeledArgument, base: .syntax, nameForDiagnostics: "availability argument", - documentation: - "An argument to an `@available` attribute that consists of a label and a value, e.g. `message: \"This has been deprecated\"`.", + documentation: "An argument to an `@available` attribute that consists of a label and a value, e.g. `message: \"This has been deprecated\"`.", children: [ Child( name: "label", @@ -104,8 +102,7 @@ public let AVAILABILITY_NODES: [Node] = [ kind: .platformVersion, base: .syntax, nameForDiagnostics: "version restriction", - documentation: - "An argument to `@available` that restricts the availability on a certain platform to a version, e.g. `iOS 10` or `swift 3.4`.", + documentation: "An argument to `@available` that restricts the availability on a certain platform to a version, e.g. `iOS 10` or `swift 3.4`.", children: [ Child( name: "platform", @@ -160,8 +157,7 @@ public let AVAILABILITY_NODES: [Node] = [ kind: .versionTuple, base: .syntax, nameForDiagnostics: "version tuple", - documentation: - "A version number like `1.2.0`. Only the first version component is required. There might be an arbitrary number of following components.", + documentation: "A version number like `1.2.0`. Only the first version component is required. There might be an arbitrary number of following components.", children: [ Child( name: "major", @@ -171,8 +167,7 @@ public let AVAILABILITY_NODES: [Node] = [ Child( name: "components", kind: .collection(kind: .versionComponentList, collectionElementName: "VersionComponent"), - documentation: - "Any version components that are not the major version . For example, for `1.2.0`, this will contain `.2.0`." + documentation: "Any version components that are not the major version . For example, for `1.2.0`, this will contain `.2.0`." ), ] ), diff --git a/Sources/CodeGeneration/SyntaxSupport/Child.swift b/Sources/CodeGeneration/SyntaxSupport/Child.swift index 9e41544..45afefc 100644 --- a/Sources/CodeGeneration/SyntaxSupport/Child.swift +++ b/Sources/CodeGeneration/SyntaxSupport/Child.swift @@ -24,6 +24,15 @@ public enum TokenChoice: Equatable { case .token: return false } } + + public var varOrCaseName: TokenSyntax { + switch self { + case .keyword(let keyword): + return keyword.spec.varOrCaseName + case .token(let token): + return token.spec.varOrCaseName + } + } } public enum ChildKind { @@ -32,14 +41,11 @@ public enum ChildKind { /// The child always contains a node that matches one of the `choices`. case nodeChoices(choices: [Child]) /// The child is a collection of `kind`. - case collection( - kind: SyntaxNodeKind, collectionElementName: String, defaultsToEmpty: Bool = false, - deprecatedCollectionElementName: String? = nil) + case collection(kind: SyntaxNodeKind, collectionElementName: String, defaultsToEmpty: Bool = false, deprecatedCollectionElementName: String? = nil) /// The child is a token that matches one of the given `choices`. /// If `requiresLeadingSpace` or `requiresTrailingSpace` is not `nil`, it /// overrides the default leading/trailing space behavior of the token. - case token( - choices: [TokenChoice], requiresLeadingSpace: Bool? = nil, requiresTrailingSpace: Bool? = nil) + case token(choices: [TokenChoice], requiresLeadingSpace: Bool? = nil, requiresTrailingSpace: Bool? = nil) public var isNodeChoices: Bool { if case .nodeChoices = self { @@ -123,11 +129,11 @@ public class Child { public var syntaxNodeKind: SyntaxNodeKind { switch kind { - case .node(let kind): + case .node(kind: let kind): return kind case .nodeChoices: return .syntax - case .collection(let kind, _, _, _): + case .collection(kind: let kind, _, _, _): return kind case .token: return .token @@ -143,8 +149,7 @@ public class Child { /// /// For any other kind of child nodes, accessing this property crashes. public var syntaxChoicesType: TypeSyntax { - precondition( - kind.isNodeChoices, "Cannot get `syntaxChoicesType` for node that doesn’t have nodeChoices") + precondition(kind.isNodeChoices, "Cannot get `syntaxChoicesType` for node that doesn’t have nodeChoices") return "\(raw: name.withFirstCharacterUppercased)" } @@ -223,7 +228,7 @@ public class Child { return choices.isEmpty case .node(let kind): return kind.isBase - case .collection(let kind, _, _, _): + case .collection(kind: let kind, _, _, _): return kind.isBase case .token: return false @@ -236,8 +241,7 @@ public class Child { /// an experimental language feature. public var apiAttributes: AttributeListSyntax { guard isExperimental else { return "" } - return AttributeListSyntax("@_spi(ExperimentalLanguageFeatures)").with( - \.trailingTrivia, .newline) + return AttributeListSyntax("@_spi(ExperimentalLanguageFeatures)").with(\.trailingTrivia, .newline) } /// If a classification is passed, it specifies the color identifiers in @@ -254,19 +258,15 @@ public class Child { documentation: String? = nil, isOptional: Bool = false ) { - precondition( - name.first?.isLowercase ?? true, "The first letter of a child’s name should be lowercase") - precondition( - deprecatedName?.first?.isLowercase ?? true, - "The first letter of a child’s deprecatedName should be lowercase") + precondition(name.first?.isLowercase ?? true, "The first letter of a child’s name should be lowercase") + precondition(deprecatedName?.first?.isLowercase ?? true, "The first letter of a child’s deprecatedName should be lowercase") self.name = name self.deprecatedName = deprecatedName self.kind = kind self.experimentalFeature = experimentalFeature self.nameForDiagnostics = nameForDiagnostics self.documentationSummary = SwiftSyntax.Trivia.docCommentTrivia(from: documentation) - self.documentationAbstract = String( - documentation?.split(whereSeparator: \.isNewline).first ?? "") + self.documentationAbstract = String(documentation?.split(whereSeparator: \.isNewline).first ?? "") self.isOptional = isOptional } } diff --git a/Sources/CodeGeneration/SyntaxSupport/CommonNodes.swift b/Sources/CodeGeneration/SyntaxSupport/CommonNodes.swift index 74031ab..9b9f511 100644 --- a/Sources/CodeGeneration/SyntaxSupport/CommonNodes.swift +++ b/Sources/CodeGeneration/SyntaxSupport/CommonNodes.swift @@ -22,8 +22,7 @@ public let COMMON_NODES: [Node] = [ kind: .codeBlockItem, base: .syntax, nameForDiagnostics: nil, - documentation: - "A CodeBlockItem is any Syntax node that appears on its own line inside a CodeBlock.", + documentation: "A CodeBlockItem is any Syntax node that appears on its own line inside a CodeBlock.", parserFunction: "parseNonOptionalCodeBlockItem", children: [ Child( @@ -57,6 +56,7 @@ public let COMMON_NODES: [Node] = [ kind: .codeBlock, base: .syntax, nameForDiagnostics: "code block", + parserFunction: "parseCodeBlock", traits: [ "Braced", "WithStatements", @@ -81,29 +81,33 @@ public let COMMON_NODES: [Node] = [ ), Node( - kind: .thrownTypeClause, + kind: .throwsClause, base: .syntax, - nameForDiagnostics: "thrown type clause", - documentation: "The specific error type that a function can throw.", - traits: [ - "Parenthesized" - ], + nameForDiagnostics: "throws clause", children: [ + Child( + name: "throwsSpecifier", + kind: .token(choices: [.keyword(.throws), .keyword(.rethrows)]), + documentation: "The `throws` keyword." + ), Child( name: "leftParen", kind: .token(choices: [.token(.leftParen)]), - documentation: "The '(' to open the thrown type clause." + documentation: "The '(' to open the thrown error type specification.", + isOptional: true ), Child( name: "type", kind: .node(kind: .type), nameForDiagnostics: "thrown type", - documentation: "The thrown error type." + documentation: "The thrown error type.", + isOptional: true ), Child( name: "rightParen", kind: .token(choices: [.token(.rightParen)]), - documentation: "The ')' to closure the thrown type clause." + documentation: "The ')' to close the thrown error type specification.", + isOptional: true ), ] ), @@ -123,16 +127,9 @@ public let COMMON_NODES: [Node] = [ isOptional: true ), Child( - name: "throwsSpecifier", - kind: .token(choices: [.keyword(.throws)]), - documentation: "The `throws` keyword.", - isOptional: true - ), - Child( - name: "thrownError", - kind: .node(kind: .thrownTypeClause), - experimentalFeature: .typedThrows, - documentation: "The specific error type thrown by this accessor.", + name: "throwsClause", + kind: .node(kind: .throwsClause), + documentation: "The clause specifying thrown errors", isOptional: true ), ] @@ -153,16 +150,9 @@ public let COMMON_NODES: [Node] = [ isOptional: true ), Child( - name: "throwsSpecifier", - kind: .token(choices: [.keyword(.throws), .keyword(.rethrows)]), - documentation: "The `throws` or `rethrows` keyword.", - isOptional: true - ), - Child( - name: "thrownError", - kind: .node(kind: .thrownTypeClause), - experimentalFeature: .typedThrows, - documentation: "The specific error type thrown by this function.", + name: "throwsClause", + kind: .node(kind: .throwsClause), + documentation: "The clause specifying thrown errors", isOptional: true ), ] @@ -201,8 +191,7 @@ public let COMMON_NODES: [Node] = [ kind: .missingDecl, base: .decl, nameForDiagnostics: "declaration", - documentation: - "In case the source code is missing a declaration, this node stands in place of the missing declaration.", + documentation: "In case the source code is missing a declaration, this node stands in place of the missing declaration.", traits: [ "MissingNode", "WithAttributes", @@ -211,22 +200,17 @@ public let COMMON_NODES: [Node] = [ children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), - documentation: - "If there were standalone attributes without a declaration to attach them to, the ``MissingDeclSyntax`` will contain these." + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + documentation: "If there were standalone attributes without a declaration to attach them to, the ``MissingDeclSyntax`` will contain these." ), Child( name: "modifiers", - kind: .collection( - kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), - documentation: - "If there were standalone modifiers without a declaration to attach them to, the ``MissingDeclSyntax`` will contain these." + kind: .collection(kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), + documentation: "If there were standalone modifiers without a declaration to attach them to, the ``MissingDeclSyntax`` will contain these." ), Child( name: "placeholder", - kind: .token( - choices: [.token(.identifier)], requiresLeadingSpace: false, requiresTrailingSpace: false), + kind: .token(choices: [.token(.identifier)], requiresLeadingSpace: false, requiresTrailingSpace: false), documentation: """ A placeholder, i.e. `<#decl#>`, that can be inserted into the source code to represent the missing declaration. @@ -240,16 +224,14 @@ public let COMMON_NODES: [Node] = [ kind: .missingExpr, base: .expr, nameForDiagnostics: "expression", - documentation: - "In case the source code is missing an expression, this node stands in place of the missing expression.", + documentation: "In case the source code is missing an expression, this node stands in place of the missing expression.", traits: [ "MissingNode" ], children: [ Child( name: "placeholder", - kind: .token( - choices: [.token(.identifier)], requiresLeadingSpace: false, requiresTrailingSpace: false), + kind: .token(choices: [.token(.identifier)], requiresLeadingSpace: false, requiresTrailingSpace: false), documentation: """ A placeholder, i.e. `<#expression#>`, that can be inserted into the source code to represent the missing expression. @@ -263,16 +245,14 @@ public let COMMON_NODES: [Node] = [ kind: .missingPattern, base: .pattern, nameForDiagnostics: "pattern", - documentation: - "In case the source code is missing a pattern, this node stands in place of the missing pattern.", + documentation: "In case the source code is missing a pattern, this node stands in place of the missing pattern.", traits: [ "MissingNode" ], children: [ Child( name: "placeholder", - kind: .token( - choices: [.token(.identifier)], requiresLeadingSpace: false, requiresTrailingSpace: false), + kind: .token(choices: [.token(.identifier)], requiresLeadingSpace: false, requiresTrailingSpace: false), documentation: """ A placeholder, i.e. `<#pattern#>`, that can be inserted into the source code to represent the missing pattern. @@ -286,16 +266,14 @@ public let COMMON_NODES: [Node] = [ kind: .missingStmt, base: .stmt, nameForDiagnostics: "statement", - documentation: - "In case the source code is missing a statement, this node stands in place of the missing statement.", + documentation: "In case the source code is missing a statement, this node stands in place of the missing statement.", traits: [ "MissingNode" ], children: [ Child( name: "placeholder", - kind: .token( - choices: [.token(.identifier)], requiresLeadingSpace: false, requiresTrailingSpace: false), + kind: .token(choices: [.token(.identifier)], requiresLeadingSpace: false, requiresTrailingSpace: false), documentation: """ A placeholder, i.e. `<#statement#>`, that can be inserted into the source code to represent the missing pattern. @@ -309,16 +287,14 @@ public let COMMON_NODES: [Node] = [ kind: .missing, base: .syntax, nameForDiagnostics: nil, - documentation: - "In case the source code is missing a syntax node, this node stands in place of the missing node.", + documentation: "In case the source code is missing a syntax node, this node stands in place of the missing node.", traits: [ "MissingNode" ], children: [ Child( name: "placeholder", - kind: .token( - choices: [.token(.identifier)], requiresLeadingSpace: false, requiresTrailingSpace: false), + kind: .token(choices: [.token(.identifier)], requiresLeadingSpace: false, requiresTrailingSpace: false), documentation: """ A placeholder, i.e. `<#syntax#>`, that can be inserted into the source code to represent the missing pattern. @@ -332,16 +308,14 @@ public let COMMON_NODES: [Node] = [ kind: .missingType, base: .type, nameForDiagnostics: "type", - documentation: - "In case the source code is missing a type, this node stands in place of the missing type.", + documentation: "In case the source code is missing a type, this node stands in place of the missing type.", traits: [ "MissingNode" ], children: [ Child( name: "placeholder", - kind: .token( - choices: [.token(.identifier)], requiresLeadingSpace: false, requiresTrailingSpace: false), + kind: .token(choices: [.token(.identifier)], requiresLeadingSpace: false, requiresTrailingSpace: false), documentation: """ A placeholder, i.e. `<#type#>`, that can be inserted into the source code to represent the missing type. @@ -379,15 +353,9 @@ public let COMMON_NODES: [Node] = [ isOptional: true ), Child( - name: "throwsSpecifier", - kind: .token(choices: [.keyword(.throws)]), - isOptional: true - ), - Child( - name: "thrownError", - kind: .node(kind: .thrownTypeClause), - experimentalFeature: .typedThrows, - documentation: "The specific error type thrown by this function type.", + name: "throwsClause", + kind: .node(kind: .throwsClause), + documentation: "The clause specifying thrown errors", isOptional: true ), ] @@ -404,8 +372,7 @@ public let COMMON_NODES: [Node] = [ kind: .unexpectedNodes, base: .syntaxCollection, nameForDiagnostics: nil, - documentation: - "A collection of syntax nodes that occurred in the source code but could not be used to form a valid syntax tree.", + documentation: "A collection of syntax nodes that occurred in the source code but could not be used to form a valid syntax tree.", elementChoices: [.syntax] ), diff --git a/Sources/CodeGeneration/SyntaxSupport/DeclNodes.swift b/Sources/CodeGeneration/SyntaxSupport/DeclNodes.swift index 54d04fc..acd632e 100644 --- a/Sources/CodeGeneration/SyntaxSupport/DeclNodes.swift +++ b/Sources/CodeGeneration/SyntaxSupport/DeclNodes.swift @@ -82,12 +82,14 @@ public let DECL_NODES: [Node] = [ base: .decl, nameForDiagnostics: "accessor", parserFunction: "parseAccessorDecl", - traits: ["WithAttributes"], + traits: [ + "WithOptionalCodeBlock", + "WithAttributes", + ], children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), nameForDiagnostics: "attributes" ), Child( @@ -180,14 +182,12 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), nameForDiagnostics: "attributes" ), Child( name: "modifiers", - kind: .collection( - kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), + kind: .collection(kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), nameForDiagnostics: "modifiers", documentation: "Modifiers like `public` that are attached to the actor declaration." ), @@ -200,8 +200,7 @@ public let DECL_NODES: [Node] = [ name: "name", deprecatedName: "identifier", kind: .token(choices: [.token(.identifier)]), - documentation: - "The name of the actor. If the name matches a reserved keyword use backticks to escape it." + documentation: "The name of the actor. If the name matches a reserved keyword use backticks to escape it." ), Child( name: "genericParameterClause", @@ -220,8 +219,7 @@ public let DECL_NODES: [Node] = [ name: "genericWhereClause", kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", - documentation: - "A `where` clause that places additional constraints on generic parameters like `where Element: Hashable`.", + documentation: "A `where` clause that places additional constraints on generic parameters like `where Element: Hashable`.", isOptional: true ), Child( @@ -270,18 +268,15 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), nameForDiagnostics: "attributes", documentation: "Attributes attached to the associated type declaration." ), Child( name: "modifiers", - kind: .collection( - kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), + kind: .collection(kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), nameForDiagnostics: "modifiers", - documentation: - "Modifiers like `public` that are attached to the associated type declaration." + documentation: "Modifiers like `public` that are attached to the associated type declaration." ), Child( name: "associatedtypeKeyword", @@ -298,23 +293,20 @@ public let DECL_NODES: [Node] = [ name: "inheritanceClause", kind: .node(kind: .inheritanceClause), nameForDiagnostics: "inheritance clause", - documentation: - "The inheritance clause describing conformances for this associated type declaration.", + documentation: "The inheritance clause describing conformances for this associated type declaration.", isOptional: true ), Child( name: "initializer", kind: .node(kind: .typeInitializerClause), - documentation: - "The type initializer clause for this associated type declaration which represents a default type assignment for the associated type.", + documentation: "The type initializer clause for this associated type declaration which represents a default type assignment for the associated type.", isOptional: true ), Child( name: "genericWhereClause", kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", - documentation: - "The `where` clause that applies to the generic parameters of this associated type declaration.", + documentation: "The `where` clause that applies to the generic parameters of this associated type declaration.", isOptional: true ), ] @@ -359,16 +351,13 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), nameForDiagnostics: "attributes", - documentation: - "Attributes attached to the class declaration, such as an `@available` attribute." + documentation: "Attributes attached to the class declaration, such as an `@available` attribute." ), Child( name: "modifiers", - kind: .collection( - kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), + kind: .collection(kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), nameForDiagnostics: "modifiers", documentation: "Modifiers like `public` that are attached to the class declaration." ), @@ -394,16 +383,14 @@ public let DECL_NODES: [Node] = [ name: "inheritanceClause", kind: .node(kind: .inheritanceClause), nameForDiagnostics: "inheritance clause", - documentation: - "The inheritance clause describing one or more conformances for this class declaration.", + documentation: "The inheritance clause describing one or more conformances for this class declaration.", isOptional: true ), Child( name: "genericWhereClause", kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", - documentation: - "The `where` clause that applies to the generic parameters of this class declaration.", + documentation: "The `where` clause that applies to the generic parameters of this class declaration.", isOptional: true ), Child( @@ -477,8 +464,10 @@ public let DECL_NODES: [Node] = [ .keyword(.private), .keyword(.public), .keyword(.reasync), + .keyword(._resultDependsOnSelf), .keyword(.required), .keyword(.static), + .keyword(.transferring), .keyword(.unowned), .keyword(.weak), ]) @@ -508,19 +497,18 @@ public let DECL_NODES: [Node] = [ traits: [ "WithAttributes", "WithModifiers", + "WithOptionalCodeBlock", ], children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), nameForDiagnostics: "attributes", documentation: "Attributes that are attached to the deinitializer." ), Child( name: "modifiers", - kind: .collection( - kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), + kind: .collection(kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), nameForDiagnostics: "modifiers", documentation: "Modifiers like `public` that are attached to the deinitializer." ), @@ -572,6 +560,8 @@ public let DECL_NODES: [Node] = [ nameForDiagnostics: "editor placeholder", documentation: """ An editor placeholder, e.g. `<#declaration#>` that is used in a position that expects a declaration. + + - Warning: This ``EditorPlaceholderDeclSyntax`` node is not generated by the parser anymore. Placeholders are represented by a ``MissingDeclSyntax``. """, traits: [ "WithAttributes", @@ -580,17 +570,13 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), - documentation: - "If there were attributes before the editor placeholder, the ``EditorPlaceholderDeclSyntax`` will contain these." + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + documentation: "If there were attributes before the editor placeholder, the ``EditorPlaceholderDeclSyntax`` will contain these." ), Child( name: "modifiers", - kind: .collection( - kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), - documentation: - "If there were modifiers before the editor placeholder, the `EditorPlaceholderDecl` will contain these." + kind: .collection(kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), + documentation: "If there were modifiers before the editor placeholder, the `EditorPlaceholderDecl` will contain these." ), Child( name: "placeholder", @@ -647,8 +633,7 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "modifiers", - kind: .collection( - kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), + kind: .collection(kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), nameForDiagnostics: "modifiers" ), Child( @@ -664,8 +649,7 @@ public let DECL_NODES: [Node] = [ Child( name: "colon", kind: .token(choices: [.token(.colon)]), - documentation: - "If the parameter has a label, the colon separating the label from the type.", + documentation: "If the parameter has a label, the colon separating the label from the type.", isOptional: true ), Child( @@ -679,15 +663,13 @@ public let DECL_NODES: [Node] = [ deprecatedName: "defaultArgument", kind: .node(kind: .initializerClause), nameForDiagnostics: "default value", - documentation: - "If the parameter has a default value, the initializer clause describing the default value.", + documentation: "If the parameter has a default value, the initializer clause describing the default value.", isOptional: true ), Child( name: "trailingComma", kind: .token(choices: [.token(.comma)]), - documentation: - "If the parameter is followed by another parameter, the comma separating them.", + documentation: "If the parameter is followed by another parameter, the comma separating them.", isOptional: true ), ] @@ -697,8 +679,7 @@ public let DECL_NODES: [Node] = [ kind: .enumCaseDecl, base: .decl, nameForDiagnostics: "enum case", - documentation: - "A `case` declaration of a Swift `enum`. It can have 1 or more `EnumCaseElement`s inside, each declaring a different case of the enum.", + documentation: "A `case` declaration of a Swift `enum`. It can have 1 or more `EnumCaseElement`s inside, each declaring a different case of the enum.", traits: [ "WithAttributes", "WithModifiers", @@ -706,15 +687,13 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), nameForDiagnostics: "attributes", documentation: "The attributes applied to the case declaration." ), Child( name: "modifiers", - kind: .collection( - kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), + kind: .collection(kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), nameForDiagnostics: "modifiers", documentation: "The declaration modifiers applied to the case declaration." ), @@ -744,8 +723,7 @@ public let DECL_NODES: [Node] = [ kind: .enumCaseElement, base: .syntax, nameForDiagnostics: nil, - documentation: - "An element of an enum case, containing the name of the case and, optionally, either associated values or an assignment to a raw value.", + documentation: "An element of an enum case, containing the name of the case and, optionally, either associated values or an assignment to a raw value.", traits: [ "WithTrailingComma" ], @@ -794,15 +772,13 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), nameForDiagnostics: "attributes", documentation: "The attributes applied to the enum declaration." ), Child( name: "modifiers", - kind: .collection( - kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), + kind: .collection(kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), nameForDiagnostics: "modifiers", documentation: "The declaration modifiers applied to the enum declaration." ), @@ -815,8 +791,7 @@ public let DECL_NODES: [Node] = [ name: "name", deprecatedName: "identifier", kind: .token(choices: [.token(.identifier)]), - documentation: - "Declares the name of this enum. If the name matches a reserved keyword use backticks to escape it." + documentation: "Declares the name of this enum. If the name matches a reserved keyword use backticks to escape it." ), Child( name: "genericParameterClause", @@ -830,16 +805,14 @@ public let DECL_NODES: [Node] = [ name: "inheritanceClause", kind: .node(kind: .inheritanceClause), nameForDiagnostics: "inheritance clause", - documentation: - "The inheritance clause describing conformances or raw values for this enum declaration.", + documentation: "The inheritance clause describing conformances or raw values for this enum declaration.", isOptional: true ), Child( name: "genericWhereClause", kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", - documentation: - "The `where` clause that applies to the generic parameters of this enum declaration.", + documentation: "The `where` clause that applies to the generic parameters of this enum declaration.", isOptional: true ), Child( @@ -863,14 +836,12 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), nameForDiagnostics: "attributes" ), Child( name: "modifiers", - kind: .collection( - kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), + kind: .collection(kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), nameForDiagnostics: "modifiers", documentation: "Modifiers like `public` that are attached to the extension declaration." ), @@ -892,8 +863,7 @@ public let DECL_NODES: [Node] = [ name: "genericWhereClause", kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", - documentation: - "A `where` clause that places additional constraints on generic parameters like `where Element: Hashable`.", + documentation: "A `where` clause that places additional constraints on generic parameters like `where Element: Hashable`.", isOptional: true ), Child( @@ -914,18 +884,17 @@ public let DECL_NODES: [Node] = [ "WithAttributes", "WithGenericParameters", "WithModifiers", + "WithOptionalCodeBlock", ], children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), nameForDiagnostics: "attributes" ), Child( name: "modifiers", - kind: .collection( - kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), + kind: .collection(kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), nameForDiagnostics: "modifiers", documentation: "Modifiers like `public` that are attached to the function declaration." ), @@ -942,8 +911,7 @@ public let DECL_NODES: [Node] = [ .token(.prefixOperator), .token(.postfixOperator), ]), - documentation: - "The name of the function. If the name matches a reserved keyword use backticks to escape it." + documentation: "The name of the function. If the name matches a reserved keyword use backticks to escape it." ), Child( name: "genericParameterClause", @@ -961,8 +929,7 @@ public let DECL_NODES: [Node] = [ name: "genericWhereClause", kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", - documentation: - "A `where` clause that places additional constraints on generic parameters like `where Element: Hashable`.", + documentation: "A `where` clause that places additional constraints on generic parameters like `where Element: Hashable`.", isOptional: true ), Child( @@ -989,14 +956,12 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), nameForDiagnostics: "attributes" ), Child( name: "modifiers", - kind: .collection( - kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), + kind: .collection(kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), nameForDiagnostics: "modifiers" ), Child( @@ -1005,8 +970,7 @@ public let DECL_NODES: [Node] = [ ), Child( name: "secondName", - kind: .token( - choices: [.token(.identifier), .token(.wildcard)], requiresLeadingSpace: true), + kind: .token(choices: [.token(.identifier), .token(.wildcard)], requiresLeadingSpace: true), nameForDiagnostics: "internal name", isOptional: true ), @@ -1150,18 +1114,15 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), nameForDiagnostics: "attributes", documentation: "Attributes attached to the import declaration, for example `@testable`." ), Child( name: "modifiers", - kind: .collection( - kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), + kind: .collection(kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), nameForDiagnostics: "modifiers", - documentation: - "Modifiers that are attached to the import declaration. Currently, no modifiers are supported by Swift." + documentation: "Modifiers that are attached to the import declaration. Currently, no modifiers are supported by Swift." ), Child( name: "importKeyword", @@ -1262,19 +1223,18 @@ public let DECL_NODES: [Node] = [ "WithAttributes", "WithGenericParameters", "WithModifiers", + "WithOptionalCodeBlock", ], children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), nameForDiagnostics: "attributes", documentation: "Attributes that are attached to the initializer." ), Child( name: "modifiers", - kind: .collection( - kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), + kind: .collection(kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), nameForDiagnostics: "modifiers", documentation: "Modifiers that are attached to the initializer declaration." ), @@ -1303,22 +1263,19 @@ public let DECL_NODES: [Node] = [ name: "signature", kind: .node(kind: .functionSignature), nameForDiagnostics: "function signature", - documentation: - "The arguments of the initializer. While the function signature allows specifying a return clause, doing so is not semantically valid." + documentation: "The arguments of the initializer. While the function signature allows specifying a return clause, doing so is not semantically valid." ), Child( name: "genericWhereClause", kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", - documentation: - "If the initializer had generic parameters, a where clause that can restrict those.", + documentation: "If the initializer had generic parameters, a where clause that can restrict those.", isOptional: true ), Child( name: "body", kind: .node(kind: .codeBlock), - documentation: - "The initializer’s body. Missing if the initializer is a requirement of a protocol declaration.", + documentation: "The initializer’s body. Missing if the initializer is a requirement of a protocol declaration.", isOptional: true ), ] @@ -1337,14 +1294,12 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), nameForDiagnostics: "attributes" ), Child( name: "modifiers", - kind: .collection( - kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), + kind: .collection(kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), nameForDiagnostics: "modifiers" ), Child( @@ -1378,8 +1333,7 @@ public let DECL_NODES: [Node] = [ name: "genericWhereClause", kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", - documentation: - "A `where` clause that places additional constraints on generic parameters like `where Element: Hashable`.", + documentation: "A `where` clause that places additional constraints on generic parameters like `where Element: Hashable`.", isOptional: true ), ] @@ -1389,8 +1343,7 @@ public let DECL_NODES: [Node] = [ kind: .macroExpansionDecl, base: .decl, nameForDiagnostics: "macro expansion", - documentation: - "The expansion of a freestanding macro in a position that expects a declaration.", + documentation: "The expansion of a freestanding macro in a position that expects a declaration.", traits: [ "FreestandingMacroExpansion", "WithAttributes", @@ -1399,14 +1352,12 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), nameForDiagnostics: "attributes" ), Child( name: "modifiers", - kind: .collection( - kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), + kind: .collection(kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), nameForDiagnostics: "modifiers" ), Child( @@ -1448,9 +1399,7 @@ public let DECL_NODES: [Node] = [ ), Child( name: "additionalTrailingClosures", - kind: .collection( - kind: .multipleTrailingClosureElementList, - collectionElementName: "AdditionalTrailingClosure", defaultsToEmpty: true) + kind: .collection(kind: .multipleTrailingClosureElementList, collectionElementName: "AdditionalTrailingClosure", defaultsToEmpty: true) ), ] ), @@ -1481,8 +1430,7 @@ public let DECL_NODES: [Node] = [ kind: .memberBlockItem, base: .syntax, nameForDiagnostics: nil, - documentation: - "A member declaration of a type consisting of a declaration and an optional semicolon;", + documentation: "A member declaration of a type consisting of a declaration and an optional semicolon;", children: [ Child( name: "decl", @@ -1535,9 +1483,7 @@ public let DECL_NODES: [Node] = [ Child( name: "name", deprecatedName: "identifier", - kind: .token(choices: [ - .token(.binaryOperator), .token(.prefixOperator), .token(.postfixOperator), - ]) + kind: .token(choices: [.token(.binaryOperator), .token(.prefixOperator), .token(.postfixOperator)]) ), Child( name: "operatorPrecedenceAndTypes", @@ -1552,8 +1498,7 @@ public let DECL_NODES: [Node] = [ kind: .operatorPrecedenceAndTypes, base: .syntax, nameForDiagnostics: nil, - documentation: - "A clause to specify precedence group in infix operator declarations, and designated types in any operator declaration.", + documentation: "A clause to specify precedence group in infix operator declarations, and designated types in any operator declaration.", children: [ Child( name: "colon", @@ -1567,8 +1512,7 @@ public let DECL_NODES: [Node] = [ ), Child( name: "designatedTypes", - kind: .collection( - kind: .designatedTypeList, collectionElementName: "DesignatedTypeElement"), + kind: .collection(kind: .designatedTypeList, collectionElementName: "DesignatedTypeElement"), documentation: "The designated types associated with this operator." ), ] @@ -1746,8 +1690,7 @@ public let DECL_NODES: [Node] = [ kind: .precedenceGroupAssignment, base: .syntax, nameForDiagnostics: "'assignment' property of precedencegroup", - documentation: - "Specifies the precedence of an operator when used in an operation that includes optional chaining.", + documentation: "Specifies the precedence of an operator when used in an operation that includes optional chaining.", children: [ Child( name: "assignmentLabel", @@ -1772,8 +1715,7 @@ public let DECL_NODES: [Node] = [ kind: .precedenceGroupAssociativity, base: .syntax, nameForDiagnostics: "'associativity' property of precedencegroup", - documentation: - "Specifies how a sequence of operators with the same precedence level are grouped together in the absence of grouping parentheses.", + documentation: "Specifies how a sequence of operators with the same precedence level are grouped together in the absence of grouping parentheses.", children: [ Child( name: "associativityLabel", @@ -1796,9 +1738,7 @@ public let DECL_NODES: [Node] = [ kind: .precedenceGroupAttributeList, base: .syntaxCollection, nameForDiagnostics: nil, - elementChoices: [ - .precedenceGroupRelation, .precedenceGroupAssignment, .precedenceGroupAssociativity, - ] + elementChoices: [.precedenceGroupRelation, .precedenceGroupAssignment, .precedenceGroupAssociativity] ), Node( @@ -1807,6 +1747,7 @@ public let DECL_NODES: [Node] = [ nameForDiagnostics: "precedencegroup", documentation: "A Swift `precedencegroup` declaration.", traits: [ + "Braced", "NamedDecl", "WithAttributes", "WithModifiers", @@ -1814,15 +1755,13 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), nameForDiagnostics: "attributes", documentation: "The attributes applied to the 'precedencegroup' declaration." ), Child( name: "modifiers", - kind: .collection( - kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), + kind: .collection(kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), nameForDiagnostics: "modifiers", documentation: "The declaration modifiers applied to the 'precedencegroup' declaration." ), @@ -1842,8 +1781,7 @@ public let DECL_NODES: [Node] = [ ), Child( name: "groupAttributes", - kind: .collection( - kind: .precedenceGroupAttributeList, collectionElementName: "GroupAttribute"), + kind: .collection(kind: .precedenceGroupAttributeList, collectionElementName: "GroupAttribute"), documentation: "The characteristics of this precedence group." ), Child( @@ -1928,16 +1866,13 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), nameForDiagnostics: "attributes", - documentation: - "Attributes attached to the protocol declaration, such as an `@available` attribute." + documentation: "Attributes attached to the protocol declaration, such as an `@available` attribute." ), Child( name: "modifiers", - kind: .collection( - kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), + kind: .collection(kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), nameForDiagnostics: "modifiers", documentation: "Modifiers attached to the protocol declaration, such as `public`." ), @@ -1963,16 +1898,14 @@ public let DECL_NODES: [Node] = [ name: "inheritanceClause", kind: .node(kind: .inheritanceClause), nameForDiagnostics: "inheritance clause", - documentation: - "The inheritance clause describing one or more conformances for this protocol declaration.", + documentation: "The inheritance clause describing one or more conformances for this protocol declaration.", isOptional: true ), Child( name: "genericWhereClause", kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", - documentation: - "The `where` clause that applies to the generic parameters of this protocol declaration.", + documentation: "The `where` clause that applies to the generic parameters of this protocol declaration.", isOptional: true ), Child( @@ -2011,8 +1944,7 @@ public let DECL_NODES: [Node] = [ Child( name: "shebang", kind: .token(choices: [.token(.shebang)]), - documentation: - "A shebang can specify the path of the compiler when using Swift source file as a script.", + documentation: "A shebang can specify the path of the compiler when using Swift source file as a script.", isOptional: true ), Child( @@ -2100,15 +2032,13 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), nameForDiagnostics: "attributes", documentation: "Attributes that are attached to the struct declaration." ), Child( name: "modifiers", - kind: .collection( - kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), + kind: .collection(kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), nameForDiagnostics: "modifiers", documentation: "Modifiers like `public` that are attached to the struct declaration." ), @@ -2121,8 +2051,7 @@ public let DECL_NODES: [Node] = [ name: "name", deprecatedName: "identifier", kind: .token(choices: [.token(.identifier)]), - documentation: - "Declares the name of this struct. If the name matches a reserved keyword use backticks to escape it." + documentation: "Declares the name of this struct. If the name matches a reserved keyword use backticks to escape it." ), Child( name: "genericParameterClause", @@ -2135,16 +2064,14 @@ public let DECL_NODES: [Node] = [ name: "inheritanceClause", kind: .node(kind: .inheritanceClause), nameForDiagnostics: "inheritance clause", - documentation: - "The struct declaration inheritance clause describing one or more conformances for this struct declaration.", + documentation: "The struct declaration inheritance clause describing one or more conformances for this struct declaration.", isOptional: true ), Child( name: "genericWhereClause", kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", - documentation: - "The `where` clause that applies to the generic parameters of this struct declaration.", + documentation: "The `where` clause that applies to the generic parameters of this struct declaration.", isOptional: true ), Child( @@ -2168,14 +2095,12 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), nameForDiagnostics: "attributes" ), Child( name: "modifiers", - kind: .collection( - kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), + kind: .collection(kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), nameForDiagnostics: "modifiers" ), Child( @@ -2203,8 +2128,7 @@ public let DECL_NODES: [Node] = [ name: "genericWhereClause", kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", - documentation: - "A `where` clause that places additional constraints on generic parameters like `where Element: Hashable`.", + documentation: "A `where` clause that places additional constraints on generic parameters like `where Element: Hashable`.", isOptional: true ), Child( @@ -2263,14 +2187,12 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), nameForDiagnostics: "attributes" ), Child( name: "modifiers", - kind: .collection( - kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), + kind: .collection(kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), nameForDiagnostics: "modifiers" ), Child( @@ -2297,8 +2219,7 @@ public let DECL_NODES: [Node] = [ name: "genericWhereClause", kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", - documentation: - "A `where` clause that places additional constraints on generic parameters like `where Element: Hashable`.", + documentation: "A `where` clause that places additional constraints on generic parameters like `where Element: Hashable`.", isOptional: true ), ] @@ -2321,14 +2242,12 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), nameForDiagnostics: "attributes" ), Child( name: "modifiers", - kind: .collection( - kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), + kind: .collection(kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), nameForDiagnostics: "modifiers", documentation: "Modifiers modifiers applied to the variable declaration." ), diff --git a/Sources/CodeGeneration/SyntaxSupport/ExperimentalFeatures.swift b/Sources/CodeGeneration/SyntaxSupport/ExperimentalFeatures.swift index fba01c1..c1ad579 100644 --- a/Sources/CodeGeneration/SyntaxSupport/ExperimentalFeatures.swift +++ b/Sources/CodeGeneration/SyntaxSupport/ExperimentalFeatures.swift @@ -15,8 +15,10 @@ import SwiftSyntax public enum ExperimentalFeature: String, CaseIterable { case referenceBindings case thenStatements - case typedThrows case doExpressions + case nonescapableTypes + case transferringArgsAndResults + case borrowingSwitch /// The name of the feature, which is used in the doc comment. public var featureName: String { @@ -25,10 +27,14 @@ public enum ExperimentalFeature: String, CaseIterable { return "reference bindings" case .thenStatements: return "'then' statements" - case .typedThrows: - return "typed throws" case .doExpressions: return "'do' expressions" + case .nonescapableTypes: + return "NonEscableTypes" + case .transferringArgsAndResults: + return "TransferringArgsAndResults" + case .borrowingSwitch: + return "borrowing pattern matching" } } diff --git a/Sources/CodeGeneration/SyntaxSupport/ExprNodes.swift b/Sources/CodeGeneration/SyntaxSupport/ExprNodes.swift index d79ec88..525687a 100644 --- a/Sources/CodeGeneration/SyntaxSupport/ExprNodes.swift +++ b/Sources/CodeGeneration/SyntaxSupport/ExprNodes.swift @@ -391,14 +391,12 @@ public let EXPR_NODES: [Node] = [ children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), nameForDiagnostics: "attributes" ), Child( name: "modifiers", - kind: .collection( - kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), + kind: .collection(kind: .declModifierList, collectionElementName: "Modifier", defaultsToEmpty: true), nameForDiagnostics: "modifiers" ), Child( @@ -435,8 +433,7 @@ public let EXPR_NODES: [Node] = [ Child( name: "trailingComma", kind: .token(choices: [.token(.comma)]), - documentation: - "If the parameter is followed by another parameter, the comma separating them.", + documentation: "If the parameter is followed by another parameter, the comma separating them.", isOptional: true ), ] @@ -558,8 +555,7 @@ public let EXPR_NODES: [Node] = [ children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), nameForDiagnostics: "attributes" ), Child( @@ -787,8 +783,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "catchClauses", - kind: .collection( - kind: .catchClauseList, collectionElementName: "CatchClause", defaultsToEmpty: true) + kind: .collection(kind: .catchClauseList, collectionElementName: "CatchClause", defaultsToEmpty: true) ), ] ), @@ -797,6 +792,9 @@ public let EXPR_NODES: [Node] = [ kind: .editorPlaceholderExpr, base: .expr, nameForDiagnostics: "editor placeholder", + documentation: """ + - Warning: This ``EditorPlaceholderExprSyntax`` node is not generated by the parser anymore. Placeholders are represented by a ``DeclReferenceExprSyntax``. + """, children: [ Child( name: "placeholder", @@ -810,8 +808,7 @@ public let EXPR_NODES: [Node] = [ kind: .exprList, base: .syntaxCollection, nameForDiagnostics: nil, - documentation: - "A list of expressions connected by operators. This list is contained by a ``SequenceExprSyntax``.", + documentation: "A list of expressions connected by operators. This list is contained by a ``SequenceExprSyntax``.", elementChoices: [.expr] ), @@ -916,9 +913,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "additionalTrailingClosures", - kind: .collection( - kind: .multipleTrailingClosureElementList, - collectionElementName: "AdditionalTrailingClosure", defaultsToEmpty: true), + kind: .collection(kind: .multipleTrailingClosureElementList, collectionElementName: "AdditionalTrailingClosure", defaultsToEmpty: true), nameForDiagnostics: "trailing closures" ), ] @@ -937,6 +932,8 @@ public let EXPR_NODES: [Node] = [ .keyword(.self), .keyword(.Self), .keyword(.`init`), + .keyword(.`deinit`), + .keyword(.`subscript`), .token(.dollarIdentifier), .token(.binaryOperator), .token(.integerLiteral), @@ -1073,8 +1070,7 @@ public let EXPR_NODES: [Node] = [ Child( name: "expression", kind: .node(kind: .expr), - documentation: - "The expression which will be checked to determine whether it can be cast to a specific type." + documentation: "The expression which will be checked to determine whether it can be cast to a specific type." ), Child( name: "isKeyword", @@ -1086,8 +1082,7 @@ public let EXPR_NODES: [Node] = [ name: "type", deprecatedName: "typeName", kind: .node(kind: .type), - documentation: - "The type against which the expression will be checked to see if the expression can be cast to it." + documentation: "The type against which the expression will be checked to see if the expression can be cast to it." ), ] ), @@ -1222,8 +1217,7 @@ public let EXPR_NODES: [Node] = [ kind: .macroExpansionExpr, base: .expr, nameForDiagnostics: "macro expansion", - documentation: - "The expansion of a freestanding macro in a position that expects an expression.", + documentation: "The expansion of a freestanding macro in a position that expects an expression.", traits: [ "FreestandingMacroExpansion" ], @@ -1267,9 +1261,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "additionalTrailingClosures", - kind: .collection( - kind: .multipleTrailingClosureElementList, - collectionElementName: "AdditionalTrailingClosure", defaultsToEmpty: true) + kind: .collection(kind: .multipleTrailingClosureElementList, collectionElementName: "AdditionalTrailingClosure", defaultsToEmpty: true) ), ] ), @@ -1584,9 +1576,7 @@ public let EXPR_NODES: [Node] = [ Child( name: "openingQuote", deprecatedName: "openQuote", - kind: .token(choices: [ - .token(.stringQuote), .token(.multilineStringQuote), .token(.singleQuote), - ]) + kind: .token(choices: [.token(.stringQuote), .token(.multilineStringQuote), .token(.singleQuote)]) ), Child( name: "segments", @@ -1595,9 +1585,7 @@ public let EXPR_NODES: [Node] = [ Child( name: "closingQuote", deprecatedName: "closeQuote", - kind: .token(choices: [ - .token(.stringQuote), .token(.multilineStringQuote), .token(.singleQuote), - ]) + kind: .token(choices: [.token(.stringQuote), .token(.multilineStringQuote), .token(.singleQuote)]) ), Child( name: "closingPounds", @@ -1619,8 +1607,7 @@ public let EXPR_NODES: [Node] = [ kind: .simpleStringLiteralExpr, base: .expr, nameForDiagnostics: "simple string literal", - documentation: - "A simple string that can’t contain string interpolation and cannot have raw string delimiters.", + documentation: "A simple string that can’t contain string interpolation and cannot have raw string delimiters.", children: [ Child( name: "openingQuote", @@ -1644,8 +1631,7 @@ public let EXPR_NODES: [Node] = [ kind: .simpleStringLiteralSegmentList, base: .syntaxCollection, nameForDiagnostics: nil, - documentation: - "String literal segments that only can contain non string interpolated or extended escaped strings", + documentation: "String literal segments that only can contain non string interpolated or extended escaped strings", elementChoices: [.stringSegment] ), @@ -1700,9 +1686,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "additionalTrailingClosures", - kind: .collection( - kind: .multipleTrailingClosureElementList, - collectionElementName: "AdditionalTrailingClosure", defaultsToEmpty: true), + kind: .collection(kind: .multipleTrailingClosureElementList, collectionElementName: "AdditionalTrailingClosure", defaultsToEmpty: true), nameForDiagnostics: "trailing closures" ), ] @@ -1924,9 +1908,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "questionOrExclamationMark", - kind: .token( - choices: [.token(.postfixQuestionMark), .token(.exclamationMark)], - requiresTrailingSpace: true), + kind: .token(choices: [.token(.postfixQuestionMark), .token(.exclamationMark)], requiresTrailingSpace: true), isOptional: true ), Child( diff --git a/Sources/CodeGeneration/SyntaxSupport/GenericNodes.swift b/Sources/CodeGeneration/SyntaxSupport/GenericNodes.swift index b5aa309..b2b8657 100644 --- a/Sources/CodeGeneration/SyntaxSupport/GenericNodes.swift +++ b/Sources/CodeGeneration/SyntaxSupport/GenericNodes.swift @@ -49,16 +49,13 @@ public let GENERIC_NODES: [Node] = [ Child( name: "parameters", deprecatedName: "genericParameterList", - kind: .collection( - kind: .genericParameterList, collectionElementName: "Parameter", - deprecatedCollectionElementName: "GenericParameter"), + kind: .collection(kind: .genericParameterList, collectionElementName: "Parameter", deprecatedCollectionElementName: "GenericParameter"), documentation: "The list of generic parameters in the clause." ), Child( name: "genericWhereClause", kind: .node(kind: .genericWhereClause), - documentation: - "A `where` clause that places additional constraints on generic parameters like `where Element: Hashable`.", + documentation: "A `where` clause that places additional constraints on generic parameters like `where Element: Hashable`.", isOptional: true ), Child( @@ -88,8 +85,7 @@ public let GENERIC_NODES: [Node] = [ children: [ Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true) + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true) ), Child( name: "eachKeyword", @@ -167,8 +163,7 @@ public let GENERIC_NODES: [Node] = [ kind: .genericWhereClause, base: .syntax, nameForDiagnostics: "'where' clause", - documentation: - "A `where` clause that places additional constraints on generic parameters like `where Element: Hashable`.", + documentation: "A `where` clause that places additional constraints on generic parameters like `where Element: Hashable`.", children: [ Child( name: "whereKeyword", @@ -210,6 +205,8 @@ public let GENERIC_NODES: [Node] = [ .keyword(._NativeRefCountedObject), .keyword(._Class), .keyword(._NativeClass), + .keyword(._BridgeObject), + .keyword(._TrivialStride), ]) ), Child( @@ -255,8 +252,7 @@ public let GENERIC_NODES: [Node] = [ Child( name: "primaryAssociatedTypes", deprecatedName: "primaryAssociatedTypeList", - kind: .collection( - kind: .primaryAssociatedTypeList, collectionElementName: "PrimaryAssociatedType") + kind: .collection(kind: .primaryAssociatedTypeList, collectionElementName: "PrimaryAssociatedType") ), Child( name: "rightAngle", @@ -308,9 +304,7 @@ public let GENERIC_NODES: [Node] = [ Child( name: "equal", deprecatedName: "equalityToken", - kind: .token(choices: [ - .token(.binaryOperator), .token(.prefixOperator), .token(.postfixOperator), - ]) + kind: .token(choices: [.token(.binaryOperator), .token(.prefixOperator), .token(.postfixOperator)]) ), Child( name: "rightType", diff --git a/Sources/CodeGeneration/SyntaxSupport/GrammarGenerator.swift b/Sources/CodeGeneration/SyntaxSupport/GrammarGenerator.swift index 6468fea..aa7e492 100644 --- a/Sources/CodeGeneration/SyntaxSupport/GrammarGenerator.swift +++ b/Sources/CodeGeneration/SyntaxSupport/GrammarGenerator.swift @@ -37,12 +37,12 @@ struct GrammarGenerator { let optionality = child.isOptional ? "?" : "" switch child.kind { case .node(let kind): - return "``\(kind.syntaxType)``\(optionality)" + return "\(kind.doccLink)\(optionality)" case .nodeChoices(let choices): let choicesDescriptions = choices.map { grammar(for: $0) } return "(\(choicesDescriptions.joined(separator: " | ")))\(optionality)" - case .collection(let kind, _, _, _): - return "``\(kind.syntaxType)``\(optionality)" + case .collection(kind: let kind, _, _, _): + return "\(kind.doccLink)\(optionality)" case .token(let choices, _, _): if choices.count == 1 { return "\(grammar(for: choices.first!))\(optionality)" diff --git a/Sources/CodeGeneration/SyntaxSupport/KeywordSpec.swift b/Sources/CodeGeneration/SyntaxSupport/KeywordSpec.swift index 3b40505..895411b 100644 --- a/Sources/CodeGeneration/SyntaxSupport/KeywordSpec.swift +++ b/Sources/CodeGeneration/SyntaxSupport/KeywordSpec.swift @@ -19,6 +19,7 @@ public struct KeywordSpec { /// The experimental feature the keyword is part of, or `nil` if this isn't /// for an experimental feature. public let experimentalFeature: ExperimentalFeature? + public let experimentalFeature2: ExperimentalFeature? /// Indicates if the token kind is switched from being an identifier to a keyword in the lexer. public let isLexerClassified: Bool @@ -43,8 +44,7 @@ public struct KeywordSpec { /// This is typically used to mark APIs as SPI when the keyword is part of an experimental language feature. public var apiAttributes: AttributeListSyntax { guard isExperimental else { return "" } - return AttributeListSyntax("@_spi(ExperimentalLanguageFeatures)").with( - \.trailingTrivia, .newline) + return AttributeListSyntax("@_spi(ExperimentalLanguageFeatures)").with(\.trailingTrivia, .newline) } /// Initializes a new `KeywordSpec` instance. @@ -60,6 +60,26 @@ public struct KeywordSpec { ) { self.name = name self.experimentalFeature = experimentalFeature + self.experimentalFeature2 = nil + self.isLexerClassified = isLexerClassified + } + + /// Initializes a new `KeywordSpec` instance. + /// + /// - Parameters: + /// - name: A name of the keyword. + /// - experimentalFeature: The experimental feature the keyword is part of, or `nil` if this isn't for an experimental feature. + /// - or: A second experimental feature the keyword is also part of, or `nil` if this isn't for an experimental feature. + /// - isLexerClassified: Indicates if the token kind is switched from being an identifier to a keyword in the lexer. + init( + _ name: String, + experimentalFeature: ExperimentalFeature, + or experimentalFeature2: ExperimentalFeature, + isLexerClassified: Bool = false + ) { + self.name = name + self.experimentalFeature = experimentalFeature + self.experimentalFeature2 = experimentalFeature2 self.isLexerClassified = isLexerClassified } } @@ -83,11 +103,14 @@ public enum Keyword: CaseIterable { case _backDeploy case _borrow case _borrowing + case _BridgeObject case _cdecl case _Class case _compilerInitialized case _const + case _consume case _consuming + case _copy case _documentation case _dynamicReplacement case _effects @@ -98,6 +121,7 @@ public enum Keyword: CaseIterable { case _local case _modify case _move + case _mutate case _mutating case _NativeClass case _NativeRefCountedObject @@ -120,6 +144,7 @@ public enum Keyword: CaseIterable { case _swift_native_objc_runtime_base case _Trivial case _TrivialAtMost + case _TrivialStride case _typeEraser case _unavailableFromAsync case _underlyingVersion @@ -184,6 +209,7 @@ public enum Keyword: CaseIterable { case discard case forward case `func` + case freestanding case get case `guard` case higherThan @@ -231,6 +257,7 @@ public enum Keyword: CaseIterable { case package case postfix case `precedencegroup` + case preconcurrency case prefix case `private` case `Protocol` @@ -240,6 +267,8 @@ public enum Keyword: CaseIterable { case renamed case `repeat` case required + case _resultDependsOn + case _resultDependsOnSelf case `rethrows` case retroactive case `return` @@ -264,6 +293,7 @@ public enum Keyword: CaseIterable { case then case `throw` case `throws` + case transferring case transpose case `true` case `try` @@ -301,6 +331,10 @@ public enum Keyword: CaseIterable { return KeywordSpec("_backDeploy") case ._borrow: return KeywordSpec("_borrow") + case ._borrowing: + return KeywordSpec("_borrowing", experimentalFeature: .referenceBindings, or: .borrowingSwitch) + case ._BridgeObject: + return KeywordSpec("_BridgeObject") case ._cdecl: return KeywordSpec("_cdecl") case ._Class: @@ -309,6 +343,12 @@ public enum Keyword: CaseIterable { return KeywordSpec("_compilerInitialized") case ._const: return KeywordSpec("_const") + case ._consume: + return KeywordSpec("_consume", experimentalFeature: .nonescapableTypes) + case ._consuming: + return KeywordSpec("_consuming", experimentalFeature: .referenceBindings) + case ._copy: + return KeywordSpec("_copy", experimentalFeature: .nonescapableTypes) case ._documentation: return KeywordSpec("_documentation") case ._dynamicReplacement: @@ -329,6 +369,10 @@ public enum Keyword: CaseIterable { return KeywordSpec("_modify") case ._move: return KeywordSpec("_move") + case ._mutate: + return KeywordSpec("_mutate", experimentalFeature: .nonescapableTypes) + case ._mutating: + return KeywordSpec("_mutating", experimentalFeature: .referenceBindings) case ._NativeClass: return KeywordSpec("_NativeClass") case ._NativeRefCountedObject: @@ -371,6 +415,8 @@ public enum Keyword: CaseIterable { return KeywordSpec("_Trivial") case ._TrivialAtMost: return KeywordSpec("_TrivialAtMost") + case ._TrivialStride: + return KeywordSpec("_TrivialStride") case ._typeEraser: return KeywordSpec("_typeEraser") case ._unavailableFromAsync: @@ -499,6 +545,8 @@ public enum Keyword: CaseIterable { return KeywordSpec("forward") case .func: return KeywordSpec("func", isLexerClassified: true) + case .freestanding: + return KeywordSpec("freestanding") case .get: return KeywordSpec("get") case .guard: @@ -611,6 +659,10 @@ public enum Keyword: CaseIterable { return KeywordSpec("repeat", isLexerClassified: true) case .required: return KeywordSpec("required") + case ._resultDependsOn: + return KeywordSpec("_resultDependsOn", experimentalFeature: .nonescapableTypes) + case ._resultDependsOnSelf: + return KeywordSpec("_resultDependsOnSelf", experimentalFeature: .nonescapableTypes) case .rethrows: return KeywordSpec("rethrows", isLexerClassified: true) case .retroactive: @@ -659,6 +711,11 @@ public enum Keyword: CaseIterable { return KeywordSpec("throw", isLexerClassified: true) case .throws: return KeywordSpec("throws", isLexerClassified: true) + case .transferring: + return KeywordSpec( + "transferring", + experimentalFeature: .transferringArgsAndResults + ) case .transpose: return KeywordSpec("transpose") case .true: @@ -673,6 +730,8 @@ public enum Keyword: CaseIterable { return KeywordSpec("unavailable") case .unchecked: return KeywordSpec("unchecked") + case .preconcurrency: + return KeywordSpec("preconcurrency") case .unowned: return KeywordSpec("unowned") case .unsafe: @@ -699,12 +758,6 @@ public enum Keyword: CaseIterable { return KeywordSpec("wrt") case .yield: return KeywordSpec("yield") - case ._borrowing: - return KeywordSpec("_borrowing", experimentalFeature: .referenceBindings) - case ._consuming: - return KeywordSpec("_consuming", experimentalFeature: .referenceBindings) - case ._mutating: - return KeywordSpec("_mutating", experimentalFeature: .referenceBindings) } } } diff --git a/Sources/CodeGeneration/SyntaxSupport/Node.swift b/Sources/CodeGeneration/SyntaxSupport/Node.swift index 44a0600..5fec1d9 100644 --- a/Sources/CodeGeneration/SyntaxSupport/Node.swift +++ b/Sources/CodeGeneration/SyntaxSupport/Node.swift @@ -147,10 +147,7 @@ public class Node { let childrenWithUnexpected: [Child] if children.isEmpty { childrenWithUnexpected = [ - Child( - name: "unexpected", - kind: .collection(kind: .unexpectedNodes, collectionElementName: "Unexpected"), - isOptional: true) + Child(name: "unexpected", kind: .collection(kind: .unexpectedNodes, collectionElementName: "Unexpected"), isOptional: true) ] } else { // Add implicitly generated UnexpectedNodes children between @@ -164,18 +161,13 @@ public class Node { if i == 0 { unexpectedName = "unexpectedBefore\(childName)" - unexpectedDeprecatedName = child.deprecatedName.map { - "unexpectedBefore\($0.withFirstCharacterUppercased)" - } + unexpectedDeprecatedName = child.deprecatedName.map { "unexpectedBefore\($0.withFirstCharacterUppercased)" } } else { - unexpectedName = - "unexpectedBetween\(children[i - 1].name.withFirstCharacterUppercased)And\(childName)" + unexpectedName = "unexpectedBetween\(children[i - 1].name.withFirstCharacterUppercased)And\(childName)" if let deprecatedName = children[i - 1].deprecatedName?.withFirstCharacterUppercased { - unexpectedDeprecatedName = - "unexpectedBetween\(deprecatedName)And\(child.deprecatedName?.withFirstCharacterUppercased ?? childName)" + unexpectedDeprecatedName = "unexpectedBetween\(deprecatedName)And\(child.deprecatedName?.withFirstCharacterUppercased ?? childName)" } else if let deprecatedName = child.deprecatedName?.withFirstCharacterUppercased { - unexpectedDeprecatedName = - "unexpectedBetween\(children[i - 1].name.withFirstCharacterUppercased)And\(deprecatedName)" + unexpectedDeprecatedName = "unexpectedBetween\(children[i - 1].name.withFirstCharacterUppercased)And\(deprecatedName)" } else { unexpectedDeprecatedName = nil } @@ -190,13 +182,8 @@ public class Node { } + [ Child( name: "unexpectedAfter\(children.last!.name.withFirstCharacterUppercased)", - deprecatedName: children.last!.deprecatedName.map { - "unexpectedAfter\($0.withFirstCharacterUppercased)" - }, - kind: .collection( - kind: .unexpectedNodes, - collectionElementName: - "UnexpectedAfter\(children.last!.name.withFirstCharacterUppercased)"), + deprecatedName: children.last!.deprecatedName.map { "unexpectedAfter\($0.withFirstCharacterUppercased)" }, + kind: .collection(kind: .unexpectedNodes, collectionElementName: "UnexpectedAfter\(children.last!.name.withFirstCharacterUppercased)"), isOptional: true ) ] @@ -237,9 +224,9 @@ public class Node { // This will repeat the syntax type before and after the dot, which is // a little unfortunate, but it's the only way I found to get docc to // generate a fully-qualified type + member. - return " - ``\($0.node.syntaxType)``.``\($0.node.syntaxType)/\(childName)``" + return " - \($0.node.doccLink).``\($0.node.syntaxType)/\(childName)``" } else { - return " - ``\($0.node.syntaxType)``" + return " - \($0.node.doccLink)" } } .joined(separator: "\n") @@ -262,7 +249,7 @@ public class Node { let list = SYNTAX_NODES .filter { $0.base == self.kind && !$0.isExperimental } - .map { "- ``\($0.kind.syntaxType)``" } + .map { "- \($0.kind.doccLink)" } .joined(separator: "\n") guard !list.isEmpty else { @@ -330,7 +317,7 @@ public struct LayoutNode { /// This includes unexpected children public var children: [Child] { switch node.data { - case .layout(let children, traits: _): + case .layout(children: let children, traits: _): return children case .collection: preconditionFailure("NodeLayoutView must wrap a Node with data `.layout`") @@ -345,7 +332,7 @@ public struct LayoutNode { /// Traits that the node conforms to. public var traits: [String] { switch node.data { - case .layout(children: _, let traits): + case .layout(children: _, traits: let traits): return traits case .collection: preconditionFailure("NodeLayoutView must wrap a Node with data `.layout`") @@ -397,7 +384,7 @@ public struct CollectionNode { switch node.data { case .layout: preconditionFailure("NodeLayoutView must wrap a Node with data `.collection`") - case .collection(let choices): + case .collection(choices: let choices): return choices } } @@ -405,9 +392,9 @@ public struct CollectionNode { public var grammar: SwiftSyntax.Trivia { let grammar: String if let onlyElement = elementChoices.only { - grammar = "``\(onlyElement.syntaxType)`` `*`" + grammar = "\(onlyElement.doccLink) `*`" } else { - grammar = "(\(elementChoices.map { "``\($0.syntaxType)``" }.joined(separator: " | "))) `*`" + grammar = "(\(elementChoices.map { "\($0.doccLink)" }.joined(separator: " | "))) `*`" } return .docCommentTrivia( @@ -420,21 +407,17 @@ public struct CollectionNode { } } -extension Child { - fileprivate var kinds: [SyntaxNodeKind] { +fileprivate extension Child { + var kinds: [SyntaxNodeKind] { switch kind { case .node(let kind): return [kind] case .nodeChoices(let choices): return choices.flatMap(\.kinds) - case .collection(let kind, _, _, _): + case .collection(kind: let kind, _, _, _): return [kind] case .token: return [.token] } } } - -extension Node { - -} diff --git a/Sources/CodeGeneration/SyntaxSupport/PatternNodes.swift b/Sources/CodeGeneration/SyntaxSupport/PatternNodes.swift index e6407e6..9113ace 100644 --- a/Sources/CodeGeneration/SyntaxSupport/PatternNodes.swift +++ b/Sources/CodeGeneration/SyntaxSupport/PatternNodes.swift @@ -57,7 +57,15 @@ public let PATTERN_NODES: [Node] = [ children: [ Child( name: "identifier", - kind: .token(choices: [.token(.identifier), .keyword(.self), .keyword(.`init`)]) + kind: .token( + choices: [ + .token(.identifier), + .keyword(.self), + .keyword(.`init`), + .keyword(.`deinit`), + .keyword(.`subscript`), + ] + ) ) ] ), @@ -138,7 +146,7 @@ public let PATTERN_NODES: [Node] = [ ### Examples ``TuplePatternSyntax`` can be used in more complex variable declarations. - For example `(x, y)` in the exmaple: + For example `(x, y)` in the example: ```swift let (x, y) = (1, 2) @@ -212,24 +220,20 @@ public let PATTERN_NODES: [Node] = [ ### Examples - ``TuplePatternSyntax`` can be used in a simple variable declarations. - For example `_` in the exmaple: + ``WildcardPatternSyntax`` matches and ignores any value. + For example `_` in the example: ```swift - let _: Int = (1, 2) + for _ in 1...3 { + // ... + } ``` """, children: [ Child( name: "wildcard", kind: .token(choices: [.token(.wildcard)]) - ), - Child( - name: "typeAnnotation", - kind: .node(kind: .typeAnnotation), - documentation: "The type of the pattern.", - isOptional: true - ), + ) ] ), diff --git a/Sources/CodeGeneration/SyntaxSupport/StmtNodes.swift b/Sources/CodeGeneration/SyntaxSupport/StmtNodes.swift index ee46aab..8d641dc 100644 --- a/Sources/CodeGeneration/SyntaxSupport/StmtNodes.swift +++ b/Sources/CodeGeneration/SyntaxSupport/StmtNodes.swift @@ -27,8 +27,7 @@ public let STMT_NODES: [Node] = [ Child( name: "availabilityArguments", deprecatedName: "availabilitySpec", - kind: .collection( - kind: .availabilityArgumentList, collectionElementName: "AvailabilityArgument") + kind: .collection(kind: .availabilityArgumentList, collectionElementName: "AvailabilityArgument") ), Child( name: "rightParen", @@ -82,8 +81,7 @@ public let STMT_NODES: [Node] = [ ), Child( name: "catchItems", - kind: .collection( - kind: .catchItemList, collectionElementName: "CatchItem", defaultsToEmpty: true) + kind: .collection(kind: .catchItemList, collectionElementName: "CatchItem", defaultsToEmpty: true) ), Child( name: "body", @@ -218,6 +216,12 @@ public let STMT_NODES: [Node] = [ name: "doKeyword", kind: .token(choices: [.keyword(.do)]) ), + Child( + name: "throwsClause", + kind: .node(kind: .throwsClause), + documentation: "The clause specifying the type of errors thrown from the 'do' block.", + isOptional: true + ), Child( name: "body", kind: .node(kind: .codeBlock), @@ -225,8 +229,7 @@ public let STMT_NODES: [Node] = [ ), Child( name: "catchClauses", - kind: .collection( - kind: .catchClauseList, collectionElementName: "CatchClause", defaultsToEmpty: true) + kind: .collection(kind: .catchClauseList, collectionElementName: "CatchClause", defaultsToEmpty: true) ), ] ), @@ -415,8 +418,7 @@ public let STMT_NODES: [Node] = [ name: "bindingSpecifier", deprecatedName: "bindingKeyword", kind: .token(choices: [ - .keyword(.let), .keyword(.var), .keyword(.inout), .keyword(._mutating), - .keyword(._borrowing), + .keyword(.let), .keyword(.var), .keyword(.inout), .keyword(._mutating), .keyword(._borrowing), .keyword(._consuming), ]) ), diff --git a/Sources/CodeGeneration/SyntaxSupport/String+Extensions.swift b/Sources/CodeGeneration/SyntaxSupport/String+Extensions.swift index a8f87e5..93884aa 100644 --- a/Sources/CodeGeneration/SyntaxSupport/String+Extensions.swift +++ b/Sources/CodeGeneration/SyntaxSupport/String+Extensions.swift @@ -10,10 +10,10 @@ // //===----------------------------------------------------------------------===// -extension StringProtocol { - public var withFirstCharacterLowercased: String { prefix(1).lowercased() + dropFirst() } - public var withFirstCharacterUppercased: String { prefix(1).uppercased() + dropFirst() } - public var backtickedIfNeeded: String { +public extension StringProtocol { + var withFirstCharacterLowercased: String { prefix(1).lowercased() + dropFirst() } + var withFirstCharacterUppercased: String { prefix(1).uppercased() + dropFirst() } + var backtickedIfNeeded: String { if Keyword.allCases.map(\.spec).contains(where: { $0.name == self && ($0.isLexerClassified || $0.name == "Type" || $0.name == "Protocol") }) { diff --git a/Sources/CodeGeneration/SyntaxSupport/SyntaxNodeKind.swift b/Sources/CodeGeneration/SyntaxSupport/SyntaxNodeKind.swift index 6b36c0b..5ea2614 100644 --- a/Sources/CodeGeneration/SyntaxSupport/SyntaxNodeKind.swift +++ b/Sources/CodeGeneration/SyntaxSupport/SyntaxNodeKind.swift @@ -99,8 +99,8 @@ public enum SyntaxNodeKind: String, CaseIterable { case dictionaryExpr case dictionaryType case differentiabilityArgument - case differentiabilityArguments case differentiabilityArgumentList + case differentiabilityArguments case differentiabilityWithRespectToArgument case differentiableAttributeArguments case discardAssignmentExpr @@ -182,6 +182,9 @@ public enum SyntaxNodeKind: String, CaseIterable { case labeledSpecializeArgument case labeledStmt case layoutRequirement + case lifetimeSpecifierArgument + case lifetimeSpecifierArgumentList + case lifetimeTypeSpecifier case macroDecl case macroExpansionDecl case macroExpansionExpr @@ -244,14 +247,15 @@ public enum SyntaxNodeKind: String, CaseIterable { case returnStmt case sameTypeRequirement case sequenceExpr + case simpleTypeSpecifier + case simpleStringLiteralExpr + case simpleStringLiteralSegmentList case someOrAnyType case sourceFile case specializeAttributeArgumentList case specializeAvailabilityArgument case specializeTargetFunctionArgument case stmt - case simpleStringLiteralExpr - case simpleStringLiteralSegmentList case stringLiteralExpr case stringLiteralSegmentList case stringSegment @@ -269,7 +273,7 @@ public enum SyntaxNodeKind: String, CaseIterable { case switchExpr case ternaryExpr case thenStmt - case thrownTypeClause + case throwsClause case throwStmt case tryExpr case tupleExpr @@ -285,6 +289,9 @@ public enum SyntaxNodeKind: String, CaseIterable { case typeEffectSpecifiers case typeExpr case typeInitializerClause + case typeSpecifier + case lifetimeSpecifierArguments + case typeSpecifierList case unavailableFromAsyncAttributeArguments case underscorePrivateAttributeArguments case unexpectedNodes @@ -299,10 +306,10 @@ public enum SyntaxNodeKind: String, CaseIterable { case whereClause case whileStmt case wildcardPattern - case yieldStmt case yieldedExpression - case yieldedExpressionsClause case yieldedExpressionList + case yieldedExpressionsClause + case yieldStmt // Nodes that have special handling throughout the codebase @@ -348,6 +355,17 @@ public enum SyntaxNodeKind: String, CaseIterable { } } + /// If this node is non-experimental a docc link wrapped in two backticks. + /// + /// For experimental nodes, the node's type name in code font. + public var doccLink: String { + if let node = SYNTAX_NODE_MAP[self], node.isExperimental { + return "`\(syntaxType)`" + } else { + return "``\(syntaxType)``" + } + } + /// For base nodes, the name of the corresponding protocol to which all the /// concrete nodes that have this base kind, conform. public var protocolType: TypeSyntax { @@ -405,8 +423,8 @@ public enum SyntaxNodeKind: String, CaseIterable { case .derivativeAttributeArguments: return "derivativeRegistrationAttributeArguments" case .designatedType: return "designatedTypeElement" case .differentiabilityArgument: return "differentiabilityParam" - case .differentiabilityArguments: return "differentiabilityParams" case .differentiabilityArgumentList: return "differentiabilityParamList" + case .differentiabilityArguments: return "differentiabilityParams" case .differentiabilityWithRespectToArgument: return "differentiabilityParamsClause" case .documentationAttributeArgumentList: return "documentationAttributeArguments" case .dynamicReplacementAttributeArguments: return "dynamicReplacementArguments" @@ -440,6 +458,7 @@ public enum SyntaxNodeKind: String, CaseIterable { case .precedenceGroupName: return "precedenceGroupNameElement" case .repeatStmt: return "repeatWhileStmt" case .someOrAnyType: return "constrainedSugarType" + case .simpleTypeSpecifier: return "typeSpecifier" case .specializeAttributeArgumentList: return "specializeAttributeSpecList" case .specializeAvailabilityArgument: return "availabilityEntry" case .specializeTargetFunctionArgument: return "targetFunctionEntry" @@ -451,8 +470,8 @@ public enum SyntaxNodeKind: String, CaseIterable { case .typeAliasDecl: return "typealiasDecl" case .unavailableFromAsyncAttributeArguments: return "unavailableFromAsyncArguments" case .yieldedExpression: return "yieldExprListElement" - case .yieldedExpressionsClause: return "yieldList" case .yieldedExpressionList: return "yieldExprList" + case .yieldedExpressionsClause: return "yieldList" default: return nil } } diff --git a/Sources/CodeGeneration/SyntaxSupport/TokenSpec.swift b/Sources/CodeGeneration/SyntaxSupport/TokenSpec.swift index f53707b..c156f10 100644 --- a/Sources/CodeGeneration/SyntaxSupport/TokenSpec.swift +++ b/Sources/CodeGeneration/SyntaxSupport/TokenSpec.swift @@ -48,8 +48,7 @@ public struct TokenSpec { /// This is typically used to mark APIs as SPI when the keyword is part of an experimental language feature. public var apiAttributes: AttributeListSyntax { guard isExperimental else { return "" } - return AttributeListSyntax("@_spi(ExperimentalLanguageFeatures)").with( - \.trailingTrivia, .newline) + return AttributeListSyntax("@_spi(ExperimentalLanguageFeatures)").with(\.trailingTrivia, .newline) } /// Initializes a new `TokenSpec` instance. diff --git a/Sources/CodeGeneration/SyntaxSupport/Traits.swift b/Sources/CodeGeneration/SyntaxSupport/Traits.swift index 137d50b..6148737 100644 --- a/Sources/CodeGeneration/SyntaxSupport/Traits.swift +++ b/Sources/CodeGeneration/SyntaxSupport/Traits.swift @@ -14,12 +14,19 @@ import SwiftSyntax public class Trait { public let traitName: String + /// The kind of syntax the trait refines. + /// + /// Base kind _must_ be a base syntax node, e.g. `.decl`, `.expr` , or + /// others. See ``SyntaxNodeKind/isBase`` for more details. + public let baseKind: SyntaxNodeKind? public let protocolName: TokenSyntax public let documentation: SwiftSyntax.Trivia public let children: [Child] - init(traitName: String, documentation: String? = nil, children: [Child]) { + init(traitName: String, baseKind: SyntaxNodeKind? = nil, documentation: String? = nil, children: [Child]) { + precondition(baseKind?.isBase != false, "`baseKind` must be a base syntax node kind") self.traitName = traitName + self.baseKind = baseKind self.protocolName = .identifier("\(traitName)Syntax") self.documentation = SwiftSyntax.Trivia.docCommentTrivia(from: documentation) self.children = children @@ -36,15 +43,20 @@ public let TRAITS: [Trait] = [ ), Trait( traitName: "DeclGroup", + baseKind: .decl, children: [ Child(name: "attributes", kind: .node(kind: .attributeList)), Child(name: "modifiers", kind: .node(kind: .declModifierList)), + Child( + name: "introducer", + kind: .token(choices: [.keyword(.actor), .keyword(.class), .keyword(.enum), .keyword(.extension), .keyword(.protocol), .keyword(.struct)]), + documentation: "The token that introduces this declaration, eg. `class` for a class declaration." + ), Child(name: "inheritanceClause", kind: .node(kind: .inheritanceClause), isOptional: true), Child( name: "genericWhereClause", kind: .node(kind: .genericWhereClause), - documentation: - "A `where` clause that places additional constraints on generic parameters like `where Element: Hashable`.", + documentation: "A `where` clause that places additional constraints on generic parameters like `where Element: Hashable`.", isOptional: true ), Child(name: "memberBlock", kind: .node(kind: .memberBlock)), @@ -53,46 +65,24 @@ public let TRAITS: [Trait] = [ Trait( traitName: "EffectSpecifiers", children: [ - Child( - name: "unexpectedBeforeAsyncSpecifier", kind: .node(kind: .unexpectedNodes), - isOptional: true), - Child( - name: "asyncSpecifier", kind: .token(choices: [.keyword(.async), .keyword(.reasync)]), - isOptional: true), - Child( - name: "unexpectedBetweenAsyncSpecifierAndThrowsSpecifier", - kind: .node(kind: .unexpectedNodes), isOptional: true), - Child( - name: "throwsSpecifier", kind: .token(choices: [.keyword(.throws), .keyword(.rethrows)]), - isOptional: true), - Child( - name: "unexpectedBetweenThrowsSpecifierAndThrownError", kind: .node(kind: .unexpectedNodes), - isOptional: true), - Child( - name: "thrownError", - kind: .node(kind: .thrownTypeClause), - experimentalFeature: .typedThrows, - documentation: "The specific thrown error type.", - isOptional: true - ), - Child( - name: "unexpectedAfterThrownError", kind: .node(kind: .unexpectedNodes), isOptional: true), + Child(name: "unexpectedBeforeAsyncSpecifier", kind: .node(kind: .unexpectedNodes), isOptional: true), + Child(name: "asyncSpecifier", kind: .token(choices: [.keyword(.async), .keyword(.reasync)]), isOptional: true), + Child(name: "unexpectedBetweenAsyncSpecifierAndThrowsClause", kind: .node(kind: .unexpectedNodes), isOptional: true), + Child(name: "throwsClause", kind: .node(kind: .throwsClause), isOptional: true), + Child(name: "unexpectedAfterThrowsClause", kind: .node(kind: .unexpectedNodes), isOptional: true), ] ), Trait( traitName: "FreestandingMacroExpansion", children: [ Child(name: "pound", deprecatedName: "poundToken", kind: .token(choices: [.token(.pound)])), - Child( - name: "macroName", deprecatedName: "macro", kind: .token(choices: [.token(.identifier)])), - Child( - name: "genericArgumentClause", kind: .node(kind: .genericArgumentClause), isOptional: true), + Child(name: "macroName", deprecatedName: "macro", kind: .token(choices: [.token(.identifier)])), + Child(name: "genericArgumentClause", kind: .node(kind: .genericArgumentClause), isOptional: true), Child(name: "leftParen", kind: .token(choices: [.token(.leftParen)]), isOptional: true), Child(name: "arguments", deprecatedName: "argumentList", kind: .node(kind: .labeledExprList)), Child(name: "rightParen", kind: .token(choices: [.token(.rightParen)]), isOptional: true), Child(name: "trailingClosure", kind: .node(kind: .closureExpr), isOptional: true), - Child( - name: "additionalTrailingClosures", kind: .node(kind: .multipleTrailingClosureElementList)), + Child(name: "additionalTrailingClosures", kind: .node(kind: .multipleTrailingClosureElementList)), ] ), Trait( @@ -155,8 +145,7 @@ public let TRAITS: [Trait] = [ Child( name: "genericWhereClause", kind: .node(kind: .genericWhereClause), - documentation: - "A `where` clause that places additional constraints on generic parameters like `where Element: Hashable`.", + documentation: "A `where` clause that places additional constraints on generic parameters like `where Element: Hashable`.", isOptional: true ), ] @@ -167,6 +156,12 @@ public let TRAITS: [Trait] = [ Child(name: "modifiers", kind: .node(kind: .declModifierList)) ] ), + Trait( + traitName: "WithOptionalCodeBlock", + children: [ + Child(name: "body", kind: .node(kind: .codeBlock), isOptional: true) + ] + ), Trait( traitName: "WithStatements", children: [ diff --git a/Sources/CodeGeneration/SyntaxSupport/Trivia.swift b/Sources/CodeGeneration/SyntaxSupport/Trivia.swift index 051c1b5..28ddb88 100644 --- a/Sources/CodeGeneration/SyntaxSupport/Trivia.swift +++ b/Sources/CodeGeneration/SyntaxSupport/Trivia.swift @@ -103,8 +103,7 @@ public class Trivia { public let TRIVIAS: [Trivia] = [ Trivia( name: "Backslash", - comment: - #"A backslash that is at the end of a line in a multi-line string literal to escape the newline."#, + comment: #"A backslash that is at the end of a line in a multi-line string literal to escape the newline."#, characters: [ Character("\\") ], @@ -186,8 +185,7 @@ public let TRIVIAS: [Trivia] = [ Trivia( name: "Pound", - comment: - #"A '#' that is at the end of a line in a multi-line string literal to escape the newline."#, + comment: #"A '#' that is at the end of a line in a multi-line string literal to escape the newline."#, characters: [ Character("#") ], diff --git a/Sources/CodeGeneration/SyntaxSupport/TypeNodes.swift b/Sources/CodeGeneration/SyntaxSupport/TypeNodes.swift index 631ff9d..93a2598 100644 --- a/Sources/CodeGeneration/SyntaxSupport/TypeNodes.swift +++ b/Sources/CodeGeneration/SyntaxSupport/TypeNodes.swift @@ -43,26 +43,19 @@ public let TYPE_NODES: [Node] = [ ], children: [ Child( - name: "specifier", - kind: .token(choices: [ - .keyword(.inout), - .keyword(.__shared), - .keyword(.__owned), - .keyword(.isolated), - .keyword(._const), - .keyword(.borrowing), - .keyword(.consuming), - ]), - isOptional: true + name: "specifiers", + kind: .collection(kind: .typeSpecifierList, collectionElementName: "Specifier", defaultsToEmpty: true), + documentation: "A list of specifiers that can be attached to the type, such as `inout`, `isolated`, or `consuming`." ), Child( name: "attributes", - kind: .collection( - kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true) + kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true), + documentation: "A list of attributes that can be attached to the type, such as `@escaping`." ), Child( name: "baseType", - kind: .node(kind: .type) + kind: .node(kind: .type), + documentation: "The type to with the specifiers and attributes are applied." ), ] ), @@ -181,9 +174,7 @@ public let TYPE_NODES: [Node] = [ Child( name: "parameters", deprecatedName: "arguments", - kind: .collection( - kind: .tupleTypeElementList, collectionElementName: "Parameter", - deprecatedCollectionElementName: "Argument") + kind: .collection(kind: .tupleTypeElementList, collectionElementName: "Parameter", deprecatedCollectionElementName: "Argument") ), Child( name: "rightParen", @@ -504,4 +495,133 @@ public let TYPE_NODES: [Node] = [ ] ), + Node( + kind: .lifetimeSpecifierArgument, + base: .syntax, + experimentalFeature: .nonescapableTypes, + nameForDiagnostics: nil, + documentation: """ + A single argument that can be added to a lifetime specifier like `borrow`, `mutate`, `consume` or `copy`. + + ### Example + `data` in `func foo(data: Array) -> borrow(data) ComplexReferenceType` + """, + traits: [ + "WithTrailingComma" + ], + children: [ + Child( + name: "parameter", + kind: .token(choices: [.token(.identifier), .keyword(.self), .token(.integerLiteral)]), + nameForDiagnostics: "parameter reference", + documentation: """ + The parameter on which the lifetime of this type depends. + + This can be an identifier referring to an external parameter name, an integer literal to refer to an unnamed + parameter or `self` if the type's lifetime depends on the object the method is called on. + """ + ), + Child( + name: "trailingComma", + kind: .token(choices: [.token(.comma)]), + isOptional: true + ), + ] + ), + + Node( + kind: .lifetimeSpecifierArgumentList, + base: .syntaxCollection, + experimentalFeature: .nonescapableTypes, + nameForDiagnostics: nil, + elementChoices: [.lifetimeSpecifierArgument] + ), + + Node( + kind: .lifetimeSpecifierArguments, + base: .syntax, + experimentalFeature: .nonescapableTypes, + nameForDiagnostics: nil, + documentation: """ + An optional argument passed to a type parameter. + + ### Example + `borrow(data)` in `func foo(data: Array) -> borrow(data) ComplexReferenceType` + """, + traits: [ + "Parenthesized" + ], + children: [ + Child( + name: "leftParen", + kind: .token(choices: [.token(.leftParen)]) + ), + Child( + name: "arguments", + kind: .collection(kind: .lifetimeSpecifierArgumentList, collectionElementName: "Arguments"), + documentation: """ + The function parameters that the lifetime of the annotated type depends on. + """ + ), + Child( + name: "rightParen", + kind: .token(choices: [.token(.rightParen)]) + ), + ] + ), + + Node( + kind: .lifetimeTypeSpecifier, + base: .syntax, + experimentalFeature: .nonescapableTypes, + nameForDiagnostics: "lifetime specifier", + documentation: "A specifier that specifies function parameter on whose lifetime a type depends", + children: [ + Child( + name: "specifier", + kind: .token(choices: [ + .keyword(._copy), + .keyword(._consume), + .keyword(._borrow), + .keyword(._mutate), + ]), + documentation: "The specifier token that's attached to the type." + ), + Child( + name: "arguments", + kind: .node(kind: .lifetimeSpecifierArguments) + ), + ] + ), + + Node( + kind: .simpleTypeSpecifier, + base: .syntax, + nameForDiagnostics: "type specifier", + documentation: "A specifier that can be attached to a type to eg. mark a parameter as `inout` or `consuming`", + children: [ + Child( + name: "specifier", + kind: .token(choices: [ + .keyword(.inout), + .keyword(.__shared), + .keyword(.__owned), + .keyword(.isolated), + .keyword(._const), + .keyword(.borrowing), + .keyword(.consuming), + .keyword(.transferring), + .keyword(._resultDependsOn), + ]), + documentation: "The specifier token that's attached to the type." + ) + ] + ), + + Node( + kind: .typeSpecifierList, + base: .syntaxCollection, + nameForDiagnostics: nil, + elementChoices: [.simpleTypeSpecifier, .lifetimeTypeSpecifier] + ), ] diff --git a/Sources/CodeGeneration/SyntaxSupport/Utils.swift b/Sources/CodeGeneration/SyntaxSupport/Utils.swift index b7ff3f8..ed2091f 100644 --- a/Sources/CodeGeneration/SyntaxSupport/Utils.swift +++ b/Sources/CodeGeneration/SyntaxSupport/Utils.swift @@ -35,51 +35,32 @@ public func lowercaseFirstWord(name: String) -> String { return name } - return name.prefix(wordIndex).lowercased() - + name[name.index(name.startIndex, offsetBy: wordIndex).. SwiftSyntax.Trivia { - guard let string else { - return [] - } - - let lines = string.split(separator: "\n", omittingEmptySubsequences: false) - let pieces = lines.enumerated().map { (index, line) in - var line = line - if index != lines.count - 1 { - line = "\(line)\n" - } - return SwiftSyntax.TriviaPiece.docLineComment("/// \(line)") - } - return SwiftSyntax.Trivia(pieces: pieces) + public static func docCommentTrivia(from string: String?) -> Self { + guard let string else { return [] } + let lines = string.split(separator: "\n", omittingEmptySubsequences: false).map { "/// \($0)" } + return .init(pieces: lines.flatMap { [.docLineComment($0), .newlines(1)] }) } /// Make a new trivia by joining together ``SwiftSyntax/TriviaPiece``s from `joining`, /// and gluing them together with pieces from `separator`. public init( joining items: [SwiftSyntax.Trivia], - separator: SwiftSyntax.Trivia = SwiftSyntax.Trivia(pieces: [ - TriviaPiece.newlines(1), TriviaPiece.docLineComment("///"), TriviaPiece.newlines(1), - ]) + separator: SwiftSyntax.Trivia = .init(pieces: [.docLineComment("///"), .newlines(1)]) ) { - - self.init( - pieces: - items - .filter { !$0.isEmpty } - .joined(separator: separator) - ) + self.init(pieces: items.filter { !$0.isEmpty }.joined(separator: separator)) } } -extension Collection { +public extension Collection { /// If the collection contains a single element, return it, otherwise `nil`. - public var only: Element? { + var only: Element? { if !isEmpty && index(after: startIndex) == endIndex { return self.first! } else { @@ -88,11 +69,10 @@ extension Collection { } } -extension TokenSyntax { - public var backtickedIfNeeded: TokenSyntax { +public extension TokenSyntax { + var backtickedIfNeeded: TokenSyntax { if Keyword.allCases.map(\.spec).contains(where: { - $0.name == self.description - && ($0.isLexerClassified || $0.name == "Type" || $0.name == "Protocol") + $0.name == self.description && ($0.isLexerClassified || $0.name == "Type" || $0.name == "Protocol") }) { return "`\(self)`" } else { diff --git a/Sources/SwiftAstGenLib/ScalaAstGenerator.swift b/Sources/SwiftAstGenLib/ScalaAstGenerator.swift index 776a512..1b6f3de 100644 --- a/Sources/SwiftAstGenLib/ScalaAstGenerator.swift +++ b/Sources/SwiftAstGenLib/ScalaAstGenerator.swift @@ -15,17 +15,28 @@ public class ScalaAstGenerator { return [base] + traits } + private func dateString() -> String { + let currentDateTime = Date() + let formatter = DateFormatter() + formatter.timeStyle = .long + formatter.dateStyle = .long + return formatter.string(from: currentDateTime) + } + private func backtickedIfNeeded(name: String) -> String { if name == "type" { return "`\(name)`" } else { return name } } - private let header: String = """ + private func header() -> String { + return """ // Automatically generated by 'SwiftAstGen --scalaAstOnly'. // Do not edit directly! + // Generated: \(dateString()) import scala.util.Try import ujson.Value """ + } public init() throws { if FileManager.default.fileExists(atPath: defaultScalaOutFileUrl.path) { @@ -132,7 +143,7 @@ public class ScalaAstGenerator { } let out = """ - \(header) + \(header()) object SwiftNodeSyntax {