From cf6ff40063d995b27e823e6c4844da5e68bdf8d9 Mon Sep 17 00:00:00 2001 From: Alex Hoppen Date: Tue, 16 May 2023 11:04:44 -0700 Subject: [PATCH] Make CodeGeneration a lot less string-based MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Because of its Python legacy the CodeGeneration tool has been heavily string-based. This PR fixes that at least to some degree. The main motivating factors here were: - Instead of using strings to specify the node type of a child node, define a `SyntaxNodeKind` enum that contains a case for each syntax node. This way you can be sure that you’re not referring to a non-existent syntax node (like we did for e.g. `InOutToken`, which we forgot to change to `.token("inout")`) - Refactor `Node` so that it contains two initializers: One for collections and one for layout nodes instead of having one initializer that has a bunch of optional and defaulted arguments. - Change a bunch of properties from returning a `String` to returning a `TypeSyntax` or `TokenSyntax` so we don‘t need to use the `raw:` interpolation style for them. In general, the API of `Node` and `SyntaxNodeKind` is what I’m happy with now. The other files can still do with some cleanup. All the changes resulted in nearly no functionaly changes of the generated code. --- CodeGeneration/Package.swift | 8 +- .../SyntaxSupport/AttributeNodes.swift | 295 ++++---- .../SyntaxSupport/AvailabilityNodes.swift | 55 +- .../BuilderInitializableTypes.swift | 41 +- .../Sources/SyntaxSupport/Child.swift | 62 +- .../Sources/SyntaxSupport/CommonNodes.swift | 107 ++- .../Sources/SyntaxSupport/DeclNodes.swift | 634 +++++++++--------- .../Sources/SyntaxSupport/ExprNodes.swift | 592 ++++++++-------- .../Sources/SyntaxSupport/GenericNodes.swift | 83 ++- .../Sources/SyntaxSupport/Node.swift | 303 ++++++--- .../Sources/SyntaxSupport/PatternNodes.swift | 52 +- .../Sources/SyntaxSupport/StmtNodes.swift | 196 +++--- .../String+Extensions.swift | 0 .../SyntaxSupport/SyntaxBaseKinds.swift | 21 - .../SyntaxSupport/SyntaxNodeKind.swift | 368 ++++++++++ .../Sources/SyntaxSupport/SyntaxNodes.swift | 8 +- .../Sources/SyntaxSupport/TokenSpec.swift | 6 +- .../Sources/SyntaxSupport/Traits.swift | 28 +- .../Sources/SyntaxSupport/TypeNodes.swift | 160 ++--- .../Sources/SyntaxSupport/Utils.swift | 31 +- .../Sources/Utils/SyntaxBuildableChild.swift | 25 +- .../Sources/Utils/SyntaxBuildableNode.swift | 42 +- .../Sources/Utils/SyntaxBuildableType.swift | 89 ++- CodeGeneration/Sources/Utils/Utils.swift | 11 + .../GenerateSwiftSyntax.swift | 15 +- .../ideutils/SyntaxClassificationFile.swift | 6 +- .../BasicFormatExtensionsFile.swift | 16 +- .../swiftparser/ParserEntryFile.swift | 2 +- .../ChildNameForDiagnosticsFile.swift | 4 +- .../SyntaxKindNameForDiagnosticsFile.swift | 4 +- .../swiftsyntax/ChildNameForKeyPathFile.swift | 6 +- .../swiftsyntax/RawSyntaxNodesFile.swift | 100 +-- .../swiftsyntax/RawSyntaxValidationFile.swift | 16 +- .../swiftsyntax/SwiftSyntaxDoccIndex.swift | 30 +- .../swiftsyntax/SyntaxAnyVisitorFile.swift | 6 +- .../swiftsyntax/SyntaxBaseNodesFile.swift | 72 +- .../swiftsyntax/SyntaxCollectionsFile.swift | 115 ++-- .../swiftsyntax/SyntaxEnumFile.swift | 6 +- .../swiftsyntax/SyntaxKindFile.swift | 14 +- .../swiftsyntax/SyntaxNodesFile.swift | 78 ++- .../swiftsyntax/SyntaxRewriterFile.swift | 34 +- .../swiftsyntax/SyntaxTraitsFile.swift | 6 +- .../swiftsyntax/SyntaxTransformFile.swift | 14 +- .../swiftsyntax/SyntaxVisitorFile.swift | 18 +- .../BuildableCollectionNodesFile.swift | 13 +- .../BuildableNodesFile.swift | 22 +- .../ResultBuildersFile.swift | 32 +- ...yStringInterpolationConformancesFile.swift | 2 +- .../generated/SwiftSyntax.md | 24 +- .../generated/SyntaxCollections.swift | 76 +-- .../SwiftSyntax/generated/SyntaxKind.swift | 2 + .../generated/raw/RawSyntaxValidation.swift | 6 +- .../generated/BuildableCollectionNodes.swift | 84 +-- 53 files changed, 2257 insertions(+), 1783 deletions(-) rename CodeGeneration/Sources/{Utils => SyntaxSupport}/String+Extensions.swift (100%) delete mode 100644 CodeGeneration/Sources/SyntaxSupport/SyntaxBaseKinds.swift create mode 100644 CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift diff --git a/CodeGeneration/Package.swift b/CodeGeneration/Package.swift index 07dccfc618d..0ea20b54eae 100644 --- a/CodeGeneration/Package.swift +++ b/CodeGeneration/Package.swift @@ -20,6 +20,7 @@ let package = Package( dependencies: [ .product(name: "SwiftSyntax", package: "swift-syntax"), .product(name: "SwiftSyntaxBuilder", package: "swift-syntax"), + .product(name: "SwiftBasicFormat", package: "swift-syntax"), .product(name: "ArgumentParser", package: "swift-argument-parser"), "SyntaxSupport", "Utils", @@ -29,11 +30,16 @@ let package = Package( ] ), .target( - name: "SyntaxSupport" + name: "SyntaxSupport", + dependencies: [ + .product(name: "SwiftSyntax", package: "swift-syntax"), + .product(name: "SwiftSyntaxBuilder", package: "swift-syntax"), + ] ), .target( name: "Utils", dependencies: [ + .product(name: "SwiftBasicFormat", package: "swift-syntax"), .product(name: "SwiftSyntax", package: "swift-syntax"), .product(name: "SwiftSyntaxBuilder", package: "swift-syntax"), "SyntaxSupport", diff --git a/CodeGeneration/Sources/SyntaxSupport/AttributeNodes.swift b/CodeGeneration/Sources/SyntaxSupport/AttributeNodes.swift index d49c67613ea..84676b38d3d 100644 --- a/CodeGeneration/Sources/SyntaxSupport/AttributeNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/AttributeNodes.swift @@ -13,13 +13,10 @@ public let ATTRIBUTE_NODES: [Node] = [ // attribute-list -> attribute attribute-list? Node( - name: "AttributeList", + kind: .attributeList, + base: .syntaxCollection, nameForDiagnostics: "attributes", - kind: "SyntaxCollection", - element: "Syntax", - elementName: "Attribute", - elementChoices: ["Attribute", "IfConfigDecl"], - omitWhenEmpty: true + elementChoices: [.attribute, .ifConfigDecl] ), // attribute -> '@' identifier '('? @@ -33,10 +30,10 @@ public let ATTRIBUTE_NODES: [Node] = [ // | back-deploy-attr-spec-list // )? ')'? Node( - name: "Attribute", + kind: .attribute, + base: .syntax, nameForDiagnostics: "attribute", - description: "An `@` attribute.", - kind: "Syntax", + documentation: "An `@` attribute.", parserFunction: "parseAttribute", children: [ Child( @@ -46,7 +43,7 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Child( name: "AttributeName", - kind: .node(kind: "Type"), + kind: .node(kind: .type), nameForDiagnostics: "name", description: "The name of the attribute.", classification: "Attribute" @@ -62,83 +59,83 @@ public let ATTRIBUTE_NODES: [Node] = [ kind: .nodeChoices(choices: [ Child( name: "ArgumentList", - kind: .node(kind: "TupleExprElementList") + kind: .node(kind: .tupleExprElementList) ), Child( name: "Token", - kind: .node(kind: "Token") + kind: .node(kind: .token) ), Child( name: "String", - kind: .node(kind: "StringLiteralExpr") + kind: .node(kind: .stringLiteralExpr) ), Child( name: "Availability", - kind: .node(kind: "AvailabilitySpecList") + kind: .node(kind: .availabilitySpecList) ), Child( name: "SpecializeArguments", - kind: .node(kind: "SpecializeAttributeSpecList") + kind: .node(kind: .specializeAttributeSpecList) ), Child( name: "ObjCName", - kind: .node(kind: "ObjCSelector") + kind: .node(kind: .objCSelector) ), Child( name: "ImplementsArguments", - kind: .node(kind: "ImplementsAttributeArguments") + kind: .node(kind: .implementsAttributeArguments) ), Child( name: "DifferentiableArguments", - kind: .node(kind: "DifferentiableAttributeArguments") + kind: .node(kind: .differentiableAttributeArguments) ), Child( name: "DerivativeRegistrationArguments", - kind: .node(kind: "DerivativeRegistrationAttributeArguments") + kind: .node(kind: .derivativeRegistrationAttributeArguments) ), Child( name: "BackDeployedArguments", - kind: .node(kind: "BackDeployedAttributeSpecList") + kind: .node(kind: .backDeployedAttributeSpecList) ), Child( name: "ConventionArguments", - kind: .node(kind: "ConventionAttributeArguments") + kind: .node(kind: .conventionAttributeArguments) ), Child( name: "ConventionWitnessMethodArguments", - kind: .node(kind: "ConventionWitnessMethodAttributeArguments") + kind: .node(kind: .conventionWitnessMethodAttributeArguments) ), Child( name: "OpaqueReturnTypeOfAttributeArguments", - kind: .node(kind: "OpaqueReturnTypeOfAttributeArguments") + kind: .node(kind: .opaqueReturnTypeOfAttributeArguments) ), Child( name: "ExposeAttributeArguments", - kind: .node(kind: "ExposeAttributeArguments") + kind: .node(kind: .exposeAttributeArguments) ), Child( name: "OriginallyDefinedInArguments", - kind: .node(kind: "OriginallyDefinedInArguments") + kind: .node(kind: .originallyDefinedInArguments) ), Child( name: "UnderscorePrivateAttributeArguments", - kind: .node(kind: "UnderscorePrivateAttributeArguments") + kind: .node(kind: .underscorePrivateAttributeArguments) ), Child( name: "DynamicReplacementArguments", - kind: .node(kind: "DynamicReplacementArguments") + kind: .node(kind: .dynamicReplacementArguments) ), Child( name: "UnavailableFromAsyncArguments", - kind: .node(kind: "UnavailableFromAsyncArguments") + kind: .node(kind: .unavailableFromAsyncArguments) ), Child( name: "EffectsArguments", - kind: .node(kind: "EffectsArguments") + kind: .node(kind: .effectsArguments) ), Child( name: "DocumentationArguments", - kind: .node(kind: "DocumentationAttributeArguments") + kind: .node(kind: .documentationAttributeArguments) ), ]), description: "The arguments of the attribute. In case the attribute takes multiple arguments, they are gather in the appropriate takes first.", @@ -154,10 +151,10 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Node( - name: "AvailabilityEntry", + kind: .availabilityEntry, + base: .syntax, nameForDiagnostics: "availability entry", - description: "The availability argument for the _specialize attribute", - kind: "Syntax", + documentation: "The availability argument for the _specialize attribute", children: [ Child( name: "Label", @@ -172,7 +169,7 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Child( name: "AvailabilityList", - kind: .collection(kind: "AvailabilitySpecList", collectionElementName: "Availability") + kind: .collection(kind: .availabilitySpecList, collectionElementName: "Availability") ), Child( name: "Semicolon", @@ -183,14 +180,14 @@ public let ATTRIBUTE_NODES: [Node] = [ // back-deploy-version-entry -> availability-version-restriction ','? Node( - name: "AvailabilityVersionRestrictionListEntry", + kind: .availabilityVersionRestrictionListEntry, + base: .syntax, nameForDiagnostics: "version", - description: "A single platform/version pair in an attribute, e.g. `iOS 10.1`.", - kind: "Syntax", + documentation: "A single platform/version pair in an attribute, e.g. `iOS 10.1`.", children: [ Child( name: "AvailabilityVersionRestriction", - kind: .node(kind: "AvailabilityVersionRestriction"), + kind: .node(kind: .availabilityVersionRestriction), classification: "Keyword" ), Child( @@ -205,19 +202,19 @@ public let ATTRIBUTE_NODES: [Node] = [ // back-deploy-version-list -> // back-deploy-version-entry back-deploy-version-list? Node( - name: "AvailabilityVersionRestrictionList", + kind: .availabilityVersionRestrictionList, + base: .syntaxCollection, nameForDiagnostics: "version list", - kind: "SyntaxCollection", - element: "AvailabilityVersionRestrictionListEntry" + elementChoices: [.availabilityVersionRestrictionListEntry] ), // The arguments of '@backDeployed(...)' // back-deployed-attr-spec-list -> 'before' ':' back-deployed-version-list Node( - name: "BackDeployedAttributeSpecList", + kind: .backDeployedAttributeSpecList, + base: .syntax, nameForDiagnostics: "'@backDeployed' arguments", - description: "A collection of arguments for the `@backDeployed` attribute", - kind: "Syntax", + documentation: "A collection of arguments for the `@backDeployed` attribute", children: [ Child( name: "BeforeLabel", @@ -231,7 +228,7 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Child( name: "VersionList", - kind: .collection(kind: "AvailabilityVersionRestrictionList", collectionElementName: "Availability"), + kind: .collection(kind: .availabilityVersionRestrictionList, collectionElementName: "Availability"), description: "The list of OS versions in which the declaration became ABI stable." ), ] @@ -239,10 +236,10 @@ public let ATTRIBUTE_NODES: [Node] = [ // convention-attribute-arguments -> token ',' 'cType'? ':' string-literal Node( - name: "ConventionAttributeArguments", + kind: .conventionAttributeArguments, + base: .syntax, nameForDiagnostics: "@convention(...) arguments", - description: "The arguments for the '@convention(...)'.", - kind: "Syntax", + documentation: "The arguments for the '@convention(...)'.", children: [ Child( name: "ConventionLabel", @@ -266,7 +263,7 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Child( name: "CTypeString", - kind: .node(kind: "StringLiteralExpr"), + kind: .node(kind: .stringLiteralExpr), isOptional: true ), ] @@ -274,10 +271,10 @@ public let ATTRIBUTE_NODES: [Node] = [ // convention-attribute-arguments -> 'witness_method' ':' identifier Node( - name: "ConventionWitnessMethodAttributeArguments", + kind: .conventionWitnessMethodAttributeArguments, + base: .syntax, nameForDiagnostics: "@convention(...) arguments for witness methods", - description: "The arguments for the '@convention(witness_method: ...)'.", - kind: "Syntax", + documentation: "The arguments for the '@convention(witness_method: ...)'.", children: [ Child( name: "WitnessMethodLabel", @@ -295,9 +292,9 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Node( - name: "DeclName", + kind: .declName, + base: .syntax, nameForDiagnostics: "declaration name", - kind: "Syntax", children: [ Child( name: "DeclBaseName", @@ -307,7 +304,7 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Child( name: "DeclNameArguments", - kind: .node(kind: "DeclNameArguments"), + kind: .node(kind: .declNameArguments), nameForDiagnostics: "arguments", description: "The argument labels of the protocol's requirement if it is a function requirement.", isOptional: true @@ -322,10 +319,10 @@ public let ATTRIBUTE_NODES: [Node] = [ // derivative-registration-attr-arguments -> // 'of' ':' func-decl-name ','? differentiability-params-clause? Node( - name: "DerivativeRegistrationAttributeArguments", + kind: .derivativeRegistrationAttributeArguments, + base: .syntax, nameForDiagnostics: "attribute arguments", - description: "The arguments for the '@derivative(of:)' and '@transpose(of:)' attributes: the 'of:' label, the original declaration name, and an optional differentiability parameter list.", - kind: "Syntax", + documentation: "The arguments for the '@derivative(of:)' and '@transpose(of:)' attributes: the 'of:' label, the original declaration name, and an optional differentiability parameter list.", children: [ Child( name: "OfLabel", @@ -339,7 +336,7 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Child( name: "OriginalDeclName", - kind: .node(kind: "QualifiedDeclName"), + kind: .node(kind: .qualifiedDeclName), description: "The referenced original declaration name." ), Child( @@ -361,7 +358,7 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Child( name: "DiffParams", - kind: .node(kind: "DifferentiabilityParamsClause"), + kind: .node(kind: .differentiabilityParamsClause), isOptional: true ), ] @@ -370,18 +367,18 @@ public let ATTRIBUTE_NODES: [Node] = [ // differentiability-param-list -> // differentiability-param differentiability-param-list? Node( - name: "DifferentiabilityParamList", + kind: .differentiabilityParamList, + base: .syntaxCollection, nameForDiagnostics: "differentiability parameters", - kind: "SyntaxCollection", - element: "DifferentiabilityParam" + elementChoices: [.differentiabilityParam] ), // differentiability-param -> ('self' | identifier | integer-literal) ','? Node( - name: "DifferentiabilityParam", + kind: .differentiabilityParam, + base: .syntax, nameForDiagnostics: "differentiability parameter", - description: "A differentiability parameter: either the \"self\" identifier, a function parameter name, or a function parameter index.", - kind: "Syntax", + documentation: "A differentiability parameter: either the \"self\" identifier, a function parameter name, or a function parameter index.", traits: [ "WithTrailingComma" ], @@ -401,10 +398,10 @@ public let ATTRIBUTE_NODES: [Node] = [ // differentiability-params-clause -> // 'wrt' ':' (differentiability-param | differentiability-params) Node( - name: "DifferentiabilityParamsClause", + kind: .differentiabilityParamsClause, + base: .syntax, nameForDiagnostics: "'@differentiable' argument", - description: "A clause containing differentiability parameters.", - kind: "Syntax", + documentation: "A clause containing differentiability parameters.", children: [ Child( name: "WrtLabel", @@ -421,11 +418,11 @@ public let ATTRIBUTE_NODES: [Node] = [ kind: .nodeChoices(choices: [ Child( name: "Parameter", - kind: .node(kind: "DifferentiabilityParam") + kind: .node(kind: .differentiabilityParam) ), Child( name: "ParameterList", - kind: .node(kind: "DifferentiabilityParams") + kind: .node(kind: .differentiabilityParams) ), ]), nameForDiagnostics: "parameters" @@ -435,10 +432,10 @@ public let ATTRIBUTE_NODES: [Node] = [ // differentiability-params -> '(' differentiability-param-list ')' Node( - name: "DifferentiabilityParams", + kind: .differentiabilityParams, + base: .syntax, nameForDiagnostics: "differentiability parameters", - description: "The differentiability parameters.", - kind: "Syntax", + documentation: "The differentiability parameters.", children: [ Child( name: "LeftParen", @@ -446,7 +443,7 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Child( name: "DiffParams", - kind: .collection(kind: "DifferentiabilityParamList", collectionElementName: "DifferentiabilityParam"), + kind: .collection(kind: .differentiabilityParamList, collectionElementName: "DifferentiabilityParam"), description: "The parameters for differentiation." ), Child( @@ -461,10 +458,10 @@ public let ATTRIBUTE_NODES: [Node] = [ // differentiability-kind? '.'? differentiability-params-clause? ','? // generic-where-clause? Node( - name: "DifferentiableAttributeArguments", + kind: .differentiableAttributeArguments, + base: .syntax, nameForDiagnostics: "'@differentiable' arguments", - description: "The arguments for the `@differentiable` attribute: an optional differentiability kind, an optional differentiability parameter clause, and an optional 'where' clause.", - kind: "Syntax", + documentation: "The arguments for the `@differentiable` attribute: an optional differentiability kind, an optional differentiability parameter clause, and an optional 'where' clause.", children: [ Child( name: "DiffKind", @@ -479,7 +476,7 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Child( name: "DiffParams", - kind: .node(kind: "DifferentiabilityParamsClause"), + kind: .node(kind: .differentiabilityParamsClause), isOptional: true ), Child( @@ -490,16 +487,16 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Child( name: "WhereClause", - kind: .node(kind: "GenericWhereClause"), + kind: .node(kind: .genericWhereClause), isOptional: true ), ] ), Node( - name: "DocumentationAttributeArgument", + kind: .documentationAttributeArgument, + base: .syntax, nameForDiagnostics: "@_documentation argument", - kind: "Syntax", traits: [ "WithTrailingComma" ], @@ -522,7 +519,7 @@ public let ATTRIBUTE_NODES: [Node] = [ ), // Keywords can be: public, internal, private, fileprivate, open Child( name: "String", - kind: .node(kind: "StringLiteralExpr") + kind: .node(kind: .stringLiteralExpr) ), ]) ), @@ -536,18 +533,18 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Node( - name: "DocumentationAttributeArguments", + kind: .documentationAttributeArguments, + base: .syntaxCollection, nameForDiagnostics: "@_documentation arguments", - description: "The arguments of the '@_documentation' attribute", - kind: "SyntaxCollection", - element: "DocumentationAttributeArgument" + documentation: "The arguments of the '@_documentation' attribute", + elementChoices: [.documentationAttributeArgument] ), Node( - name: "DynamicReplacementArguments", + kind: .dynamicReplacementArguments, + base: .syntax, nameForDiagnostics: "@_dynamicReplacement argument", - description: "The arguments for the '@_dynamicReplacement' attribute", - kind: "Syntax", + documentation: "The arguments for the '@_dynamicReplacement' attribute", children: [ Child( name: "ForLabel", @@ -559,28 +556,28 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Child( name: "Declname", - kind: .node(kind: "DeclName") + kind: .node(kind: .declName) ), ] ), Node( - name: "EffectsArguments", + kind: .effectsArguments, + base: .syntaxCollection, nameForDiagnostics: "@_effects arguments", - description: "The arguments of the '@_effect' attribute. These will be parsed during the SIL stage.", - kind: "SyntaxCollection", - element: "Token" + documentation: "The arguments of the '@_effect' attribute. These will be parsed during the SIL stage.", + elementChoices: [.token] ), Node( - name: "ExposeAttributeArguments", + kind: .exposeAttributeArguments, + base: .syntax, nameForDiagnostics: "@_expose arguments", - description: "The arguments for the '@_expose' attribute", - kind: "Syntax", + documentation: "The arguments for the '@_expose' attribute", children: [ Child( name: "Language", - kind: .node(kind: "Token") + kind: .node(kind: .token) ), Child( name: "Comma", @@ -589,7 +586,7 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Child( name: "CxxName", - kind: .node(kind: "StringLiteralExpr"), + kind: .node(kind: .stringLiteralExpr), isOptional: true ), ] @@ -599,14 +596,14 @@ public let ATTRIBUTE_NODES: [Node] = [ // implements-attr-arguments -> simple-type-identifier ',' // (identifier | operator) decl-name-arguments Node( - name: "ImplementsAttributeArguments", + kind: .implementsAttributeArguments, + base: .syntax, nameForDiagnostics: "@_implements arguemnts", - description: "The arguments for the `@_implements` attribute of the form `Type, methodName(arg1Label:arg2Label:)`", - kind: "Syntax", + documentation: "The arguments for the `@_implements` attribute of the form `Type, methodName(arg1Label:arg2Label:)`", children: [ Child( name: "Type", - kind: .node(kind: "Type"), + kind: .node(kind: .type), nameForDiagnostics: "type", description: "The type for which the method with this attribute implements a requirement." ), @@ -617,13 +614,13 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Child( name: "DeclBaseName", - kind: .node(kind: "Token"), + kind: .node(kind: .token), nameForDiagnostics: "declaration base name", description: "The base name of the protocol's requirement." ), Child( name: "DeclNameArguments", - kind: .node(kind: "DeclNameArguments"), + kind: .node(kind: .declNameArguments), nameForDiagnostics: "declaration name arguments", description: "The argument labels of the protocol's requirement if it is a function requirement.", isOptional: true @@ -634,17 +631,17 @@ public let ATTRIBUTE_NODES: [Node] = [ // Representation of e.g. 'exported: true,' // labeled-specialize-entry -> identifier ':' token ','? Node( - name: "LabeledSpecializeEntry", + kind: .labeledSpecializeEntry, + base: .syntax, nameForDiagnostics: "attribute argument", - description: "A labeled argument for the `@_specialize` attribute like `exported: true`", - kind: "Syntax", + documentation: "A labeled argument for the `@_specialize` attribute like `exported: true`", traits: [ "WithTrailingComma" ], children: [ Child( name: "Label", - kind: .node(kind: "Token"), + kind: .node(kind: .token), nameForDiagnostics: "label", description: "The label of the argument" ), @@ -655,7 +652,7 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Child( name: "Value", - kind: .node(kind: "Token"), + kind: .node(kind: .token), nameForDiagnostics: "value", description: "The value for this argument" ), @@ -670,14 +667,14 @@ public let ATTRIBUTE_NODES: [Node] = [ // objc-selector-piece -> identifier? ':'? Node( - name: "ObjCSelectorPiece", + kind: .objCSelectorPiece, + base: .syntax, nameForDiagnostics: "Objective-C selector piece", - description: "A piece of an Objective-C selector. Either consisting of just an identifier for a nullary selector, an identifier and a colon for a labeled argument or just a colon for an unlabeled argument", - kind: "Syntax", + documentation: "A piece of an Objective-C selector. Either consisting of just an identifier for a nullary selector, an identifier and a colon for a labeled argument or just a colon for an unlabeled argument", children: [ Child( name: "Name", - kind: .node(kind: "Token"), + kind: .node(kind: .token), nameForDiagnostics: "name", isOptional: true ), @@ -691,22 +688,22 @@ public let ATTRIBUTE_NODES: [Node] = [ // objc-selector -> objc-selector-piece objc-selector? Node( - name: "ObjCSelector", + kind: .objCSelector, + base: .syntaxCollection, nameForDiagnostics: "Objective-C selector", - kind: "SyntaxCollection", - element: "ObjCSelectorPiece" + elementChoices: [.objCSelectorPiece] ), // opaque-return-type-of-arguments -> string-literal ',' integer-literal Node( - name: "OpaqueReturnTypeOfAttributeArguments", + kind: .opaqueReturnTypeOfAttributeArguments, + base: .syntax, nameForDiagnostics: "opaque return type arguments", - description: "The arguments for the '@_opaqueReturnTypeOf()'.", - kind: "Syntax", + documentation: "The arguments for the '@_opaqueReturnTypeOf()'.", children: [ Child( name: "MangledName", - kind: .node(kind: "StringLiteralExpr"), + kind: .node(kind: .stringLiteralExpr), description: "The mangled name of a declaration." ), Child( @@ -722,10 +719,10 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Node( - name: "OriginallyDefinedInArguments", + kind: .originallyDefinedInArguments, + base: .syntax, nameForDiagnostics: "@_originallyDefinedIn arguments", - description: "The arguments for the '@_originallyDefinedIn' attribute", - kind: "Syntax", + documentation: "The arguments for the '@_originallyDefinedIn' attribute", children: [ Child( name: "ModuleLabel", @@ -737,7 +734,7 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Child( name: "ModuleName", - kind: .node(kind: "StringLiteralExpr") + kind: .node(kind: .stringLiteralExpr) ), Child( name: "Comma", @@ -745,7 +742,7 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Child( name: "Platforms", - kind: .collection(kind: "AvailabilityVersionRestrictionList", collectionElementName: "Platform") + kind: .collection(kind: .availabilityVersionRestrictionList, collectionElementName: "Platform") ), ] ), @@ -760,14 +757,14 @@ public let ATTRIBUTE_NODES: [Node] = [ // base-type -> // member-type-identifier | base-type-identifier Node( - name: "QualifiedDeclName", + kind: .qualifiedDeclName, + base: .syntax, nameForDiagnostics: "declaration name", - description: "An optionally qualified function declaration name (e.g. `+(_:_:)`, `A.B.C.foo(_:_:)`).", - kind: "Syntax", + documentation: "An optionally qualified function declaration name (e.g. `+(_:_:)`, `A.B.C.foo(_:_:)`).", children: [ Child( name: "BaseType", - kind: .node(kind: "Type"), + kind: .node(kind: .type), nameForDiagnostics: "base type", description: "The base type of the qualified name, optionally specified.", isOptional: true @@ -785,7 +782,7 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Child( name: "Arguments", - kind: .node(kind: "DeclNameArguments"), + kind: .node(kind: .declNameArguments), nameForDiagnostics: "arguments", description: "The argument labels of the referenced function, optionally specified.", isOptional: true @@ -799,22 +796,20 @@ public let ATTRIBUTE_NODES: [Node] = [ // | generic-where-clause // specialize-spec-attr-list? Node( - name: "SpecializeAttributeSpecList", + kind: .specializeAttributeSpecList, + base: .syntaxCollection, nameForDiagnostics: "argument to '@_specialize", - description: "A collection of arguments for the `@_specialize` attribute", - kind: "SyntaxCollection", - element: "Syntax", - elementName: "SpecializeAttribute", - elementChoices: ["LabeledSpecializeEntry", "AvailabilityEntry", "TargetFunctionEntry", "GenericWhereClause"] + documentation: "A collection of arguments for the `@_specialize` attribute", + elementChoices: [.labeledSpecializeEntry, .availabilityEntry, .targetFunctionEntry, .genericWhereClause] ), // Representation of e.g. 'exported: true,' // labeled-specialize-entry -> identifier ':' token ','? Node( - name: "TargetFunctionEntry", + kind: .targetFunctionEntry, + base: .syntax, nameForDiagnostics: "attribute argument", - description: "A labeled argument for the `@_specialize` attribute with a function decl value like `target: myFunc(_:)`", - kind: "Syntax", + documentation: "A labeled argument for the `@_specialize` attribute with a function decl value like `target: myFunc(_:)`", traits: [ "WithTrailingComma" ], @@ -832,7 +827,7 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Child( name: "Declname", - kind: .node(kind: "DeclName"), + kind: .node(kind: .declName), nameForDiagnostics: "declaration name", description: "The value for this argument" ), @@ -846,10 +841,10 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Node( - name: "UnavailableFromAsyncArguments", + kind: .unavailableFromAsyncArguments, + base: .syntax, nameForDiagnostics: "@_unavailableFromAsync argument", - description: "The arguments for the '@_unavailableFromAsync' attribute", - kind: "Syntax", + documentation: "The arguments for the '@_unavailableFromAsync' attribute", children: [ Child( name: "MessageLabel", @@ -861,16 +856,16 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Child( name: "Message", - kind: .node(kind: "StringLiteralExpr") + kind: .node(kind: .stringLiteralExpr) ), ] ), Node( - name: "UnderscorePrivateAttributeArguments", + kind: .underscorePrivateAttributeArguments, + base: .syntax, nameForDiagnostics: "@_private argument", - description: "The arguments for the '@_private' attribute", - kind: "Syntax", + documentation: "The arguments for the '@_private' attribute", children: [ Child( name: "SourceFileLabel", @@ -882,7 +877,7 @@ public let ATTRIBUTE_NODES: [Node] = [ ), Child( name: "Filename", - kind: .node(kind: "StringLiteralExpr") + kind: .node(kind: .stringLiteralExpr) ), ] ), diff --git a/CodeGeneration/Sources/SyntaxSupport/AvailabilityNodes.swift b/CodeGeneration/Sources/SyntaxSupport/AvailabilityNodes.swift index 9eec1c5ba78..cf801b8f2fa 100644 --- a/CodeGeneration/Sources/SyntaxSupport/AvailabilityNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/AvailabilityNodes.swift @@ -17,10 +17,10 @@ public let AVAILABILITY_NODES: [Node] = [ // | availability-version-restriction ','? // | availability-versioned-argument ','? Node( - name: "AvailabilityArgument", + kind: .availabilityArgument, + base: .syntax, nameForDiagnostics: "availability argument", - description: "A single argument to an `@available` argument like `*`, `iOS 10.1`, or `message: \"This has been deprecated\"`.", - kind: "Syntax", + documentation: "A single argument to an `@available` argument like `*`, `iOS 10.1`, or `message: \"This has been deprecated\"`.", children: [ Child( name: "Entry", @@ -31,11 +31,11 @@ public let AVAILABILITY_NODES: [Node] = [ ), Child( name: "AvailabilityVersionRestriction", - kind: .node(kind: "AvailabilityVersionRestriction") + kind: .node(kind: .availabilityVersionRestriction) ), Child( name: "AvailabilityLabeledArgument", - kind: .node(kind: "AvailabilityLabeledArgument") + kind: .node(kind: .availabilityLabeledArgument) ), ]), description: "The actual argument" @@ -52,10 +52,10 @@ public let AVAILABILITY_NODES: [Node] = [ // Representation of 'deprecated: 2.3', 'message: "Hello world"' etc. // availability-versioned-argument -> identifier ':' version-tuple Node( - name: "AvailabilityLabeledArgument", + kind: .availabilityLabeledArgument, + base: .syntax, nameForDiagnostics: "availability argument", - description: "A argument to an `@available` attribute that consists of a label and a value, e.g. `message: \"This has been deprecated\"`.", - kind: "Syntax", + documentation: "A argument to an `@available` attribute that consists of a label and a value, e.g. `message: \"This has been deprecated\"`.", children: [ Child( name: "Label", @@ -73,11 +73,11 @@ public let AVAILABILITY_NODES: [Node] = [ kind: .nodeChoices(choices: [ Child( name: "String", - kind: .node(kind: "StringLiteralExpr") + kind: .node(kind: .stringLiteralExpr) ), Child( name: "Version", - kind: .node(kind: "VersionTuple") + kind: .node(kind: .versionTuple) ), ]), nameForDiagnostics: "value", @@ -88,19 +88,19 @@ public let AVAILABILITY_NODES: [Node] = [ // availability-spec-list -> availability-entry availability-spec-list? Node( - name: "AvailabilitySpecList", + kind: .availabilitySpecList, + base: .syntaxCollection, nameForDiagnostics: "'@availability' arguments", - kind: "SyntaxCollection", - element: "AvailabilityArgument" + elementChoices: [.availabilityArgument] ), // Representation for 'iOS 10', 'swift 3.4' etc. // availability-version-restriction -> identifier version-tuple Node( - name: "AvailabilityVersionRestriction", + kind: .availabilityVersionRestriction, + base: .syntax, nameForDiagnostics: "version restriction", - description: "An argument to `@available` that restricts the availability on a certain platform to a version, e.g. `iOS 10` or `swift 3.4`.", - kind: "Syntax", + 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", @@ -111,7 +111,7 @@ public let AVAILABILITY_NODES: [Node] = [ ), Child( name: "Version", - kind: .node(kind: "VersionTuple"), + kind: .node(kind: .versionTuple), nameForDiagnostics: "version", isOptional: true ), @@ -120,10 +120,10 @@ public let AVAILABILITY_NODES: [Node] = [ // version-tuple-element -> '.' integer-literal Node( - name: "VersionComponent", + kind: .versionComponent, + base: .syntax, nameForDiagnostics: nil, - description: "An element to represent a single component in a version, like `.1`.", - kind: "Syntax", + documentation: "An element to represent a single component in a version, like `.1`.", children: [ Child( name: "Period", @@ -140,19 +140,18 @@ public let AVAILABILITY_NODES: [Node] = [ // version-list -> version-tuple-element version-list? Node( - name: "VersionComponentList", + kind: .versionComponentList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "VersionComponent", - omitWhenEmpty: true + elementChoices: [.versionComponent] ), // version-tuple -> integer-literal version-list? Node( - name: "VersionTuple", + kind: .versionTuple, + base: .syntax, nameForDiagnostics: "version tuple", - description: "A version number like `1.2.0`. Only the first version component is required. There might be an arbitrary number of following components.", - kind: "Syntax", + 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", @@ -161,7 +160,7 @@ public let AVAILABILITY_NODES: [Node] = [ ), Child( name: "Components", - kind: .collection(kind: "VersionComponentList", collectionElementName: "VersionComponent"), + kind: .collection(kind: .versionComponentList, collectionElementName: "VersionComponent"), description: "Any version components that are not the major version . For example, for `1.2.0`, this will contain `.2.0`", isOptional: true ), diff --git a/CodeGeneration/Sources/SyntaxSupport/BuilderInitializableTypes.swift b/CodeGeneration/Sources/SyntaxSupport/BuilderInitializableTypes.swift index 4d41a68d9d4..eb50caeaccf 100644 --- a/CodeGeneration/Sources/SyntaxSupport/BuilderInitializableTypes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/BuilderInitializableTypes.swift @@ -10,23 +10,26 @@ // //===----------------------------------------------------------------------===// -public let BUILDER_INITIALIZABLE_TYPES: [String: String?] = [ - "CodeBlock": "CodeBlockItemList", - "MemberDeclBlock": "MemberDeclList", - "CodeBlockItemList": nil, - "MemberDeclList": nil, - "PatternBindingList": nil, - "SwitchCaseList": nil, - "ArrayElementList": nil, - "TupleExprElementList": nil, - "EnumCaseElementList": nil, - "FunctionParameterList": nil, - "GenericParameterList": nil, - "GenericRequirementList": nil, - "InheritedTypeList": nil, - "ClosureCaptureItemList": nil, - "CaseItemList": nil, - "GenericArgumentList": nil, - "TuplePatternElementList": nil, - "ExprList": nil, +/// As keys, contains all node kinds that can be initialized using a result +/// builder. If the value is not nil, the result builder construct the value's +/// type and synthesize all other members to form the node. +public let BUILDER_INITIALIZABLE_TYPES: [SyntaxNodeKind: SyntaxNodeKind?] = [ + .codeBlock: .codeBlockItemList, + .memberDeclBlock: .memberDeclList, + .codeBlockItemList: nil, + .memberDeclList: nil, + .patternBindingList: nil, + .switchCaseList: nil, + .arrayElementList: nil, + .tupleExprElementList: nil, + .enumCaseElementList: nil, + .functionParameterList: nil, + .genericParameterList: nil, + .genericRequirementList: nil, + .inheritedTypeList: nil, + .closureCaptureItemList: nil, + .caseItemList: nil, + .genericArgumentList: nil, + .tuplePatternElementList: nil, + .exprList: nil, ] diff --git a/CodeGeneration/Sources/SyntaxSupport/Child.swift b/CodeGeneration/Sources/SyntaxSupport/Child.swift index 178f1e355f0..6b2b755e14f 100644 --- a/CodeGeneration/Sources/SyntaxSupport/Child.swift +++ b/CodeGeneration/Sources/SyntaxSupport/Child.swift @@ -26,11 +26,11 @@ public enum TokenChoice { public enum ChildKind { /// The child always contains a node of the given `kind`. - case node(kind: String) + case node(kind: SyntaxNodeKind) /// 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: String, collectionElementName: String) + case collection(kind: SyntaxNodeKind, collectionElementName: String) /// 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. @@ -66,18 +66,28 @@ public class Child { public let isOptional: Bool public let classification: SyntaxClassification? - public var swiftName: String { - return lowercaseFirstWord(name: name) - } - - public var syntaxKind: String { + public var syntaxNodeKind: SyntaxNodeKind { switch kind { case .node(kind: let kind): return kind case .nodeChoices: - return "Syntax" + return .syntax case .collection(kind: let kind, collectionElementName: _): return kind + case .token: + return .token + } + } + + /// A name of this child that's suitable to be used for variable or enum case names. + public var varName: String { + return lowercaseFirstWord(name: name) + } + + /// If the child ends with "token" in the kind, it's considered a token node. + /// Grab the existing reference to that token from the global list. + public var tokenKind: String? { + switch kind { case .token(choices: let choices, requiresLeadingSpace: _, requiresTrailingSpace: _): if choices.count == 1 { switch choices.first! { @@ -91,22 +101,7 @@ public class Child { return "Token" } } - } - } - - public var swiftSyntaxKind: String { - return lowercaseFirstWord(name: syntaxKind) - } - - public var typeName: String { - return kindToType(kind: syntaxKind) - } - - /// If the child ends with "token" in the kind, it's considered a token node. Grab the existing reference to that token from the global list. - public var tokenKind: String? { - if syntaxKind.hasSuffix("Token") { - return syntaxKind - } else { + default: return nil } } @@ -123,7 +118,12 @@ public class Child { /// Whether this child has syntax kind `UnexpectedNodes`. public var isUnexpectedNodes: Bool { - syntaxKind == "UnexpectedNodes" + switch kind { + case .collection(kind: .unexpectedNodes, collectionElementName: _): + return true + default: + return false + } } /// Returns `true` if this child's type is one of the base syntax kinds and @@ -131,11 +131,13 @@ public class Child { public var hasBaseType: Bool { switch kind { case .nodeChoices(let choices): - return choices.isEmpty && SYNTAX_BASE_KINDS.contains(syntaxKind) - case .node, - .collection, - .token: - return SYNTAX_BASE_KINDS.contains(syntaxKind) + return choices.isEmpty + case .node(let kind): + return kind.isBase + case .collection(kind: let kind, collectionElementName: _): + return kind.isBase + case .token: + return false } } diff --git a/CodeGeneration/Sources/SyntaxSupport/CommonNodes.swift b/CodeGeneration/Sources/SyntaxSupport/CommonNodes.swift index dd5ad4d9896..4e28d3418cd 100644 --- a/CodeGeneration/Sources/SyntaxSupport/CommonNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/CommonNodes.swift @@ -13,18 +13,18 @@ public let COMMON_NODES: [Node] = [ // code-block-item-list -> code-block-item code-block-item-list? Node( - name: "CodeBlockItemList", + kind: .codeBlockItemList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "CodeBlockItem" + elementChoices: [.codeBlockItem] ), // code-block-item = (decl | stmt | expr) ';'? Node( - name: "CodeBlockItem", + kind: .codeBlockItem, + base: .syntax, nameForDiagnostics: nil, - description: "A CodeBlockItem is any Syntax node that appears on its own line inside a CodeBlock.", - kind: "Syntax", + documentation: "A CodeBlockItem is any Syntax node that appears on its own line inside a CodeBlock.", parserFunction: "parseNonOptionalCodeBlockItem", children: [ Child( @@ -32,15 +32,15 @@ public let COMMON_NODES: [Node] = [ kind: .nodeChoices(choices: [ Child( name: "Decl", - kind: .node(kind: "Decl") + kind: .node(kind: .decl) ), Child( name: "Stmt", - kind: .node(kind: "Stmt") + kind: .node(kind: .stmt) ), Child( name: "Expr", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), ]), description: "The underlying node inside the code block." @@ -51,15 +51,14 @@ public let COMMON_NODES: [Node] = [ description: "If present, the trailing semicolon at the end of the item.", isOptional: true ), - ], - omitWhenEmpty: true + ] ), // code-block -> '{' stmt-list '}' Node( - name: "CodeBlock", + kind: .codeBlock, + base: .syntax, nameForDiagnostics: "code block", - kind: "Syntax", traits: [ "Braced", "WithStatements", @@ -71,7 +70,7 @@ public let COMMON_NODES: [Node] = [ ), Child( name: "Statements", - kind: .collection(kind: "CodeBlockItemList", collectionElementName: "Statement"), + kind: .collection(kind: .codeBlockItemList, collectionElementName: "Statement"), nameForDiagnostics: "statements", isIndented: true ), @@ -85,9 +84,9 @@ public let COMMON_NODES: [Node] = [ // accessor-effect-specifiers -> (async)? (throws)? Node( - name: "AccessorEffectSpecifiers", + kind: .accessorEffectSpecifiers, + base: .syntax, nameForDiagnostics: "accessor specifiers", - kind: "Syntax", traits: [ "EffectSpecifiers" ], @@ -107,9 +106,9 @@ public let COMMON_NODES: [Node] = [ // funtion-effect-specifiers -> (async | reasync)? (throws | rethrows)? Node( - name: "FunctionEffectSpecifiers", + kind: .functionEffectSpecifiers, + base: .syntax, nameForDiagnostics: "effect specifiers", - kind: "Syntax", traits: [ "EffectSpecifiers" ], @@ -128,24 +127,24 @@ public let COMMON_NODES: [Node] = [ ), Node( - name: "Decl", + kind: .decl, + base: .syntax, nameForDiagnostics: "declaration", - kind: "Syntax", parserFunction: "parseDeclaration" ), Node( - name: "Expr", + kind: .expr, + base: .syntax, nameForDiagnostics: "expression", - kind: "Syntax", parserFunction: "parseExpression" ), Node( - name: "MissingDecl", + kind: .missingDecl, + base: .decl, nameForDiagnostics: "declaration", - description: "In case the source code is missing a declaration, this node stands in place of the missing declaration.", - kind: "Decl", + documentation: "In case the source code is missing a declaration, this node stands in place of the missing declaration.", traits: [ "WithAttributes", "WithModifiers", @@ -153,13 +152,13 @@ public let COMMON_NODES: [Node] = [ children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), description: "If there were standalone attributes without a declaration to attach them to, the `MissingDeclSyntax` will contain these.", isOptional: true ), Child( name: "Modifiers", - kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"), + kind: .collection(kind: .modifierList, collectionElementName: "Modifier"), description: "If there were standalone modifiers without a declaration to attach them to, the `MissingDeclSyntax` will contain these.", isOptional: true ), @@ -175,10 +174,10 @@ public let COMMON_NODES: [Node] = [ ), Node( - name: "MissingExpr", + kind: .missingExpr, + base: .expr, nameForDiagnostics: "expression", - description: "In case the source code is missing a expression, this node stands in place of the missing expression.", - kind: "Expr", + documentation: "In case the source code is missing a expression, this node stands in place of the missing expression.", children: [ Child( name: "Placeholder", @@ -192,10 +191,10 @@ public let COMMON_NODES: [Node] = [ ), Node( - name: "MissingPattern", + kind: .missingPattern, + base: .pattern, nameForDiagnostics: "pattern", - description: "In case the source code is missing a pattern, this node stands in place of the missing pattern.", - kind: "Pattern", + documentation: "In case the source code is missing a pattern, this node stands in place of the missing pattern.", children: [ Child( name: "Placeholder", @@ -209,10 +208,10 @@ public let COMMON_NODES: [Node] = [ ), Node( - name: "MissingStmt", + kind: .missingStmt, + base: .stmt, nameForDiagnostics: "statement", - description: "In case the source code is missing a statement, this node stands in place of the missing statement.", - kind: "Stmt", + documentation: "In case the source code is missing a statement, this node stands in place of the missing statement.", children: [ Child( name: "Placeholder", @@ -226,10 +225,10 @@ public let COMMON_NODES: [Node] = [ ), Node( - name: "Missing", + kind: .missing, + base: .syntax, nameForDiagnostics: nil, - description: "In case the source code is missing a syntax node, this node stands in place of the missing node.", - kind: "Syntax", + documentation: "In case the source code is missing a syntax node, this node stands in place of the missing node.", children: [ Child( name: "Placeholder", @@ -243,10 +242,10 @@ public let COMMON_NODES: [Node] = [ ), Node( - name: "MissingType", + kind: .missingType, + base: .type, nameForDiagnostics: "type", - description: "In case the source code is missing a type, this node stands in place of the missing type.", - kind: "Type", + documentation: "In case the source code is missing a type, this node stands in place of the missing type.", children: [ Child( name: "Placeholder", @@ -259,24 +258,24 @@ public let COMMON_NODES: [Node] = [ ), Node( - name: "Pattern", + kind: .pattern, + base: .syntax, nameForDiagnostics: "pattern", - kind: "Syntax", parserFunction: "parsePattern" ), Node( - name: "Stmt", + kind: .stmt, + base: .syntax, nameForDiagnostics: "statement", - kind: "Syntax", parserFunction: "parseStatement" ), // type-effect-specifiers -> async? throws? Node( - name: "TypeEffectSpecifiers", + kind: .typeEffectSpecifiers, + base: .syntax, nameForDiagnostics: "effect specifiers", - kind: "Syntax", traits: [ "EffectSpecifiers" ], @@ -295,18 +294,18 @@ public let COMMON_NODES: [Node] = [ ), Node( - name: "Type", + kind: .type, + base: .syntax, nameForDiagnostics: "type", - kind: "Syntax", parserFunction: "parseType" ), Node( - name: "UnexpectedNodes", + kind: .unexpectedNodes, + base: .syntaxCollection, nameForDiagnostics: nil, - description: "A collection of syntax nodes that occurred in the source code but could not be used to form a valid syntax tree.", - kind: "SyntaxCollection", - element: "Syntax" + 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/CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift b/CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift index 8a6983745d0..eb18f9e954f 100644 --- a/CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift @@ -12,9 +12,9 @@ public let DECL_NODES: [Node] = [ Node( - name: "ImportPathComponent", + kind: .importPathComponent, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", children: [ Child( name: "Name", @@ -30,16 +30,16 @@ public let DECL_NODES: [Node] = [ ), Node( - name: "ImportPath", + kind: .importPath, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "ImportPathComponent" + elementChoices: [.importPathComponent] ), Node( - name: "AccessorBlock", + kind: .accessorBlock, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", traits: [ "Braced" ], @@ -50,7 +50,7 @@ public let DECL_NODES: [Node] = [ ), Child( name: "Accessors", - kind: .collection(kind: "AccessorList", collectionElementName: "Accessor"), + kind: .collection(kind: .accessorList, collectionElementName: "Accessor"), isIndented: true ), Child( @@ -62,23 +62,21 @@ public let DECL_NODES: [Node] = [ ), Node( - name: "AccessorDecl", + kind: .accessorDecl, + base: .decl, nameForDiagnostics: "accessor", - kind: "Decl", - traits: [ - "WithAttributes" - ], parserFunction: "parseAccessorDecl", + traits: ["WithAttributes"], children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), nameForDiagnostics: "attributes", isOptional: true ), Child( name: "Modifier", - kind: .node(kind: "DeclModifier"), + kind: .node(kind: .declModifier), nameForDiagnostics: "modifiers", isOptional: true ), @@ -88,35 +86,35 @@ public let DECL_NODES: [Node] = [ ), Child( name: "Parameter", - kind: .node(kind: "AccessorParameter"), + kind: .node(kind: .accessorParameter), nameForDiagnostics: "parameter", isOptional: true ), Child( name: "EffectSpecifiers", - kind: .node(kind: "AccessorEffectSpecifiers"), + kind: .node(kind: .accessorEffectSpecifiers), isOptional: true ), Child( name: "Body", - kind: .node(kind: "CodeBlock"), + kind: .node(kind: .codeBlock), isOptional: true ), ] ), Node( - name: "AccessorList", + kind: .accessorList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "AccessorDecl" + elementChoices: [.accessorDecl] ), // (value) Node( - name: "AccessorParameter", + kind: .accessorParameter, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", traits: [ "Parenthesized" ], @@ -145,9 +143,9 @@ public let DECL_NODES: [Node] = [ // '{' actor-members '}' // actor-name -> identifier Node( - name: "ActorDecl", + kind: .actorDecl, + base: .decl, nameForDiagnostics: "actor", - kind: "Decl", traits: [ "DeclGroup", "IdentifiedDecl", @@ -157,13 +155,13 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), nameForDiagnostics: "attributes", isOptional: true ), Child( name: "Modifiers", - kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"), + kind: .collection(kind: .modifierList, collectionElementName: "Modifier"), nameForDiagnostics: "modifiers", isOptional: true ), @@ -177,25 +175,25 @@ public let DECL_NODES: [Node] = [ ), Child( name: "GenericParameterClause", - kind: .node(kind: "GenericParameterClause"), + kind: .node(kind: .genericParameterClause), nameForDiagnostics: "generic parameter clause", isOptional: true ), Child( name: "InheritanceClause", - kind: .node(kind: "TypeInheritanceClause"), + kind: .node(kind: .typeInheritanceClause), nameForDiagnostics: "type inheritance clause", isOptional: true ), Child( name: "GenericWhereClause", - kind: .node(kind: "GenericWhereClause"), + kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", isOptional: true ), Child( name: "MemberBlock", - kind: .node(kind: "MemberDeclBlock") + kind: .node(kind: .memberDeclBlock) ), ] ), @@ -206,9 +204,10 @@ public let DECL_NODES: [Node] = [ // generic-where-clause? // associatedtype-name -> identifier Node( - name: "AssociatedtypeDecl", + kind: .associatedtypeDecl, + base: .decl, nameForDiagnostics: "associatedtype declaration", - description: """ + documentation: """ An associated type declaration like the following. ```swift @@ -233,7 +232,6 @@ public let DECL_NODES: [Node] = [ associatedtype Iterator: IteratorProtocol where Iterator.Element == Item ``` """, - kind: "Decl", traits: [ "IdentifiedDecl", "WithAttributes", @@ -242,14 +240,14 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), nameForDiagnostics: "attributes", description: "Attributes attached to the associated type declaration.", isOptional: true ), Child( name: "Modifiers", - kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"), + kind: .collection(kind: .modifierList, collectionElementName: "Modifier"), nameForDiagnostics: "modifiers", description: "Modifiers attached to the associated type declaration.", isOptional: true @@ -266,20 +264,20 @@ public let DECL_NODES: [Node] = [ ), Child( name: "InheritanceClause", - kind: .node(kind: "TypeInheritanceClause"), + kind: .node(kind: .typeInheritanceClause), nameForDiagnostics: "inheritance clause", description: "The inheritance clause describing conformances for this associated type declaration.", isOptional: true ), Child( name: "Initializer", - kind: .node(kind: "TypeInitializerClause"), + kind: .node(kind: .typeInitializerClause), description: "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"), + kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", description: "The `where` clause that applies to the generic parameters of this associated type declaration.", isOptional: true @@ -295,9 +293,10 @@ public let DECL_NODES: [Node] = [ // '{' class-members '}' // class-name -> identifier Node( - name: "ClassDecl", + kind: .classDecl, + base: .decl, nameForDiagnostics: "class", - description: """ + documentation: """ A class declaration like the following. ```swift @@ -320,7 +319,6 @@ public let DECL_NODES: [Node] = [ A class declaration may be declared without any members. """, - kind: "Decl", traits: [ "DeclGroup", "IdentifiedDecl", @@ -330,14 +328,14 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), nameForDiagnostics: "attributes", description: "Attributes attached to the class declaration, such as an `@available` attribute.", isOptional: true ), Child( name: "Modifiers", - kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"), + kind: .collection(kind: .modifierList, collectionElementName: "Modifier"), nameForDiagnostics: "modifiers", description: "Modifiers attached to the class declaration, such as `public`.", isOptional: true @@ -354,37 +352,37 @@ public let DECL_NODES: [Node] = [ ), Child( name: "GenericParameterClause", - kind: .node(kind: "GenericParameterClause"), + kind: .node(kind: .genericParameterClause), nameForDiagnostics: "generic parameter clause", description: "The generic parameters, if any, of the class declaration.", isOptional: true ), Child( name: "InheritanceClause", - kind: .node(kind: "TypeInheritanceClause"), + kind: .node(kind: .typeInheritanceClause), nameForDiagnostics: "inheritance clause", description: "The inheritance clause describing one or more conformances for this class declaration.", isOptional: true ), Child( name: "GenericWhereClause", - kind: .node(kind: "GenericWhereClause"), + kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", description: "The `where` clause that applies to the generic parameters of this class declaration.", isOptional: true ), Child( name: "MemberBlock", - kind: .node(kind: "MemberDeclBlock"), + kind: .node(kind: .memberDeclBlock), description: "The members of the class declaration. As class extension declarations may declare additional members, the contents of this member block isn't guaranteed to be a complete list of members for this type." ), ] ), Node( - name: "DeclModifierDetail", + kind: .declModifierDetail, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", traits: [ "Parenthesized" ], @@ -405,9 +403,9 @@ public let DECL_NODES: [Node] = [ ), Node( - name: "DeclModifier", + kind: .declModifier, + base: .syntax, nameForDiagnostics: "modifier", - kind: "Syntax", children: [ Child( name: "Name", @@ -453,16 +451,17 @@ public let DECL_NODES: [Node] = [ ), Child( name: "Detail", - kind: .node(kind: "DeclModifierDetail"), + kind: .node(kind: .declModifierDetail), isOptional: true ), ] ), Node( - name: "DeinitializerDecl", + kind: .deinitializerDecl, + base: .decl, nameForDiagnostics: "deinitializer", - description: """ + documentation: """ A deinitializer declaration like the following. ```swift @@ -470,7 +469,6 @@ public let DECL_NODES: [Node] = [ } ``` """, - kind: "Decl", traits: [ "WithAttributes", "WithModifiers", @@ -478,14 +476,14 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), nameForDiagnostics: "attributes", description: "Attributes that are attached to the deinitializer.", isOptional: true ), Child( name: "Modifiers", - kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"), + kind: .collection(kind: .modifierList, collectionElementName: "Modifier"), nameForDiagnostics: "modifiers", description: "Modifiers that are attached to the deinitializer.", isOptional: true @@ -497,7 +495,7 @@ public let DECL_NODES: [Node] = [ ), Child( name: "Body", - kind: .node(kind: "CodeBlock"), + kind: .node(kind: .codeBlock), description: "The deinitializer's body.", isOptional: true ), @@ -505,9 +503,9 @@ public let DECL_NODES: [Node] = [ ), Node( - name: "DesignatedTypeElement", + kind: .designatedTypeElement, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", children: [ Child( name: "LeadingComma", @@ -515,24 +513,24 @@ public let DECL_NODES: [Node] = [ ), Child( name: "Name", - kind: .node(kind: "Token") + kind: .node(kind: .token) ), ] ), // designated-type-list -> (',' identifier)* Node( - name: "DesignatedTypeList", + kind: .designatedTypeList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "DesignatedTypeElement" + elementChoices: [.designatedTypeElement] ), // <#content#> Node( - name: "EditorPlaceholderDecl", + kind: .editorPlaceholderDecl, + base: .decl, nameForDiagnostics: "editor placeholder", - kind: "Decl", children: [ Child( name: "Identifier", @@ -542,9 +540,9 @@ public let DECL_NODES: [Node] = [ ), Node( - name: "EnumCaseParameterClause", + kind: .enumCaseParameterClause, + base: .syntax, nameForDiagnostics: "parameter clause", - kind: "Syntax", traits: [ "Parenthesized" ], @@ -556,7 +554,7 @@ public let DECL_NODES: [Node] = [ ), Child( name: "ParameterList", - kind: .collection(kind: "EnumCaseParameterList", collectionElementName: "Parameter"), + kind: .collection(kind: .enumCaseParameterList, collectionElementName: "Parameter"), nameForDiagnostics: "parameters", description: "The actual parameters.", isIndented: true @@ -570,25 +568,22 @@ public let DECL_NODES: [Node] = [ ), Node( - name: "EnumCaseParameterList", + kind: .enumCaseParameterList, + base: .syntaxCollection, nameForDiagnostics: "parameter list", - kind: "SyntaxCollection", - element: "EnumCaseParameter" + elementChoices: [.enumCaseParameter] ), Node( - name: "EnumCaseParameter", + kind: .enumCaseParameter, + base: .syntax, nameForDiagnostics: "parameter", - kind: "Syntax", - traits: [ - "WithTrailingComma", - "WithModifiers", - ], parserFunction: "parseEnumCaseParameter", + traits: ["WithTrailingComma", "WithModifiers"], children: [ Child( name: "Modifiers", - kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"), + kind: .collection(kind: .modifierList, collectionElementName: "Modifier"), nameForDiagnostics: "modifiers", isOptional: true ), @@ -610,13 +605,13 @@ public let DECL_NODES: [Node] = [ ), Child( name: "Type", - kind: .node(kind: "Type"), + kind: .node(kind: .type), nameForDiagnostics: "type", description: "The parameter's type." ), Child( name: "DefaultArgument", - kind: .node(kind: "InitializerClause"), + kind: .node(kind: .initializerClause), nameForDiagnostics: "default argument", description: "If the parameter has a default value, the initializer clause describing the default value.", isOptional: true @@ -631,10 +626,10 @@ public let DECL_NODES: [Node] = [ ), Node( - name: "EnumCaseDecl", + kind: .enumCaseDecl, + base: .decl, nameForDiagnostics: "enum case", - description: "A `case` declaration of a Swift `enum`. It can have 1 or more `EnumCaseElement`s inside, each declaring a different case of the enum.", - kind: "Decl", + 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", @@ -642,14 +637,14 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), nameForDiagnostics: "attributes", description: "The attributes applied to the case declaration.", isOptional: true ), Child( name: "Modifiers", - kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"), + kind: .collection(kind: .modifierList, collectionElementName: "Modifier"), nameForDiagnostics: "modifiers", description: "The declaration modifiers applied to the case declaration.", isOptional: true @@ -661,7 +656,7 @@ public let DECL_NODES: [Node] = [ ), Child( name: "Elements", - kind: .collection(kind: "EnumCaseElementList", collectionElementName: "Element"), + kind: .collection(kind: .enumCaseElementList, collectionElementName: "Element"), nameForDiagnostics: "elements", description: "The elements this case declares." ), @@ -669,18 +664,18 @@ public let DECL_NODES: [Node] = [ ), Node( - name: "EnumCaseElementList", + kind: .enumCaseElementList, + base: .syntaxCollection, nameForDiagnostics: nil, - description: "A collection of 0 or more `EnumCaseElement`s.", - kind: "SyntaxCollection", - element: "EnumCaseElement" + documentation: "A collection of 0 or more `EnumCaseElement`s.", + elementChoices: [.enumCaseElement] ), Node( - name: "EnumCaseElement", + kind: .enumCaseElement, + base: .syntax, nameForDiagnostics: nil, - description: "An element of an enum case, containing the name of the case and, optionally, either associated values or an assignment to a raw value.", - kind: "Syntax", + 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" ], @@ -692,14 +687,14 @@ public let DECL_NODES: [Node] = [ ), Child( name: "AssociatedValue", - kind: .node(kind: "EnumCaseParameterClause"), + kind: .node(kind: .enumCaseParameterClause), nameForDiagnostics: "associated values", description: "The set of associated values of the case.", isOptional: true ), Child( name: "RawValue", - kind: .node(kind: "InitializerClause"), + kind: .node(kind: .initializerClause), description: "The raw value of this enum element, if present.", isOptional: true ), @@ -713,10 +708,10 @@ public let DECL_NODES: [Node] = [ ), Node( - name: "EnumDecl", + kind: .enumDecl, + base: .decl, nameForDiagnostics: "enum", - description: "A Swift `enum` declaration.", - kind: "Decl", + documentation: "A Swift `enum` declaration.", traits: [ "DeclGroup", "IdentifiedDecl", @@ -726,14 +721,14 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), nameForDiagnostics: "attributes", description: "The attributes applied to the enum declaration.", isOptional: true ), Child( name: "Modifiers", - kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"), + kind: .collection(kind: .modifierList, collectionElementName: "Modifier"), nameForDiagnostics: "modifiers", description: "The declaration modifiers applied to the enum declaration.", isOptional: true @@ -750,28 +745,28 @@ public let DECL_NODES: [Node] = [ ), Child( name: "GenericParameterClause", - kind: .node(kind: "GenericParameterClause"), + kind: .node(kind: .genericParameterClause), nameForDiagnostics: "generic parameter clause", description: "The generic parameters, if any, for this enum declaration.", isOptional: true ), Child( name: "InheritanceClause", - kind: .node(kind: "TypeInheritanceClause"), + kind: .node(kind: .typeInheritanceClause), nameForDiagnostics: "inheritance clause", description: "The inheritance clause describing conformances or raw values for this enum declaration.", isOptional: true ), Child( name: "GenericWhereClause", - kind: .node(kind: "GenericWhereClause"), + kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", description: "The `where` clause that applies to the generic parameters of this enum declaration.", isOptional: true ), Child( name: "MemberBlock", - kind: .node(kind: "MemberDeclBlock"), + kind: .node(kind: .memberDeclBlock), description: "The cases and other members associated with this enum declaration. Because enum extension declarations may declare additional members the contents of this member block isn't guaranteed to be a complete list of members for this type." ), ] @@ -784,9 +779,9 @@ public let DECL_NODES: [Node] = [ // '{' extension-members '}' // extension-name -> identifier Node( - name: "ExtensionDecl", + kind: .extensionDecl, + base: .decl, nameForDiagnostics: "extension", - kind: "Decl", traits: [ "DeclGroup", "WithAttributes", @@ -795,13 +790,13 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), nameForDiagnostics: "attributes", isOptional: true ), Child( name: "Modifiers", - kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"), + kind: .collection(kind: .modifierList, collectionElementName: "Modifier"), nameForDiagnostics: "modifiers", isOptional: true ), @@ -811,31 +806,31 @@ public let DECL_NODES: [Node] = [ ), Child( name: "ExtendedType", - kind: .node(kind: "Type") + kind: .node(kind: .type) ), Child( name: "InheritanceClause", - kind: .node(kind: "TypeInheritanceClause"), + kind: .node(kind: .typeInheritanceClause), nameForDiagnostics: "inheritance clause", isOptional: true ), Child( name: "GenericWhereClause", - kind: .node(kind: "GenericWhereClause"), + kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", isOptional: true ), Child( name: "MemberBlock", - kind: .node(kind: "MemberDeclBlock") + kind: .node(kind: .memberDeclBlock) ), ] ), Node( - name: "FunctionDecl", + kind: .functionDecl, + base: .decl, nameForDiagnostics: "function", - kind: "Decl", traits: [ "IdentifiedDecl", "WithAttributes", @@ -844,13 +839,13 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), nameForDiagnostics: "attributes", isOptional: true ), Child( name: "Modifiers", - kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"), + kind: .collection(kind: .modifierList, collectionElementName: "Modifier"), nameForDiagnostics: "modifiers", isOptional: true ), @@ -864,59 +859,55 @@ public let DECL_NODES: [Node] = [ ), Child( name: "GenericParameterClause", - kind: .node(kind: "GenericParameterClause"), + kind: .node(kind: .genericParameterClause), nameForDiagnostics: "generic parameter clause", isOptional: true ), Child( name: "Signature", - kind: .node(kind: "FunctionSignature"), + kind: .node(kind: .functionSignature), nameForDiagnostics: "function signature" ), Child( name: "GenericWhereClause", - kind: .node(kind: "GenericWhereClause"), + kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", isOptional: true ), Child( name: "Body", - kind: .node(kind: "CodeBlock"), + kind: .node(kind: .codeBlock), isOptional: true ), ] ), Node( - name: "FunctionParameterList", + kind: .functionParameterList, + base: .syntaxCollection, nameForDiagnostics: "parameter list", - kind: "SyntaxCollection", - element: "FunctionParameter" + elementChoices: [.functionParameter] ), // parameter -> // external-parameter-name? local-parameter-name ':' // type '...'? '='? expression? ','? Node( - name: "FunctionParameter", + kind: .functionParameter, + base: .syntax, nameForDiagnostics: "parameter", - kind: "Syntax", - traits: [ - "WithTrailingComma", - "WithAttributes", - "WithModifiers", - ], parserFunction: "parseFunctionParameter", + traits: ["WithTrailingComma", "WithAttributes", "WithModifiers"], children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), nameForDiagnostics: "attributes", isOptional: true ), Child( name: "Modifiers", - kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"), + kind: .collection(kind: .modifierList, collectionElementName: "Modifier"), nameForDiagnostics: "modifiers", isOptional: true ), @@ -938,7 +929,7 @@ public let DECL_NODES: [Node] = [ ), Child( name: "Type", - kind: .node(kind: "Type"), + kind: .node(kind: .type), nameForDiagnostics: "type" ), Child( @@ -948,7 +939,7 @@ public let DECL_NODES: [Node] = [ ), Child( name: "DefaultArgument", - kind: .node(kind: "InitializerClause"), + kind: .node(kind: .initializerClause), nameForDiagnostics: "default argument", isOptional: true ), @@ -963,40 +954,40 @@ public let DECL_NODES: [Node] = [ // function-signature -> // '(' parameter-list? ')' function-effect-specifiers? return-clause? Node( - name: "FunctionSignature", + kind: .functionSignature, + base: .syntax, nameForDiagnostics: "function signature", - kind: "Syntax", children: [ Child( name: "Input", - kind: .node(kind: "ParameterClause") + kind: .node(kind: .parameterClause) ), Child( name: "EffectSpecifiers", - kind: .node(kind: "FunctionEffectSpecifiers"), + kind: .node(kind: .functionEffectSpecifiers), isOptional: true ), Child( name: "Output", - kind: .node(kind: "ReturnClause"), + kind: .node(kind: .returnClause), isOptional: true ), ] ), Node( - name: "IfConfigClauseList", + kind: .ifConfigClauseList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "IfConfigClause" + elementChoices: [.ifConfigClause] ), // if-config-clause -> // ('#if' | '#elseif' | '#else') expr? (stmt-list | switch-case-list) Node( - name: "IfConfigClause", + kind: .ifConfigClause, + base: .syntax, nameForDiagnostics: "conditional compilation clause", - kind: "Syntax", children: [ Child( name: "PoundKeyword", @@ -1006,7 +997,7 @@ public let DECL_NODES: [Node] = [ ), Child( name: "Condition", - kind: .node(kind: "Expr"), + kind: .node(kind: .expr), nameForDiagnostics: "condition", isOptional: true, classification: "BuildConfigId" @@ -1016,23 +1007,23 @@ public let DECL_NODES: [Node] = [ kind: .nodeChoices(choices: [ Child( name: "Statements", - kind: .node(kind: "CodeBlockItemList") + kind: .node(kind: .codeBlockItemList) ), Child( name: "SwitchCases", - kind: .node(kind: "SwitchCaseList") + kind: .node(kind: .switchCaseList) ), Child( name: "Decls", - kind: .node(kind: "MemberDeclList") + kind: .node(kind: .memberDeclList) ), Child( name: "PostfixExpression", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), Child( name: "Attributes", - kind: .node(kind: "AttributeList") + kind: .node(kind: .attributeList) ), ]), isOptional: true @@ -1043,13 +1034,13 @@ public let DECL_NODES: [Node] = [ // if-config-decl -> '#if' expr stmt-list else-if-directive-clause-list // else-clause? '#endif' Node( - name: "IfConfigDecl", + kind: .ifConfigDecl, + base: .decl, nameForDiagnostics: "conditional compilation block", - kind: "Decl", children: [ Child( name: "Clauses", - kind: .collection(kind: "IfConfigClauseList", collectionElementName: "Clause") + kind: .collection(kind: .ifConfigClauseList, collectionElementName: "Clause") ), Child( name: "PoundEndif", @@ -1061,16 +1052,16 @@ public let DECL_NODES: [Node] = [ ), Node( - name: "ImportDecl", + kind: .importDecl, + base: .decl, nameForDiagnostics: "import", - description: """ + documentation: """ An import declaration like the following. ```swift import Foundation ``` """, - kind: "Decl", traits: [ "WithAttributes", "WithModifiers", @@ -1078,14 +1069,14 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), nameForDiagnostics: "attributes", description: "Attributes attached to the import declaration, for example `@testable`.", isOptional: true ), Child( name: "Modifiers", - kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"), + kind: .collection(kind: .modifierList, collectionElementName: "Modifier"), nameForDiagnostics: "modifiers", description: "Modifiers attached to the import declaration. Currently, no modifiers are supported by Swift.", isOptional: true @@ -1103,30 +1094,30 @@ public let DECL_NODES: [Node] = [ ), Child( name: "Path", - kind: .collection(kind: "ImportPath", collectionElementName: "PathComponent"), + kind: .collection(kind: .importPath, collectionElementName: "PathComponent"), description: "The path to the module, submodule or symbol being imported." ), ] ), Node( - name: "InheritedTypeList", + kind: .inheritedTypeList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "InheritedType" + elementChoices: [.inheritedType] ), Node( - name: "InheritedType", + kind: .inheritedType, + base: .syntax, nameForDiagnostics: "inherited type", - kind: "Syntax", traits: [ "WithTrailingComma" ], children: [ Child( name: "TypeName", - kind: .node(kind: "Type") + kind: .node(kind: .type) ), Child( name: "TrailingComma", @@ -1138,9 +1129,9 @@ public let DECL_NODES: [Node] = [ // initializer -> '=' expr Node( - name: "InitializerClause", + kind: .initializerClause, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", children: [ Child( name: "Equal", @@ -1148,15 +1139,16 @@ public let DECL_NODES: [Node] = [ ), Child( name: "Value", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), ] ), Node( - name: "InitializerDecl", + kind: .initializerDecl, + base: .decl, nameForDiagnostics: "initializer", - description: """ + documentation: """ An initializer declaration like the following. ```swift @@ -1166,7 +1158,6 @@ public let DECL_NODES: [Node] = [ The body is optional because this node also represents initializer requirements inside protocols. """, - kind: "Decl", traits: [ "WithAttributes", "WithModifiers", @@ -1174,14 +1165,14 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), nameForDiagnostics: "attributes", description: "Attributes that are attached to the initializer.", isOptional: true ), Child( name: "Modifiers", - kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"), + kind: .collection(kind: .modifierList, collectionElementName: "Modifier"), nameForDiagnostics: "modifiers", description: "Modifiers attached to the initializer", isOptional: true @@ -1199,27 +1190,27 @@ public let DECL_NODES: [Node] = [ ), Child( name: "GenericParameterClause", - kind: .node(kind: "GenericParameterClause"), + kind: .node(kind: .genericParameterClause), nameForDiagnostics: "generic parameter clause", description: "Generic parameters of the initializer.", isOptional: true ), Child( name: "Signature", - kind: .node(kind: "FunctionSignature"), + kind: .node(kind: .functionSignature), nameForDiagnostics: "function signature", description: "The arguments of the initializer. While the function signature allows specifying an return clause, doing so is not semantically valid." ), Child( name: "GenericWhereClause", - kind: .node(kind: "GenericWhereClause"), + kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", description: "If the initializer had generic parameters, a where clause that can restrict those", isOptional: true ), Child( name: "Body", - kind: .node(kind: "CodeBlock"), + kind: .node(kind: .codeBlock), description: "The initializer’s body. Missing if the initialier is a requirement of a protocol declaration.", isOptional: true ), @@ -1227,9 +1218,9 @@ public let DECL_NODES: [Node] = [ ), Node( - name: "MacroDecl", + kind: .macroDecl, + base: .decl, nameForDiagnostics: "macro", - kind: "Decl", traits: [ "IdentifiedDecl", "WithAttributes", @@ -1238,13 +1229,13 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), nameForDiagnostics: "attributes", isOptional: true ), Child( name: "Modifiers", - kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"), + kind: .collection(kind: .modifierList, collectionElementName: "Modifier"), nameForDiagnostics: "modifiers", isOptional: true ), @@ -1258,24 +1249,24 @@ public let DECL_NODES: [Node] = [ ), Child( name: "GenericParameterClause", - kind: .node(kind: "GenericParameterClause"), + kind: .node(kind: .genericParameterClause), nameForDiagnostics: "generic parameter clause", isOptional: true ), Child( name: "Signature", - kind: .node(kind: "FunctionSignature"), + kind: .node(kind: .functionSignature), nameForDiagnostics: "macro signature" ), Child( name: "Definition", - kind: .node(kind: "InitializerClause"), + kind: .node(kind: .initializerClause), nameForDiagnostics: "macro definition", isOptional: true ), Child( name: "GenericWhereClause", - kind: .node(kind: "GenericWhereClause"), + kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", isOptional: true ), @@ -1284,9 +1275,9 @@ public let DECL_NODES: [Node] = [ // e.g., "#embed("filename.txt")" Node( - name: "MacroExpansionDecl", + kind: .macroExpansionDecl, + base: .decl, nameForDiagnostics: "macro expansion", - kind: "Decl", traits: [ "FreestandingMacroExpansion", "WithAttributes", @@ -1295,13 +1286,13 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), nameForDiagnostics: "attributes", isOptional: true ), Child( name: "Modifiers", - kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"), + kind: .collection(kind: .modifierList, collectionElementName: "Modifier"), nameForDiagnostics: "modifiers", isOptional: true ), @@ -1316,7 +1307,7 @@ public let DECL_NODES: [Node] = [ ), Child( name: "GenericArguments", - kind: .node(kind: "GenericArgumentClause"), + kind: .node(kind: .genericArgumentClause), isOptional: true ), Child( @@ -1326,7 +1317,7 @@ public let DECL_NODES: [Node] = [ ), Child( name: "ArgumentList", - kind: .collection(kind: "TupleExprElementList", collectionElementName: "Argument") + kind: .collection(kind: .tupleExprElementList, collectionElementName: "Argument") ), Child( name: "RightParen", @@ -1335,25 +1326,23 @@ public let DECL_NODES: [Node] = [ ), Child( name: "TrailingClosure", - kind: .node(kind: "ClosureExpr"), + kind: .node(kind: .closureExpr), isOptional: true ), Child( name: "AdditionalTrailingClosures", - kind: .collection(kind: "MultipleTrailingClosureElementList", collectionElementName: "AdditionalTrailingClosure"), + kind: .collection(kind: .multipleTrailingClosureElementList, collectionElementName: "AdditionalTrailingClosure"), isOptional: true ), ] ), Node( - name: "MemberDeclBlock", + kind: .memberDeclBlock, + base: .syntax, nameForDiagnostics: "member block", - kind: "Syntax", - traits: [ - "Braced" - ], parserFunction: "parseMemberDeclList", + traits: ["Braced"], children: [ Child( name: "LeftBrace", @@ -1361,7 +1350,7 @@ public let DECL_NODES: [Node] = [ ), Child( name: "Members", - kind: .collection(kind: "MemberDeclList", collectionElementName: "Member"), + kind: .collection(kind: .memberDeclList, collectionElementName: "Member"), isIndented: true ), Child( @@ -1374,14 +1363,14 @@ public let DECL_NODES: [Node] = [ // member-decl = decl ';'? Node( - name: "MemberDeclListItem", + kind: .memberDeclListItem, + base: .syntax, nameForDiagnostics: nil, - description: "A member declaration of a type consisting of a declaration and an optional semicolon;", - kind: "Syntax", + documentation: "A member declaration of a type consisting of a declaration and an optional semicolon;", children: [ Child( name: "Decl", - kind: .node(kind: "Decl"), + kind: .node(kind: .decl), description: "The declaration of the type member." ), Child( @@ -1390,16 +1379,15 @@ public let DECL_NODES: [Node] = [ description: "An optional trailing semicolon.", isOptional: true ), - ], - omitWhenEmpty: true + ] ), // member-decl-list = member-decl member-decl-list? Node( - name: "MemberDeclList", + kind: .memberDeclList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "MemberDeclListItem" + elementChoices: [.memberDeclListItem] ), // declaration-modifier -> access-level-modifier @@ -1425,20 +1413,18 @@ public let DECL_NODES: [Node] = [ // | 'weak' // mutation-modifier -> 'mutating' | 'nonmutating' Node( - name: "ModifierList", + kind: .modifierList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "DeclModifier", - elementName: "Modifier", - omitWhenEmpty: true + elementChoices: [.declModifier] ), // operator-decl -> attribute? modifiers? 'operator' operator Node( - name: "OperatorDecl", + kind: .operatorDecl, + base: .decl, nameForDiagnostics: "operator declaration", - description: "A Swift `operator` declaration.", - kind: "Decl", + documentation: "A Swift `operator` declaration.", traits: [ "IdentifiedDecl", "WithAttributes", @@ -1447,14 +1433,14 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), nameForDiagnostics: "attributes", description: "The attributes applied to the 'operator' declaration.", isOptional: true ), Child( name: "Modifiers", - kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"), + kind: .collection(kind: .modifierList, collectionElementName: "Modifier"), nameForDiagnostics: "modifiers", description: "The declaration modifiers applied to the 'operator' declaration.", isOptional: true, @@ -1471,7 +1457,7 @@ public let DECL_NODES: [Node] = [ ), Child( name: "OperatorPrecedenceAndTypes", - kind: .node(kind: "OperatorPrecedenceAndTypes"), + kind: .node(kind: .operatorPrecedenceAndTypes), description: "Optionally specify a precedence group and designated types.", isOptional: true ), @@ -1480,10 +1466,10 @@ public let DECL_NODES: [Node] = [ // infix-operator-group -> ':' identifier designated-type-list? Node( - name: "OperatorPrecedenceAndTypes", + kind: .operatorPrecedenceAndTypes, + base: .syntax, nameForDiagnostics: nil, - description: "A clause to specify precedence group in infix operator declarations, and designated types in any operator declaration.", - kind: "Syntax", + documentation: "A clause to specify precedence group in infix operator declarations, and designated types in any operator declaration.", children: [ Child( name: "Colon", @@ -1497,16 +1483,16 @@ public let DECL_NODES: [Node] = [ ), Child( name: "DesignatedTypes", - kind: .collection(kind: "DesignatedTypeList", collectionElementName: "DesignatedTypeElement"), + kind: .collection(kind: .designatedTypeList, collectionElementName: "DesignatedTypeElement"), description: "The designated types associated with this operator." ), ] ), Node( - name: "ParameterClause", + kind: .parameterClause, + base: .syntax, nameForDiagnostics: "parameter clause", - kind: "Syntax", traits: [ "Parenthesized" ], @@ -1517,7 +1503,7 @@ public let DECL_NODES: [Node] = [ ), Child( name: "ParameterList", - kind: .collection(kind: "FunctionParameterList", collectionElementName: "Parameter"), + kind: .collection(kind: .functionParameterList, collectionElementName: "Parameter"), nameForDiagnostics: "parameters", isIndented: true ), @@ -1529,34 +1515,34 @@ public let DECL_NODES: [Node] = [ ), Node( - name: "PatternBindingList", + kind: .patternBindingList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "PatternBinding" + elementChoices: [.patternBinding] ), // Pattern: Type = Value { get {} }, Node( - name: "PatternBinding", + kind: .patternBinding, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", traits: [ "WithTrailingComma" ], children: [ Child( name: "Pattern", - kind: .node(kind: "Pattern") + kind: .node(kind: .pattern) ), Child( name: "TypeAnnotation", - kind: .node(kind: "TypeAnnotation"), + kind: .node(kind: .typeAnnotation), nameForDiagnostics: "type annotation", isOptional: true ), Child( name: "Initializer", - kind: .node(kind: "InitializerClause"), + kind: .node(kind: .initializerClause), isOptional: true ), Child( @@ -1564,11 +1550,11 @@ public let DECL_NODES: [Node] = [ kind: .nodeChoices(choices: [ Child( name: "Accessors", - kind: .node(kind: "AccessorBlock") + kind: .node(kind: .accessorBlock) ), Child( name: "Getter", - kind: .node(kind: "CodeBlock") + kind: .node(kind: .codeBlock) ), ]), isOptional: true @@ -1582,9 +1568,9 @@ public let DECL_NODES: [Node] = [ ), Node( - name: "PoundSourceLocationArgs", + kind: .poundSourceLocationArgs, + base: .syntax, nameForDiagnostics: "'#sourceLocation' arguments", - kind: "Syntax", children: [ Child( name: "FileArgLabel", @@ -1596,7 +1582,7 @@ public let DECL_NODES: [Node] = [ ), Child( name: "FileName", - kind: .node(kind: "StringLiteralExpr"), + kind: .node(kind: .stringLiteralExpr), nameForDiagnostics: "file name" ), Child( @@ -1620,9 +1606,9 @@ public let DECL_NODES: [Node] = [ ), Node( - name: "PoundSourceLocation", + kind: .poundSourceLocation, + base: .decl, nameForDiagnostics: "'#sourceLocation' directive", - kind: "Decl", traits: [ "Parenthesized" ], @@ -1637,7 +1623,7 @@ public let DECL_NODES: [Node] = [ ), Child( name: "Args", - kind: .node(kind: "PoundSourceLocationArgs"), + kind: .node(kind: .poundSourceLocationArgs), nameForDiagnostics: "arguments", isOptional: true ), @@ -1651,10 +1637,10 @@ public let DECL_NODES: [Node] = [ // precedence-group-assignment -> // 'assignment' ':' ('true' | 'false') Node( - name: "PrecedenceGroupAssignment", + kind: .precedenceGroupAssignment, + base: .syntax, nameForDiagnostics: "'assignment' property of precedencegroup", - description: "Specifies the precedence of an operator when used in an operation that includes optional chaining.", - kind: "Syntax", + documentation: "Specifies the precedence of an operator when used in an operation that includes optional chaining.", children: [ Child( name: "AssignmentKeyword", @@ -1675,10 +1661,10 @@ public let DECL_NODES: [Node] = [ // precedence-group-associativity -> // 'associativity' ':' ('left' | 'right' | 'none') Node( - name: "PrecedenceGroupAssociativity", + kind: .precedenceGroupAssociativity, + base: .syntax, nameForDiagnostics: "'associativity' property of precedencegroup", - description: "Specifies how a sequence of operators with the same precedence level are grouped together in the absence of grouping parentheses.", - kind: "Syntax", + documentation: "Specifies how a sequence of operators with the same precedence level are grouped together in the absence of grouping parentheses.", children: [ Child( name: "AssociativityKeyword", @@ -1700,22 +1686,20 @@ public let DECL_NODES: [Node] = [ // (precedence-group-relation | precedence-group-assignment | // precedence-group-associativity )* Node( - name: "PrecedenceGroupAttributeList", + kind: .precedenceGroupAttributeList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "Syntax", - elementName: "PrecedenceGroupAttribute", - elementChoices: ["PrecedenceGroupRelation", "PrecedenceGroupAssignment", "PrecedenceGroupAssociativity"] + elementChoices: [.precedenceGroupRelation, .precedenceGroupAssignment, .precedenceGroupAssociativity] ), // precedence-group-decl -> attributes? modifiers? 'precedencegroup' // identifier '{' precedence-group-attribute-list // '}' Node( - name: "PrecedenceGroupDecl", + kind: .precedenceGroupDecl, + base: .decl, nameForDiagnostics: "precedencegroup", - description: "A Swift `precedencegroup` declaration.", - kind: "Decl", + documentation: "A Swift `precedencegroup` declaration.", traits: [ "IdentifiedDecl", "WithAttributes", @@ -1724,14 +1708,14 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), nameForDiagnostics: "attributes", description: "The attributes applied to the 'precedencegroup' declaration.", isOptional: true ), Child( name: "Modifiers", - kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"), + kind: .collection(kind: .modifierList, collectionElementName: "Modifier"), nameForDiagnostics: "modifiers", description: "The declaration modifiers applied to the 'precedencegroup' declaration.", isOptional: true @@ -1751,7 +1735,7 @@ public let DECL_NODES: [Node] = [ ), Child( name: "GroupAttributes", - kind: .collection(kind: "PrecedenceGroupAttributeList", collectionElementName: "GroupAttribute"), + kind: .collection(kind: .precedenceGroupAttributeList, collectionElementName: "GroupAttribute"), description: "The characteristics of this precedence group." ), Child( @@ -1762,9 +1746,9 @@ public let DECL_NODES: [Node] = [ ), Node( - name: "PrecedenceGroupNameElement", + kind: .precedenceGroupNameElement, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", children: [ Child( name: "Name", @@ -1782,19 +1766,19 @@ public let DECL_NODES: [Node] = [ // precedence-group-name-list -> // identifier (',' identifier)* Node( - name: "PrecedenceGroupNameList", + kind: .precedenceGroupNameList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "PrecedenceGroupNameElement" + elementChoices: [.precedenceGroupNameElement] ), // precedence-group-relation -> // ('higherThan' | 'lowerThan') ':' precedence-group-name-list Node( - name: "PrecedenceGroupRelation", + kind: .precedenceGroupRelation, + base: .syntax, nameForDiagnostics: "'relation' property of precedencegroup", - description: "Specify the new precedence group's relation to existing precedence groups.", - kind: "Syntax", + documentation: "Specify the new precedence group's relation to existing precedence groups.", children: [ Child( name: "HigherThanOrLowerThan", @@ -1808,16 +1792,17 @@ public let DECL_NODES: [Node] = [ ), Child( name: "OtherNames", - kind: .collection(kind: "PrecedenceGroupNameList", collectionElementName: "OtherName"), + kind: .collection(kind: .precedenceGroupNameList, collectionElementName: "OtherName"), description: "The name of other precedence group to which this precedence group relates." ), ] ), Node( - name: "ProtocolDecl", + kind: .protocolDecl, + base: .decl, nameForDiagnostics: "protocol", - description: """ + documentation: """ A protocol declaration like the following. ```swift @@ -1826,7 +1811,6 @@ public let DECL_NODES: [Node] = [ } ``` """, - kind: "Decl", traits: [ "DeclGroup", "IdentifiedDecl", @@ -1836,14 +1820,14 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), nameForDiagnostics: "attributes", description: "Attributes attached to the protocol declaration, such as an `@available` attribute.", isOptional: true ), Child( name: "Modifiers", - kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"), + kind: .collection(kind: .modifierList, collectionElementName: "Modifier"), nameForDiagnostics: "modifiers", description: "Modifiers attached to the protocol declaration, such as `public`.", isOptional: true @@ -1860,28 +1844,28 @@ public let DECL_NODES: [Node] = [ ), Child( name: "PrimaryAssociatedTypeClause", - kind: .node(kind: "PrimaryAssociatedTypeClause"), + kind: .node(kind: .primaryAssociatedTypeClause), nameForDiagnostics: "primary associated type clause", description: "The primary associated type for the protocol.", isOptional: true ), Child( name: "InheritanceClause", - kind: .node(kind: "TypeInheritanceClause"), + kind: .node(kind: .typeInheritanceClause), nameForDiagnostics: "inheritance clause", description: "The inheritance clause describing one or more conformances for this protocol declaration.", isOptional: true ), Child( name: "GenericWhereClause", - kind: .node(kind: "GenericWhereClause"), + kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", description: "The `where` clause that applies to the generic parameters of this protocol declaration.", isOptional: true ), Child( name: "MemberBlock", - kind: .node(kind: "MemberDeclBlock"), + kind: .node(kind: .memberDeclBlock), description: "The members of the protocol declaration." ), ] @@ -1890,9 +1874,9 @@ public let DECL_NODES: [Node] = [ // return-clause -> // '->' type Node( - name: "ReturnClause", + kind: .returnClause, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", children: [ Child( name: "Arrow", @@ -1900,7 +1884,7 @@ public let DECL_NODES: [Node] = [ ), Child( name: "ReturnType", - kind: .node(kind: "Type"), + kind: .node(kind: .type), nameForDiagnostics: "return type" ), ] @@ -1908,21 +1892,19 @@ public let DECL_NODES: [Node] = [ // source-file = code-block-item-list eof Node( - name: "SourceFile", + kind: .sourceFile, + base: .syntax, nameForDiagnostics: "source file", - kind: "Syntax", - traits: [ - "WithStatements" - ], parserFunction: "parseSourceFile", + traits: ["WithStatements"], children: [ Child( name: "Statements", - kind: .collection(kind: "CodeBlockItemList", collectionElementName: "Statement") + kind: .collection(kind: .codeBlockItemList, collectionElementName: "Statement") ), Child( name: "EOFToken", - kind: .node(kind: "EOFToken") + kind: .token(choices: [.token(tokenKind: "EOFToken")]) ), ] ), @@ -1935,9 +1917,10 @@ public let DECL_NODES: [Node] = [ // '{' struct-members '}' // struct-name -> identifier Node( - name: "StructDecl", + kind: .structDecl, + base: .decl, nameForDiagnostics: "struct", - description: """ + documentation: """ A struct declaration like the following. ```swift @@ -1994,7 +1977,6 @@ public let DECL_NODES: [Node] = [ } ``` """, - kind: "Decl", traits: [ "DeclGroup", "IdentifiedDecl", @@ -2004,14 +1986,14 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), nameForDiagnostics: "attributes", description: "Attributes that are attached to the struct declaration.", isOptional: true ), Child( name: "Modifiers", - kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"), + kind: .collection(kind: .modifierList, collectionElementName: "Modifier"), nameForDiagnostics: "modifiers", description: "Modifiers that are attached to the struct declaration.", isOptional: true @@ -2028,37 +2010,37 @@ public let DECL_NODES: [Node] = [ ), Child( name: "GenericParameterClause", - kind: .node(kind: "GenericParameterClause"), + kind: .node(kind: .genericParameterClause), nameForDiagnostics: "generic parameter clause", description: "The generic parameters, if any, of the struct declaration.", isOptional: true ), Child( name: "InheritanceClause", - kind: .node(kind: "TypeInheritanceClause"), + kind: .node(kind: .typeInheritanceClause), nameForDiagnostics: "type inheritance clause", description: "The struct declaration inheritance clause describing one or more conformances for this struct declaration.", isOptional: true ), Child( name: "GenericWhereClause", - kind: .node(kind: "GenericWhereClause"), + kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", description: "The `where` clause that applies to the generic parameters of this struct declaration.", isOptional: true ), Child( name: "MemberBlock", - kind: .node(kind: "MemberDeclBlock"), + kind: .node(kind: .memberDeclBlock), description: "The members of the struct declaration. Because struct extension declarations may declare additional members the contents of this member block isn't guaranteed to be a complete list of members for this type." ), ] ), Node( - name: "SubscriptDecl", + kind: .subscriptDecl, + base: .decl, nameForDiagnostics: "subscript", - kind: "Decl", traits: [ "WithAttributes", "WithModifiers", @@ -2066,13 +2048,13 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), nameForDiagnostics: "attributes", isOptional: true ), Child( name: "Modifiers", - kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"), + kind: .collection(kind: .modifierList, collectionElementName: "Modifier"), nameForDiagnostics: "modifiers", isOptional: true ), @@ -2082,21 +2064,21 @@ public let DECL_NODES: [Node] = [ ), Child( name: "GenericParameterClause", - kind: .node(kind: "GenericParameterClause"), + kind: .node(kind: .genericParameterClause), nameForDiagnostics: "generic parameter clause", isOptional: true ), Child( name: "Indices", - kind: .node(kind: "ParameterClause") + kind: .node(kind: .parameterClause) ), Child( name: "Result", - kind: .node(kind: "ReturnClause") + kind: .node(kind: .returnClause) ), Child( name: "GenericWhereClause", - kind: .node(kind: "GenericWhereClause"), + kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", isOptional: true ), @@ -2105,11 +2087,11 @@ public let DECL_NODES: [Node] = [ kind: .nodeChoices(choices: [ Child( name: "Accessors", - kind: .node(kind: "AccessorBlock") + kind: .node(kind: .accessorBlock) ), Child( name: "Getter", - kind: .node(kind: "CodeBlock") + kind: .node(kind: .codeBlock) ), ]), isOptional: true @@ -2119,9 +2101,9 @@ public let DECL_NODES: [Node] = [ // type-inheritance-clause -> ':' type Node( - name: "TypeInheritanceClause", + kind: .typeInheritanceClause, + base: .syntax, nameForDiagnostics: "inheritance clause", - kind: "Syntax", children: [ Child( name: "Colon", @@ -2129,16 +2111,16 @@ public let DECL_NODES: [Node] = [ ), Child( name: "InheritedTypeCollection", - kind: .collection(kind: "InheritedTypeList", collectionElementName: "InheritedType") + kind: .collection(kind: .inheritedTypeList, collectionElementName: "InheritedType") ), ] ), // type-assignment -> '=' type Node( - name: "TypeInitializerClause", + kind: .typeInitializerClause, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", children: [ Child( name: "Equal", @@ -2146,7 +2128,7 @@ public let DECL_NODES: [Node] = [ ), Child( name: "Value", - kind: .node(kind: "Type"), + kind: .node(kind: .type), nameForDiagnostics: "type" ), ] @@ -2157,9 +2139,9 @@ public let DECL_NODES: [Node] = [ // type-assignment // typealias-name -> identifier Node( - name: "TypealiasDecl", + kind: .typealiasDecl, + base: .decl, nameForDiagnostics: "typealias declaration", - kind: "Decl", traits: [ "IdentifiedDecl", "WithAttributes", @@ -2167,13 +2149,13 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), nameForDiagnostics: "attributes", isOptional: true ), Child( name: "Modifiers", - kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"), + kind: .collection(kind: .modifierList, collectionElementName: "Modifier"), nameForDiagnostics: "modifiers", isOptional: true ), @@ -2187,17 +2169,17 @@ public let DECL_NODES: [Node] = [ ), Child( name: "GenericParameterClause", - kind: .node(kind: "GenericParameterClause"), + kind: .node(kind: .genericParameterClause), nameForDiagnostics: "generic parameter clause", isOptional: true ), Child( name: "Initializer", - kind: .node(kind: "TypeInitializerClause") + kind: .node(kind: .typeInitializerClause) ), Child( name: "GenericWhereClause", - kind: .node(kind: "GenericWhereClause"), + kind: .node(kind: .genericWhereClause), nameForDiagnostics: "generic where clause", isOptional: true ), @@ -2205,9 +2187,9 @@ public let DECL_NODES: [Node] = [ ), Node( - name: "VariableDecl", + kind: .variableDecl, + base: .decl, nameForDiagnostics: "variable", - kind: "Decl", traits: [ "WithAttributes", "WithModifiers", @@ -2215,13 +2197,13 @@ public let DECL_NODES: [Node] = [ children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), nameForDiagnostics: "attributes", isOptional: true ), Child( name: "Modifiers", - kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"), + kind: .collection(kind: .modifierList, collectionElementName: "Modifier"), nameForDiagnostics: "modifiers", isOptional: true ), @@ -2231,7 +2213,7 @@ public let DECL_NODES: [Node] = [ ), Child( name: "Bindings", - kind: .collection(kind: "PatternBindingList", collectionElementName: "Binding") + kind: .collection(kind: .patternBindingList, collectionElementName: "Binding") ), ] ), diff --git a/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift b/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift index 496d15636a0..2b713d3bc6a 100644 --- a/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift @@ -12,24 +12,24 @@ public let EXPR_NODES: [Node] = [ Node( - name: "ArrayElementList", + kind: .arrayElementList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "ArrayElement" + elementChoices: [.arrayElement] ), // element inside an array expression: expression ','? Node( - name: "ArrayElement", + kind: .arrayElement, + base: .syntax, nameForDiagnostics: "array element", - kind: "Syntax", traits: [ "WithTrailingComma" ], children: [ Child( name: "Expression", - kind: .node(kind: "Expr"), + kind: .node(kind: .expr), nameForDiagnostics: "value" ), Child( @@ -42,9 +42,9 @@ public let EXPR_NODES: [Node] = [ // Array literal, e.g. [1, 2, 3] Node( - name: "ArrayExpr", + kind: .arrayExpr, + base: .expr, nameForDiagnostics: "array", - kind: "Expr", children: [ Child( name: "LeftSquare", @@ -52,7 +52,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "Elements", - kind: .collection(kind: "ArrayElementList", collectionElementName: "Element"), + kind: .collection(kind: .arrayElementList, collectionElementName: "Element"), isIndented: true ), Child( @@ -65,13 +65,13 @@ public let EXPR_NODES: [Node] = [ // arrow-expr -> 'async'? 'throws'? '->' // NOTE: This appears only in SequenceExpr. Node( - name: "ArrowExpr", + kind: .arrowExpr, + base: .expr, nameForDiagnostics: nil, - kind: "Expr", children: [ Child( name: "EffectSpecifiers", - kind: .node(kind: "TypeEffectSpecifiers"), + kind: .node(kind: .typeEffectSpecifiers), isOptional: true ), Child( @@ -86,13 +86,13 @@ public let EXPR_NODES: [Node] = [ // result of "folding" a SequenceExpr based on knowing the precedence // relationships amongst the different infix operators. Node( - name: "AsExpr", + kind: .asExpr, + base: .expr, nameForDiagnostics: "'as'", - kind: "Expr", children: [ Child( name: "Expression", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), Child( name: "AsTok", @@ -105,16 +105,16 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "TypeName", - kind: .node(kind: "Type") + kind: .node(kind: .type) ), ] ), // An = expression. Node( - name: "AssignmentExpr", + kind: .assignmentExpr, + base: .expr, nameForDiagnostics: nil, - kind: "Expr", children: [ Child( name: "AssignToken", @@ -126,9 +126,9 @@ public let EXPR_NODES: [Node] = [ // The await operator. // await foo() Node( - name: "AwaitExpr", + kind: .awaitExpr, + base: .expr, nameForDiagnostics: "'await' expression", - kind: "Expr", children: [ Child( name: "AwaitKeyword", @@ -136,7 +136,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "Expression", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), ] ), @@ -144,9 +144,9 @@ public let EXPR_NODES: [Node] = [ // An operator like + or -. // NOTE: This appears only in SequenceExpr. Node( - name: "BinaryOperatorExpr", + kind: .binaryOperatorExpr, + base: .expr, nameForDiagnostics: "operator", - kind: "Expr", children: [ Child( name: "OperatorToken", @@ -157,9 +157,9 @@ public let EXPR_NODES: [Node] = [ // true or false Node( - name: "BooleanLiteralExpr", + kind: .booleanLiteralExpr, + base: .expr, nameForDiagnostics: "bool literal", - kind: "Expr", children: [ Child( name: "BooleanLiteral", @@ -170,9 +170,9 @@ public let EXPR_NODES: [Node] = [ // The borrow expr Node( - name: "BorrowExpr", + kind: .borrowExpr, + base: .expr, nameForDiagnostics: "'_borrow' expression", - kind: "Expr", children: [ Child( name: "BorrowKeyword", @@ -180,16 +180,16 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "Expression", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), ] ), // the canImport expr in if config expression Node( - name: "CanImportExpr", + kind: .canImportExpr, + base: .expr, nameForDiagnostics: "'canImport' expression", - kind: "Expr", children: [ Child( name: "CanImportKeyword", @@ -205,7 +205,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "VersionInfo", - kind: .node(kind: "CanImportVersionInfo"), + kind: .node(kind: .canImportVersionInfo), isOptional: true ), Child( @@ -216,9 +216,9 @@ public let EXPR_NODES: [Node] = [ ), Node( - name: "CanImportVersionInfo", + kind: .canImportVersionInfo, + base: .expr, nameForDiagnostics: nil, - kind: "Expr", children: [ Child( name: "Comma", @@ -234,27 +234,27 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "VersionTuple", - kind: .node(kind: "VersionTuple") + kind: .node(kind: .versionTuple) ), ] ), // case-item -> pattern where-clause? ','? Node( - name: "CaseItem", + kind: .caseItem, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", traits: [ "WithTrailingComma" ], children: [ Child( name: "Pattern", - kind: .node(kind: "Pattern") + kind: .node(kind: .pattern) ), Child( name: "WhereClause", - kind: .node(kind: "WhereClause"), + kind: .node(kind: .whereClause), isOptional: true ), Child( @@ -266,16 +266,16 @@ public let EXPR_NODES: [Node] = [ ), Node( - name: "ClosureCaptureItemList", + kind: .closureCaptureItemList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "ClosureCaptureItem" + elementChoices: [.closureCaptureItem] ), Node( - name: "ClosureCaptureItemSpecifier", + kind: .closureCaptureItemSpecifier, + base: .syntax, nameForDiagnostics: "closure capture specifier", - kind: "Syntax", children: [ Child( name: "Specifier", @@ -300,16 +300,16 @@ public let EXPR_NODES: [Node] = [ ), Node( - name: "ClosureCaptureItem", + kind: .closureCaptureItem, + base: .syntax, nameForDiagnostics: "closure capture item", - kind: "Syntax", traits: [ "WithTrailingComma" ], children: [ Child( name: "Specifier", - kind: .node(kind: "ClosureCaptureItemSpecifier"), + kind: .node(kind: .closureCaptureItemSpecifier), isOptional: true ), Child( @@ -324,7 +324,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "Expression", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), Child( name: "TrailingComma", @@ -335,9 +335,9 @@ public let EXPR_NODES: [Node] = [ ), Node( - name: "ClosureCaptureSignature", + kind: .closureCaptureSignature, + base: .syntax, nameForDiagnostics: "closure capture signature", - kind: "Syntax", children: [ Child( name: "LeftSquare", @@ -345,7 +345,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "Items", - kind: .collection(kind: "ClosureCaptureItemList", collectionElementName: "Item"), + kind: .collection(kind: .closureCaptureItemList, collectionElementName: "Item"), isOptional: true ), Child( @@ -356,25 +356,21 @@ public let EXPR_NODES: [Node] = [ ), Node( - name: "ClosureParameter", + kind: .closureParameter, + base: .syntax, nameForDiagnostics: "parameter", - kind: "Syntax", - traits: [ - "WithTrailingComma", - "WithAttributes", - "WithModifiers", - ], parserFunction: "parseClosureParameter", + traits: ["WithTrailingComma", "WithAttributes", "WithModifiers"], children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), nameForDiagnostics: "attributes", isOptional: true ), Child( name: "Modifiers", - kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"), + kind: .collection(kind: .modifierList, collectionElementName: "Modifier"), nameForDiagnostics: "modifiers", isOptional: true ), @@ -397,7 +393,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "Type", - kind: .node(kind: "Type"), + kind: .node(kind: .type), nameForDiagnostics: "type", description: "The type of the parameter.", isOptional: true @@ -418,16 +414,16 @@ public let EXPR_NODES: [Node] = [ ), Node( - name: "ClosureParameterList", + kind: .closureParameterList, + base: .syntaxCollection, nameForDiagnostics: "parameter list", - kind: "SyntaxCollection", - element: "ClosureParameter" + elementChoices: [.closureParameter] ), Node( - name: "ClosureParameterClause", + kind: .closureParameterClause, + base: .syntax, nameForDiagnostics: "parameter clause", - kind: "Syntax", traits: [ "Parenthesized" ], @@ -439,7 +435,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "ParameterList", - kind: .collection(kind: "ClosureParameterList", collectionElementName: "Parameter"), + kind: .collection(kind: .closureParameterList, collectionElementName: "Parameter"), nameForDiagnostics: "parameters", description: "The actual parameters.", isIndented: true @@ -453,9 +449,9 @@ public let EXPR_NODES: [Node] = [ ), Node( - name: "ClosureExpr", + kind: .closureExpr, + base: .expr, nameForDiagnostics: "closure", - kind: "Expr", traits: [ "Braced", "WithStatements", @@ -467,12 +463,12 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "Signature", - kind: .node(kind: "ClosureSignature"), + kind: .node(kind: .closureSignature), isOptional: true ), Child( name: "Statements", - kind: .collection(kind: "CodeBlockItemList", collectionElementName: "Statement"), + kind: .collection(kind: .codeBlockItemList, collectionElementName: "Statement"), isIndented: true ), Child( @@ -485,16 +481,16 @@ public let EXPR_NODES: [Node] = [ // a, b, c Node( - name: "ClosureParamList", + kind: .closureParamList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "ClosureParam" + elementChoices: [.closureParam] ), Node( - name: "ClosureParam", + kind: .closureParam, + base: .syntax, nameForDiagnostics: "closure parameter", - kind: "Syntax", traits: [ "WithTrailingComma" ], @@ -513,22 +509,22 @@ public let EXPR_NODES: [Node] = [ ), Node( - name: "ClosureSignature", + kind: .closureSignature, + base: .syntax, nameForDiagnostics: "closure signature", - kind: "Syntax", traits: [ "WithAttributes" ], children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), nameForDiagnostics: "attributes", isOptional: true ), Child( name: "Capture", - kind: .node(kind: "ClosureCaptureSignature"), + kind: .node(kind: .closureCaptureSignature), isOptional: true ), Child( @@ -536,23 +532,23 @@ public let EXPR_NODES: [Node] = [ kind: .nodeChoices(choices: [ Child( name: "SimpleInput", - kind: .node(kind: "ClosureParamList") + kind: .node(kind: .closureParamList) ), Child( name: "Input", - kind: .node(kind: "ClosureParameterClause") + kind: .node(kind: .closureParameterClause) ), ]), isOptional: true ), Child( name: "EffectSpecifiers", - kind: .node(kind: "TypeEffectSpecifiers"), + kind: .node(kind: .typeEffectSpecifiers), isOptional: true ), Child( name: "Output", - kind: .node(kind: "ReturnClause"), + kind: .node(kind: .returnClause), isOptional: true ), Child( @@ -563,23 +559,23 @@ public let EXPR_NODES: [Node] = [ ), Node( - name: "DeclNameArgumentList", + kind: .declNameArgumentList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "DeclNameArgument" + elementChoices: [.declNameArgument] ), // declname-arguments -> '(' declname-argument-list ')' // declname-argument-list -> declname-argument* // declname-argument -> identifier ':' Node( - name: "DeclNameArgument", + kind: .declNameArgument, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", children: [ Child( name: "Name", - kind: .node(kind: "Token") + kind: .node(kind: .token) ), Child( name: "Colon", @@ -589,9 +585,9 @@ public let EXPR_NODES: [Node] = [ ), Node( - name: "DeclNameArguments", + kind: .declNameArguments, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", traits: [ "Parenthesized" ], @@ -602,7 +598,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "Arguments", - kind: .collection(kind: "DeclNameArgumentList", collectionElementName: "Argument") + kind: .collection(kind: .declNameArgumentList, collectionElementName: "Argument") ), Child( name: "RightParen", @@ -612,24 +608,24 @@ public let EXPR_NODES: [Node] = [ ), Node( - name: "DictionaryElementList", + kind: .dictionaryElementList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "DictionaryElement" + elementChoices: [.dictionaryElement] ), // element inside an array expression: expression ','? Node( - name: "DictionaryElement", + kind: .dictionaryElement, + base: .syntax, nameForDiagnostics: "dictionary element", - kind: "Syntax", traits: [ "WithTrailingComma" ], children: [ Child( name: "KeyExpression", - kind: .node(kind: "Expr"), + kind: .node(kind: .expr), nameForDiagnostics: "key" ), Child( @@ -638,7 +634,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "ValueExpression", - kind: .node(kind: "Expr"), + kind: .node(kind: .expr), nameForDiagnostics: "value", isIndented: true ), @@ -652,9 +648,9 @@ public let EXPR_NODES: [Node] = [ // Dictionary literal, e.g. [1:1, 2:2, 3:3] Node( - name: "DictionaryExpr", + kind: .dictionaryExpr, + base: .expr, nameForDiagnostics: "dictionary", - kind: "Expr", children: [ Child( name: "LeftSquare", @@ -669,7 +665,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "Elements", - kind: .node(kind: "DictionaryElementList") + kind: .node(kind: .dictionaryElementList) ), ]), isIndented: true @@ -683,9 +679,9 @@ public let EXPR_NODES: [Node] = [ // A _ expression. Node( - name: "DiscardAssignmentExpr", + kind: .discardAssignmentExpr, + base: .expr, nameForDiagnostics: nil, - kind: "Expr", children: [ Child( name: "Wildcard", @@ -696,9 +692,9 @@ public let EXPR_NODES: [Node] = [ // <#content#> Node( - name: "EditorPlaceholderExpr", + kind: .editorPlaceholderExpr, + base: .expr, nameForDiagnostics: "editor placeholder", - kind: "Expr", children: [ Child( name: "Identifier", @@ -708,19 +704,18 @@ public let EXPR_NODES: [Node] = [ ), Node( - name: "ExprList", + kind: .exprList, + base: .syntaxCollection, nameForDiagnostics: nil, - description: "A list of expressions connected by operators. This list is contained by a `SequenceExprSyntax`.", - kind: "SyntaxCollection", - element: "Expr", - elementName: "Expression" + documentation: "A list of expressions connected by operators. This list is contained by a `SequenceExprSyntax`.", + elementChoices: [.expr] ), // expression segment in a string interpolation expression. Node( - name: "ExpressionSegment", + kind: .expressionSegment, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", traits: [ "Parenthesized" ], @@ -742,7 +737,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "Expressions", - kind: .collection(kind: "TupleExprElementList", collectionElementName: "Expression") + kind: .collection(kind: .tupleExprElementList, collectionElementName: "Expression") ), Child( name: "RightParen", @@ -758,9 +753,9 @@ public let EXPR_NODES: [Node] = [ // -3.9 // +4e20 Node( - name: "FloatLiteralExpr", + kind: .floatLiteralExpr, + base: .expr, nameForDiagnostics: "floating literal", - kind: "Expr", children: [ Child( name: "FloatingDigits", @@ -771,13 +766,13 @@ public let EXPR_NODES: [Node] = [ // forced-value-expr -> expr '!' Node( - name: "ForcedValueExpr", + kind: .forcedValueExpr, + base: .expr, nameForDiagnostics: "force unwrap", - kind: "Expr", children: [ Child( name: "Expression", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), Child( name: "ExclamationMark", @@ -789,13 +784,13 @@ public let EXPR_NODES: [Node] = [ // call-expr -> expr '(' call-argument-list ')' closure-expr? // | expr closure-expr Node( - name: "FunctionCallExpr", + kind: .functionCallExpr, + base: .expr, nameForDiagnostics: "function call", - kind: "Expr", children: [ Child( name: "CalledExpression", - kind: .node(kind: "Expr"), + kind: .node(kind: .expr), nameForDiagnostics: "called expression" ), Child( @@ -805,7 +800,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "ArgumentList", - kind: .collection(kind: "TupleExprElementList", collectionElementName: "Argument"), + kind: .collection(kind: .tupleExprElementList, collectionElementName: "Argument"), nameForDiagnostics: "arguments", isIndented: true ), @@ -816,13 +811,13 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "TrailingClosure", - kind: .node(kind: "ClosureExpr"), + kind: .node(kind: .closureExpr), nameForDiagnostics: "trailing closure", isOptional: true ), Child( name: "AdditionalTrailingClosures", - kind: .collection(kind: "MultipleTrailingClosureElementList", collectionElementName: "AdditionalTrailingClosure"), + kind: .collection(kind: .multipleTrailingClosureElementList, collectionElementName: "AdditionalTrailingClosure"), nameForDiagnostics: "trailing closures", isOptional: true ), @@ -831,9 +826,9 @@ public let EXPR_NODES: [Node] = [ // An identifier expression. Node( - name: "IdentifierExpr", + kind: .identifierExpr, + base: .expr, nameForDiagnostics: nil, - kind: "Expr", children: [ Child( name: "Identifier", @@ -841,7 +836,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "DeclNameArguments", - kind: .node(kind: "DeclNameArguments"), + kind: .node(kind: .declNameArguments), isOptional: true ), ] @@ -853,9 +848,9 @@ public let EXPR_NODES: [Node] = [ // This node represents both an 'if' expression, as well as an 'if' statement // when wrapped in a ExpressionStmt node. Node( - name: "IfExpr", + kind: .ifExpr, + base: .expr, nameForDiagnostics: "'if' statement", - kind: "Expr", traits: [ "WithCodeBlock" ], @@ -866,16 +861,16 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "Conditions", - kind: .collection(kind: "ConditionElementList", collectionElementName: "Condition") + kind: .collection(kind: .conditionElementList, collectionElementName: "Condition") ), Child( name: "Body", - kind: .node(kind: "CodeBlock"), + kind: .node(kind: .codeBlock), nameForDiagnostics: "body" ), Child( name: "ElseKeyword", - kind: .node(kind: "ElseToken"), + kind: .token(choices: [.keyword(text: "else")]), isOptional: true ), Child( @@ -883,11 +878,11 @@ public let EXPR_NODES: [Node] = [ kind: .nodeChoices(choices: [ Child( name: "IfExpr", - kind: .node(kind: "IfExpr") + kind: .node(kind: .ifExpr) ), Child( name: "CodeBlock", - kind: .node(kind: "CodeBlock") + kind: .node(kind: .codeBlock) ), ]), nameForDiagnostics: "else body", @@ -899,9 +894,9 @@ public let EXPR_NODES: [Node] = [ // An inout expression. // &x Node( - name: "InOutExpr", + kind: .inOutExpr, + base: .expr, nameForDiagnostics: "inout expression", - kind: "Expr", children: [ Child( name: "Ampersand", @@ -909,7 +904,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "Expression", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), ] ), @@ -919,21 +914,21 @@ public let EXPR_NODES: [Node] = [ // result of "folding" a SequenceExpr based on knowing the precedence // relationships amongst the different infix operators. Node( - name: "InfixOperatorExpr", + kind: .infixOperatorExpr, + base: .expr, nameForDiagnostics: nil, - kind: "Expr", children: [ Child( name: "LeftOperand", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), Child( name: "OperatorOperand", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), Child( name: "RightOperand", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), ] ), @@ -943,9 +938,9 @@ public let EXPR_NODES: [Node] = [ // +3_400 // +0x4f Node( - name: "IntegerLiteralExpr", + kind: .integerLiteralExpr, + base: .expr, nameForDiagnostics: "integer literal", - kind: "Expr", children: [ Child( name: "Digits", @@ -959,9 +954,10 @@ public let EXPR_NODES: [Node] = [ // result of "folding" a SequenceExpr based on knowing the precedence // relationships amongst the different infix operators. Node( - name: "IsExpr", + kind: .isExpr, + base: .expr, nameForDiagnostics: "'is'", - description: """ + documentation: """ An `is` expression like the following. ```swift @@ -970,11 +966,10 @@ public let EXPR_NODES: [Node] = [ This node is only generated after operators are folded using the `SwiftOperators` library. Beforehand, the parser does not know the precedences of operators and thus represents `is` by an `UnresolvedIsExpr`. """, - kind: "Expr", children: [ Child( name: "Expression", - kind: .node(kind: "Expr"), + kind: .node(kind: .expr), description: "The expression which will be checked to determine whether it can be cast to a specific type." ), Child( @@ -984,7 +979,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "TypeName", - kind: .node(kind: "Type"), + kind: .node(kind: .type), description: "The type against which the expression will be checked to see if the expression can be cast to it." ), ] @@ -992,17 +987,17 @@ public let EXPR_NODES: [Node] = [ // The components of a key path Node( - name: "KeyPathComponentList", + kind: .keyPathComponentList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "KeyPathComponent" + elementChoices: [.keyPathComponent] ), // A single key path component. Node( - name: "KeyPathComponent", + kind: .keyPathComponent, + base: .syntax, nameForDiagnostics: "key path component", - kind: "Syntax", children: [ Child( name: "Period", @@ -1014,15 +1009,15 @@ public let EXPR_NODES: [Node] = [ kind: .nodeChoices(choices: [ Child( name: "Property", - kind: .node(kind: "KeyPathPropertyComponent") + kind: .node(kind: .keyPathPropertyComponent) ), Child( name: "Subscript", - kind: .node(kind: "KeyPathSubscriptComponent") + kind: .node(kind: .keyPathSubscriptComponent) ), Child( name: "Optional", - kind: .node(kind: "KeyPathOptionalComponent") + kind: .node(kind: .keyPathOptionalComponent) ), ]) ), @@ -1031,9 +1026,9 @@ public let EXPR_NODES: [Node] = [ // e.g. "\a.b[2].a" Node( - name: "KeyPathExpr", + kind: .keyPathExpr, + base: .expr, nameForDiagnostics: "key path", - kind: "Expr", children: [ Child( name: "Backslash", @@ -1041,22 +1036,22 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "Root", - kind: .node(kind: "Type"), + kind: .node(kind: .type), nameForDiagnostics: "root", isOptional: true ), Child( name: "Components", - kind: .collection(kind: "KeyPathComponentList", collectionElementName: "KeyPathComponent") + kind: .collection(kind: .keyPathComponentList, collectionElementName: "KeyPathComponent") ), ] ), // A key path component like '?' or '!'. Node( - name: "KeyPathOptionalComponent", + kind: .keyPathOptionalComponent, + base: .syntax, nameForDiagnostics: "key path optional component", - kind: "Syntax", children: [ Child( name: "QuestionOrExclamationMark", @@ -1067,9 +1062,9 @@ public let EXPR_NODES: [Node] = [ // A key path component like .property or .1. Node( - name: "KeyPathPropertyComponent", + kind: .keyPathPropertyComponent, + base: .syntax, nameForDiagnostics: "key path property component", - kind: "Syntax", children: [ Child( name: "Identifier", @@ -1077,12 +1072,12 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "DeclNameArguments", - kind: .node(kind: "DeclNameArguments"), + kind: .node(kind: .declNameArguments), isOptional: true ), Child( name: "GenericArgumentClause", - kind: .node(kind: "GenericArgumentClause"), + kind: .node(kind: .genericArgumentClause), isOptional: true ), ] @@ -1090,9 +1085,9 @@ public let EXPR_NODES: [Node] = [ // A key path component like .[17] Node( - name: "KeyPathSubscriptComponent", + kind: .keyPathSubscriptComponent, + base: .syntax, nameForDiagnostics: "key path subscript component", - kind: "Syntax", children: [ Child( name: "LeftBracket", @@ -1100,7 +1095,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "ArgumentList", - kind: .collection(kind: "TupleExprElementList", collectionElementName: "Argument"), + kind: .collection(kind: .tupleExprElementList, collectionElementName: "Argument"), nameForDiagnostics: "arguments" ), Child( @@ -1112,9 +1107,9 @@ public let EXPR_NODES: [Node] = [ // e.g., "#embed("filename.txt")" Node( - name: "MacroExpansionExpr", + kind: .macroExpansionExpr, + base: .expr, nameForDiagnostics: "macro expansion", - kind: "Expr", traits: [ "FreestandingMacroExpansion" ], @@ -1130,7 +1125,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "GenericArguments", - kind: .node(kind: "GenericArgumentClause"), + kind: .node(kind: .genericArgumentClause), isOptional: true ), Child( @@ -1140,7 +1135,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "ArgumentList", - kind: .collection(kind: "TupleExprElementList", collectionElementName: "Argument") + kind: .collection(kind: .tupleExprElementList, collectionElementName: "Argument") ), Child( name: "RightParen", @@ -1149,12 +1144,12 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "TrailingClosure", - kind: .node(kind: "ClosureExpr"), + kind: .node(kind: .closureExpr), isOptional: true ), Child( name: "AdditionalTrailingClosures", - kind: .collection(kind: "MultipleTrailingClosureElementList", collectionElementName: "AdditionalTrailingClosure"), + kind: .collection(kind: .multipleTrailingClosureElementList, collectionElementName: "AdditionalTrailingClosure"), isOptional: true ), ] @@ -1162,13 +1157,13 @@ public let EXPR_NODES: [Node] = [ // expr?.name Node( - name: "MemberAccessExpr", + kind: .memberAccessExpr, + base: .expr, nameForDiagnostics: "member access", - kind: "Expr", children: [ Child( name: "Base", - kind: .node(kind: "Expr"), + kind: .node(kind: .expr), nameForDiagnostics: "base", isOptional: true ), @@ -1178,12 +1173,12 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "Name", - kind: .node(kind: "Token"), + kind: .node(kind: .token), nameForDiagnostics: "name" ), Child( name: "DeclNameArguments", - kind: .node(kind: "DeclNameArguments"), + kind: .node(kind: .declNameArguments), isOptional: true ), ] @@ -1191,9 +1186,9 @@ public let EXPR_NODES: [Node] = [ // The move expr Node( - name: "MoveExpr", + kind: .moveExpr, + base: .expr, nameForDiagnostics: "'consume' expression", - kind: "Expr", children: [ Child( name: "MoveKeyword", @@ -1201,15 +1196,15 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "Expression", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), ] ), Node( - name: "CopyExpr", + kind: .copyExpr, + base: .expr, nameForDiagnostics: "'copy' expression", - kind: "Expr", children: [ Child( name: "CopyKeyword", @@ -1217,23 +1212,23 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "Expression", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), ] ), Node( - name: "MultipleTrailingClosureElementList", + kind: .multipleTrailingClosureElementList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "MultipleTrailingClosureElement" + elementChoices: [.multipleTrailingClosureElement] ), // trailing-closure-element -> identifier ':' closure-expression Node( - name: "MultipleTrailingClosureElement", + kind: .multipleTrailingClosureElement, + base: .syntax, nameForDiagnostics: "trailing closure", - kind: "Syntax", children: [ Child( name: "Label", @@ -1246,16 +1241,16 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "Closure", - kind: .node(kind: "ClosureExpr") + kind: .node(kind: .closureExpr) ), ] ), // A nil expression. Node( - name: "NilLiteralExpr", + kind: .nilLiteralExpr, + base: .expr, nameForDiagnostics: nil, - kind: "Expr", children: [ Child( name: "NilKeyword", @@ -1266,13 +1261,13 @@ public let EXPR_NODES: [Node] = [ // optional-chaining-expr -> expr '?' Node( - name: "OptionalChainingExpr", + kind: .optionalChainingExpr, + base: .expr, nameForDiagnostics: "optional chaining", - kind: "Expr", children: [ Child( name: "Expression", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), Child( name: "QuestionMark", @@ -1283,9 +1278,9 @@ public let EXPR_NODES: [Node] = [ // A pack element expr spelled with 'each'. Node( - name: "PackElementExpr", + kind: .packElementExpr, + base: .expr, nameForDiagnostics: nil, - kind: "Expr", children: [ Child( name: "EachKeyword", @@ -1293,16 +1288,16 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "PackRefExpr", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), ] ), // A pack expansion expr spelled with 'repeat'. Node( - name: "PackExpansionExpr", + kind: .packExpansionExpr, + base: .expr, nameForDiagnostics: nil, - kind: "Expr", children: [ Child( name: "RepeatKeyword", @@ -1310,38 +1305,38 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "PatternExpr", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), ] ), // postfix '#if' expression Node( - name: "PostfixIfConfigExpr", + kind: .postfixIfConfigExpr, + base: .expr, nameForDiagnostics: nil, - kind: "Expr", children: [ Child( name: "Base", - kind: .node(kind: "Expr"), + kind: .node(kind: .expr), isOptional: true ), Child( name: "Config", - kind: .node(kind: "IfConfigDecl") + kind: .node(kind: .ifConfigDecl) ), ] ), // postfix-unary-expr -> expr postfix-operator Node( - name: "PostfixUnaryExpr", + kind: .postfixUnaryExpr, + base: .expr, nameForDiagnostics: "postfix expression", - kind: "Expr", children: [ Child( name: "Expression", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), Child( name: "OperatorToken", @@ -1354,9 +1349,9 @@ public let EXPR_NODES: [Node] = [ // -x // !true Node( - name: "PrefixOperatorExpr", + kind: .prefixOperatorExpr, + base: .expr, nameForDiagnostics: "operator", - kind: "Expr", children: [ Child( name: "OperatorToken", @@ -1365,7 +1360,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "PostfixExpression", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), ] ), @@ -1373,9 +1368,9 @@ public let EXPR_NODES: [Node] = [ // e.g '(a|c)*', the contents of the literal is opaque to the C++ Swift // parser though. Node( - name: "RegexLiteralExpr", + kind: .regexLiteralExpr, + base: .expr, nameForDiagnostics: "regex literal", - kind: "Expr", children: [ Child( name: "OpeningPounds", @@ -1404,39 +1399,39 @@ public let EXPR_NODES: [Node] = [ // A flat list of expressions before sequence folding, e.g. 1 + 2 + 3. Node( - name: "SequenceExpr", + kind: .sequenceExpr, + base: .expr, nameForDiagnostics: nil, - kind: "Expr", children: [ Child( name: "Elements", - kind: .collection(kind: "ExprList", collectionElementName: "Element") + kind: .collection(kind: .exprList, collectionElementName: "Element") ) ] ), // specialize-expr -> expr generic-argument-clause? Node( - name: "SpecializeExpr", + kind: .specializeExpr, + base: .expr, nameForDiagnostics: nil, - kind: "Expr", children: [ Child( name: "Expression", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), Child( name: "GenericArgumentClause", - kind: .node(kind: "GenericArgumentClause") + kind: .node(kind: .genericArgumentClause) ), ] ), // e.g. "abc \(foo()) def" Node( - name: "StringLiteralExpr", + kind: .stringLiteralExpr, + base: .expr, nameForDiagnostics: "string literal", - kind: "Expr", children: [ Child( name: "OpenDelimiter", @@ -1449,7 +1444,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "Segments", - kind: .collection(kind: "StringLiteralSegments", collectionElementName: "Segment") + kind: .collection(kind: .stringLiteralSegments, collectionElementName: "Segment") ), Child( name: "CloseQuote", @@ -1464,19 +1459,17 @@ public let EXPR_NODES: [Node] = [ ), Node( - name: "StringLiteralSegments", + kind: .stringLiteralSegments, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "Syntax", - elementName: "Segment", - elementChoices: ["StringSegment", "ExpressionSegment"] + elementChoices: [.stringSegment, .expressionSegment] ), // string literal segment in a string interpolation expression. Node( - name: "StringSegment", + kind: .stringSegment, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", children: [ Child( name: "Content", @@ -1487,13 +1480,13 @@ public let EXPR_NODES: [Node] = [ // subscript-expr -> expr '[' call-argument-list ']' closure-expr? Node( - name: "SubscriptExpr", + kind: .subscriptExpr, + base: .expr, nameForDiagnostics: "subscript", - kind: "Expr", children: [ Child( name: "CalledExpression", - kind: .node(kind: "Expr"), + kind: .node(kind: .expr), nameForDiagnostics: "called expression" ), Child( @@ -1502,7 +1495,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "ArgumentList", - kind: .collection(kind: "TupleExprElementList", collectionElementName: "Argument"), + kind: .collection(kind: .tupleExprElementList, collectionElementName: "Argument"), nameForDiagnostics: "arguments" ), Child( @@ -1511,13 +1504,13 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "TrailingClosure", - kind: .node(kind: "ClosureExpr"), + kind: .node(kind: .closureExpr), nameForDiagnostics: "trailing closure", isOptional: true ), Child( name: "AdditionalTrailingClosures", - kind: .collection(kind: "MultipleTrailingClosureElementList", collectionElementName: "AdditionalTrailingClosure"), + kind: .collection(kind: .multipleTrailingClosureElementList, collectionElementName: "AdditionalTrailingClosure"), nameForDiagnostics: "trailing closures", isOptional: true ), @@ -1526,9 +1519,9 @@ public let EXPR_NODES: [Node] = [ // An 'super' expression. Node( - name: "SuperRefExpr", + kind: .superRefExpr, + base: .expr, nameForDiagnostics: nil, - kind: "Expr", children: [ Child( name: "SuperKeyword", @@ -1539,9 +1532,9 @@ public let EXPR_NODES: [Node] = [ // switch-case-label -> 'case' case-item-list ':' Node( - name: "SwitchCaseLabel", + kind: .switchCaseLabel, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", children: [ Child( name: "CaseKeyword", @@ -1549,7 +1542,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "CaseItems", - kind: .collection(kind: "CaseItemList", collectionElementName: "CaseItem") + kind: .collection(kind: .caseItemList, collectionElementName: "CaseItem") ), Child( name: "Colon", @@ -1560,28 +1553,24 @@ public let EXPR_NODES: [Node] = [ // switch-case-list -> switch-case switch-case-list? Node( - name: "SwitchCaseList", + kind: .switchCaseList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "Syntax", - elementName: "SwitchCase", - elementChoices: ["SwitchCase", "IfConfigDecl"] + elementChoices: [.switchCase, .ifConfigDecl] ), // switch-case -> unknown-attr? switch-case-label stmt-list // | unknown-attr? switch-default-label stmt-list Node( - name: "SwitchCase", + kind: .switchCase, + base: .syntax, nameForDiagnostics: "switch case", - kind: "Syntax", - traits: [ - "WithStatements" - ], parserFunction: "parseSwitchCase", + traits: ["WithStatements"], children: [ Child( name: "UnknownAttr", - kind: .node(kind: "Attribute"), + kind: .node(kind: .attribute), isOptional: true ), Child( @@ -1589,18 +1578,18 @@ public let EXPR_NODES: [Node] = [ kind: .nodeChoices(choices: [ Child( name: "Default", - kind: .node(kind: "SwitchDefaultLabel") + kind: .node(kind: .switchDefaultLabel) ), Child( name: "Case", - kind: .node(kind: "SwitchCaseLabel") + kind: .node(kind: .switchCaseLabel) ), ]), nameForDiagnostics: "label" ), Child( name: "Statements", - kind: .collection(kind: "CodeBlockItemList", collectionElementName: "Statement"), + kind: .collection(kind: .codeBlockItemList, collectionElementName: "Statement"), isIndented: true ), ] @@ -1608,9 +1597,9 @@ public let EXPR_NODES: [Node] = [ // switch-default-label -> 'default' ':' Node( - name: "SwitchDefaultLabel", + kind: .switchDefaultLabel, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", children: [ Child( name: "DefaultKeyword", @@ -1629,9 +1618,9 @@ public let EXPR_NODES: [Node] = [ // This node represents both a 'switch' expression, as well as a 'switch' // statement when wrapped in a ExpressionStmt node. Node( - name: "SwitchExpr", + kind: .switchExpr, + base: .expr, nameForDiagnostics: "'switch' statement", - kind: "Expr", traits: [ "Braced" ], @@ -1642,7 +1631,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "Expression", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), Child( name: "LeftBrace", @@ -1650,7 +1639,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "Cases", - kind: .collection(kind: "SwitchCaseList", collectionElementName: "Case") + kind: .collection(kind: .switchCaseList, collectionElementName: "Case") ), Child( name: "RightBrace", @@ -1665,13 +1654,13 @@ public let EXPR_NODES: [Node] = [ // result of "folding" a SequenceExpr based on knowing the precedence // relationships amongst the different infix operators. Node( - name: "TernaryExpr", + kind: .ternaryExpr, + base: .expr, nameForDiagnostics: "ternay expression", - kind: "Expr", children: [ Child( name: "ConditionExpression", - kind: .node(kind: "Expr"), + kind: .node(kind: .expr), nameForDiagnostics: "condition" ), Child( @@ -1680,7 +1669,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "FirstChoice", - kind: .node(kind: "Expr"), + kind: .node(kind: .expr), nameForDiagnostics: "first choice" ), Child( @@ -1689,7 +1678,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "SecondChoice", - kind: .node(kind: "Expr"), + kind: .node(kind: .expr), nameForDiagnostics: "second choice" ), ] @@ -1700,9 +1689,9 @@ public let EXPR_NODES: [Node] = [ // try? foo() // try! foo() Node( - name: "TryExpr", + kind: .tryExpr, + base: .expr, nameForDiagnostics: "'try' expression", - kind: "Expr", children: [ Child( name: "TryKeyword", @@ -1715,23 +1704,23 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "Expression", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), ] ), Node( - name: "TupleExprElementList", + kind: .tupleExprElementList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "TupleExprElement" + elementChoices: [.tupleExprElement] ), // An element inside a tuple element list Node( - name: "TupleExprElement", + kind: .tupleExprElement, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", traits: [ "WithTrailingComma" ], @@ -1749,7 +1738,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "Expression", - kind: .node(kind: "Expr"), + kind: .node(kind: .expr), nameForDiagnostics: "value" ), Child( @@ -1761,9 +1750,9 @@ public let EXPR_NODES: [Node] = [ ), Node( - name: "TupleExpr", + kind: .tupleExpr, + base: .expr, nameForDiagnostics: "tuple", - kind: "Expr", traits: [ "Parenthesized" ], @@ -1774,7 +1763,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "ElementList", - kind: .collection(kind: "TupleExprElementList", collectionElementName: "Element"), + kind: .collection(kind: .tupleExprElementList, collectionElementName: "Element"), isIndented: true ), Child( @@ -1786,13 +1775,13 @@ public let EXPR_NODES: [Node] = [ // Type Node( - name: "TypeExpr", + kind: .typeExpr, + base: .expr, nameForDiagnostics: nil, - kind: "Expr", children: [ Child( name: "Type", - kind: .node(kind: "Type") + kind: .node(kind: .type) ) ] ), @@ -1801,9 +1790,9 @@ public let EXPR_NODES: [Node] = [ // "as" type casting operator without operands. // NOTE: This appears only in SequenceExpr. Node( - name: "UnresolvedAsExpr", + kind: .unresolvedAsExpr, + base: .expr, nameForDiagnostics: "'as'", - kind: "Expr", children: [ Child( name: "AsTok", @@ -1821,9 +1810,9 @@ public let EXPR_NODES: [Node] = [ // "is" type casting operator without operands. // NOTE: This appears only in SequenceExpr. Node( - name: "UnresolvedIsExpr", + kind: .unresolvedIsExpr, + base: .expr, nameForDiagnostics: "'is'", - kind: "Expr", children: [ Child( name: "IsTok", @@ -1833,13 +1822,13 @@ public let EXPR_NODES: [Node] = [ ), // unresolved-pattern-expr -> pattern Node( - name: "UnresolvedPatternExpr", + kind: .unresolvedPatternExpr, + base: .expr, nameForDiagnostics: nil, - kind: "Expr", children: [ Child( name: "Pattern", - kind: .node(kind: "Pattern") + kind: .node(kind: .pattern) ) ] ), @@ -1848,9 +1837,9 @@ public let EXPR_NODES: [Node] = [ // Ternary expression without the condition and the second choice. // NOTE: This appears only in SequenceExpr. Node( - name: "UnresolvedTernaryExpr", + kind: .unresolvedTernaryExpr, + base: .expr, nameForDiagnostics: "ternary operator", - kind: "Expr", children: [ Child( name: "QuestionMark", @@ -1858,7 +1847,7 @@ public let EXPR_NODES: [Node] = [ ), Child( name: "FirstChoice", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), Child( name: "ColonMark", @@ -1868,13 +1857,13 @@ public let EXPR_NODES: [Node] = [ ), Node( - name: "YieldExprListElement", + kind: .yieldExprListElement, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", children: [ Child( name: "Expression", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), Child( name: "Comma", @@ -1885,11 +1874,10 @@ public let EXPR_NODES: [Node] = [ ), Node( - name: "YieldExprList", + kind: .yieldExprList, + base: .syntaxCollection, nameForDiagnostics: "yield list", - kind: "SyntaxCollection", - element: "YieldExprListElement", - elementName: "Yields" + elementChoices: [.yieldExprListElement] ), ] diff --git a/CodeGeneration/Sources/SyntaxSupport/GenericNodes.swift b/CodeGeneration/Sources/SyntaxSupport/GenericNodes.swift index 7fe9ee2a16a..5f060b970aa 100644 --- a/CodeGeneration/Sources/SyntaxSupport/GenericNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/GenericNodes.swift @@ -13,13 +13,13 @@ public let GENERIC_NODES: [Node] = [ // conformance-requirement -> type-identifier : type-identifier Node( - name: "ConformanceRequirement", + kind: .conformanceRequirement, + base: .syntax, nameForDiagnostics: "conformance requirement", - kind: "Syntax", children: [ Child( name: "LeftTypeIdentifier", - kind: .node(kind: "Type") + kind: .node(kind: .type) ), Child( name: "Colon", @@ -27,16 +27,16 @@ public let GENERIC_NODES: [Node] = [ ), Child( name: "RightTypeIdentifier", - kind: .node(kind: "Type") + kind: .node(kind: .type) ), ] ), // generic-parameter-clause -> '<' generic-parameter-list generic-where-clause? '>' Node( - name: "GenericParameterClause", + kind: .genericParameterClause, + base: .syntax, nameForDiagnostics: "generic parameter clause", - kind: "Syntax", parserFunction: "parseGenericParameters", children: [ Child( @@ -45,11 +45,11 @@ public let GENERIC_NODES: [Node] = [ ), Child( name: "GenericParameterList", - kind: .collection(kind: "GenericParameterList", collectionElementName: "GenericParameter") + kind: .collection(kind: .genericParameterList, collectionElementName: "GenericParameter") ), Child( name: "GenericWhereClause", - kind: .node(kind: "GenericWhereClause"), + kind: .node(kind: .genericWhereClause), isOptional: true ), Child( @@ -60,19 +60,19 @@ public let GENERIC_NODES: [Node] = [ ), Node( - name: "GenericParameterList", + kind: .genericParameterList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "GenericParameter" + elementChoices: [.genericParameter] ), // generic-parameter -> type-name // | type-name : type-identifier // | type-name : protocol-composition-type Node( - name: "GenericParameter", + kind: .genericParameter, + base: .syntax, nameForDiagnostics: "generic parameter", - kind: "Syntax", traits: [ "WithTrailingComma", "WithAttributes", @@ -80,7 +80,7 @@ public let GENERIC_NODES: [Node] = [ children: [ Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), isOptional: true ), Child( @@ -101,7 +101,7 @@ public let GENERIC_NODES: [Node] = [ ), Child( name: "InheritedType", - kind: .node(kind: "Type"), + kind: .node(kind: .type), nameForDiagnostics: "inherited type", isOptional: true ), @@ -114,19 +114,18 @@ public let GENERIC_NODES: [Node] = [ ), Node( - name: "GenericRequirementList", + kind: .genericRequirementList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "GenericRequirement", - elementName: "GenericRequirement" + elementChoices: [.genericRequirement] ), // generic-requirement -> // (same-type-requirement|conformance-requirement|layout-requirement) ','? Node( - name: "GenericRequirement", + kind: .genericRequirement, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", traits: [ "WithTrailingComma" ], @@ -136,15 +135,15 @@ public let GENERIC_NODES: [Node] = [ kind: .nodeChoices(choices: [ Child( name: "SameTypeRequirement", - kind: .node(kind: "SameTypeRequirement") + kind: .node(kind: .sameTypeRequirement) ), Child( name: "ConformanceRequirement", - kind: .node(kind: "ConformanceRequirement") + kind: .node(kind: .conformanceRequirement) ), Child( name: "LayoutRequirement", - kind: .node(kind: "LayoutRequirement") + kind: .node(kind: .layoutRequirement) ), ]) ), @@ -158,9 +157,9 @@ public let GENERIC_NODES: [Node] = [ // generic-where-clause -> 'where' requirement-list Node( - name: "GenericWhereClause", + kind: .genericWhereClause, + base: .syntax, nameForDiagnostics: "'where' clause", - kind: "Syntax", children: [ Child( name: "WhereKeyword", @@ -168,7 +167,7 @@ public let GENERIC_NODES: [Node] = [ ), Child( name: "RequirementList", - kind: .collection(kind: "GenericRequirementList", collectionElementName: "Requirement") + kind: .collection(kind: .genericRequirementList, collectionElementName: "Requirement") ), ] ), @@ -176,13 +175,13 @@ public let GENERIC_NODES: [Node] = [ // layout-requirement -> type-name : layout-constraint // layout-constraint -> identifier '('? integer-literal? ','? integer-literal? ')'? Node( - name: "LayoutRequirement", + kind: .layoutRequirement, + base: .syntax, nameForDiagnostics: "layout requirement", - kind: "Syntax", children: [ Child( name: "TypeIdentifier", - kind: .node(kind: "Type"), + kind: .node(kind: .type), nameForDiagnostics: "constrained type" ), Child( @@ -225,9 +224,9 @@ public let GENERIC_NODES: [Node] = [ // primary-associated-type-clause -> '<' primary-associated-type-list '>' Node( - name: "PrimaryAssociatedTypeClause", + kind: .primaryAssociatedTypeClause, + base: .syntax, nameForDiagnostics: "primary associated type clause", - kind: "Syntax", children: [ Child( name: "LeftAngleBracket", @@ -235,7 +234,7 @@ public let GENERIC_NODES: [Node] = [ ), Child( name: "PrimaryAssociatedTypeList", - kind: .collection(kind: "PrimaryAssociatedTypeList", collectionElementName: "PrimaryAssociatedType") + kind: .collection(kind: .primaryAssociatedTypeList, collectionElementName: "PrimaryAssociatedType") ), Child( name: "RightAngleBracket", @@ -245,17 +244,17 @@ public let GENERIC_NODES: [Node] = [ ), Node( - name: "PrimaryAssociatedTypeList", + kind: .primaryAssociatedTypeList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "PrimaryAssociatedType" + elementChoices: [.primaryAssociatedType] ), // primary-associated-type -> type-name ','? Node( - name: "PrimaryAssociatedType", + kind: .primaryAssociatedType, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", traits: [ "WithTrailingComma" ], @@ -275,13 +274,13 @@ public let GENERIC_NODES: [Node] = [ // same-type-requirement -> type-identifier == type Node( - name: "SameTypeRequirement", + kind: .sameTypeRequirement, + base: .syntax, nameForDiagnostics: "same type requirement", - kind: "Syntax", children: [ Child( name: "LeftTypeIdentifier", - kind: .node(kind: "Type"), + kind: .node(kind: .type), nameForDiagnostics: "left-hand type" ), Child( @@ -290,7 +289,7 @@ public let GENERIC_NODES: [Node] = [ ), Child( name: "RightTypeIdentifier", - kind: .node(kind: "Type"), + kind: .node(kind: .type), nameForDiagnostics: "right-hand type" ), ] diff --git a/CodeGeneration/Sources/SyntaxSupport/Node.swift b/CodeGeneration/Sources/SyntaxSupport/Node.swift index 7f25aa6420b..80a7844206d 100644 --- a/CodeGeneration/Sources/SyntaxSupport/Node.swift +++ b/CodeGeneration/Sources/SyntaxSupport/Node.swift @@ -11,109 +11,108 @@ //===----------------------------------------------------------------------===// import Foundation - -/// A Syntax node, possibly with children. -/// If the kind is "SyntaxCollection", then this node is considered a Syntax -/// Collection that will expose itself as a typedef rather than a concrete -/// subclass. +import SwiftSyntax + +/// The definition of a syntax node that, when generated, conforms to +/// `SyntaxProtocol`. +/// +/// There are two fundemantally different kinds of nodes: +/// - Layout nodes contain a fixed number of children of possibly different, +/// but fixed types. +/// - Collection nodes contains an arbitrary number of children but all those +/// children are of the same type. public class Node { - public let syntaxKind: String - public let swiftSyntaxKind: String - public let name: String - public let nameForDiagnostics: String? - public let description: String? - public let baseKind: String - public let parserFunction: String? - public let traits: [String] - public let children: [Child] - public let nonUnexpectedChildren: [Child] - public let collectionElementName: String? - public let collectionElementChoices: [String]? - public let omitWhenEmpty: Bool - public let collectionElement: String - - /// Returns `true` if this node declares one of the base syntax kinds. - public var isBase: Bool { - return SYNTAX_BASE_KINDS.contains(syntaxKind) + fileprivate enum Data { + case layout(children: [Child], traits: [String]) + case collection(choices: [SyntaxNodeKind]) } - /// Returns `true` if this node is a subclass of SyntaxCollection. - public var isSyntaxCollection: Bool { - return baseKind == "SyntaxCollection" - } + /// Contains the layout or collection specific data of this syntax node. + /// + /// To access this, use the `layoutNode` or `collectionNode` properties, which + /// offer the members. + fileprivate let data: Data - /// Returns `true` if this node should have a `validate` method associated. - public var requiresValidation: Bool { - return isBuildable - } + /// The kind of the node. There must be exactly one `Node` for every case in + /// `SyntaxNodeKind`. + public let kind: SyntaxNodeKind - /// Returns `true` if this node is an `Unknown` syntax subclass. - public var isUnknown: Bool { - return syntaxKind.contains("Unknown") - } + /// The kind of node’s supertype. This kind must have `isBase == true` + public let base: SyntaxNodeKind - /// Returns `true` if this node is an `Unknown` syntax subclass. - public var isMissing: Bool { - return syntaxKind.contains("Missing") - } - - /// Returns `true` if this node should have a builder associated. - public var isBuildable: Bool { - return !isBase && !isUnknown && !isMissing && !isSyntaxCollection - } + /// When the node name is printed for diagnostics, this name is used. + /// If `nil`, `nameForDiagnostics` will print the parent node’s name. + public let nameForDiagnostics: String? - /// Returns 'True' if this node shall not be created while parsing if it has no children. - public var shallBeOmittedWhenEmpty: Bool { - return omitWhenEmpty - } + /// A doc comment describing the node. + /// + /// The comment does not end with a newline. + public let documentation: SwiftSyntax.Trivia - /// Returns true if this child has a token kind. - public var isToken: Bool { - return syntaxKind.contains("Token") || collectionElement.contains("Token") - } + /// If the syntax node can be constructed by parsing a string, the parser + /// function that should be invoked to create this node. + public let parserFunction: String? - public var isVisitable: Bool { - return !isBase + /// A name for this node that is suitable to be used as a variables or enum + /// case's name. + public var varOrCaseName: TokenSyntax { + return kind.varOrCaseName } - public var hasOptionalBaseTypeChild: Bool { - return children.contains { child in - if child.hasOptionalBaseType { - return true + /// If this is a layout node, return a view of the node that provides access + /// to the layout-node specific properties. + public var layoutNode: LayoutNode? { + switch data { + case .layout: + if kind.isBase { + return nil } else { - return false + return LayoutNode(node: self) } + default: + return nil } } + /// If this is a collection node, return a view of the node that provides access + /// to the collection node specific properties. + public var collectionNode: CollectionNode? { + switch data { + case .layout: + return nil + default: + return CollectionNode(node: self) + } + } + + /// Construct the specification for a layout syntax node. init( - name: String, + kind: SyntaxNodeKind, + base: SyntaxNodeKind, nameForDiagnostics: String?, - description: String? = nil, - kind: String, - traits: [String] = [], + documentation: String? = nil, parserFunction: String? = nil, - children: [Child] = [], - element: String = "", - elementName: String? = nil, - elementChoices: [String]? = nil, - omitWhenEmpty: Bool = false + traits: [String] = [], + children: [Child] = [] ) { - self.syntaxKind = name - self.swiftSyntaxKind = lowercaseFirstWord(name: name) - self.name = kindToType(kind: self.syntaxKind) + precondition(base != .syntaxCollection) + precondition(base.isBase, "unknown base kind '\(base)' for node '\(kind)'") + + self.kind = kind + self.base = base self.nameForDiagnostics = nameForDiagnostics - self.description = description + self.documentation = docCommentTrivia(from: documentation) self.parserFunction = parserFunction - self.traits = traits - self.baseKind = kind - if kind == "SyntaxCollection" { - self.children = children - } else if children.count > 0 { + let childrenWithUnexpected: [Child] + if children.isEmpty { + childrenWithUnexpected = [ + Child(name: "Unexpected", kind: .collection(kind: .unexpectedNodes, collectionElementName: "Unexpected"), isOptional: true) + ] + } else { // Add implicitly generated UnexpectedNodes children between // any two defined children - self.children = + childrenWithUnexpected = children.enumerated().flatMap { (i, child) -> [Child] in let unexpectedName: String if i == 0 { @@ -121,44 +120,128 @@ public class Node { } else { unexpectedName = "UnexpectedBetween\(children[i - 1].name)And\(child.name)" } - return [ - Child( - name: unexpectedName, - kind: .collection(kind: "UnexpectedNodes", collectionElementName: unexpectedName), - isOptional: true - ), - child, - ] - } - + (!children.isEmpty - ? [ - Child( - name: "UnexpectedAfter\(children.last!.name)", - kind: .collection(kind: "UnexpectedNodes", collectionElementName: "UnexpectedAfter\(children.last!.name)"), - isOptional: true - ) - ] : []) - } else { - self.children = [ - Child(name: "Unexpected", kind: .collection(kind: "UnexpectedNodes", collectionElementName: "Unexpected"), isOptional: true) - ] + let unexpectedBefore = Child( + name: unexpectedName, + kind: .collection(kind: .unexpectedNodes, collectionElementName: unexpectedName), + isOptional: true + ) + return [unexpectedBefore, child] + } + [ + Child( + name: "UnexpectedAfter\(children.last!.name)", + kind: .collection(kind: .unexpectedNodes, collectionElementName: "UnexpectedAfter\(children.last!.name)"), + isOptional: true + ) + ] } + self.data = .layout(children: childrenWithUnexpected, traits: traits) + } - self.nonUnexpectedChildren = children.filter { !$0.isUnexpectedNodes } + /// Construct the specification for a collection syntax node. + /// + /// `base` must be `.syntaxCollection`. + init( + kind: SyntaxNodeKind, + base: SyntaxNodeKind, + nameForDiagnostics: String?, + documentation: String? = nil, + parserFunction: String? = nil, + elementChoices: [SyntaxNodeKind] + ) { + self.kind = kind + precondition(base == .syntaxCollection) + self.base = base + self.nameForDiagnostics = nameForDiagnostics + self.documentation = docCommentTrivia(from: documentation) + self.parserFunction = parserFunction + + assert(!elementChoices.isEmpty) + self.data = .collection(choices: elementChoices) + } +} + +/// Provides a view into a layout node that offers access to the layout-specific +/// properties. +@dynamicMemberLookup +public struct LayoutNode { + /// The underlying node + public let node: Node + + fileprivate init(node: Node) { + switch node.data { + case .layout: + break + default: + preconditionFailure("NodeLayoutView must wrap a `Node` with data `.layout`") + } + self.node = node + } + + /// Allow transparent accesss to the properties of the underlying `Node`. + public subscript(dynamicMember keyPath: KeyPath) -> T { + return node[keyPath: keyPath] + } + + /// The children of the layout node. + /// + /// This includes unexpected children + public var children: [Child] { + switch node.data { + case .layout(children: let children, traits: _): + return children + case .collection: + preconditionFailure("NodeLayoutView must wrap a Node with data `.layout`") + } + } + + /// All children in the node that are not unexpected. + public var nonUnexpectedChildren: [Child] { + return children.filter { !$0.isUnexpectedNodes } + } - if !SYNTAX_BASE_KINDS.contains(baseKind) { - fatalError("unknown base kind '\(baseKind)' for node '\(syntaxKind)'") + /// Traits that the node conforms to. + public var traits: [String] { + switch node.data { + case .layout(children: _, traits: let traits): + return traits + case .collection: + preconditionFailure("NodeLayoutView must wrap a Node with data `.layout`") } + } +} - self.omitWhenEmpty = omitWhenEmpty - self.collectionElement = element +/// Provides a view into a collection node that offers access to the +/// collection-specific properties. +@dynamicMemberLookup +public struct CollectionNode { + /// The underlying node + public let node: Node + + fileprivate init(node: Node) { + switch node.data { + case .collection: + break + default: + preconditionFailure("NodeLayoutView must wrap a `Node` with data `.layout`") + } + self.node = node + } - // If there's a preferred name for the collection element that differs - // from its supertype, use that. - self.collectionElementName = elementName ?? self.collectionElement - self.collectionElementChoices = elementChoices ?? [] + /// Allow transparent accesss to the properties of the underlying `Node`. + public subscript(dynamicMember keyPath: KeyPath) -> T { + return node[keyPath: keyPath] + } - // For SyntaxCollections make sure that the elementName is set. - precondition(!isSyntaxCollection || elementName != nil || element != "") + /// The kinds the elements can have. + /// + /// This can be more than one in which case each element an have either of + /// these kinds. + public var elementChoices: [SyntaxNodeKind] { + switch node.data { + case .layout: + preconditionFailure("NodeLayoutView must wrap a Node with data `.collection`") + case .collection(choices: let choices): + return choices + } } } diff --git a/CodeGeneration/Sources/SyntaxSupport/PatternNodes.swift b/CodeGeneration/Sources/SyntaxSupport/PatternNodes.swift index 556761d5bb7..14f4df837fa 100644 --- a/CodeGeneration/Sources/SyntaxSupport/PatternNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/PatternNodes.swift @@ -13,21 +13,21 @@ public let PATTERN_NODES: [Node] = [ // expr-pattern -> expr Node( - name: "ExpressionPattern", + kind: .expressionPattern, + base: .pattern, nameForDiagnostics: "pattern", - kind: "Pattern", children: [ Child( name: "Expression", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ) ] ), // identifier-pattern -> identifier Node( - name: "IdentifierPattern", + kind: .identifierPattern, + base: .pattern, nameForDiagnostics: "pattern", - kind: "Pattern", children: [ Child( name: "Identifier", @@ -38,9 +38,9 @@ public let PATTERN_NODES: [Node] = [ // is-type-pattern -> 'is' type Node( - name: "IsTypePattern", + kind: .isTypePattern, + base: .pattern, nameForDiagnostics: "'is' pattern", - kind: "Pattern", children: [ Child( name: "IsKeyword", @@ -48,7 +48,7 @@ public let PATTERN_NODES: [Node] = [ ), Child( name: "Type", - kind: .node(kind: "Type") + kind: .node(kind: .type) ), ] ), @@ -56,17 +56,17 @@ public let PATTERN_NODES: [Node] = [ // tuple-pattern-element-list -> tuple-pattern-element // tuple-pattern-element-list? Node( - name: "TuplePatternElementList", + kind: .tuplePatternElementList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "TuplePatternElement" + elementChoices: [.tuplePatternElement] ), // tuple-pattern-element -> identifier? ':' pattern ','? Node( - name: "TuplePatternElement", + kind: .tuplePatternElement, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", traits: [ "WithTrailingComma" ], @@ -84,7 +84,7 @@ public let PATTERN_NODES: [Node] = [ ), Child( name: "Pattern", - kind: .node(kind: "Pattern") + kind: .node(kind: .pattern) ), Child( name: "TrailingComma", @@ -96,9 +96,9 @@ public let PATTERN_NODES: [Node] = [ // tuple-pattern -> '(' tuple-pattern-element-list ')' Node( - name: "TuplePattern", + kind: .tuplePattern, + base: .pattern, nameForDiagnostics: "tuple pattern", - kind: "Pattern", traits: [ "Parenthesized" ], @@ -109,7 +109,7 @@ public let PATTERN_NODES: [Node] = [ ), Child( name: "Elements", - kind: .collection(kind: "TuplePatternElementList", collectionElementName: "Element") + kind: .collection(kind: .tuplePatternElementList, collectionElementName: "Element") ), Child( name: "RightParen", @@ -120,9 +120,9 @@ public let PATTERN_NODES: [Node] = [ // type-annotation -> ':' type Node( - name: "TypeAnnotation", + kind: .typeAnnotation, + base: .syntax, nameForDiagnostics: "type annotation", - kind: "Syntax", children: [ Child( name: "Colon", @@ -130,7 +130,7 @@ public let PATTERN_NODES: [Node] = [ ), Child( name: "Type", - kind: .node(kind: "Type") + kind: .node(kind: .type) ), ] ), @@ -139,9 +139,9 @@ public let PATTERN_NODES: [Node] = [ // | 'var' pattern // | 'inout' pattern Node( - name: "ValueBindingPattern", + kind: .valueBindingPattern, + base: .pattern, nameForDiagnostics: "value binding pattern", - kind: "Pattern", children: [ Child( name: "BindingKeyword", @@ -149,16 +149,16 @@ public let PATTERN_NODES: [Node] = [ ), Child( name: "ValuePattern", - kind: .node(kind: "Pattern") + kind: .node(kind: .pattern) ), ] ), // wildcard-pattern -> '_' type-annotation? Node( - name: "WildcardPattern", + kind: .wildcardPattern, + base: .pattern, nameForDiagnostics: "wildcard pattern", - kind: "Pattern", children: [ Child( name: "Wildcard", @@ -166,7 +166,7 @@ public let PATTERN_NODES: [Node] = [ ), Child( name: "TypeAnnotation", - kind: .node(kind: "TypeAnnotation"), + kind: .node(kind: .typeAnnotation), isOptional: true ), ] diff --git a/CodeGeneration/Sources/SyntaxSupport/StmtNodes.swift b/CodeGeneration/Sources/SyntaxSupport/StmtNodes.swift index 6ac93415202..47dbe062341 100644 --- a/CodeGeneration/Sources/SyntaxSupport/StmtNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/StmtNodes.swift @@ -13,9 +13,9 @@ public let STMT_NODES: [Node] = [ // availability-condition -> '#available' '(' availability-spec ')' Node( - name: "AvailabilityCondition", + kind: .availabilityCondition, + base: .syntax, nameForDiagnostics: "availability condition", - kind: "Syntax", children: [ Child( name: "AvailabilityKeyword", @@ -27,7 +27,7 @@ public let STMT_NODES: [Node] = [ ), Child( name: "AvailabilitySpec", - kind: .collection(kind: "AvailabilitySpecList", collectionElementName: "AvailabilityArgument") + kind: .collection(kind: .availabilitySpecList, collectionElementName: "AvailabilityArgument") ), Child( name: "RightParen", @@ -38,9 +38,9 @@ public let STMT_NODES: [Node] = [ // break-stmt -> 'break' identifier? ';'? Node( - name: "BreakStmt", + kind: .breakStmt, + base: .stmt, nameForDiagnostics: "'break' statement", - kind: "Stmt", children: [ Child( name: "BreakKeyword", @@ -57,29 +57,27 @@ public let STMT_NODES: [Node] = [ // case-item-list -> case-item case-item-list? Node( - name: "CaseItemList", + kind: .caseItemList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "CaseItem" + elementChoices: [.caseItem] ), // catch-clause-list -> catch-clause catch-clause-list? Node( - name: "CatchClauseList", + kind: .catchClauseList, + base: .syntaxCollection, nameForDiagnostics: "'catch' clause", - kind: "SyntaxCollection", - element: "CatchClause" + elementChoices: [.catchClause] ), // catch-clause 'catch' case-item-list? code-block Node( - name: "CatchClause", + kind: .catchClause, + base: .syntax, nameForDiagnostics: "'catch' clause", - kind: "Syntax", - traits: [ - "WithCodeBlock" - ], parserFunction: "parseCatchClause", + traits: ["WithCodeBlock"], children: [ Child( name: "CatchKeyword", @@ -87,41 +85,41 @@ public let STMT_NODES: [Node] = [ ), Child( name: "CatchItems", - kind: .collection(kind: "CatchItemList", collectionElementName: "CatchItem"), + kind: .collection(kind: .catchItemList, collectionElementName: "CatchItem"), isOptional: true ), Child( name: "Body", - kind: .node(kind: "CodeBlock") + kind: .node(kind: .codeBlock) ), ] ), // catch-item-list -> catch-item catch-item-list? Node( - name: "CatchItemList", + kind: .catchItemList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "CatchItem" + elementChoices: [.catchItem] ), // catch-item -> pattern? where-clause? ','? Node( - name: "CatchItem", + kind: .catchItem, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", traits: [ "WithTrailingComma" ], children: [ Child( name: "Pattern", - kind: .node(kind: "Pattern"), + kind: .node(kind: .pattern), isOptional: true ), Child( name: "WhereClause", - kind: .node(kind: "WhereClause"), + kind: .node(kind: .whereClause), isOptional: true ), Child( @@ -135,10 +133,10 @@ public let STMT_NODES: [Node] = [ // condition-list -> condition // | condition ','? condition-list Node( - name: "ConditionElementList", + kind: .conditionElementList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "ConditionElement" + elementChoices: [.conditionElement] ), // condition -> expression @@ -146,9 +144,9 @@ public let STMT_NODES: [Node] = [ // | case-condition // | optional-binding-condition Node( - name: "ConditionElement", + kind: .conditionElement, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", traits: [ "WithTrailingComma" ], @@ -158,19 +156,19 @@ public let STMT_NODES: [Node] = [ kind: .nodeChoices(choices: [ Child( name: "Expression", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), Child( name: "Availability", - kind: .node(kind: "AvailabilityCondition") + kind: .node(kind: .availabilityCondition) ), Child( name: "MatchingPattern", - kind: .node(kind: "MatchingPatternCondition") + kind: .node(kind: .matchingPatternCondition) ), Child( name: "OptionalBinding", - kind: .node(kind: "OptionalBindingCondition") + kind: .node(kind: .optionalBindingCondition) ), ]) ), @@ -184,9 +182,9 @@ public let STMT_NODES: [Node] = [ // continue-stmt -> 'continue' label? ';'? Node( - name: "ContinueStmt", + kind: .continueStmt, + base: .stmt, nameForDiagnostics: "'continue' statement", - kind: "Stmt", children: [ Child( name: "ContinueKeyword", @@ -203,9 +201,9 @@ public let STMT_NODES: [Node] = [ // defer-stmt -> 'defer' code-block ';'? Node( - name: "DeferStmt", + kind: .deferStmt, + base: .stmt, nameForDiagnostics: "'defer' statement", - kind: "Stmt", traits: [ "WithCodeBlock" ], @@ -216,16 +214,16 @@ public let STMT_NODES: [Node] = [ ), Child( name: "Body", - kind: .node(kind: "CodeBlock") + kind: .node(kind: .codeBlock) ), ] ), // do-stmt -> identifier? ':'? 'do' code-block catch-clause-list ';'? Node( - name: "DoStmt", + kind: .doStmt, + base: .stmt, nameForDiagnostics: "'do' statement", - kind: "Stmt", traits: [ "WithCodeBlock" ], @@ -236,12 +234,12 @@ public let STMT_NODES: [Node] = [ ), Child( name: "Body", - kind: .node(kind: "CodeBlock"), + kind: .node(kind: .codeBlock), nameForDiagnostics: "body" ), Child( name: "CatchClauses", - kind: .collection(kind: "CatchClauseList", collectionElementName: "CatchClause"), + kind: .collection(kind: .catchClauseList, collectionElementName: "CatchClause"), isOptional: true ), ] @@ -249,22 +247,22 @@ public let STMT_NODES: [Node] = [ // expr-stmt -> expression ';'? Node( - name: "ExpressionStmt", + kind: .expressionStmt, + base: .stmt, nameForDiagnostics: "expression", - kind: "Stmt", children: [ Child( name: "Expression", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ) ] ), // fallthrough-stmt -> 'fallthrough' ';'? Node( - name: "FallthroughStmt", + kind: .fallthroughStmt, + base: .stmt, nameForDiagnostics: "'fallthrough' statement", - kind: "Stmt", children: [ Child( name: "FallthroughKeyword", @@ -277,9 +275,9 @@ public let STMT_NODES: [Node] = [ // 'for' 'try'? 'await'? 'case'? pattern 'in' expr 'where'? // expr code-block ';'? Node( - name: "ForInStmt", + kind: .forInStmt, + base: .stmt, nameForDiagnostics: "'for' statement", - kind: "Stmt", traits: [ "WithCodeBlock" ], @@ -305,11 +303,11 @@ public let STMT_NODES: [Node] = [ ), Child( name: "Pattern", - kind: .node(kind: "Pattern") + kind: .node(kind: .pattern) ), Child( name: "TypeAnnotation", - kind: .node(kind: "TypeAnnotation"), + kind: .node(kind: .typeAnnotation), isOptional: true ), Child( @@ -318,16 +316,16 @@ public let STMT_NODES: [Node] = [ ), Child( name: "SequenceExpr", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), Child( name: "WhereClause", - kind: .node(kind: "WhereClause"), + kind: .node(kind: .whereClause), isOptional: true ), Child( name: "Body", - kind: .node(kind: "CodeBlock"), + kind: .node(kind: .codeBlock), nameForDiagnostics: "body" ), ] @@ -335,9 +333,9 @@ public let STMT_NODES: [Node] = [ // discard-stmt -> 'discard' expr ';'? Node( - name: "DiscardStmt", + kind: .discardStmt, + base: .stmt, nameForDiagnostics: "'discard' statement", - kind: "Stmt", children: [ Child( name: "DiscardKeyword", @@ -348,16 +346,16 @@ public let STMT_NODES: [Node] = [ ), Child( name: "Expression", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), ] ), // guard-stmt -> 'guard' condition-list 'else' code-block ';'? Node( - name: "GuardStmt", + kind: .guardStmt, + base: .stmt, nameForDiagnostics: "'guard' statement", - kind: "Stmt", traits: [ "WithCodeBlock" ], @@ -368,7 +366,7 @@ public let STMT_NODES: [Node] = [ ), Child( name: "Conditions", - kind: .collection(kind: "ConditionElementList", collectionElementName: "Condition"), + kind: .collection(kind: .conditionElementList, collectionElementName: "Condition"), nameForDiagnostics: "condition" ), Child( @@ -377,7 +375,7 @@ public let STMT_NODES: [Node] = [ ), Child( name: "Body", - kind: .node(kind: "CodeBlock"), + kind: .node(kind: .codeBlock), nameForDiagnostics: "body" ), ] @@ -385,9 +383,9 @@ public let STMT_NODES: [Node] = [ // labeled-stmt -> label ':' stmt Node( - name: "LabeledStmt", + kind: .labeledStmt, + base: .stmt, nameForDiagnostics: "labeled statement", - kind: "Stmt", children: [ Child( name: "LabelName", @@ -400,15 +398,15 @@ public let STMT_NODES: [Node] = [ ), Child( name: "Statement", - kind: .node(kind: "Stmt") + kind: .node(kind: .stmt) ), ] ), Node( - name: "MatchingPatternCondition", + kind: .matchingPatternCondition, + base: .syntax, nameForDiagnostics: "pattern matching", - kind: "Syntax", children: [ Child( name: "CaseKeyword", @@ -416,24 +414,24 @@ public let STMT_NODES: [Node] = [ ), Child( name: "Pattern", - kind: .node(kind: "Pattern") + kind: .node(kind: .pattern) ), Child( name: "TypeAnnotation", - kind: .node(kind: "TypeAnnotation"), + kind: .node(kind: .typeAnnotation), isOptional: true ), Child( name: "Initializer", - kind: .node(kind: "InitializerClause") + kind: .node(kind: .initializerClause) ), ] ), Node( - name: "OptionalBindingCondition", + kind: .optionalBindingCondition, + base: .syntax, nameForDiagnostics: "optional binding", - kind: "Syntax", children: [ Child( name: "BindingKeyword", @@ -441,16 +439,16 @@ public let STMT_NODES: [Node] = [ ), Child( name: "Pattern", - kind: .node(kind: "Pattern") + kind: .node(kind: .pattern) ), Child( name: "TypeAnnotation", - kind: .node(kind: "TypeAnnotation"), + kind: .node(kind: .typeAnnotation), isOptional: true ), Child( name: "Initializer", - kind: .node(kind: "InitializerClause"), + kind: .node(kind: .initializerClause), isOptional: true ), ] @@ -458,9 +456,9 @@ public let STMT_NODES: [Node] = [ // repeat-while-stmt -> label? ':'? 'repeat' code-block 'while' expr ';'? Node( - name: "RepeatWhileStmt", + kind: .repeatWhileStmt, + base: .stmt, nameForDiagnostics: "'repeat' statement", - kind: "Stmt", traits: [ "WithCodeBlock" ], @@ -471,7 +469,7 @@ public let STMT_NODES: [Node] = [ ), Child( name: "Body", - kind: .node(kind: "CodeBlock"), + kind: .node(kind: .codeBlock), nameForDiagnostics: "body" ), Child( @@ -480,7 +478,7 @@ public let STMT_NODES: [Node] = [ ), Child( name: "Condition", - kind: .node(kind: "Expr"), + kind: .node(kind: .expr), nameForDiagnostics: "condition" ), ] @@ -488,9 +486,9 @@ public let STMT_NODES: [Node] = [ // return-stmt -> 'return' expr? ';'? Node( - name: "ReturnStmt", + kind: .returnStmt, + base: .stmt, nameForDiagnostics: "'return' statement", - kind: "Stmt", children: [ Child( name: "ReturnKeyword", @@ -498,7 +496,7 @@ public let STMT_NODES: [Node] = [ ), Child( name: "Expression", - kind: .node(kind: "Expr"), + kind: .node(kind: .expr), isOptional: true ), ] @@ -506,9 +504,9 @@ public let STMT_NODES: [Node] = [ // throw-stmt -> 'throw' expr ';'? Node( - name: "ThrowStmt", + kind: .throwStmt, + base: .stmt, nameForDiagnostics: "'throw' statement", - kind: "Stmt", children: [ Child( name: "ThrowKeyword", @@ -516,15 +514,15 @@ public let STMT_NODES: [Node] = [ ), Child( name: "Expression", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), ] ), Node( - name: "WhereClause", + kind: .whereClause, + base: .syntax, nameForDiagnostics: "'where' clause", - kind: "Syntax", children: [ Child( name: "WhereKeyword", @@ -532,16 +530,16 @@ public let STMT_NODES: [Node] = [ ), Child( name: "GuardResult", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), ] ), // while-stmt -> label? ':'? 'while' condition-list code-block ';'? Node( - name: "WhileStmt", + kind: .whileStmt, + base: .stmt, nameForDiagnostics: "'while' statement", - kind: "Stmt", traits: [ "WithCodeBlock" ], @@ -552,19 +550,19 @@ public let STMT_NODES: [Node] = [ ), Child( name: "Conditions", - kind: .collection(kind: "ConditionElementList", collectionElementName: "Condition") + kind: .collection(kind: .conditionElementList, collectionElementName: "Condition") ), Child( name: "Body", - kind: .node(kind: "CodeBlock") + kind: .node(kind: .codeBlock) ), ] ), Node( - name: "YieldList", + kind: .yieldList, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", children: [ Child( name: "LeftParen", @@ -572,7 +570,7 @@ public let STMT_NODES: [Node] = [ ), Child( name: "ElementList", - kind: .collection(kind: "YieldExprList", collectionElementName: "Element") + kind: .collection(kind: .yieldExprList, collectionElementName: "Element") ), Child( name: "RightParen", @@ -583,9 +581,9 @@ public let STMT_NODES: [Node] = [ // yield-stmt -> 'yield' '('? expr-list? ')'? Node( - name: "YieldStmt", + kind: .yieldStmt, + base: .stmt, nameForDiagnostics: "'yield' statement", - kind: "Stmt", children: [ Child( name: "YieldKeyword", @@ -596,11 +594,11 @@ public let STMT_NODES: [Node] = [ kind: .nodeChoices(choices: [ Child( name: "YieldList", - kind: .node(kind: "YieldList") + kind: .node(kind: .yieldList) ), Child( name: "SimpleYield", - kind: .node(kind: "Expr") + kind: .node(kind: .expr) ), ]) ), diff --git a/CodeGeneration/Sources/Utils/String+Extensions.swift b/CodeGeneration/Sources/SyntaxSupport/String+Extensions.swift similarity index 100% rename from CodeGeneration/Sources/Utils/String+Extensions.swift rename to CodeGeneration/Sources/SyntaxSupport/String+Extensions.swift diff --git a/CodeGeneration/Sources/SyntaxSupport/SyntaxBaseKinds.swift b/CodeGeneration/Sources/SyntaxSupport/SyntaxBaseKinds.swift deleted file mode 100644 index 318dca5624c..00000000000 --- a/CodeGeneration/Sources/SyntaxSupport/SyntaxBaseKinds.swift +++ /dev/null @@ -1,21 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public let SYNTAX_BASE_KINDS: [String] = [ - "Decl", - "Expr", - "Pattern", - "Stmt", - "Syntax", - "SyntaxCollection", - "Type", -] diff --git a/CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift b/CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift new file mode 100644 index 00000000000..81ac3299b70 --- /dev/null +++ b/CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift @@ -0,0 +1,368 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +import SwiftSyntax +import SwiftSyntaxBuilder + +/// For every syntax node that shall be generated, this enum contains a case. +/// +/// Using the cases of this enum, children of syntax nodes can refer the syntax +/// node that defines their layout. +public enum SyntaxNodeKind: String, CaseIterable { + // Please keep this list sorted alphabetically + + case accessorBlock + case accessorDecl + case accessorEffectSpecifiers + case accessorList + case accessorParameter + case actorDecl + case arrayElementList + case arrayElement + case arrayExpr + case arrayType + case arrowExpr + case asExpr + case assignmentExpr + case associatedtypeDecl + case attributeList + case attribute + case attributedType + case availabilityArgument + case availabilityCondition + case availabilityEntry + case availabilityLabeledArgument + case availabilitySpecList + case availabilityVersionRestrictionListEntry + case availabilityVersionRestrictionList + case availabilityVersionRestriction + case awaitExpr + case backDeployedAttributeSpecList + case binaryOperatorExpr + case booleanLiteralExpr + case borrowExpr + case breakStmt + case canImportExpr + case canImportVersionInfo + case caseItemList + case caseItem + case catchClauseList + case catchClause + case catchItemList + case catchItem + case classDecl + case classRestrictionType + case closureCaptureItemList + case closureCaptureItemSpecifier + case closureCaptureItem + case closureCaptureSignature + case closureExpr + case closureParamList + case closureParam + case closureParameterClause + case closureParameterList + case closureParameter + case closureSignature + case codeBlockItemList + case codeBlockItem + case codeBlock + case compositionTypeElementList + case compositionTypeElement + case compositionType + case conditionElementList + case conditionElement + case conformanceRequirement + case constrainedSugarType + case continueStmt + case conventionAttributeArguments + case conventionWitnessMethodAttributeArguments + case copyExpr + case declModifierDetail + case declModifier + case declNameArgumentList + case declNameArgument + case declNameArguments + case declName + case decl + case deferStmt + case deinitializerDecl + case derivativeRegistrationAttributeArguments + case designatedTypeElement + case designatedTypeList + case dictionaryElementList + case dictionaryElement + case dictionaryExpr + case dictionaryType + case differentiabilityParamList + case differentiabilityParam + case differentiabilityParamsClause + case differentiabilityParams + case differentiableAttributeArguments + case discardAssignmentExpr + case discardStmt + case doStmt + case documentationAttributeArgument + case documentationAttributeArguments + case dynamicReplacementArguments + case editorPlaceholderDecl + case editorPlaceholderExpr + case effectsArguments + case enumCaseDecl + case enumCaseElementList + case enumCaseElement + case enumCaseParameterClause + case enumCaseParameterList + case enumCaseParameter + case enumDecl + case exposeAttributeArguments + case exprList + case expr + case expressionPattern + case expressionSegment + case expressionStmt + case extensionDecl + case fallthroughStmt + case floatLiteralExpr + case forInStmt + case forcedValueExpr + case functionCallExpr + case functionDecl + case functionEffectSpecifiers + case functionParameterList + case functionParameter + case functionSignature + case functionType + case genericArgumentClause + case genericArgumentList + case genericArgument + case genericParameterClause + case genericParameterList + case genericParameter + case genericRequirementList + case genericRequirement + case genericWhereClause + case guardStmt + case identifierExpr + case identifierPattern + case ifConfigClauseList + case ifConfigClause + case ifConfigDecl + case ifExpr + case implementsAttributeArguments + case implicitlyUnwrappedOptionalType + case importDecl + case importPathComponent + case importPath + case inOutExpr + case infixOperatorExpr + case inheritedTypeList + case inheritedType + case initializerClause + case initializerDecl + case integerLiteralExpr + case isExpr + case isTypePattern + case keyPathComponentList + case keyPathComponent + case keyPathExpr + case keyPathOptionalComponent + case keyPathPropertyComponent + case keyPathSubscriptComponent + case labeledSpecializeEntry + case labeledStmt + case layoutRequirement + case macroDecl + case macroExpansionDecl + case macroExpansionExpr + case matchingPatternCondition + case memberAccessExpr + case memberDeclBlock + case memberDeclListItem + case memberDeclList + case memberTypeIdentifier + case metatypeType + case missingDecl + case missingExpr + case missingPattern + case missingStmt + case missing + case missingType + case modifierList + case moveExpr + case multipleTrailingClosureElementList + case multipleTrailingClosureElement + case namedOpaqueReturnType + case nilLiteralExpr + case objCSelectorPiece + case objCSelector + case opaqueReturnTypeOfAttributeArguments + case operatorDecl + case operatorPrecedenceAndTypes + case optionalBindingCondition + case optionalChainingExpr + case optionalType + case originallyDefinedInArguments + case packElementExpr + case packExpansionExpr + case packExpansionType + case packReferenceType + case parameterClause + case patternBindingList + case patternBinding + case pattern + case postfixIfConfigExpr + case postfixUnaryExpr + case poundSourceLocationArgs + case poundSourceLocation + case precedenceGroupAssignment + case precedenceGroupAssociativity + case precedenceGroupAttributeList + case precedenceGroupDecl + case precedenceGroupNameElement + case precedenceGroupNameList + case precedenceGroupRelation + case prefixOperatorExpr + case primaryAssociatedTypeClause + case primaryAssociatedTypeList + case primaryAssociatedType + case protocolDecl + case qualifiedDeclName + case regexLiteralExpr + case repeatWhileStmt + case returnClause + case returnStmt + case sameTypeRequirement + case sequenceExpr + case simpleTypeIdentifier + case sourceFile + case specializeAttributeSpecList + case specializeExpr + case stmt + case stringLiteralExpr + case stringLiteralSegments + case stringSegment + case structDecl + case subscriptDecl + case subscriptExpr + case superRefExpr + case suppressedType + case switchCaseLabel + case switchCaseList + case switchCase + case switchDefaultLabel + case switchExpr + case targetFunctionEntry + case ternaryExpr + case throwStmt + case tryExpr + case tupleExprElementList + case tupleExprElement + case tupleExpr + case tuplePatternElementList + case tuplePatternElement + case tuplePattern + case tupleTypeElementList + case tupleTypeElement + case tupleType + case typeAnnotation + case typeEffectSpecifiers + case typeExpr + case typeInheritanceClause + case typeInitializerClause + case type + case typealiasDecl + case unavailableFromAsyncArguments + case underscorePrivateAttributeArguments + case unexpectedNodes + case unresolvedAsExpr + case unresolvedIsExpr + case unresolvedPatternExpr + case unresolvedTernaryExpr + case valueBindingPattern + case variableDecl + case versionComponentList + case versionComponent + case versionTuple + case whereClause + case whileStmt + case wildcardPattern + case yieldExprListElement + case yieldExprList + case yieldList + case yieldStmt + + // Nodes that have special handling throught the codebase + + case syntax + case syntaxCollection + case token + + /// `true` if this is one of the `missing*` cases. + public var isMissing: Bool { + switch self { + case .missingDecl, .missingExpr, .missingPattern, .missingStmt, .missing, .missingType: + return true + default: + return false + } + } + + /// Whether this is one of the syntax base nodes. + public var isBase: Bool { + switch self { + case .decl, .expr, .pattern, .stmt, .syntax, .syntaxCollection, .type: + return true + default: + return false + } + } + + /// A name for this node that is suitable to be used as a variables or enum + /// case's name. + public var varOrCaseName: TokenSyntax { + return .identifier(rawValue) + } + + /// The type name of this node in the SwiftSyntax module. + public var syntaxType: TypeSyntax { + switch self { + case .syntax: + return "Syntax" + case .syntaxCollection: + return "SyntaxCollection" + default: + return "\(raw: rawValue.withFirstCharacterUppercased)Syntax" + } + } + + /// 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 { + return "\(syntaxType)Protocol" + } + + /// The name of this node at the `RawSyntax` level. + public var rawType: TypeSyntax { + return "Raw\(syntaxType)" + } + + /// For base nodes, the name of the corresponding raw protocol to which all the + /// concrete raw nodes that have this base kind, conform. + public var rawProtocolType: TypeSyntax { + switch self { + case .syntax, .syntaxCollection: + return "RawSyntaxNodeProtocol" + default: + return "Raw\(raw: rawValue.withFirstCharacterUppercased)SyntaxNodeProtocol" + } + } +} diff --git a/CodeGeneration/Sources/SyntaxSupport/SyntaxNodes.swift b/CodeGeneration/Sources/SyntaxSupport/SyntaxNodes.swift index 6e73255e9bb..f06a97fa329 100644 --- a/CodeGeneration/Sources/SyntaxSupport/SyntaxNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/SyntaxNodes.swift @@ -19,11 +19,11 @@ public let SYNTAX_NODES: [Node] = + GENERIC_NODES + TYPE_NODES + PATTERN_NODES - + AVAILABILITY_NODES).sorted { $0.name < $1.name } + + AVAILABILITY_NODES).sorted { $0.kind.syntaxType.description < $1.kind.syntaxType.description } /// A lookup table of nodes indexed by their kind. -public let SYNTAX_NODE_MAP: [String: Node] = Dictionary( - uniqueKeysWithValues: SYNTAX_NODES.map { node in (node.syntaxKind, node) } +public let SYNTAX_NODE_MAP: [SyntaxNodeKind: Node] = Dictionary( + uniqueKeysWithValues: SYNTAX_NODES.map { node in (node.kind, node) } ) -public let NON_BASE_SYNTAX_NODES = SYNTAX_NODES.filter { !$0.isBase } +public let NON_BASE_SYNTAX_NODES = SYNTAX_NODES.filter { !$0.kind.isBase } diff --git a/CodeGeneration/Sources/SyntaxSupport/TokenSpec.swift b/CodeGeneration/Sources/SyntaxSupport/TokenSpec.swift index 1686c9b42b0..9984570784c 100644 --- a/CodeGeneration/Sources/SyntaxSupport/TokenSpec.swift +++ b/CodeGeneration/Sources/SyntaxSupport/TokenSpec.swift @@ -217,4 +217,8 @@ public let SYNTAX_TOKENS: [TokenSpec] = [ MiscSpec(name: "Wildcard", kind: "_", nameForDiagnostics: "wildcard", text: "_"), ] -public let SYNTAX_TOKEN_MAP = Dictionary(uniqueKeysWithValues: SYNTAX_TOKENS.map { ("\($0.name)Token", $0) }) +// FIXME: Generate the EOF token as part of the normal SYNTAX_TOKENS and remove the special handling for it. +public let SYNTAX_TOKEN_MAP = Dictionary( + uniqueKeysWithValues: (SYNTAX_TOKENS + [MiscSpec(name: "EOF", kind: "eof", nameForDiagnostics: "end of file", text: "")]) + .map { ("\($0.name)Token", $0) } +) diff --git a/CodeGeneration/Sources/SyntaxSupport/Traits.swift b/CodeGeneration/Sources/SyntaxSupport/Traits.swift index 2698a77d3ba..a25941a89af 100644 --- a/CodeGeneration/Sources/SyntaxSupport/Traits.swift +++ b/CodeGeneration/Sources/SyntaxSupport/Traits.swift @@ -33,19 +33,19 @@ public let TRAITS: [Trait] = [ Trait( traitName: "DeclGroup", children: [ - Child(name: "Attributes", kind: .node(kind: "AttributeList"), isOptional: true), - Child(name: "Modifiers", kind: .node(kind: "ModifierList"), isOptional: true), - Child(name: "MemberBlock", kind: .node(kind: "MemberDeclBlock")), + Child(name: "Attributes", kind: .node(kind: .attributeList), isOptional: true), + Child(name: "Modifiers", kind: .node(kind: .modifierList), isOptional: true), + Child(name: "MemberBlock", kind: .node(kind: .memberDeclBlock)), ] ), Trait( traitName: "EffectSpecifiers", children: [ - Child(name: "UnexpectedBeforeAsyncSpecifier", kind: .node(kind: "UnexpectedNodes"), isOptional: true), + Child(name: "UnexpectedBeforeAsyncSpecifier", kind: .node(kind: .unexpectedNodes), isOptional: true), Child(name: "AsyncSpecifier", kind: .token(choices: [.keyword(text: "async"), .keyword(text: "reasync")]), isOptional: true), - Child(name: "UnexpectedBetweenAsyncSpecifierAndThrowsSpecifier", kind: .node(kind: "UnexpectedNodes"), isOptional: true), + Child(name: "UnexpectedBetweenAsyncSpecifierAndThrowsSpecifier", kind: .node(kind: .unexpectedNodes), isOptional: true), Child(name: "ThrowsSpecifier", kind: .token(choices: [.keyword(text: "throws"), .keyword(text: "rethrows")]), isOptional: true), - Child(name: "UnexpectedAfterThrowsSpecifier", kind: .node(kind: "UnexpectedNodes"), isOptional: true), + Child(name: "UnexpectedAfterThrowsSpecifier", kind: .node(kind: .unexpectedNodes), isOptional: true), ] ), Trait( @@ -53,12 +53,12 @@ public let TRAITS: [Trait] = [ children: [ Child(name: "PoundToken", kind: .token(choices: [.token(tokenKind: "PoundToken")])), Child(name: "Macro", kind: .token(choices: [.token(tokenKind: "IdentifierToken")])), - Child(name: "GenericArguments", kind: .node(kind: "GenericArgumentClause"), isOptional: true), + Child(name: "GenericArguments", kind: .node(kind: .genericArgumentClause), isOptional: true), Child(name: "LeftParen", kind: .token(choices: [.token(tokenKind: "LeftParenToken")]), isOptional: true), - Child(name: "ArgumentList", kind: .node(kind: "TupleExprElementList")), + Child(name: "ArgumentList", kind: .node(kind: .tupleExprElementList)), Child(name: "RightParen", kind: .token(choices: [.token(tokenKind: "RightParenToken")]), isOptional: true), - Child(name: "TrailingClosure", kind: .node(kind: "ClosureExpr"), isOptional: true), - Child(name: "AdditionalTrailingClosures", kind: .node(kind: "MultipleTrailingClosureElementList"), isOptional: true), + Child(name: "TrailingClosure", kind: .node(kind: .closureExpr), isOptional: true), + Child(name: "AdditionalTrailingClosures", kind: .node(kind: .multipleTrailingClosureElementList), isOptional: true), ] ), Trait( @@ -77,25 +77,25 @@ public let TRAITS: [Trait] = [ Trait( traitName: "WithAttributes", children: [ - Child(name: "Attributes", kind: .node(kind: "AttributeList"), isOptional: true) + Child(name: "Attributes", kind: .node(kind: .attributeList), isOptional: true) ] ), Trait( traitName: "WithCodeBlock", children: [ - Child(name: "Body", kind: .node(kind: "CodeBlock")) + Child(name: "Body", kind: .node(kind: .codeBlock)) ] ), Trait( traitName: "WithModifiers", children: [ - Child(name: "Modifiers", kind: .node(kind: "ModifierList"), isOptional: true) + Child(name: "Modifiers", kind: .node(kind: .modifierList), isOptional: true) ] ), Trait( traitName: "WithStatements", children: [ - Child(name: "Statements", kind: .node(kind: "CodeBlockItemList")) + Child(name: "Statements", kind: .node(kind: .codeBlockItemList)) ] ), Trait( diff --git a/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift b/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift index ea511f5c686..ca2e88269a3 100644 --- a/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift @@ -13,9 +13,9 @@ public let TYPE_NODES: [Node] = [ // array-type -> '[' type ']' Node( - name: "ArrayType", + kind: .arrayType, + base: .type, nameForDiagnostics: "array type", - kind: "Type", children: [ Child( name: "LeftSquareBracket", @@ -23,7 +23,7 @@ public let TYPE_NODES: [Node] = [ ), Child( name: "ElementType", - kind: .node(kind: "Type") + kind: .node(kind: .type) ), Child( name: "RightSquareBracket", @@ -35,9 +35,9 @@ public let TYPE_NODES: [Node] = [ // attributed-type -> type-specifier? attribute-list? type // type-specifier -> 'inout' | 'borrowing' | 'consuming' | '__owned' | '__shared' Node( - name: "AttributedType", + kind: .attributedType, + base: .type, nameForDiagnostics: "type", - kind: "Type", traits: [ "WithAttributes" ], @@ -49,20 +49,20 @@ public let TYPE_NODES: [Node] = [ ), Child( name: "Attributes", - kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"), + kind: .collection(kind: .attributeList, collectionElementName: "Attribute"), isOptional: true ), Child( name: "BaseType", - kind: .node(kind: "Type") + kind: .node(kind: .type) ), ] ), // class-restriction-type -> 'class' Node( - name: "ClassRestrictionType", + kind: .classRestrictionType, + base: .type, nameForDiagnostics: nil, - kind: "Type", children: [ Child( name: "ClassKeyword", @@ -74,25 +74,25 @@ public let TYPE_NODES: [Node] = [ // composition-typeelement-list -> composition-type-element // composition-type-element-list? Node( - name: "CompositionTypeElementList", + kind: .compositionTypeElementList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "CompositionTypeElement" + elementChoices: [.compositionTypeElement] ), // composition-type-element -> type '&' Node( - name: "CompositionTypeElement", + kind: .compositionTypeElement, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", children: [ Child( name: "Type", - kind: .node(kind: "Type") + kind: .node(kind: .type) ), Child( name: "Ampersand", - kind: .node(kind: "Token"), + kind: .node(kind: .token), isOptional: true ), ] @@ -100,22 +100,22 @@ public let TYPE_NODES: [Node] = [ // composition-type -> composition-type-element-list Node( - name: "CompositionType", + kind: .compositionType, + base: .type, nameForDiagnostics: "type composition", - kind: "Type", children: [ Child( name: "Elements", - kind: .collection(kind: "CompositionTypeElementList", collectionElementName: "Element") + kind: .collection(kind: .compositionTypeElementList, collectionElementName: "Element") ) ] ), // constrained-sugar-type -> ('some'|'any') type Node( - name: "ConstrainedSugarType", + kind: .constrainedSugarType, + base: .type, nameForDiagnostics: "type", - kind: "Type", children: [ Child( name: "SomeOrAnySpecifier", @@ -123,16 +123,16 @@ public let TYPE_NODES: [Node] = [ ), Child( name: "BaseType", - kind: .node(kind: "Type") + kind: .node(kind: .type) ), ] ), // dictionary-type -> '[' type ':' type ']' Node( - name: "DictionaryType", + kind: .dictionaryType, + base: .type, nameForDiagnostics: "dictionary type", - kind: "Type", children: [ Child( name: "LeftSquareBracket", @@ -140,7 +140,7 @@ public let TYPE_NODES: [Node] = [ ), Child( name: "KeyType", - kind: .node(kind: "Type"), + kind: .node(kind: .type), nameForDiagnostics: "key type" ), Child( @@ -149,7 +149,7 @@ public let TYPE_NODES: [Node] = [ ), Child( name: "ValueType", - kind: .node(kind: "Type"), + kind: .node(kind: .type), nameForDiagnostics: "value type" ), Child( @@ -163,9 +163,9 @@ public let TYPE_NODES: [Node] = [ // function-type -> attribute-list '(' function-type-argument-list ')' // type-effect-specifiers? return-clause Node( - name: "FunctionType", + kind: .functionType, + base: .type, nameForDiagnostics: "function type", - kind: "Type", traits: [ "Parenthesized" ], @@ -176,7 +176,7 @@ public let TYPE_NODES: [Node] = [ ), Child( name: "Arguments", - kind: .collection(kind: "TupleTypeElementList", collectionElementName: "Argument"), + kind: .collection(kind: .tupleTypeElementList, collectionElementName: "Argument"), isIndented: true ), Child( @@ -185,21 +185,21 @@ public let TYPE_NODES: [Node] = [ ), Child( name: "EffectSpecifiers", - kind: .node(kind: "TypeEffectSpecifiers"), + kind: .node(kind: .typeEffectSpecifiers), isOptional: true ), Child( name: "Output", - kind: .node(kind: "ReturnClause") + kind: .node(kind: .returnClause) ), ] ), // generic-argument-clause -> '<' generic-argument-list '>' Node( - name: "GenericArgumentClause", + kind: .genericArgumentClause, + base: .syntax, nameForDiagnostics: "generic argument clause", - kind: "Syntax", children: [ Child( name: "LeftAngleBracket", @@ -207,7 +207,7 @@ public let TYPE_NODES: [Node] = [ ), Child( name: "Arguments", - kind: .collection(kind: "GenericArgumentList", collectionElementName: "Argument") + kind: .collection(kind: .genericArgumentList, collectionElementName: "Argument") ), Child( name: "RightAngleBracket", @@ -218,26 +218,26 @@ public let TYPE_NODES: [Node] = [ // generic-argument-list -> generic-argument generic-argument-list? Node( - name: "GenericArgumentList", + kind: .genericArgumentList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "GenericArgument" + elementChoices: [.genericArgument] ), // A generic argument. // Dictionary // ^~~~ ^~~~~~ Node( - name: "GenericArgument", + kind: .genericArgument, + base: .syntax, nameForDiagnostics: "generic argument", - kind: "Syntax", traits: [ "WithTrailingComma" ], children: [ Child( name: "ArgumentType", - kind: .node(kind: "Type") + kind: .node(kind: .type) ), Child( name: "TrailingComma", @@ -249,13 +249,13 @@ public let TYPE_NODES: [Node] = [ // implicitly-unwrapped-optional-type -> type '!' Node( - name: "ImplicitlyUnwrappedOptionalType", + kind: .implicitlyUnwrappedOptionalType, + base: .type, nameForDiagnostics: "implicitly unwrapped optional type", - kind: "Type", children: [ Child( name: "WrappedType", - kind: .node(kind: "Type") + kind: .node(kind: .type) ), Child( name: "ExclamationMark", @@ -266,13 +266,13 @@ public let TYPE_NODES: [Node] = [ // member-type-identifier -> type '.' identifier generic-argument-clause? Node( - name: "MemberTypeIdentifier", + kind: .memberTypeIdentifier, + base: .type, nameForDiagnostics: "member type", - kind: "Type", children: [ Child( name: "BaseType", - kind: .node(kind: "Type"), + kind: .node(kind: .type), nameForDiagnostics: "base type" ), Child( @@ -287,7 +287,7 @@ public let TYPE_NODES: [Node] = [ ), Child( name: "GenericArgumentClause", - kind: .node(kind: "GenericArgumentClause"), + kind: .node(kind: .genericArgumentClause), isOptional: true ), ] @@ -295,13 +295,13 @@ public let TYPE_NODES: [Node] = [ // metatype-type -> type '.' 'Type' // | type '.' 'Protocol Node( - name: "MetatypeType", + kind: .metatypeType, + base: .type, nameForDiagnostics: "metatype", - kind: "Type", children: [ Child( name: "BaseType", - kind: .node(kind: "Type"), + kind: .node(kind: .type), nameForDiagnostics: "base type" ), Child( @@ -317,30 +317,30 @@ public let TYPE_NODES: [Node] = [ // named-opaque-return-type -> generic-argument-clause type Node( - name: "NamedOpaqueReturnType", + kind: .namedOpaqueReturnType, + base: .type, nameForDiagnostics: "named opaque return type", - kind: "Type", children: [ Child( name: "GenericParameterClause", - kind: .node(kind: "GenericParameterClause") + kind: .node(kind: .genericParameterClause) ), Child( name: "BaseType", - kind: .node(kind: "Type") + kind: .node(kind: .type) ), ] ), // optional-type -> type '?' Node( - name: "OptionalType", + kind: .optionalType, + base: .type, nameForDiagnostics: "optional type", - kind: "Type", children: [ Child( name: "WrappedType", - kind: .node(kind: "Type") + kind: .node(kind: .type) ), Child( name: "QuestionMark", @@ -351,9 +351,9 @@ public let TYPE_NODES: [Node] = [ // suppressed-type -> '~' type Node( - name: "SuppressedType", + kind: .suppressedType, + base: .type, nameForDiagnostics: "suppressed type conformance", - kind: "Type", children: [ Child( name: "WithoutTilde", @@ -361,16 +361,16 @@ public let TYPE_NODES: [Node] = [ ), Child( name: "PatternType", - kind: .node(kind: "Type") + kind: .node(kind: .type) ), ] ), // pack-expansion-type -> type '...' Node( - name: "PackExpansionType", + kind: .packExpansionType, + base: .type, nameForDiagnostics: "variadic expansion", - kind: "Type", children: [ Child( name: "RepeatKeyword", @@ -378,16 +378,16 @@ public let TYPE_NODES: [Node] = [ ), Child( name: "PatternType", - kind: .node(kind: "Type") + kind: .node(kind: .type) ), ] ), // pack-reference-type -> 'each' type Node( - name: "PackReferenceType", + kind: .packReferenceType, + base: .type, nameForDiagnostics: "pack reference", - kind: "Type", children: [ Child( name: "EachKeyword", @@ -395,16 +395,16 @@ public let TYPE_NODES: [Node] = [ ), Child( name: "PackType", - kind: .node(kind: "Type") + kind: .node(kind: .type) ), ] ), // simple-type-identifier -> identifier generic-argument-clause? Node( - name: "SimpleTypeIdentifier", + kind: .simpleTypeIdentifier, + base: .type, nameForDiagnostics: "type", - kind: "Type", children: [ Child( name: "Name", @@ -413,7 +413,7 @@ public let TYPE_NODES: [Node] = [ ), Child( name: "GenericArgumentClause", - kind: .node(kind: "GenericArgumentClause"), + kind: .node(kind: .genericArgumentClause), isOptional: true ), ] @@ -421,24 +421,24 @@ public let TYPE_NODES: [Node] = [ // tuple-type-element-list -> tuple-type-element tuple-type-element-list? Node( - name: "TupleTypeElementList", + kind: .tupleTypeElementList, + base: .syntaxCollection, nameForDiagnostics: nil, - kind: "SyntaxCollection", - element: "TupleTypeElement" + elementChoices: [.tupleTypeElement] ), // tuple-type-element -> identifier? ':'? type-annotation ','? Node( - name: "TupleTypeElement", + kind: .tupleTypeElement, + base: .syntax, nameForDiagnostics: nil, - kind: "Syntax", traits: [ "WithTrailingComma" ], children: [ Child( name: "InOut", - kind: .node(kind: "InoutToken"), + kind: .token(choices: [.keyword(text: "inout")]), isOptional: true ), Child( @@ -460,7 +460,7 @@ public let TYPE_NODES: [Node] = [ ), Child( name: "Type", - kind: .node(kind: "Type") + kind: .node(kind: .type) ), Child( name: "Ellipsis", @@ -469,7 +469,7 @@ public let TYPE_NODES: [Node] = [ ), Child( name: "Initializer", - kind: .node(kind: "InitializerClause"), + kind: .node(kind: .initializerClause), isOptional: true ), Child( @@ -482,9 +482,9 @@ public let TYPE_NODES: [Node] = [ // tuple-type -> '(' tuple-type-element-list ')' Node( - name: "TupleType", + kind: .tupleType, + base: .type, nameForDiagnostics: "tuple type", - kind: "Type", traits: [ "Parenthesized" ], @@ -495,7 +495,7 @@ public let TYPE_NODES: [Node] = [ ), Child( name: "Elements", - kind: .collection(kind: "TupleTypeElementList", collectionElementName: "Element"), + kind: .collection(kind: .tupleTypeElementList, collectionElementName: "Element"), isIndented: true ), Child( diff --git a/CodeGeneration/Sources/SyntaxSupport/Utils.swift b/CodeGeneration/Sources/SyntaxSupport/Utils.swift index 59f13e4fa27..edfab5440f8 100644 --- a/CodeGeneration/Sources/SyntaxSupport/Utils.swift +++ b/CodeGeneration/Sources/SyntaxSupport/Utils.swift @@ -10,19 +10,7 @@ // //===----------------------------------------------------------------------===// -/// Converts a SyntaxKind to a type name, checking to see if the kind is -/// Syntax or SyntaxCollection first. -/// A type name is the same as the SyntaxKind name with the suffix "Syntax" -/// added. -func kindToType(kind: String) -> String { - if ["Syntax", "SyntaxCollection"].contains(kind) { - return kind - } else if kind.hasSuffix("Token") { - return "TokenSyntax" - } - - return kind + "Syntax" -} +import SwiftSyntax /// Lowercases the first word in the provided camelCase or PascalCase string. /// EOF -> eof @@ -49,3 +37,20 @@ public func lowercaseFirstWord(name: String) -> String { 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) +} diff --git a/CodeGeneration/Sources/Utils/SyntaxBuildableChild.swift b/CodeGeneration/Sources/Utils/SyntaxBuildableChild.swift index 90eef257aa3..40d209787cd 100644 --- a/CodeGeneration/Sources/Utils/SyntaxBuildableChild.swift +++ b/CodeGeneration/Sources/Utils/SyntaxBuildableChild.swift @@ -14,14 +14,32 @@ import SwiftSyntax import SwiftSyntaxBuilder import SyntaxSupport +/// Something that can either be a node of the given kind or a token of the +/// given token kind. +public enum SyntaxOrTokenNodeKind: Hashable { + case node(kind: SyntaxNodeKind) + case token(tokenKind: String) +} + /// Extension to the `Child` type to provide functionality specific to /// SwiftSyntaxBuilder. public extension Child { /// The type of this child, represented by a `SyntaxBuildableType`, which can /// be used to create the corresponding `Buildable` and `ExpressibleAs` types. var type: SyntaxBuildableType { - SyntaxBuildableType( - syntaxKind: syntaxKind, + let buildableKind: SyntaxOrTokenNodeKind + switch kind { + case .node(kind: let kind): + buildableKind = .node(kind: kind) + case .nodeChoices: + buildableKind = .node(kind: .syntax) + case .collection(kind: let kind, collectionElementName: _): + buildableKind = .node(kind: kind) + case .token: + buildableKind = .token(tokenKind: self.tokenKind!) + } + return SyntaxBuildableType( + kind: buildableKind, isOptional: isOptional ) } @@ -62,6 +80,9 @@ public extension Child { if token.isKeyword { return InitializerClauseSyntax(value: ExprSyntax(".\(raw: token.swiftKind)()")) } + if token.name == "EOF" { + return InitializerClauseSyntax(value: ExprSyntax(".eof()")) + } if token.text != nil { return InitializerClauseSyntax(value: ExprSyntax(".\(raw: token.swiftKind)Token()")) } diff --git a/CodeGeneration/Sources/Utils/SyntaxBuildableNode.swift b/CodeGeneration/Sources/Utils/SyntaxBuildableNode.swift index 6f80ec6d1ff..fd71e8e1e3a 100644 --- a/CodeGeneration/Sources/Utils/SyntaxBuildableNode.swift +++ b/CodeGeneration/Sources/Utils/SyntaxBuildableNode.swift @@ -17,48 +17,42 @@ import SyntaxSupport public extension Node { /// The node's syntax kind as `SyntaxBuildableType`. var type: SyntaxBuildableType { - SyntaxBuildableType(syntaxKind: syntaxKind) + SyntaxBuildableType(kind: .node(kind: kind)) } /// The node's syntax kind as `SyntaxBuildableType`. var baseType: SyntaxBuildableType { - if baseKind == "SyntaxCollection" { - return SyntaxBuildableType(syntaxKind: "Syntax") + if base == .syntaxCollection { + return SyntaxBuildableType(kind: .node(kind: .syntax)) } else { - return SyntaxBuildableType(syntaxKind: baseKind) + return SyntaxBuildableType(kind: .node(kind: base)) } - } - /// If documentation exists for this node, return it as a single-line string. - /// Otherwise return an empty string or a description of collection if this - /// node is a syntax collection. - var documentation: String { - let description = self.description ?? "" - if description.isEmpty && isSyntaxCollection { - return "`\(syntaxKind)` represents a collection of `\(collectionElementType.syntaxBaseName)`" - } else { - return flattened(indentedDocumentation: description) + static func from(type: SyntaxBuildableType) -> Node { + guard case .node(kind: let kind) = type.kind, let node = SYNTAX_NODE_MAP[kind] else { + fatalError("Base name \(type) does not have a syntax node") } + return node } +} - /// Assuming this node is a syntax collection, the type of its elements. - var collectionElementType: SyntaxBuildableType { - precondition(isSyntaxCollection) - return SyntaxBuildableType(syntaxKind: collectionElement) - } - +public extension LayoutNode { /// Assuming this node has a single child without a default value, that child. var singleNonDefaultedChild: Child { let nonDefaultedParams = children.filter { $0.defaultInitialization == nil } precondition(nonDefaultedParams.count == 1) return nonDefaultedParams[0] } +} - static func from(type: SyntaxBuildableType) -> Node { - guard let node = SYNTAX_NODE_MAP[type.syntaxKind] else { - fatalError("Base name \(type.syntaxKind) does not have a syntax node") +public extension CollectionNode { + /// Assuming this node is a syntax collection, the type of its elements. + var collectionElementType: SyntaxBuildableType { + if elementChoices.count > 1 { + return SyntaxBuildableType(kind: .node(kind: .syntax)) + } else { + return SyntaxBuildableType(kind: .node(kind: elementChoices.first!)) } - return node } } diff --git a/CodeGeneration/Sources/Utils/SyntaxBuildableType.swift b/CodeGeneration/Sources/Utils/SyntaxBuildableType.swift index 1177ab9c805..1ccd72c2cd1 100644 --- a/CodeGeneration/Sources/Utils/SyntaxBuildableType.swift +++ b/CodeGeneration/Sources/Utils/SyntaxBuildableType.swift @@ -19,34 +19,41 @@ import SyntaxSupport /// the `*Buildable`, `ExpressibleAs*` and `*Syntax` Swift types from the syntax /// kind. public struct SyntaxBuildableType: Hashable { - public let syntaxKind: String - public let tokenKind: String? + public let kind: SyntaxOrTokenNodeKind public let isOptional: Bool - public init(syntaxKind: String, isOptional: Bool = false) { + public init(kind: SyntaxOrTokenNodeKind, isOptional: Bool = false) { self.isOptional = isOptional - if syntaxKind.hasSuffix("Token") { - // There are different token kinds but all of them are represented by `Token` in the Swift source (see `kindToType` in `SyntaxSupport/Utils.swift`). - self.syntaxKind = "Token" - self.tokenKind = syntaxKind - } else { - self.syntaxKind = syntaxKind - self.tokenKind = nil - } + self.kind = kind } /// Whether this is a token. public var isToken: Bool { - syntaxKind == "Token" + switch kind { + case .token: + return true + default: + return false + } } /// The token if this is a token. public var token: TokenSpec? { - tokenKind.flatMap { SYNTAX_TOKEN_MAP[$0] } + switch kind { + case .token(let tokenKind): + return SYNTAX_TOKEN_MAP[tokenKind] + default: + return nil + } } public var isBaseType: Bool { - return SYNTAX_BASE_KINDS.contains(syntaxKind) + switch kind { + case .node(let kind): + return kind.isBase + default: + return false + } } /// If the type has a default value (because it is optional or a token @@ -61,7 +68,7 @@ public struct SyntaxBuildableType: Hashable { } else if token.text != nil { return ExprSyntax(".\(raw: lowercaseFirstWord(name: token.name))Token()") } - } else if tokenKind == "EOFToken" { + } else if case .token("EOFToken") = kind { return ExprSyntax(".eof()") } return nil @@ -69,16 +76,10 @@ public struct SyntaxBuildableType: Hashable { /// Whether the type is a syntax collection. public var isSyntaxCollection: Bool { - syntaxKind == "SyntaxCollection" + kind == .node(kind: .syntaxCollection) || (baseType.map(\.isSyntaxCollection) ?? false) } - /// The raw base name of this kind. Used for the `build*` methods in the - /// defined in the buildable types. - public var baseName: String { - syntaxKind - } - /// Return the `Buildable` type that is the main entry point for building /// SwiftSyntax trees using `SwiftSyntaxBuilder`. /// @@ -95,25 +96,40 @@ public struct SyntaxBuildableType: Hashable { /// Used for certain syntax collections and block-like structures (e.g. `CodeBlock`, /// `MemberDeclList`). public var isBuilderInitializable: Bool { - BUILDER_INITIALIZABLE_TYPES.keys.contains(syntaxKind) + switch kind { + case .node(let kind): + return BUILDER_INITIALIZABLE_TYPES.keys.contains(kind) + case .token: + return false + } } /// A type suitable for initializing this type through a result builder (e.g. /// returns `CodeBlockItemList` for `CodeBlock`) and otherwise itself. public var builderInitializableType: Self { - Self( - syntaxKind: BUILDER_INITIALIZABLE_TYPES[syntaxKind].flatMap { $0 } ?? syntaxKind, - isOptional: isOptional - ) + switch kind { + case .node(let kind): + if case .some(.some(let builderInitializableType)) = BUILDER_INITIALIZABLE_TYPES[kind] { + return Self( + kind: .node(kind: builderInitializableType), + isOptional: isOptional + ) + } else { + return self + } + case .token: + return self + } } /// The corresponding `*Syntax` type defined in the `SwiftSyntax` module, /// without any question marks attached. public var syntaxBaseName: String { - if syntaxKind == "Syntax" { - return "Syntax" - } else { - return "\(syntaxKind)Syntax" + switch kind { + case .node(kind: let kind): + return "\(kind.syntaxType)" + case .token: + return "TokenSyntax" } } @@ -140,13 +156,18 @@ public struct SyntaxBuildableType: Hashable { /// Assuming that this is a collection type, the non-optional type of the result builder /// that can be used to build the collection. - public var resultBuilderBaseName: String { - "\(syntaxKind)Builder" + public var resultBuilderType: TypeSyntax { + switch kind { + case .node(kind: let kind): + return TypeSyntax("\(raw: kind.rawValue.withFirstCharacterUppercased)Builder") + case .token: + preconditionFailure("Tokens cannot be constructed using result builders") + } } /// Whether this type has the `WithTrailingComma` trait. public var hasWithTrailingCommaTrait: Bool { - SYNTAX_NODES.contains { $0.type == self && $0.traits.contains("WithTrailingComma") } + SYNTAX_NODES.compactMap(\.layoutNode).contains { $0.type == self && $0.traits.contains("WithTrailingComma") } } /// If this type is not a base kind, its base type (see `SyntaxBuildableNode.base_type()`), diff --git a/CodeGeneration/Sources/Utils/Utils.swift b/CodeGeneration/Sources/Utils/Utils.swift index c78ec820793..0ebc4b145ed 100644 --- a/CodeGeneration/Sources/Utils/Utils.swift +++ b/CodeGeneration/Sources/Utils/Utils.swift @@ -28,3 +28,14 @@ public func flattened(indentedDocumentation: String) -> String { .replacingOccurrences(of: "\n", with: "") .trimmingCharacters(in: .whitespacesAndNewlines) } + +public extension Collection { + /// If the collection contains a single element, return it, otherwise `nil`. + var only: Element? { + if !isEmpty && index(after: startIndex) == endIndex { + return self.first! + } else { + return nil + } + } +} diff --git a/CodeGeneration/Sources/generate-swiftsyntax/GenerateSwiftSyntax.swift b/CodeGeneration/Sources/generate-swiftsyntax/GenerateSwiftSyntax.swift index 4d1696b1db9..65c9e1ae4a9 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/GenerateSwiftSyntax.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/GenerateSwiftSyntax.swift @@ -15,6 +15,7 @@ import Dispatch import Foundation import SwiftSyntax import SwiftSyntaxBuilder +import SyntaxSupport import Utils private let generatedDirName = "generated" @@ -25,13 +26,13 @@ private let swiftParserGeneratedDir = ["SwiftParser", generatedDirName] private let swiftParserDiagnosticsGeneratedDir = ["SwiftParserDiagnostics", generatedDirName] private let swiftSyntaxGeneratedDir = ["SwiftSyntax", generatedDirName] private let swiftSyntaxBuilderGeneratedDir = ["SwiftSyntaxBuilder", generatedDirName] -private let BASE_KIND_FILES = [ - "Decl": "SyntaxDeclNodes.swift", - "Expr": "SyntaxExprNodes.swift", - "Pattern": "SyntaxPatternNodes.swift", - "Stmt": "SyntaxStmtNodes.swift", - "Syntax": "SyntaxNodes.swift", - "Type": "SyntaxTypeNodes.swift", +private let BASE_KIND_FILES: [SyntaxNodeKind: String] = [ + .decl: "SyntaxDeclNodes.swift", + .expr: "SyntaxExprNodes.swift", + .pattern: "SyntaxPatternNodes.swift", + .stmt: "SyntaxStmtNodes.swift", + .syntax: "SyntaxNodes.swift", + .type: "SyntaxTypeNodes.swift", ] struct GeneratedFileSpec { diff --git a/CodeGeneration/Sources/generate-swiftsyntax/templates/ideutils/SyntaxClassificationFile.swift b/CodeGeneration/Sources/generate-swiftsyntax/templates/ideutils/SyntaxClassificationFile.swift index 92d3b5c60fb..61e2e8e4d7b 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/templates/ideutils/SyntaxClassificationFile.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/templates/ideutils/SyntaxClassificationFile.swift @@ -18,10 +18,10 @@ import Utils // Collects the list of classifications to use for contextual classification. fileprivate var node_child_classifications: [ChildClassification] { var result = [ChildClassification]() - for node in SYNTAX_NODES { + for node in SYNTAX_NODES.compactMap(\.layoutNode) { for (index, child) in node.children.enumerated() where child.classification?.name != nil { result.append( - ChildClassification(node: node, childIndex: index, child: child) + ChildClassification(node: node.node, childIndex: index, child: child) ) } } @@ -58,7 +58,7 @@ let syntaxClassificationFile = SourceFileSyntax(leadingTrivia: copyrightHeader) ) { try SwitchExprSyntax("switch keyPath") { for childClassification in node_child_classifications { - SwitchCaseSyntax("case \\\(raw: childClassification.parent.type.syntaxBaseName).\(raw: childClassification.child.swiftName):") { + SwitchCaseSyntax("case \\\(raw: childClassification.parent.type.syntaxBaseName).\(raw: childClassification.child.varName):") { StmtSyntax("return (.\(raw: childClassification.classification!.swiftName), \(raw: childClassification.force))") } } diff --git a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftbasicformat/BasicFormatExtensionsFile.swift b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftbasicformat/BasicFormatExtensionsFile.swift index e56a80f5ddd..2a10e9a2a34 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftbasicformat/BasicFormatExtensionsFile.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftbasicformat/BasicFormatExtensionsFile.swift @@ -81,9 +81,9 @@ let basicFormatExtensionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) try! ExtensionDeclSyntax("fileprivate extension AnyKeyPath") { try VariableDeclSyntax("var requiresIndent: Bool") { try SwitchExprSyntax("switch self") { - for node in SYNTAX_NODES where !node.isBase { + for node in SYNTAX_NODES.compactMap(\.layoutNode) { for child in node.children where child.isIndented { - SwitchCaseSyntax("case \\\(raw: node.type.syntaxBaseName).\(raw: child.swiftName):") { + SwitchCaseSyntax("case \\\(raw: node.type.syntaxBaseName).\(raw: child.varName):") { StmtSyntax("return true") } } @@ -96,9 +96,9 @@ let basicFormatExtensionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) try VariableDeclSyntax("var requiresLeadingNewline: Bool") { try SwitchExprSyntax("switch self") { - for node in SYNTAX_NODES where !node.isBase { + for node in SYNTAX_NODES.compactMap(\.layoutNode) { for child in node.children where child.requiresLeadingNewline { - SwitchCaseSyntax("case \\\(raw: node.type.syntaxBaseName).\(raw: child.swiftName):") { + SwitchCaseSyntax("case \\\(raw: node.type.syntaxBaseName).\(raw: child.varName):") { StmtSyntax("return true") } } @@ -111,10 +111,10 @@ let basicFormatExtensionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) try VariableDeclSyntax("var requiresLeadingSpace: Bool?") { try SwitchExprSyntax("switch self") { - for node in SYNTAX_NODES where !node.isBase { + for node in SYNTAX_NODES.compactMap(\.layoutNode) { for child in node.children { if let requiresLeadingSpace = child.requiresLeadingSpace { - SwitchCaseSyntax("case \\\(raw: node.type.syntaxBaseName).\(raw: child.swiftName):") { + SwitchCaseSyntax("case \\\(raw: node.type.syntaxBaseName).\(raw: child.varName):") { StmtSyntax("return \(literal: requiresLeadingSpace)") } } @@ -128,10 +128,10 @@ let basicFormatExtensionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) try VariableDeclSyntax("var requiresTrailingSpace: Bool?") { try SwitchExprSyntax("switch self") { - for node in SYNTAX_NODES where !node.isBase { + for node in SYNTAX_NODES.compactMap(\.layoutNode) { for child in node.children { if let requiresTrailingSpace = child.requiresTrailingSpace { - SwitchCaseSyntax("case \\\(raw: node.type.syntaxBaseName).\(raw: child.swiftName):") { + SwitchCaseSyntax("case \\\(raw: node.type.syntaxBaseName).\(raw: child.varName):") { StmtSyntax("return \(literal: requiresTrailingSpace)") } } diff --git a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftparser/ParserEntryFile.swift b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftparser/ParserEntryFile.swift index 3b28b5b97dd..57529e29563 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftparser/ParserEntryFile.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftparser/ParserEntryFile.swift @@ -61,7 +61,7 @@ let parserEntryFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { if let parserFunction = node.parserFunction { DeclSyntax( """ - extension \(raw: node.name): SyntaxParseable { + extension \(node.kind.syntaxType): SyntaxParseable { public static func parse(from parser: inout Parser) -> Self { let node = parser.\(raw: parserFunction)() let raw = RawSyntax(parser.parseRemainder(into: node)) diff --git a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftparserdiagnostics/ChildNameForDiagnosticsFile.swift b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftparserdiagnostics/ChildNameForDiagnosticsFile.swift index b0de7450f29..6fa493e5561 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftparserdiagnostics/ChildNameForDiagnosticsFile.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftparserdiagnostics/ChildNameForDiagnosticsFile.swift @@ -22,10 +22,10 @@ let childNameForDiagnosticFile = SourceFileSyntax(leadingTrivia: copyrightHeader "private func childNameForDiagnostics(_ keyPath: AnyKeyPath) -> String?" ) { try! SwitchExprSyntax("switch keyPath") { - for node in NON_BASE_SYNTAX_NODES where !node.isSyntaxCollection { + for node in NON_BASE_SYNTAX_NODES.compactMap(\.layoutNode) { for child in node.children { if let nameForDiagnostics = child.nameForDiagnostics { - SwitchCaseSyntax("case \\\(raw: node.type.syntaxBaseName).\(raw: child.swiftName):") { + SwitchCaseSyntax("case \\\(raw: node.type.syntaxBaseName).\(raw: child.varName):") { StmtSyntax(#"return "\#(raw: nameForDiagnostics)""#) } } diff --git a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftparserdiagnostics/SyntaxKindNameForDiagnosticsFile.swift b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftparserdiagnostics/SyntaxKindNameForDiagnosticsFile.swift index fefa05cc789..c46e74de41d 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftparserdiagnostics/SyntaxKindNameForDiagnosticsFile.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftparserdiagnostics/SyntaxKindNameForDiagnosticsFile.swift @@ -27,8 +27,8 @@ let syntaxKindNameForDiagnosticFile = SourceFileSyntax(leadingTrivia: copyrightH for node in NON_BASE_SYNTAX_NODES { if let nameForDiagnostics = node.nameForDiagnostics { - SwitchCaseSyntax("case .\(raw: node.swiftSyntaxKind):") { - StmtSyntax("return \"\(raw: nameForDiagnostics)\"") + SwitchCaseSyntax("case .\(node.varOrCaseName):") { + StmtSyntax("return \(literal: nameForDiagnostics)") } } } diff --git a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/ChildNameForKeyPathFile.swift b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/ChildNameForKeyPathFile.swift index 47a6e5d6008..933b4a4a137 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/ChildNameForKeyPathFile.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/ChildNameForKeyPathFile.swift @@ -25,12 +25,12 @@ let childNameForKeyPathFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { """ ) { try! SwitchExprSyntax("switch keyPath") { - for node in NON_BASE_SYNTAX_NODES where !node.isSyntaxCollection { + for node in NON_BASE_SYNTAX_NODES.compactMap(\.layoutNode) { for child in node.children { SwitchCaseSyntax( """ - case \\\(raw: node.type.syntaxBaseName).\(raw: child.swiftName): - return \(literal: child.swiftName) + case \\\(raw: node.type.syntaxBaseName).\(raw: child.varName): + return \(literal: child.varName) """ ) } diff --git a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/RawSyntaxNodesFile.swift b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/RawSyntaxNodesFile.swift index cea707bd7f0..7c998ee8264 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/RawSyntaxNodesFile.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/RawSyntaxNodesFile.swift @@ -15,12 +15,35 @@ import SwiftSyntaxBuilder import SyntaxSupport import Utils +fileprivate extension Node { + var childrenChoicesEnums: [(name: TokenSyntax, choices: [(caseName: TokenSyntax, kind: SyntaxNodeKind)])] { + let node = self + if let node = node.layoutNode { + return node.children.compactMap { child -> (name: TokenSyntax, choices: [(caseName: TokenSyntax, kind: SyntaxNodeKind)])? in + switch child.kind { + case .nodeChoices(let choices): + return (.identifier(child.name), choices.map { (.identifier($0.varName), $0.syntaxNodeKind) }) + default: + return nil + } + } + } else if let node = node.collectionNode, node.elementChoices.count > 1 { + let choices = node.elementChoices.map { choice -> (TokenSyntax, SyntaxNodeKind) in + (SYNTAX_NODE_MAP[choice]!.varOrCaseName, SYNTAX_NODE_MAP[choice]!.kind) + } + return [(.identifier("Element"), choices)] + } else { + return [] + } + } +} + let rawSyntaxNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { - for node in SYNTAX_NODES where node.isBase { + for node in SYNTAX_NODES where node.kind.isBase { DeclSyntax( """ @_spi(RawSyntax) - public protocol Raw\(raw: node.name)NodeProtocol: Raw\(raw: node.baseType.syntaxKind)NodeProtocol {} + public protocol \(node.kind.rawType)NodeProtocol: \(raw: node.base.rawProtocolType) {} """ ) } @@ -29,36 +52,23 @@ let rawSyntaxNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { try! StructDeclSyntax( """ @_spi(RawSyntax) - public struct Raw\(raw: node.name): Raw\(raw: (node.isBase ? node.name : node.baseType.syntaxBaseName))NodeProtocol + public struct \(node.kind.rawType): \(node.kind.isBase ? node.kind.rawProtocolType : node.base.rawProtocolType)) """ ) { - let enums: [(String, [(swiftName: String, typeName: String)])] = - node.children.compactMap { child -> (String, [(String, String)])? in - switch child.kind { - case .nodeChoices(let choices): - return (child.name, choices.map { ($0.swiftName, $0.typeName) }) - default: - return nil - } - } - + (node.collectionElementChoices?.isEmpty == false - ? [("Element", node.collectionElementChoices!.map { choice -> (String, String) in (SYNTAX_NODE_MAP[choice]!.swiftSyntaxKind, SYNTAX_NODE_MAP[choice]!.name) })] - : []) - - for (name, choices) in enums { + for (name, choices) in node.childrenChoicesEnums { try EnumDeclSyntax( """ - public enum \(raw: name): RawSyntaxNodeProtocol + public enum \(name): RawSyntaxNodeProtocol """ ) { - for (swiftName, typeName) in choices { - DeclSyntax("case `\(raw: swiftName)`(Raw\(raw: typeName))") + for (caseName, kind) in choices { + DeclSyntax("case `\(caseName)`(\(kind.rawType))") } DeclSyntax( """ public static func isKindOf(_ raw: RawSyntax) -> Bool { - return \(raw: choices.map { "Raw\($0.typeName).isKindOf(raw)" }.joined(separator: " || ")) + return \(raw: choices.map { "\($0.kind.rawType).isKindOf(raw)" }.joined(separator: " || ")) } """ ) @@ -72,10 +82,10 @@ let rawSyntaxNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { } try InitializerDeclSyntax("public init?(_ other: some RawSyntaxNodeProtocol)") { - for (swiftName, typeName) in choices { + for (swiftName, kind) in choices { StmtSyntax( """ - if let node = Raw\(raw: typeName)(other) { + if let node = \(kind.rawType)(other) { self = .\(raw: swiftName)(node) return } @@ -98,13 +108,13 @@ let rawSyntaxNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { ) try FunctionDeclSyntax("public static func isKindOf(_ raw: RawSyntax) -> Bool") { - if node.isBase { + if node.kind.isBase { let cases = CaseItemListSyntax { - for n in SYNTAX_NODES where n.baseKind == node.syntaxKind { + for n in SYNTAX_NODES where n.base == node.kind { CaseItemSyntax( pattern: ExpressionPatternSyntax( - expression: ExprSyntax(".\(raw: n.swiftSyntaxKind)") + expression: ExprSyntax(".\(raw: n.varOrCaseName)") ) ) } @@ -119,7 +129,7 @@ let rawSyntaxNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { """ ) } else { - StmtSyntax("return raw.kind == .\(raw: node.swiftSyntaxKind)") + StmtSyntax("return raw.kind == .\(node.varOrCaseName)") } } @@ -151,23 +161,23 @@ let rawSyntaxNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { """ ) - if node.isBase { + if node.kind.isBase { DeclSyntax( """ - public init(_ other: some Raw\(raw: node.name)NodeProtocol) { + public init(_ other: some \(node.kind.rawType)NodeProtocol) { self.init(unchecked: other.raw) } """ ) } - if node.isSyntaxCollection { - let element = node.collectionElementChoices?.isEmpty == false ? "Element" : "Raw\(node.collectionElementType.syntaxBaseName)" + if let node = node.collectionNode { + let element = node.elementChoices.only != nil ? "\(node.elementChoices.only!.rawType)" : "Element" DeclSyntax( """ public init(elements: [\(raw: element)], arena: __shared SyntaxArena) { let raw = RawSyntax.makeLayout( - kind: .\(raw: node.swiftSyntaxKind), uninitializedCount: elements.count, arena: arena) { layout in + kind: .\(node.varOrCaseName), uninitializedCount: elements.count, arena: arena) { layout in guard var ptr = layout.baseAddress else { return } for elem in elements { ptr.initialize(to: elem.raw) @@ -188,12 +198,12 @@ let rawSyntaxNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { ) } - if node.isBuildable || node.isMissing { + if let node = node.layoutNode { let params = FunctionParameterListSyntax { for child in node.children { FunctionParameterSyntax( - firstName: child.isUnexpectedNodes ? .wildcardToken(trailingTrivia: .space) : .identifier(child.swiftName), - secondName: child.isUnexpectedNodes ? .identifier(child.swiftName) : nil, + firstName: child.isUnexpectedNodes ? .wildcardToken(trailingTrivia: .space) : .identifier(child.varName), + secondName: child.isUnexpectedNodes ? .identifier(child.varName) : nil, colon: .colonToken(), type: child.rawParameterType, defaultArgument: child.isUnexpectedNodes ? child.defaultInitialization : nil @@ -208,7 +218,7 @@ let rawSyntaxNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { ExprSyntax("layout.initialize(repeating: nil)") for (index, child) in node.children.enumerated() { let optionalMark = child.isOptional ? "?" : "" - ExprSyntax("layout[\(raw: index)] = \(raw: child.swiftName)\(raw: optionalMark).raw") + ExprSyntax("layout[\(raw: index)] = \(raw: child.varName)\(raw: optionalMark).raw") .with(\.leadingTrivia, .newline) } } @@ -216,25 +226,25 @@ let rawSyntaxNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ let raw = RawSyntax.makeLayout( - kind: .\(raw: node.swiftSyntaxKind), uninitializedCount: \(raw: node.children.count), arena: arena) { layout in + kind: .\(node.varOrCaseName), uninitializedCount: \(raw: node.children.count), arena: arena) { layout in \(list) } """ ) } else { - DeclSyntax("let raw = RawSyntax.makeEmptyLayout(kind: .\(raw: node.swiftSyntaxKind), arena: arena)") + DeclSyntax("let raw = RawSyntax.makeEmptyLayout(kind: .\(node.varOrCaseName), arena: arena)") } ExprSyntax("self.init(unchecked: raw)") } for (index, child) in node.children.enumerated() { - try VariableDeclSyntax("public var \(raw: child.swiftName): Raw\(raw: child.type.buildable)") { + try VariableDeclSyntax("public var \(raw: child.varName): Raw\(raw: child.type.buildable)") { let iuoMark = child.isOptional ? "" : "!" - if child.typeName == "Syntax" { + if child.syntaxNodeKind == .syntax { ExprSyntax("layoutView.children[\(raw: index)]\(raw: iuoMark)") } else { - ExprSyntax("layoutView.children[\(raw: index)].map(Raw\(raw: child.typeName).init(raw:))\(raw: iuoMark)") + ExprSyntax("layoutView.children[\(raw: index)].map(\(child.syntaxNodeKind.rawType).init(raw:))\(raw: iuoMark)") } } } @@ -245,13 +255,13 @@ let rawSyntaxNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { fileprivate extension Child { var rawParameterType: TypeSyntax { - let paramType: String + let paramType: TypeSyntax if case ChildKind.nodeChoices = kind { - paramType = name + paramType = "\(raw: name)" } else { - paramType = "Raw\(typeName)" + paramType = syntaxNodeKind.rawType } - return type.optionalWrapped(type: SimpleTypeIdentifierSyntax(name: .identifier(paramType))) + return type.optionalWrapped(type: paramType) } } diff --git a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/RawSyntaxValidationFile.swift b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/RawSyntaxValidationFile.swift index 0eb9825d1af..4f6eb71050a 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/RawSyntaxValidationFile.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/RawSyntaxValidationFile.swift @@ -195,8 +195,8 @@ let rawSyntaxValidationFile = try! SourceFileSyntax(leadingTrivia: copyrightHead ) for node in NON_BASE_SYNTAX_NODES { - try SwitchCaseSyntax("case .\(raw: node.swiftSyntaxKind):") { - if node.isBuildable || node.isMissing { + try SwitchCaseSyntax("case .\(node.varOrCaseName):") { + if let node = node.layoutNode { ExprSyntax("assert(layout.count == \(raw: node.children.count))") for (index, child) in node.children.enumerated() { switch child.kind { @@ -226,21 +226,21 @@ let rawSyntaxValidationFile = try! SourceFileSyntax(leadingTrivia: copyrightHead ExprSyntax("assertNoError(kind, \(raw: index), verify(layout[\(raw: index)], as: Raw\(raw: child.type.buildable).self))") } } - } else if node.isSyntaxCollection { + } else if let node = node.collectionNode { try ForInStmtSyntax("for (index, element) in layout.enumerated()") { - if let collectionElementChoices = node.collectionElementChoices, !collectionElementChoices.isEmpty { + if let onlyElement = node.elementChoices.only { + ExprSyntax("assertNoError(kind, index, verify(element, as: \(onlyElement.rawType).self))") + } else { let verifiedChoices = ArrayExprSyntax { - for choiceName in node.collectionElementChoices! { + for choiceName in node.elementChoices { let choice = SYNTAX_NODE_MAP[choiceName]! ArrayElementSyntax( leadingTrivia: .newline, - expression: ExprSyntax("verify(element, as: Raw\(raw: choice.name).self)") + expression: ExprSyntax("verify(element, as: \(raw: choice.kind.rawType).self)") ) } } ExprSyntax("assertAnyHasNoError(kind, index, \(verifiedChoices))") - } else { - ExprSyntax("assertNoError(kind, index, verify(element, as: Raw\(node.collectionElementType.buildable).self))") } } } diff --git a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SwiftSyntaxDoccIndex.swift b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SwiftSyntaxDoccIndex.swift index 89040006c58..88b0059e182 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SwiftSyntaxDoccIndex.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SwiftSyntaxDoccIndex.swift @@ -27,17 +27,17 @@ let nodesSections: String = { result += "\n" } - var nodeKinds = [ - ("Decl", "Declarations"), - ("Expr", "Expressions"), - ("Pattern", "Patterns"), - ("Stmt", "Statements"), - ("Type", "Types"), + var nodeKinds: [(SyntaxNodeKind, String)] = [ + (.decl, "Declarations"), + (.expr, "Expressions"), + (.pattern, "Patterns"), + (.stmt, "Statements"), + (.type, "Types"), ] for (baseKind, heading) in nodeKinds { - let baseTypes = ["\(baseKind)Syntax", "\(baseKind)SyntaxProtocol", "Missing\(baseKind)Syntax"] - let leafTypes = SYNTAX_NODES.filter({ $0.baseKind == baseKind && !$0.isMissing }).map(\.name) + let baseTypes = ["\(baseKind.syntaxType)", "\(baseKind.syntaxType)Protocol", "Missing\(baseKind.syntaxType)"] + let leafTypes = SYNTAX_NODES.filter({ $0.base == baseKind && !$0.kind.isMissing }).map(\.kind.syntaxType.description) addSection(heading: heading, types: baseTypes + leafTypes) } @@ -49,18 +49,18 @@ let nodesSections: String = { "SyntaxChildrenIndexData", ] + SYNTAX_NODES.flatMap({ (node: Node) -> [String] in - guard node.isSyntaxCollection else { + guard let node = node.collectionNode else { return [] } - if !handledSyntaxTypes.contains(node.collectionElement) && SYNTAX_NODE_MAP[node.collectionElement] != nil { - return ["\(node.name)", "\(node.collectionElement)Syntax"] - } else { - return ["\(node.name)"] - } + return [node.kind.syntaxType.description] + + node.elementChoices + .filter { SYNTAX_NODE_MAP[$0] != nil } + .map(\.syntaxType.description) + .filter { !handledSyntaxTypes.contains($0) } }) ) - addSection(heading: "Miscellaneous Syntax", types: SYNTAX_NODES.map(\.name).filter({ !handledSyntaxTypes.contains($0) })) + addSection(heading: "Miscellaneous Syntax", types: SYNTAX_NODES.map(\.kind.syntaxType.description).filter({ !handledSyntaxTypes.contains($0) })) addSection(heading: "Traits", types: TRAITS.map(\.traitName)) diff --git a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxAnyVisitorFile.swift b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxAnyVisitorFile.swift index 69724902058..dcbb9baffef 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxAnyVisitorFile.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxAnyVisitorFile.swift @@ -76,10 +76,10 @@ let syntaxAnyVisitorFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { """ ) - for node in SYNTAX_NODES where node.isVisitable { + for node in SYNTAX_NODES where !node.kind.isBase { DeclSyntax( """ - override open func visit(_ node: \(raw: node.name)) -> SyntaxVisitorContinueKind { + override open func visit(_ node: \(node.kind.syntaxType)) -> SyntaxVisitorContinueKind { return visitAny(node._syntaxNode) } """ @@ -87,7 +87,7 @@ let syntaxAnyVisitorFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ - override open func visitPost(_ node: \(raw: node.name)) { + override open func visitPost(_ node: \(node.kind.syntaxType)) { visitAnyPost(node._syntaxNode) } """ diff --git a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxBaseNodesFile.swift b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxBaseNodesFile.swift index d08c8576b93..a7b51661fb2 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxBaseNodesFile.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxBaseNodesFile.swift @@ -16,15 +16,15 @@ import SyntaxSupport import Utils let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { - for node in SYNTAX_NODES where node.isBase { + for node in SYNTAX_NODES where node.kind.isBase { DeclSyntax( """ - // MARK: - \(raw: node.name) + // MARK: - \(node.kind.syntaxType) - /// Protocol to which all `\(raw: node.name)` nodes conform. Extension point to add - /// common methods to all `\(raw: node.name)` nodes. + /// Protocol to which all `\(node.kind.syntaxType)` nodes conform. Extension point to add + /// common methods to all `\(node.kind.syntaxType)` nodes. /// DO NOT CONFORM TO THIS PROTOCOL YOURSELF! - public protocol \(raw: node.name)Protocol: \(raw: node.baseType.baseName)Protocol {} + public protocol \(node.kind.protocolType): \(raw: node.base.protocolType) {} """ ) @@ -32,10 +32,10 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ /// Check whether the non-type erased version of this syntax node conforms to - /// \(raw: node.name)Protocol. + /// \(node.kind.protocolType). /// Note that this will incur an existential conversion. - func isProtocol(_: \(raw: node.name)Protocol.Protocol) -> Bool { - return self.asProtocol(\(raw: node.name)Protocol.self) != nil + func isProtocol(_: \(node.kind.protocolType).Protocol) -> Bool { + return self.asProtocol(\(node.kind.protocolType).self) != nil } """ ) @@ -43,10 +43,10 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ /// Return the non-type erased version of this syntax node if it conforms to - /// \(raw: node.name)Protocol. Otherwise return nil. + /// \(node.kind.protocolType). Otherwise return nil. /// Note that this will incur an existential conversion. - func asProtocol(_: \(raw: node.name)Protocol.Protocol) -> \(raw: node.name)Protocol? { - return self.asProtocol(SyntaxProtocol.self) as? \(raw: node.name)Protocol + func asProtocol(_: \(node.kind.protocolType).Protocol) -> \(node.kind.protocolType)? { + return self.asProtocol(SyntaxProtocol.self) as? \(node.kind.protocolType) } """ ) @@ -54,16 +54,16 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { try! StructDeclSyntax( """ - \(raw: node.description ?? "") - public struct \(raw: node.name): \(raw: node.name)Protocol, SyntaxHashable + \(raw: node.documentation) + public struct \(node.kind.syntaxType): \(node.kind.protocolType), SyntaxHashable """ ) { DeclSyntax("public let _syntaxNode: Syntax") DeclSyntax( """ - /// Create a `\(raw: node.name)` node from a specialized syntax node. - public init(_ syntax: some \(raw: node.name)Protocol) { + /// Create a `\(node.kind.syntaxType)` node from a specialized syntax node. + public init(_ syntax: some \(node.kind.protocolType)) { // We know this cast is going to succeed. Go through init(_: SyntaxData) // to do a sanity check and verify the kind matches in debug builds and get // maximum performance in release builds. @@ -74,8 +74,8 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ - /// Create a `\(raw: node.name)` node from a specialized optional syntax node. - public init?(_ syntax: (some \(raw: node.name)Protocol)?) { + /// Create a `\(node.kind.syntaxType)` node from a specialized optional syntax node. + public init?(_ syntax: (some \(node.kind.protocolType))?) { guard let syntax = syntax else { return nil } self.init(syntax) } @@ -84,7 +84,7 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ - public init(fromProtocol syntax: \(raw: node.name)Protocol) { + public init(fromProtocol syntax: \(node.kind.protocolType)) { // We know this cast is going to succeed. Go through init(_: SyntaxData) // to do a sanity check and verify the kind matches in debug builds and get // maximum performance in release builds. @@ -95,8 +95,8 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ - /// Create a `\(raw: node.name)` node from a specialized optional syntax node. - public init?(fromProtocol syntax: \(raw: node.name)Protocol?) { + /// Create a `\(node.kind.syntaxType)` node from a specialized optional syntax node. + public init?(fromProtocol syntax: \(node.kind.protocolType)?) { guard let syntax = syntax else { return nil } self.init(fromProtocol: syntax) } @@ -109,10 +109,10 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { SwitchCaseSyntax( label: .case( SwitchCaseLabelSyntax { - for childNode in SYNTAX_NODES where childNode.baseKind == node.syntaxKind { + for childNode in SYNTAX_NODES where childNode.base == node.kind { CaseItemSyntax( pattern: ExpressionPatternSyntax( - expression: ExprSyntax(".\(raw: childNode.swiftSyntaxKind)") + expression: ExprSyntax(".\(childNode.varOrCaseName)") ) ) } @@ -131,7 +131,7 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { try InitializerDeclSyntax( """ - /// Creates a `\(raw: node.name)` node from the given `SyntaxData`. This assumes + /// Creates a `\(node.kind.syntaxType)` node from the given `SyntaxData`. This assumes /// that the `SyntaxData` is of the correct kind. If it is not, the behaviour /// is undefined. internal init(_ data: SyntaxData) @@ -142,10 +142,10 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { SwitchCaseSyntax( label: .case( SwitchCaseLabelSyntax { - for childNode in SYNTAX_NODES where childNode.baseKind == node.syntaxKind { + for childNode in SYNTAX_NODES where childNode.base == node.kind { CaseItemSyntax( pattern: ExpressionPatternSyntax( - expression: ExprSyntax(".\(raw: childNode.swiftSyntaxKind)") + expression: ExprSyntax(".\(childNode.varOrCaseName)") ) ) } @@ -156,7 +156,7 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { } SwitchCaseSyntax("default:") { - ExprSyntax("preconditionFailure(\"Unable to create \(raw: node.name) from \\(data.raw.kind)\")") + ExprSyntax("preconditionFailure(\"Unable to create \(node.kind.syntaxType) from \\(data.raw.kind)\")") } } } @@ -166,7 +166,7 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ - public func `is`(_ syntaxType: S.Type) -> Bool { + public func `is`(_ syntaxType: S.Type) -> Bool { return self.as(syntaxType) != nil } """ @@ -174,7 +174,7 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ - public func `as`(_ syntaxType: S.Type) -> S? { + public func `as`(_ syntaxType: S.Type) -> S? { return S.init(self) } """ @@ -182,7 +182,7 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ - public func cast(_ syntaxType: S.Type) -> S { + public func cast(_ syntaxType: S.Type) -> S { return self.as(S.self)! } """ @@ -190,11 +190,11 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ - /// Syntax nodes always conform to `\(raw: node.name)Protocol`. This API is just + /// Syntax nodes always conform to `\(node.kind.protocolType)`. This API is just /// added for consistency. /// Note that this will incur an existential conversion. @available(*, deprecated, message: "Expression always evaluates to true") - public func isProtocol(_: \(raw: node.name)Protocol.Protocol) -> Bool { + public func isProtocol(_: \(raw: node.kind.protocolType).Protocol) -> Bool { return true } """ @@ -204,18 +204,18 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { """ /// Return the non-type erased version of this syntax node. /// Note that this will incur an existential conversion. - public func asProtocol(_: \(raw: node.name)Protocol.Protocol) -> \(raw: node.name)Protocol { - return Syntax(self).asProtocol(\(raw: node.name)Protocol.self)! + public func asProtocol(_: \(node.kind.protocolType).Protocol) -> \(node.kind.protocolType) { + return Syntax(self).asProtocol(\(node.kind.protocolType).self)! } """ ) try VariableDeclSyntax("public static var structure: SyntaxNodeStructure") { let choices = ArrayExprSyntax { - for childNode in SYNTAX_NODES where childNode.baseKind == node.syntaxKind { + for childNode in SYNTAX_NODES where childNode.base == node.kind { ArrayElementSyntax( leadingTrivia: .newline, - expression: ExprSyntax(".node(\(raw: childNode.name).self)") + expression: ExprSyntax(".node(\(childNode.kind.syntaxType).self)") ) } } @@ -236,7 +236,7 @@ let syntaxBaseNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { for node in NON_BASE_SYNTAX_NODES { ArrayElementSyntax( leadingTrivia: .newline, - expression: ExprSyntax(".node(\(raw: node.name).self)") + expression: ExprSyntax(".node(\(node.kind.syntaxType).self)") ) } } diff --git a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxCollectionsFile.swift b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxCollectionsFile.swift index 30807fbed78..1dad9ea35f1 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxCollectionsFile.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxCollectionsFile.swift @@ -37,38 +37,41 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { """ ) - for node in SYNTAX_NODES where node.isSyntaxCollection { + for node in SYNTAX_NODES.compactMap(\.collectionNode) { let documentation = - node.description.map { "/// " + $0 } - ?? """ - /// `\(node.name)` represents a collection of one or more - /// `\(node.collectionElement)` nodes. \(node.name) behaves - /// as a regular Swift collection, and has accessors that return new - /// versions of the collection with different children. - """ + !node.documentation.isEmpty + ? node.documentation + : """ + /// `\(node.kind.syntaxType)` represents a collection of one or more + /// `\(node.collectionElementType.syntaxBaseName)` nodes. \(node.kind.syntaxType) behaves + /// as a regular Swift collection, and has accessors that return new + /// versions of the collection with different children. + """ try! StructDeclSyntax( """ \(raw: documentation) - public struct \(raw: node.name): SyntaxCollection, SyntaxHashable + public struct \(raw: node.kind.syntaxType): SyntaxCollection, SyntaxHashable """ ) { - if let collectionElementChoices = node.collectionElementChoices, !collectionElementChoices.isEmpty { + if let onlyElement = node.elementChoices.only { + DeclSyntax("public typealias Element = \(onlyElement.syntaxType)") + } else { try EnumDeclSyntax( """ public enum Element: SyntaxChildChoices """ ) { - for choiceName in collectionElementChoices { + for choiceName in node.elementChoices { let choice = SYNTAX_NODE_MAP[choiceName]! - DeclSyntax("case `\(raw: choice.swiftSyntaxKind)`(\(raw: choice.name))") + DeclSyntax("case `\(choice.varOrCaseName)`(\(choice.kind.syntaxType))") } try VariableDeclSyntax("public var _syntaxNode: Syntax") { SwitchExprSyntax(switchKeyword: .keyword(.switch), expression: ExprSyntax("self")) { - for choiceName in node.collectionElementChoices ?? [] { + for choiceName in node.elementChoices { let choice = SYNTAX_NODE_MAP[choiceName]! - SwitchCaseSyntax("case .\(raw: choice.swiftSyntaxKind)(let node):") { + SwitchCaseSyntax("case .\(choice.varOrCaseName)(let node):") { StmtSyntax("return node._syntaxNode") } } @@ -77,13 +80,13 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax("init(_ data: SyntaxData) { self.init(Syntax(data))! }") - for choiceName in node.collectionElementChoices ?? [] { + for choiceName in node.elementChoices { let choiceNode = SYNTAX_NODE_MAP[choiceName]! - if choiceNode.isBase { + if choiceNode.kind.isBase { DeclSyntax( """ - public init(_ node: some \(raw: choiceNode.name)Protocol) { - self = .\(raw: choiceNode.swiftSyntaxKind)(\(raw: choiceNode.name)(node)) + public init(_ node: some \(choiceNode.kind.protocolType)) { + self = .\(choiceNode.varOrCaseName)(\(choiceNode.kind.syntaxType)(node)) } """ ) @@ -91,8 +94,8 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { } else { DeclSyntax( """ - public init(_ node: \(raw: choiceNode.name)) { - self = .\(raw: choiceNode.swiftSyntaxKind)(node) + public init(_ node: \(choiceNode.kind.syntaxType)) { + self = .\(choiceNode.varOrCaseName)(node) } """ ) @@ -100,12 +103,12 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { } try InitializerDeclSyntax("public init?(_ node: some SyntaxProtocol)") { - for choiceName in node.collectionElementChoices ?? [] { + for choiceName in node.elementChoices { let choiceNode = SYNTAX_NODE_MAP[choiceName]! StmtSyntax( """ - if let node = node.as(\(raw: choiceNode.name).self) { - self = .\(raw: choiceNode.swiftSyntaxKind)(node) + if let node = node.as(\(choiceNode.kind.syntaxType).self) { + self = .\(choiceNode.varOrCaseName)(node) return } """ @@ -117,11 +120,11 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { try VariableDeclSyntax("public static var structure: SyntaxNodeStructure") { let choices = ArrayExprSyntax { - for choiceName in node.collectionElementChoices ?? [] { + for choiceName in node.elementChoices { let choice = SYNTAX_NODE_MAP[choiceName]! ArrayElementSyntax( leadingTrivia: .newline, - expression: ExprSyntax(".node(\(raw: choice.name).self)") + expression: ExprSyntax(".node(\(choice.kind.syntaxType).self)") ) } } @@ -129,8 +132,6 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { StmtSyntax("return .choices(\(choices))") } } - } else { - DeclSyntax("public typealias Element = \(raw: node.collectionElementType.syntaxBaseName)") } DeclSyntax("public let _syntaxNode: Syntax") @@ -146,7 +147,7 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ public init?(_ node: some SyntaxProtocol) { - guard node.raw.kind == .\(raw: node.swiftSyntaxKind) else { return nil } + guard node.raw.kind == .\(node.varOrCaseName) else { return nil } self._syntaxNode = node._syntaxNode } """ @@ -158,7 +159,7 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { /// that the `SyntaxData` is of the correct kind. If it is not, the behaviour /// is undefined. internal init(_ data: SyntaxData) { - precondition(data.raw.kind == .\(raw: node.swiftSyntaxKind)) + precondition(data.raw.kind == .\(node.varOrCaseName)) self._syntaxNode = Syntax(data) } """ @@ -168,7 +169,7 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { """ public init(_ children: [Element]) { let data: SyntaxData = withExtendedLifetime(SyntaxArena()) { arena in - let raw = RawSyntax.makeLayout(kind: SyntaxKind.\(raw: node.swiftSyntaxKind), + let raw = RawSyntax.makeLayout(kind: SyntaxKind.\(node.varOrCaseName), from: children.map { $0.raw }, arena: arena) return SyntaxData.forRoot(raw) } @@ -186,29 +187,29 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ - /// Creates a new `\(raw: node.name)` by replacing the underlying layout with + /// Creates a new `\(node.kind.syntaxType)` by replacing the underlying layout with /// a different set of raw syntax nodes. /// /// - Parameter layout: The new list of raw syntax nodes underlying this /// collection. - /// - Returns: A new `\(raw: node.name)` with the new layout underlying it. - internal func replacingLayout(_ layout: [RawSyntax?]) -> \(raw: node.name) { + /// - Returns: A new `\(node.kind.syntaxType)` with the new layout underlying it. + internal func replacingLayout(_ layout: [RawSyntax?]) -> \(node.kind.syntaxType) { let arena = SyntaxArena() let newRaw = layoutView.replacingLayout(with: layout, arena: arena) let newData = data.replacingSelf(newRaw, arena: arena) - return \(raw: node.name)(newData) + return \(node.kind.syntaxType)(newData) } """ ) DeclSyntax( """ - /// Creates a new `\(raw: node.name)` by appending the provided syntax element + /// Creates a new `\(node.kind.syntaxType)` by appending the provided syntax element /// to the children. /// /// - Parameter syntax: The element to append. - /// - Returns: A new `\(raw: node.name)` with that element appended to the end. - public func appending(_ syntax: Element) -> \(raw: node.name) { + /// - Returns: A new `\(node.kind.syntaxType)` with that element appended to the end. + public func appending(_ syntax: Element) -> \(node.kind.syntaxType) { var newLayout = layoutView.formLayoutArray() newLayout.append(syntax.raw) return replacingLayout(newLayout) @@ -218,13 +219,13 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ - /// Creates a new `\(raw: node.name)` by prepending the provided syntax element + /// Creates a new `\(node.kind.syntaxType)` by prepending the provided syntax element /// to the children. /// /// - Parameter syntax: The element to prepend. - /// - Returns: A new `\(raw: node.name)` with that element prepended to the + /// - Returns: A new `\(node.kind.syntaxType)` with that element prepended to the /// beginning. - public func prepending(_ syntax: Element) -> \(raw: node.name) { + public func prepending(_ syntax: Element) -> \(node.kind.syntaxType) { return inserting(syntax, at: 0) } """ @@ -232,15 +233,15 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ - /// Creates a new `\(raw: node.name)` by inserting the provided syntax element + /// Creates a new `\(node.kind.syntaxType)` by inserting the provided syntax element /// at the provided index in the children. /// /// - Parameters: /// - syntax: The element to insert. /// - index: The index at which to insert the element in the collection. /// - /// - Returns: A new `\(raw: node.name)` with that element appended to the end. - public func inserting(_ syntax: Element, at index: Int) -> \(raw: node.name) { + /// - Returns: A new `\(node.kind.syntaxType)` with that element appended to the end. + public func inserting(_ syntax: Element, at index: Int) -> \(node.kind.syntaxType) { var newLayout = layoutView.formLayoutArray() /// Make sure the index is a valid insertion index (0 to 1 past the end) precondition((newLayout.startIndex...newLayout.endIndex).contains(index), @@ -253,15 +254,15 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ - /// Creates a new `\(raw: node.name)` by replacing the syntax element + /// Creates a new `\(node.kind.syntaxType)` by replacing the syntax element /// at the provided index. /// /// - Parameters: /// - index: The index at which to replace the element in the collection. /// - syntax: The element to replace with. /// - /// - Returns: A new `\(raw: node.name)` with the new element at the provided index. - public func replacing(childAt index: Int, with syntax: Element) -> \(raw: node.name) { + /// - Returns: A new `\(node.kind.syntaxType)` with the new element at the provided index. + public func replacing(childAt index: Int, with syntax: Element) -> \(node.kind.syntaxType) { var newLayout = layoutView.formLayoutArray() /// Make sure the index is a valid index for replacing precondition((newLayout.startIndex.. \(raw: node.name) { + public func removing(childAt index: Int) -> \(node.kind.syntaxType) { var newLayout = layoutView.formLayoutArray() newLayout.remove(at: index) return replacingLayout(newLayout) @@ -290,10 +291,10 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ - /// Creates a new `\(raw: node.name)` by removing the first element. + /// Creates a new `\(node.kind.syntaxType)` by removing the first element. /// - /// - Returns: A new `\(raw: node.name)` with the first element removed. - public func removingFirst() -> \(raw: node.name) { + /// - Returns: A new `\(node.kind.syntaxType)` with the first element removed. + public func removingFirst() -> \(node.kind.syntaxType) { var newLayout = layoutView.formLayoutArray() newLayout.removeFirst() return replacingLayout(newLayout) @@ -303,10 +304,10 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ - /// Creates a new `\(raw: node.name)` by removing the last element. + /// Creates a new `\(node.kind.syntaxType)` by removing the last element. /// - /// - Returns: A new `\(raw: node.name)` with the last element removed. - public func removingLast() -> \(raw: node.name) { + /// - Returns: A new `\(node.kind.syntaxType)` with the last element removed. + public func removingLast() -> \(node.kind.syntaxType) { var newLayout = layoutView.formLayoutArray() newLayout.removeLast() return replacingLayout(newLayout) @@ -317,8 +318,8 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { try! ExtensionDeclSyntax( """ - /// Conformance for `\(raw: node.name)` to the `BidirectionalCollection` protocol. - extension \(raw: node.name): BidirectionalCollection + /// Conformance for `\(node.kind.syntaxType)` to the `BidirectionalCollection` protocol. + extension \(node.kind.syntaxType): BidirectionalCollection """ ) { DeclSyntax("public typealias Index = SyntaxChildrenIndex") diff --git a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxEnumFile.swift b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxEnumFile.swift index 94866633f9b..517c2bdaf90 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxEnumFile.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxEnumFile.swift @@ -24,7 +24,7 @@ let syntaxEnumFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { ) { DeclSyntax("case token(TokenSyntax)") for node in NON_BASE_SYNTAX_NODES { - DeclSyntax("case \(raw: node.swiftSyntaxKind)(\(raw: node.name))") + DeclSyntax("case \(node.varOrCaseName)(\(node.kind.syntaxType))") } } @@ -45,8 +45,8 @@ let syntaxEnumFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { } for node in NON_BASE_SYNTAX_NODES { - SwitchCaseSyntax("case .\(raw: node.swiftSyntaxKind):") { - StmtSyntax("return .\(raw: node.swiftSyntaxKind)(\(raw: node.name)(self)!)") + SwitchCaseSyntax("case .\(node.varOrCaseName):") { + StmtSyntax("return .\(node.varOrCaseName)(\(node.kind.syntaxType)(self)!)") } } } diff --git a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxKindFile.swift b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxKindFile.swift index 303b40c294d..56e128c8718 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxKindFile.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxKindFile.swift @@ -24,13 +24,13 @@ let syntaxKindFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { ) { DeclSyntax("case token") for node in NON_BASE_SYNTAX_NODES { - DeclSyntax("case \(raw: node.swiftSyntaxKind)") + DeclSyntax("case \(node.varOrCaseName)") } try VariableDeclSyntax("public var isSyntaxCollection: Bool") { try SwitchExprSyntax("switch self") { - for node in SYNTAX_NODES where node.baseKind == "SyntaxCollection" { - SwitchCaseSyntax("case .\(raw: node.swiftSyntaxKind):") { + for node in SYNTAX_NODES where node.base == .syntaxCollection { + SwitchCaseSyntax("case .\(node.varOrCaseName):") { StmtSyntax("return true") } } @@ -43,8 +43,8 @@ let syntaxKindFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { try VariableDeclSyntax("public var isMissing: Bool") { try SwitchExprSyntax("switch self") { - for name in SYNTAX_BASE_KINDS where !["Syntax", "SyntaxCollection"].contains(name) { - SwitchCaseSyntax("case .missing\(raw: name):") { + for name in SyntaxNodeKind.allCases where name.isMissing { + SwitchCaseSyntax("case .\(name.varOrCaseName):") { StmtSyntax("return true") } } @@ -62,8 +62,8 @@ let syntaxKindFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { } for node in NON_BASE_SYNTAX_NODES { - SwitchCaseSyntax("case .\(raw: node.swiftSyntaxKind):") { - StmtSyntax("return \(raw: node.name).self") + SwitchCaseSyntax("case .\(node.varOrCaseName):") { + StmtSyntax("return \(node.kind.syntaxType).self") } } } diff --git a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxNodesFile.swift b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxNodesFile.swift index 49b8b1e4834..a91e434720c 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxNodesFile.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxNodesFile.swift @@ -31,17 +31,16 @@ extension Child { /// files at a managable file size, it is to be invoked multiple times with the /// variable `emitKind` set to a base kind listed in /// It then only emits those syntax nodes whose base kind are that specified kind. -func syntaxNode(emitKind: String) -> SourceFileSyntax { +func syntaxNode(emitKind: SyntaxNodeKind) -> SourceFileSyntax { SourceFileSyntax(leadingTrivia: copyrightHeader) { - for node in SYNTAX_NODES where !node.isBase && node.collectionElement.isEmpty && node.baseKind == emitKind { + for node in SYNTAX_NODES.compactMap(\.layoutNode) where node.base == emitKind { // We are actually handling this node now - let nodeDoc = node.description?.split(separator: "\n", omittingEmptySubsequences: false).map { "/// \($0)" }.joined(separator: "\n") try! StructDeclSyntax( """ - // MARK: - \(raw: node.name) + // MARK: - \(raw: node.kind.syntaxType) - \(raw: nodeDoc ?? "") - public struct \(raw: node.name): \(raw: node.baseType.syntaxBaseName)Protocol, SyntaxHashable + \(raw: node.documentation) + public struct \(raw: node.kind.syntaxType): \(raw: node.baseType.syntaxBaseName)Protocol, SyntaxHashable """ ) { for child in node.children { @@ -59,7 +58,7 @@ func syntaxNode(emitKind: String) -> SourceFileSyntax { DeclSyntax( """ public init?(_ node: some SyntaxProtocol) { - guard node.raw.kind == .\(raw: node.swiftSyntaxKind) else { return nil } + guard node.raw.kind == .\(raw: node.varOrCaseName) else { return nil } self._syntaxNode = node._syntaxNode } """ @@ -67,11 +66,11 @@ func syntaxNode(emitKind: String) -> SourceFileSyntax { DeclSyntax( """ - /// Creates a `\(raw: node.name)` node from the given `SyntaxData`. This assumes + /// Creates a `\(node.kind.syntaxType)` node from the given `SyntaxData`. This assumes /// that the `SyntaxData` is of the correct kind. If it is not, the behaviour /// is undefined. internal init(_ data: SyntaxData) { - precondition(data.raw.kind == .\(raw: node.swiftSyntaxKind)) + precondition(data.raw.kind == .\(raw: node.varOrCaseName)) self._syntaxNode = Syntax(data) } """ @@ -80,7 +79,7 @@ func syntaxNode(emitKind: String) -> SourceFileSyntax { try! InitializerDeclSyntax("\(node.generateInitializerDeclHeader())") { let parameters = ClosureParameterListSyntax { for child in node.children { - ClosureParameterSyntax(firstName: .identifier(child.swiftName)) + ClosureParameterSyntax(firstName: .identifier(child.varName)) } } @@ -98,7 +97,7 @@ func syntaxNode(emitKind: String) -> SourceFileSyntax { for child in node.children { ArrayElementSyntax( expression: MemberAccessExprSyntax( - base: child.type.optionalChained(expr: ExprSyntax("\(raw: child.swiftName)")), + base: child.type.optionalChained(expr: ExprSyntax("\(raw: child.varName)")), dot: .periodToken(), name: "raw" ) @@ -115,13 +114,13 @@ func syntaxNode(emitKind: String) -> SourceFileSyntax { rightParen: .rightParenToken(), trailingClosure: ClosureExprSyntax(signature: closureSignature) { if node.children.isEmpty { - DeclSyntax("let raw = RawSyntax.makeEmptyLayout(kind: SyntaxKind.\(raw: node.swiftSyntaxKind), arena: arena)") + DeclSyntax("let raw = RawSyntax.makeEmptyLayout(kind: SyntaxKind.\(raw: node.varOrCaseName), arena: arena)") } else { DeclSyntax("let layout: [RawSyntax?] = \(layoutList)") DeclSyntax( """ let raw = RawSyntax.makeLayout( - kind: SyntaxKind.\(raw: node.swiftSyntaxKind), + kind: SyntaxKind.\(raw: node.varOrCaseName), from: layout, arena: arena, leadingTrivia: leadingTrivia, @@ -154,13 +153,13 @@ func syntaxNode(emitKind: String) -> SourceFileSyntax { // Children properties // =================== - let childType: String = child.kind.isNodeChoicesEmpty ? child.typeName : child.name + let childType: TypeSyntax = child.kind.isNodeChoicesEmpty ? child.syntaxNodeKind.syntaxType : "\(raw: child.name)" let type = child.isOptional ? TypeSyntax("\(raw: childType)?") : TypeSyntax("\(raw: childType)") try! VariableDeclSyntax( """ \(raw: child.docComment) - public var \(raw: child.swiftName): \(type) + public var \(raw: child.varName): \(type) """ ) { AccessorDeclSyntax(accessorKind: .keyword(.get)) { @@ -174,7 +173,7 @@ func syntaxNode(emitKind: String) -> SourceFileSyntax { AccessorDeclSyntax( """ set(value) { - self = \(raw: node.name)(data.replacingChild(at: \(raw: index), with: value\(raw: child.isOptional ? "?" : "").raw, arena: SyntaxArena())) + self = \(node.kind.syntaxType)(data.replacingChild(at: \(raw: index), with: value\(raw: child.isOptional ? "?" : "").raw, arena: SyntaxArena())) } """ ) @@ -185,8 +184,7 @@ func syntaxNode(emitKind: String) -> SourceFileSyntax { // =============== // We don't currently support adding elements to a specific unexpected collection. // If needed, this could be added in the future, but for now withUnexpected should be sufficient. - if let childNode = SYNTAX_NODE_MAP[child.syntaxKind], - childNode.isSyntaxCollection, + if let childNode = SYNTAX_NODE_MAP[child.syntaxNodeKind]?.collectionNode, !child.isUnexpectedNodes, case .collection(_, let childElt) = child.kind { @@ -194,23 +192,23 @@ func syntaxNode(emitKind: String) -> SourceFileSyntax { DeclSyntax( """ - /// Adds the provided `\(raw: childElt)` to the node's `\(raw: child.swiftName)` + /// Adds the provided `\(raw: childElt)` to the node's `\(raw: child.varName)` /// collection. /// - param element: The new `\(raw: childElt)` to add to the node's - /// `\(raw: child.swiftName)` collection. + /// `\(raw: child.varName)` collection. /// - returns: A copy of the receiver with the provided `\(raw: childElt)` - /// appended to its `\(raw: child.swiftName)` collection. - public func add\(raw: childElt)(_ element: \(raw: childEltType)) -> \(raw: node.name) { + /// appended to its `\(raw: child.varName)` collection. + public func add\(raw: childElt)(_ element: \(raw: childEltType)) -> \(node.kind.syntaxType) { var collection: RawSyntax let arena = SyntaxArena() if let col = raw.layoutView!.children[\(raw: index)] { collection = col.layoutView!.appending(element.raw, arena: arena) } else { - collection = RawSyntax.makeLayout(kind: SyntaxKind.\(raw: childNode.swiftSyntaxKind), + collection = RawSyntax.makeLayout(kind: SyntaxKind.\(raw: childNode.varOrCaseName), from: [element.raw], arena: arena) } let newData = data.replacingChild(at: \(raw: index), with: collection, arena: arena) - return \(raw: node.name)(newData) + return \(node.kind.syntaxType)(newData) } """ ) @@ -221,7 +219,7 @@ func syntaxNode(emitKind: String) -> SourceFileSyntax { let layout = ArrayExprSyntax { for child in node.children { ArrayElementSyntax( - expression: ExprSyntax(#"\Self.\#(raw: child.swiftName)"#) + expression: ExprSyntax(#"\Self.\#(raw: child.varName)"#) ) } } @@ -240,13 +238,13 @@ private func generateSyntaxChildChoices(for child: Child) throws -> EnumDeclSynt return try! EnumDeclSyntax("public enum \(raw: child.name): SyntaxChildChoices") { for choice in choices { - DeclSyntax("case `\(raw: choice.swiftName)`(\(raw: choice.typeName))") + DeclSyntax("case `\(raw: choice.varName)`(\(raw: choice.syntaxNodeKind.syntaxType))") } try! VariableDeclSyntax("public var _syntaxNode: Syntax") { try! SwitchExprSyntax("switch self") { for choice in choices { - SwitchCaseSyntax("case .\(raw: choice.swiftName)(let node):") { + SwitchCaseSyntax("case .\(raw: choice.varName)(let node):") { StmtSyntax("return node._syntaxNode") } } @@ -256,11 +254,11 @@ private func generateSyntaxChildChoices(for child: Child) throws -> EnumDeclSynt DeclSyntax("init(_ data: SyntaxData) { self.init(Syntax(data))! }") for choice in choices { - if let choiceNode = SYNTAX_NODE_MAP[choice.syntaxKind], choiceNode.isBase { + if let choiceNode = SYNTAX_NODE_MAP[choice.syntaxNodeKind], choiceNode.kind.isBase { DeclSyntax( """ - public init(_ node: some \(raw: choiceNode.name)Protocol) { - self = .\(raw: choice.swiftName)(\(raw: choiceNode.name)(node)) + public init(_ node: some \(choiceNode.kind.protocolType)) { + self = .\(raw: choice.varName)(\(choiceNode.kind.syntaxType)(node)) } """ ) @@ -268,8 +266,8 @@ private func generateSyntaxChildChoices(for child: Child) throws -> EnumDeclSynt } else { DeclSyntax( """ - public init(_ node: \(raw: choice.typeName)) { - self = .\(raw: choice.swiftName)(node) + public init(_ node: \(choice.syntaxNodeKind.syntaxType)) { + self = .\(raw: choice.varName)(node) } """ ) @@ -280,8 +278,8 @@ private func generateSyntaxChildChoices(for child: Child) throws -> EnumDeclSynt for choice in choices { StmtSyntax( """ - if let node = node.as(\(raw: choice.typeName).self) { - self = .\(raw: choice.swiftName)(node) + if let node = node.as(\(choice.syntaxNodeKind.syntaxType).self) { + self = .\(raw: choice.varName)(node) return } """ @@ -295,7 +293,7 @@ private func generateSyntaxChildChoices(for child: Child) throws -> EnumDeclSynt let choices = ArrayExprSyntax { for choice in choices { ArrayElementSyntax( - expression: ExprSyntax(".node(\(raw: choice.typeName).self)") + expression: ExprSyntax(".node(\(choice.syntaxNodeKind.syntaxType).self)") ) } } @@ -305,7 +303,7 @@ private func generateSyntaxChildChoices(for child: Child) throws -> EnumDeclSynt } } -fileprivate extension Node { +fileprivate extension LayoutNode { func generateInitializerDeclHeader() -> PartialSyntaxNodeString { if children.isEmpty { return "public init()" @@ -316,9 +314,9 @@ fileprivate extension Node { if !child.kind.isNodeChoicesEmpty { paramType = "\(raw: child.name)" } else if child.hasBaseType { - paramType = "some \(raw: child.typeName)Protocol" + paramType = "some \(raw: child.syntaxNodeKind.protocolType)" } else { - paramType = "\(raw: child.typeName)" + paramType = child.syntaxNodeKind.syntaxType } if child.isOptional { @@ -331,8 +329,8 @@ fileprivate extension Node { return FunctionParameterSyntax( leadingTrivia: .newline, - firstName: child.isUnexpectedNodes ? .wildcardToken(trailingTrivia: .space) : .identifier(child.swiftName), - secondName: child.isUnexpectedNodes ? .identifier(child.swiftName) : nil, + firstName: child.isUnexpectedNodes ? .wildcardToken(trailingTrivia: .space) : .identifier(child.varName), + secondName: child.isUnexpectedNodes ? .identifier(child.varName) : nil, colon: .colonToken(), type: paramType, defaultArgument: child.defaultInitialization diff --git a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxRewriterFile.swift b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxRewriterFile.swift index 63bec20d436..cd9c08b354c 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxRewriterFile.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxRewriterFile.swift @@ -32,25 +32,25 @@ let syntaxRewriterFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { ) { DeclSyntax("public init() {}") - for node in SYNTAX_NODES where node.isVisitable { - if node.baseType.baseName == "Syntax" && node.name != "MissingSyntax" { + for node in SYNTAX_NODES where !node.kind.isBase { + if (node.base == .syntax || node.base == .syntaxCollection) && node.kind != .missing { DeclSyntax( """ - /// Visit a `\(raw: node.name)`. + /// Visit a `\(node.kind.syntaxType)`. /// - Parameter node: the node that is being visited /// - Returns: the rewritten node - open func visit(_ node: \(raw: node.name)) -> \(raw: node.name) { - return Syntax(visitChildren(node)).cast(\(raw: node.name).self) + open func visit(_ node: \(node.kind.syntaxType)) -> \(node.kind.syntaxType) { + return Syntax(visitChildren(node)).cast(\(node.kind.syntaxType).self) } """ ) } else { DeclSyntax( """ - /// Visit a `\(raw: node.name)`. + /// Visit a `\(node.kind.syntaxType)`. /// - Parameter node: the node that is being visited /// - Returns: the rewritten node - open func visit(_ node: \(raw: node.name)) -> \(raw: node.baseType.syntaxBaseName) { + open func visit(_ node: \(node.kind.syntaxType)) -> \(raw: node.baseType.syntaxBaseName) { return \(raw: node.baseType.syntaxBaseName)(visitChildren(node)) } """ @@ -119,14 +119,14 @@ let syntaxRewriterFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { """ ) - for baseKind in SYNTAX_BASE_KINDS.filter({ !["Syntax", "SyntaxCollection"].contains($0) }) { + for baseKind in SyntaxNodeKind.allCases where baseKind.isBase && baseKind != .syntax && baseKind != .syntaxCollection { DeclSyntax( """ - /// Visit any \(raw: baseKind)Syntax node. + /// Visit any \(raw: baseKind.syntaxType) node. /// - Parameter node: the node that is being visited /// - Returns: the rewritten node - public func visit(_ node: \(raw: baseKind)Syntax) -> \(raw: baseKind)Syntax { - return visit(node.data).cast(\(raw: baseKind)Syntax.self) + public func visit(_ node: \(raw: baseKind.syntaxType)) -> \(raw: baseKind.syntaxType) { + return visit(node.data).cast(\(raw: baseKind.syntaxType).self) } """ ) @@ -136,8 +136,8 @@ let syntaxRewriterFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ /// Implementation detail of visit(_:). Do not call directly. - private func visitImpl\(raw: node.name)(_ data: SyntaxData) -> Syntax { - let node = \(raw: node.name)(data) + private func visitImpl\(node.kind.syntaxType)(_ data: SyntaxData) -> Syntax { + let node = \(node.kind.syntaxType)(data) // Accessing _syntaxNode directly is faster than calling Syntax(node) visitPre(node._syntaxNode) defer { visitPost(node._syntaxNode) } @@ -207,8 +207,8 @@ let syntaxRewriterFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { } for node in NON_BASE_SYNTAX_NODES { - SwitchCaseSyntax("case .\(raw: node.swiftSyntaxKind):") { - StmtSyntax("return visitImpl\(raw: node.name)") + SwitchCaseSyntax("case .\(node.varOrCaseName):") { + StmtSyntax("return visitImpl\(node.kind.syntaxType)") } } } @@ -235,8 +235,8 @@ let syntaxRewriterFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { } for node in NON_BASE_SYNTAX_NODES { - SwitchCaseSyntax("case .\(raw: node.swiftSyntaxKind):") { - StmtSyntax("return visitImpl\(raw: node.name)(data)") + SwitchCaseSyntax("case .\(node.varOrCaseName):") { + StmtSyntax("return visitImpl\(node.kind.syntaxType)(data)") } } } diff --git a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxTraitsFile.swift b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxTraitsFile.swift index 0caaf37d65a..dccc409d2c7 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxTraitsFile.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxTraitsFile.swift @@ -25,7 +25,7 @@ let syntaxTraitsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { """ ) { for child in trait.children { - DeclSyntax("var \(raw: child.swiftName): \(raw: child.typeName)\(raw: child.isOptional ? "?" : "") { get set }") + DeclSyntax("var \(raw: child.varName): \(child.syntaxNodeKind.syntaxType)\(raw: child.isOptional ? "?" : "") { get set }") } } @@ -69,7 +69,7 @@ let syntaxTraitsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { } } - for node in SYNTAX_NODES where !node.isBase && !node.traits.isEmpty { - DeclSyntax("extension \(raw: node.name): \(raw: node.traits.map { $0 + "Syntax" }.joined(separator: ", ")) {}") + for node in SYNTAX_NODES.compactMap(\.layoutNode) where !node.traits.isEmpty { + DeclSyntax("extension \(node.kind.syntaxType): \(raw: node.traits.map { $0 + "Syntax" }.joined(separator: ", ")) {}") } } diff --git a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxTransformFile.swift b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxTransformFile.swift index 064c8a71217..97489464f3b 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxTransformFile.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxTransformFile.swift @@ -23,13 +23,13 @@ let syntaxTransformFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax("func visit(_ token: TokenSyntax) -> ResultType") - for node in SYNTAX_NODES where node.isVisitable { + for node in SYNTAX_NODES where !node.kind.isBase { DeclSyntax( """ - /// Visiting `\(raw: node.name)` specifically. + /// Visiting `\(node.kind.syntaxType)` specifically. /// - Parameter node: the node we are visiting. /// - Returns: the sum of whatever the child visitors return. - func visit(_ node: \(raw: node.name)) -> ResultType + func visit(_ node: \(node.kind.syntaxType)) -> ResultType """ ) } @@ -44,13 +44,13 @@ let syntaxTransformFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { """ ) - for node in SYNTAX_NODES where node.isVisitable { + for node in SYNTAX_NODES where !node.kind.isBase { DeclSyntax( """ - /// Visiting `\(raw: node.name)` specifically. + /// Visiting `\(node.kind.syntaxType)` specifically. /// - Parameter node: the node we are visiting. /// - Returns: nil by default. - public func visit(_ node: \(raw: node.name)) -> ResultType { + public func visit(_ node: \(node.kind.syntaxType)) -> ResultType { visitAny(Syntax(node)) } """ @@ -63,7 +63,7 @@ let syntaxTransformFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { StmtSyntax("return visit(node)") } for node in NON_BASE_SYNTAX_NODES { - SwitchCaseSyntax("case .\(raw: node.swiftSyntaxKind)(let derived):") { + SwitchCaseSyntax("case .\(node.varOrCaseName)(let derived):") { StmtSyntax("return visit(derived)") } } diff --git a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxVisitorFile.swift b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxVisitorFile.swift index f0d6a9a57d3..4538ad2bc9f 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxVisitorFile.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxVisitorFile.swift @@ -50,13 +50,13 @@ let syntaxVisitorFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { """ ) - for node in SYNTAX_NODES where node.isVisitable { + for node in SYNTAX_NODES where !node.kind.isBase { DeclSyntax( """ - /// Visiting `\(raw: node.name)` specifically. + /// Visiting `\(node.kind.syntaxType)` specifically. /// - Parameter node: the node we are visiting. /// - Returns: how should we continue visiting. - open func visit(_ node: \(raw: node.name)) -> SyntaxVisitorContinueKind { + open func visit(_ node: \(node.kind.syntaxType)) -> SyntaxVisitorContinueKind { return .visitChildren } """ @@ -64,9 +64,9 @@ let syntaxVisitorFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ - /// The function called after visiting `\(raw: node.name)` and its descendents. + /// The function called after visiting `\(node.kind.syntaxType)` and its descendents. /// - node: the node we just finished visiting. - open func visitPost(_ node: \(raw: node.name)) {} + open func visitPost(_ node: \(node.kind.syntaxType)) {} """ ) } @@ -94,8 +94,8 @@ let syntaxVisitorFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ /// Implementation detail of doVisit(_:_:). Do not call directly. - private func visitImpl\(raw: node.name)(_ data: SyntaxData) { - let node = \(raw: node.name)(data) + private func visitImpl\(node.kind.syntaxType)(_ data: SyntaxData) { + let node = \(node.kind.syntaxType)(data) let needsChildren = (visit(node) == .visitChildren) // Avoid calling into visitChildren if possible. if needsChildren && !node.raw.layoutView!.children.isEmpty { @@ -126,8 +126,8 @@ let syntaxVisitorFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { } for node in NON_BASE_SYNTAX_NODES { - SwitchCaseSyntax("case .\(raw: node.swiftSyntaxKind):") { - ExprSyntax("visitImpl\(raw: node.name)(data)") + SwitchCaseSyntax("case .\(node.varOrCaseName):") { + ExprSyntax("visitImpl\(node.kind.syntaxType)(data)") } } } diff --git a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntaxbuilder/BuildableCollectionNodesFile.swift b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntaxbuilder/BuildableCollectionNodesFile.swift index d6c021fa8e9..40272da5169 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntaxbuilder/BuildableCollectionNodesFile.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntaxbuilder/BuildableCollectionNodesFile.swift @@ -19,14 +19,19 @@ import SwiftBasicFormat let buildableCollectionNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax("import SwiftSyntax") - for node in SYNTAX_NODES where node.isSyntaxCollection { + for node in SYNTAX_NODES.compactMap(\.collectionNode) { let elementType = node.collectionElementType - let docComment = node.documentation.isEmpty ? "" : "/// \(node.documentation)\n" + let docComment = node.documentation.isEmpty ? [.docLineComment("/// `\(node.kind.syntaxType)` represents a collection of `\(elementType.syntaxBaseName)`")] : node.documentation // Generate collection node struct - try! ExtensionDeclSyntax("\(raw: docComment)extension \(raw: node.type.syntaxBaseName): ExpressibleByArrayLiteral") { + try! ExtensionDeclSyntax( + """ + \(raw: docComment) + extension \(raw: node.type.syntaxBaseName): ExpressibleByArrayLiteral + """ + ) { // Generate initializers - if elementType.isBaseType && node.collectionElementChoices?.isEmpty ?? true { + if elementType.isBaseType && node.elementChoices.count == 1 { DeclSyntax( """ public init(_ elements: \(ArrayTypeSyntax(elementType: elementType.parameterType))) { diff --git a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntaxbuilder/BuildableNodesFile.swift b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntaxbuilder/BuildableNodesFile.swift index 24860e6a68b..caad4246b09 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntaxbuilder/BuildableNodesFile.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntaxbuilder/BuildableNodesFile.swift @@ -18,7 +18,7 @@ import Utils let buildableNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax("import SwiftSyntax") - for node in SYNTAX_NODES where node.isBuildable { + for node in SYNTAX_NODES.compactMap(\.layoutNode) { let type = node.type if let convenienceInit = try! createConvenienceInitializer(node: node) { @@ -35,13 +35,13 @@ let buildableNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { private func convertFromSyntaxProtocolToSyntaxType(child: Child) -> ExprSyntax { if child.type.isBaseType && !child.kind.isNodeChoices { - return ExprSyntax("\(raw: child.type.syntaxBaseName)(fromProtocol: \(raw: child.swiftName))") + return ExprSyntax("\(raw: child.type.syntaxBaseName)(fromProtocol: \(raw: child.varName))") } - return ExprSyntax("\(raw: child.swiftName)") + return ExprSyntax("\(raw: child.varName)") } /// Create a builder-based convenience initializer, if needed. -private func createConvenienceInitializer(node: Node) throws -> InitializerDeclSyntax? { +private func createConvenienceInitializer(node: LayoutNode) throws -> InitializerDeclSyntax? { // Only create the convenience initializer if at least one parameter // is different than in the default initializer generated above. var shouldCreateInitializer = false @@ -61,30 +61,30 @@ private func createConvenienceInitializer(node: Node) throws -> InitializerDeclS shouldCreateInitializer = true let builderInitializableType = child.type.builderInitializableType if child.type.builderInitializableType != child.type { - let param = Node.from(type: child.type).singleNonDefaultedChild + let param = Node.from(type: child.type).layoutNode!.singleNonDefaultedChild if child.isOptional { - produceExpr = ExprSyntax("\(raw: child.swiftName)Builder().map { \(raw: child.type.syntaxBaseName)(\(raw: param.swiftName): $0) }") + produceExpr = ExprSyntax("\(raw: child.varName)Builder().map { \(raw: child.type.syntaxBaseName)(\(raw: param.varName): $0) }") } else { - produceExpr = ExprSyntax("\(raw: child.type.syntaxBaseName)(\(raw: param.swiftName): \(raw: child.swiftName)Builder())") + produceExpr = ExprSyntax("\(raw: child.type.syntaxBaseName)(\(raw: param.varName): \(raw: child.varName)Builder())") } } else { - produceExpr = ExprSyntax("\(raw: child.swiftName)Builder()") + produceExpr = ExprSyntax("\(raw: child.varName)Builder()") } builderParameters.append( - FunctionParameterSyntax("@\(raw: builderInitializableType.resultBuilderBaseName) \(raw: child.swiftName)Builder: () throws-> \(raw: builderInitializableType.syntax)") + FunctionParameterSyntax("@\(builderInitializableType.resultBuilderType) \(raw: child.varName)Builder: () throws-> \(raw: builderInitializableType.syntax)") ) } else { produceExpr = convertFromSyntaxProtocolToSyntaxType(child: child) normalParameters.append( FunctionParameterSyntax( - firstName: .identifier(child.swiftName), + firstName: .identifier(child.varName), colon: .colonToken(), type: child.parameterType, defaultArgument: child.defaultInitialization ) ) } - delegatedInitArgs.append(TupleExprElementSyntax(label: child.isUnexpectedNodes ? nil : child.swiftName, expression: produceExpr)) + delegatedInitArgs.append(TupleExprElementSyntax(label: child.isUnexpectedNodes ? nil : child.varName, expression: produceExpr)) } guard shouldCreateInitializer else { diff --git a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntaxbuilder/ResultBuildersFile.swift b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntaxbuilder/ResultBuildersFile.swift index fae43a49501..37646399e03 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntaxbuilder/ResultBuildersFile.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntaxbuilder/ResultBuildersFile.swift @@ -18,15 +18,15 @@ import Utils let resultBuildersFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax("import SwiftSyntax") - for node in SYNTAX_NODES where node.isSyntaxCollection { - let type = SyntaxBuildableType(syntaxKind: node.syntaxKind) + for node in SYNTAX_NODES.compactMap(\.collectionNode) { + let type = SyntaxBuildableType(kind: .node(kind: node.kind)) let elementType = node.collectionElementType - let expressionType: TypeSyntax = (node.collectionElementChoices?.isEmpty ?? true) ? elementType.parameterType : TypeSyntax("\(type.buildable).Element") + let expressionType: TypeSyntax = node.elementChoices.count == 1 ? elementType.parameterType : TypeSyntax("\(type.buildable).Element") try! StructDeclSyntax( """ @resultBuilder - public struct \(raw: type.syntaxKind)Builder + public struct \(type.resultBuilderType) """ ) { DeclSyntax( @@ -73,16 +73,18 @@ let resultBuildersFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { """ ) - for elementChoice in node.collectionElementChoices ?? [] { - DeclSyntax( - """ - /// If declared, provides contextual type information for statement - /// expressions to translate them into partial results. - public static func buildExpression(_ expression: \(raw: elementChoice)Syntax) -> Self.Component { - return buildExpression(.init(expression)) - } - """ - ) + if node.elementChoices.count > 1 { + for elementChoice in node.elementChoices { + DeclSyntax( + """ + /// If declared, provides contextual type information for statement + /// expressions to translate them into partial results. + public static func buildExpression(_ expression: \(elementChoice.syntaxType)) -> Self.Component { + return buildExpression(.init(expression)) + } + """ + ) + } } DeclSyntax( @@ -172,7 +174,7 @@ let resultBuildersFile = SourceFileSyntax(leadingTrivia: copyrightHeader) { DeclSyntax( """ public extension \(raw: type.syntaxBaseName) { - init(@\(raw: type.resultBuilderBaseName) itemsBuilder: () throws -> \(raw: type.syntaxBaseName)) rethrows { + init(@\(type.resultBuilderType) itemsBuilder: () throws -> \(raw: type.syntaxBaseName)) rethrows { self = try itemsBuilder() } } diff --git a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntaxbuilder/SyntaxExpressibleByStringInterpolationConformancesFile.swift b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntaxbuilder/SyntaxExpressibleByStringInterpolationConformancesFile.swift index 4c64c838fbb..8d4016f3cb1 100644 --- a/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntaxbuilder/SyntaxExpressibleByStringInterpolationConformancesFile.swift +++ b/CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntaxbuilder/SyntaxExpressibleByStringInterpolationConformancesFile.swift @@ -35,7 +35,7 @@ let syntaxExpressibleByStringInterpolationConformancesFile = SourceFileSyntax(le } for node in SYNTAX_NODES where node.parserFunction != nil { - DeclSyntax("extension \(raw: node.name): SyntaxExpressibleByStringInterpolation {}") + DeclSyntax("extension \(node.kind.syntaxType): SyntaxExpressibleByStringInterpolation {}") } DeclSyntax( diff --git a/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md b/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md index 4d782c2e74a..aa94f4e9508 100644 --- a/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md +++ b/Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md @@ -205,10 +205,10 @@ These articles are intended for developers wishing to contribute to SwiftSyntax - - - -- - - - +- - - - @@ -247,7 +247,6 @@ These articles are intended for developers wishing to contribute to SwiftSyntax - - - -- - - - @@ -275,13 +274,23 @@ These articles are intended for developers wishing to contribute to SwiftSyntax - - - +- +- +- - - - - - +- +- +- +- - +- +- - +- - - - @@ -299,9 +308,7 @@ These articles are intended for developers wishing to contribute to SwiftSyntax - - - -- - -- - - - @@ -323,18 +330,15 @@ These articles are intended for developers wishing to contribute to SwiftSyntax - - - -- - - - - -- - - - - - -- - - - @@ -345,19 +349,13 @@ These articles are intended for developers wishing to contribute to SwiftSyntax - - - -- -- -- - - - - - -- - -- - -- - - - diff --git a/Sources/SwiftSyntax/generated/SyntaxCollections.swift b/Sources/SwiftSyntax/generated/SyntaxCollections.swift index 22e6ccbd349..d31e32951ca 100644 --- a/Sources/SwiftSyntax/generated/SyntaxCollections.swift +++ b/Sources/SwiftSyntax/generated/SyntaxCollections.swift @@ -29,7 +29,7 @@ public extension SyntaxCollection { } /// `AccessorListSyntax` represents a collection of one or more -/// `AccessorDecl` nodes. AccessorListSyntax behaves +/// `AccessorDeclSyntax` nodes. AccessorListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct AccessorListSyntax: SyntaxCollection, SyntaxHashable { @@ -238,7 +238,7 @@ extension AccessorListSyntax: BidirectionalCollection { } /// `ArrayElementListSyntax` represents a collection of one or more -/// `ArrayElement` nodes. ArrayElementListSyntax behaves +/// `ArrayElementSyntax` nodes. ArrayElementListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct ArrayElementListSyntax: SyntaxCollection, SyntaxHashable { @@ -698,7 +698,7 @@ extension AttributeListSyntax: BidirectionalCollection { } /// `AvailabilitySpecListSyntax` represents a collection of one or more -/// `AvailabilityArgument` nodes. AvailabilitySpecListSyntax behaves +/// `AvailabilityArgumentSyntax` nodes. AvailabilitySpecListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct AvailabilitySpecListSyntax: SyntaxCollection, SyntaxHashable { @@ -907,7 +907,7 @@ extension AvailabilitySpecListSyntax: BidirectionalCollection { } /// `AvailabilityVersionRestrictionListSyntax` represents a collection of one or more -/// `AvailabilityVersionRestrictionListEntry` nodes. AvailabilityVersionRestrictionListSyntax behaves +/// `AvailabilityVersionRestrictionListEntrySyntax` nodes. AvailabilityVersionRestrictionListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct AvailabilityVersionRestrictionListSyntax: SyntaxCollection, SyntaxHashable { @@ -1116,7 +1116,7 @@ extension AvailabilityVersionRestrictionListSyntax: BidirectionalCollection { } /// `CaseItemListSyntax` represents a collection of one or more -/// `CaseItem` nodes. CaseItemListSyntax behaves +/// `CaseItemSyntax` nodes. CaseItemListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct CaseItemListSyntax: SyntaxCollection, SyntaxHashable { @@ -1325,7 +1325,7 @@ extension CaseItemListSyntax: BidirectionalCollection { } /// `CatchClauseListSyntax` represents a collection of one or more -/// `CatchClause` nodes. CatchClauseListSyntax behaves +/// `CatchClauseSyntax` nodes. CatchClauseListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct CatchClauseListSyntax: SyntaxCollection, SyntaxHashable { @@ -1534,7 +1534,7 @@ extension CatchClauseListSyntax: BidirectionalCollection { } /// `CatchItemListSyntax` represents a collection of one or more -/// `CatchItem` nodes. CatchItemListSyntax behaves +/// `CatchItemSyntax` nodes. CatchItemListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct CatchItemListSyntax: SyntaxCollection, SyntaxHashable { @@ -1743,7 +1743,7 @@ extension CatchItemListSyntax: BidirectionalCollection { } /// `ClosureCaptureItemListSyntax` represents a collection of one or more -/// `ClosureCaptureItem` nodes. ClosureCaptureItemListSyntax behaves +/// `ClosureCaptureItemSyntax` nodes. ClosureCaptureItemListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct ClosureCaptureItemListSyntax: SyntaxCollection, SyntaxHashable { @@ -1952,7 +1952,7 @@ extension ClosureCaptureItemListSyntax: BidirectionalCollection { } /// `ClosureParamListSyntax` represents a collection of one or more -/// `ClosureParam` nodes. ClosureParamListSyntax behaves +/// `ClosureParamSyntax` nodes. ClosureParamListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct ClosureParamListSyntax: SyntaxCollection, SyntaxHashable { @@ -2161,7 +2161,7 @@ extension ClosureParamListSyntax: BidirectionalCollection { } /// `ClosureParameterListSyntax` represents a collection of one or more -/// `ClosureParameter` nodes. ClosureParameterListSyntax behaves +/// `ClosureParameterSyntax` nodes. ClosureParameterListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct ClosureParameterListSyntax: SyntaxCollection, SyntaxHashable { @@ -2370,7 +2370,7 @@ extension ClosureParameterListSyntax: BidirectionalCollection { } /// `CodeBlockItemListSyntax` represents a collection of one or more -/// `CodeBlockItem` nodes. CodeBlockItemListSyntax behaves +/// `CodeBlockItemSyntax` nodes. CodeBlockItemListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct CodeBlockItemListSyntax: SyntaxCollection, SyntaxHashable { @@ -2579,7 +2579,7 @@ extension CodeBlockItemListSyntax: BidirectionalCollection { } /// `CompositionTypeElementListSyntax` represents a collection of one or more -/// `CompositionTypeElement` nodes. CompositionTypeElementListSyntax behaves +/// `CompositionTypeElementSyntax` nodes. CompositionTypeElementListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct CompositionTypeElementListSyntax: SyntaxCollection, SyntaxHashable { @@ -2788,7 +2788,7 @@ extension CompositionTypeElementListSyntax: BidirectionalCollection { } /// `ConditionElementListSyntax` represents a collection of one or more -/// `ConditionElement` nodes. ConditionElementListSyntax behaves +/// `ConditionElementSyntax` nodes. ConditionElementListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct ConditionElementListSyntax: SyntaxCollection, SyntaxHashable { @@ -2997,7 +2997,7 @@ extension ConditionElementListSyntax: BidirectionalCollection { } /// `DeclNameArgumentListSyntax` represents a collection of one or more -/// `DeclNameArgument` nodes. DeclNameArgumentListSyntax behaves +/// `DeclNameArgumentSyntax` nodes. DeclNameArgumentListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct DeclNameArgumentListSyntax: SyntaxCollection, SyntaxHashable { @@ -3206,7 +3206,7 @@ extension DeclNameArgumentListSyntax: BidirectionalCollection { } /// `DesignatedTypeListSyntax` represents a collection of one or more -/// `DesignatedTypeElement` nodes. DesignatedTypeListSyntax behaves +/// `DesignatedTypeElementSyntax` nodes. DesignatedTypeListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct DesignatedTypeListSyntax: SyntaxCollection, SyntaxHashable { @@ -3415,7 +3415,7 @@ extension DesignatedTypeListSyntax: BidirectionalCollection { } /// `DictionaryElementListSyntax` represents a collection of one or more -/// `DictionaryElement` nodes. DictionaryElementListSyntax behaves +/// `DictionaryElementSyntax` nodes. DictionaryElementListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct DictionaryElementListSyntax: SyntaxCollection, SyntaxHashable { @@ -3624,7 +3624,7 @@ extension DictionaryElementListSyntax: BidirectionalCollection { } /// `DifferentiabilityParamListSyntax` represents a collection of one or more -/// `DifferentiabilityParam` nodes. DifferentiabilityParamListSyntax behaves +/// `DifferentiabilityParamSyntax` nodes. DifferentiabilityParamListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct DifferentiabilityParamListSyntax: SyntaxCollection, SyntaxHashable { @@ -4451,7 +4451,7 @@ extension EnumCaseElementListSyntax: BidirectionalCollection { } /// `EnumCaseParameterListSyntax` represents a collection of one or more -/// `EnumCaseParameter` nodes. EnumCaseParameterListSyntax behaves +/// `EnumCaseParameterSyntax` nodes. EnumCaseParameterListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct EnumCaseParameterListSyntax: SyntaxCollection, SyntaxHashable { @@ -4866,7 +4866,7 @@ extension ExprListSyntax: BidirectionalCollection { } /// `FunctionParameterListSyntax` represents a collection of one or more -/// `FunctionParameter` nodes. FunctionParameterListSyntax behaves +/// `FunctionParameterSyntax` nodes. FunctionParameterListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct FunctionParameterListSyntax: SyntaxCollection, SyntaxHashable { @@ -5075,7 +5075,7 @@ extension FunctionParameterListSyntax: BidirectionalCollection { } /// `GenericArgumentListSyntax` represents a collection of one or more -/// `GenericArgument` nodes. GenericArgumentListSyntax behaves +/// `GenericArgumentSyntax` nodes. GenericArgumentListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct GenericArgumentListSyntax: SyntaxCollection, SyntaxHashable { @@ -5284,7 +5284,7 @@ extension GenericArgumentListSyntax: BidirectionalCollection { } /// `GenericParameterListSyntax` represents a collection of one or more -/// `GenericParameter` nodes. GenericParameterListSyntax behaves +/// `GenericParameterSyntax` nodes. GenericParameterListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct GenericParameterListSyntax: SyntaxCollection, SyntaxHashable { @@ -5493,7 +5493,7 @@ extension GenericParameterListSyntax: BidirectionalCollection { } /// `GenericRequirementListSyntax` represents a collection of one or more -/// `GenericRequirement` nodes. GenericRequirementListSyntax behaves +/// `GenericRequirementSyntax` nodes. GenericRequirementListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct GenericRequirementListSyntax: SyntaxCollection, SyntaxHashable { @@ -5702,7 +5702,7 @@ extension GenericRequirementListSyntax: BidirectionalCollection { } /// `IfConfigClauseListSyntax` represents a collection of one or more -/// `IfConfigClause` nodes. IfConfigClauseListSyntax behaves +/// `IfConfigClauseSyntax` nodes. IfConfigClauseListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct IfConfigClauseListSyntax: SyntaxCollection, SyntaxHashable { @@ -5911,7 +5911,7 @@ extension IfConfigClauseListSyntax: BidirectionalCollection { } /// `ImportPathSyntax` represents a collection of one or more -/// `ImportPathComponent` nodes. ImportPathSyntax behaves +/// `ImportPathComponentSyntax` nodes. ImportPathSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct ImportPathSyntax: SyntaxCollection, SyntaxHashable { @@ -6120,7 +6120,7 @@ extension ImportPathSyntax: BidirectionalCollection { } /// `InheritedTypeListSyntax` represents a collection of one or more -/// `InheritedType` nodes. InheritedTypeListSyntax behaves +/// `InheritedTypeSyntax` nodes. InheritedTypeListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct InheritedTypeListSyntax: SyntaxCollection, SyntaxHashable { @@ -6329,7 +6329,7 @@ extension InheritedTypeListSyntax: BidirectionalCollection { } /// `KeyPathComponentListSyntax` represents a collection of one or more -/// `KeyPathComponent` nodes. KeyPathComponentListSyntax behaves +/// `KeyPathComponentSyntax` nodes. KeyPathComponentListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct KeyPathComponentListSyntax: SyntaxCollection, SyntaxHashable { @@ -6538,7 +6538,7 @@ extension KeyPathComponentListSyntax: BidirectionalCollection { } /// `MemberDeclListSyntax` represents a collection of one or more -/// `MemberDeclListItem` nodes. MemberDeclListSyntax behaves +/// `MemberDeclListItemSyntax` nodes. MemberDeclListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct MemberDeclListSyntax: SyntaxCollection, SyntaxHashable { @@ -6747,7 +6747,7 @@ extension MemberDeclListSyntax: BidirectionalCollection { } /// `ModifierListSyntax` represents a collection of one or more -/// `DeclModifier` nodes. ModifierListSyntax behaves +/// `DeclModifierSyntax` nodes. ModifierListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct ModifierListSyntax: SyntaxCollection, SyntaxHashable { @@ -6956,7 +6956,7 @@ extension ModifierListSyntax: BidirectionalCollection { } /// `MultipleTrailingClosureElementListSyntax` represents a collection of one or more -/// `MultipleTrailingClosureElement` nodes. MultipleTrailingClosureElementListSyntax behaves +/// `MultipleTrailingClosureElementSyntax` nodes. MultipleTrailingClosureElementListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct MultipleTrailingClosureElementListSyntax: SyntaxCollection, SyntaxHashable { @@ -7165,7 +7165,7 @@ extension MultipleTrailingClosureElementListSyntax: BidirectionalCollection { } /// `ObjCSelectorSyntax` represents a collection of one or more -/// `ObjCSelectorPiece` nodes. ObjCSelectorSyntax behaves +/// `ObjCSelectorPieceSyntax` nodes. ObjCSelectorSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct ObjCSelectorSyntax: SyntaxCollection, SyntaxHashable { @@ -7374,7 +7374,7 @@ extension ObjCSelectorSyntax: BidirectionalCollection { } /// `PatternBindingListSyntax` represents a collection of one or more -/// `PatternBinding` nodes. PatternBindingListSyntax behaves +/// `PatternBindingSyntax` nodes. PatternBindingListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct PatternBindingListSyntax: SyntaxCollection, SyntaxHashable { @@ -7846,7 +7846,7 @@ extension PrecedenceGroupAttributeListSyntax: BidirectionalCollection { } /// `PrecedenceGroupNameListSyntax` represents a collection of one or more -/// `PrecedenceGroupNameElement` nodes. PrecedenceGroupNameListSyntax behaves +/// `PrecedenceGroupNameElementSyntax` nodes. PrecedenceGroupNameListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct PrecedenceGroupNameListSyntax: SyntaxCollection, SyntaxHashable { @@ -8055,7 +8055,7 @@ extension PrecedenceGroupNameListSyntax: BidirectionalCollection { } /// `PrimaryAssociatedTypeListSyntax` represents a collection of one or more -/// `PrimaryAssociatedType` nodes. PrimaryAssociatedTypeListSyntax behaves +/// `PrimaryAssociatedTypeSyntax` nodes. PrimaryAssociatedTypeListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct PrimaryAssociatedTypeListSyntax: SyntaxCollection, SyntaxHashable { @@ -9039,7 +9039,7 @@ extension SwitchCaseListSyntax: BidirectionalCollection { } /// `TupleExprElementListSyntax` represents a collection of one or more -/// `TupleExprElement` nodes. TupleExprElementListSyntax behaves +/// `TupleExprElementSyntax` nodes. TupleExprElementListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct TupleExprElementListSyntax: SyntaxCollection, SyntaxHashable { @@ -9248,7 +9248,7 @@ extension TupleExprElementListSyntax: BidirectionalCollection { } /// `TuplePatternElementListSyntax` represents a collection of one or more -/// `TuplePatternElement` nodes. TuplePatternElementListSyntax behaves +/// `TuplePatternElementSyntax` nodes. TuplePatternElementListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct TuplePatternElementListSyntax: SyntaxCollection, SyntaxHashable { @@ -9457,7 +9457,7 @@ extension TuplePatternElementListSyntax: BidirectionalCollection { } /// `TupleTypeElementListSyntax` represents a collection of one or more -/// `TupleTypeElement` nodes. TupleTypeElementListSyntax behaves +/// `TupleTypeElementSyntax` nodes. TupleTypeElementListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct TupleTypeElementListSyntax: SyntaxCollection, SyntaxHashable { @@ -9872,7 +9872,7 @@ extension UnexpectedNodesSyntax: BidirectionalCollection { } /// `VersionComponentListSyntax` represents a collection of one or more -/// `VersionComponent` nodes. VersionComponentListSyntax behaves +/// `VersionComponentSyntax` nodes. VersionComponentListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct VersionComponentListSyntax: SyntaxCollection, SyntaxHashable { @@ -10081,7 +10081,7 @@ extension VersionComponentListSyntax: BidirectionalCollection { } /// `YieldExprListSyntax` represents a collection of one or more -/// `YieldExprListElement` nodes. YieldExprListSyntax behaves +/// `YieldExprListElementSyntax` nodes. YieldExprListSyntax behaves /// as a regular Swift collection, and has accessors that return new /// versions of the collection with different children. public struct YieldExprListSyntax: SyntaxCollection, SyntaxHashable { diff --git a/Sources/SwiftSyntax/generated/SyntaxKind.swift b/Sources/SwiftSyntax/generated/SyntaxKind.swift index f9bee40132d..2b475a6bf2e 100644 --- a/Sources/SwiftSyntax/generated/SyntaxKind.swift +++ b/Sources/SwiftSyntax/generated/SyntaxKind.swift @@ -403,6 +403,8 @@ public enum SyntaxKind { return true case .missingStmt: return true + case .missing: + return true case .missingType: return true default: diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift index abb33872e7a..4cd02542024 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift @@ -1453,7 +1453,7 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) assertNoError(kind, 5, verify(layout[5], as: RawCodeBlockSyntax.self)) assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 7, verify(layout[7], as: RawTokenSyntax?.self)) + assertNoError(kind, 7, verify(layout[7], as: RawTokenSyntax?.self, tokenChoices: [.keyword("else")])) assertNoError(kind, 8, verify(layout[8], as: RawUnexpectedNodesSyntax?.self)) assertAnyHasNoError(kind, 9, [ verify(layout[9], as: RawSyntax?.self)]) @@ -2254,7 +2254,7 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) assertNoError(kind, 1, verify(layout[1], as: RawCodeBlockItemListSyntax.self)) assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax.self)) + assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.eof)])) assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) case .specializeAttributeSpecList: for (index, element) in layout.enumerated() { @@ -2502,7 +2502,7 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { case .tupleTypeElement: assert(layout.count == 17) assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self)) - assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax?.self)) + assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax?.self, tokenChoices: [.keyword("inout")])) assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.identifier), .tokenKind(.wildcard)])) assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self)) diff --git a/Sources/SwiftSyntaxBuilder/generated/BuildableCollectionNodes.swift b/Sources/SwiftSyntaxBuilder/generated/BuildableCollectionNodes.swift index 078febb8ff1..1e05764984b 100644 --- a/Sources/SwiftSyntaxBuilder/generated/BuildableCollectionNodes.swift +++ b/Sources/SwiftSyntaxBuilder/generated/BuildableCollectionNodes.swift @@ -14,126 +14,126 @@ import SwiftSyntax -/// `AccessorList` represents a collection of `AccessorDeclSyntax` +/// `AccessorListSyntax` represents a collection of `AccessorDeclSyntax` extension AccessorListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `ArrayElementList` represents a collection of `ArrayElementSyntax` +/// `ArrayElementListSyntax` represents a collection of `ArrayElementSyntax` extension ArrayElementListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `AttributeList` represents a collection of `Syntax` +/// `AttributeListSyntax` represents a collection of `Syntax` extension AttributeListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `AvailabilitySpecList` represents a collection of `AvailabilityArgumentSyntax` +/// `AvailabilitySpecListSyntax` represents a collection of `AvailabilityArgumentSyntax` extension AvailabilitySpecListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `AvailabilityVersionRestrictionList` represents a collection of `AvailabilityVersionRestrictionListEntrySyntax` +/// `AvailabilityVersionRestrictionListSyntax` represents a collection of `AvailabilityVersionRestrictionListEntrySyntax` extension AvailabilityVersionRestrictionListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `CaseItemList` represents a collection of `CaseItemSyntax` +/// `CaseItemListSyntax` represents a collection of `CaseItemSyntax` extension CaseItemListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `CatchClauseList` represents a collection of `CatchClauseSyntax` +/// `CatchClauseListSyntax` represents a collection of `CatchClauseSyntax` extension CatchClauseListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `CatchItemList` represents a collection of `CatchItemSyntax` +/// `CatchItemListSyntax` represents a collection of `CatchItemSyntax` extension CatchItemListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `ClosureCaptureItemList` represents a collection of `ClosureCaptureItemSyntax` +/// `ClosureCaptureItemListSyntax` represents a collection of `ClosureCaptureItemSyntax` extension ClosureCaptureItemListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `ClosureParamList` represents a collection of `ClosureParamSyntax` +/// `ClosureParamListSyntax` represents a collection of `ClosureParamSyntax` extension ClosureParamListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `ClosureParameterList` represents a collection of `ClosureParameterSyntax` +/// `ClosureParameterListSyntax` represents a collection of `ClosureParameterSyntax` extension ClosureParameterListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `CodeBlockItemList` represents a collection of `CodeBlockItemSyntax` +/// `CodeBlockItemListSyntax` represents a collection of `CodeBlockItemSyntax` extension CodeBlockItemListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `CompositionTypeElementList` represents a collection of `CompositionTypeElementSyntax` +/// `CompositionTypeElementListSyntax` represents a collection of `CompositionTypeElementSyntax` extension CompositionTypeElementListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `ConditionElementList` represents a collection of `ConditionElementSyntax` +/// `ConditionElementListSyntax` represents a collection of `ConditionElementSyntax` extension ConditionElementListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `DeclNameArgumentList` represents a collection of `DeclNameArgumentSyntax` +/// `DeclNameArgumentListSyntax` represents a collection of `DeclNameArgumentSyntax` extension DeclNameArgumentListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `DesignatedTypeList` represents a collection of `DesignatedTypeElementSyntax` +/// `DesignatedTypeListSyntax` represents a collection of `DesignatedTypeElementSyntax` extension DesignatedTypeListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `DictionaryElementList` represents a collection of `DictionaryElementSyntax` +/// `DictionaryElementListSyntax` represents a collection of `DictionaryElementSyntax` extension DictionaryElementListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `DifferentiabilityParamList` represents a collection of `DifferentiabilityParamSyntax` +/// `DifferentiabilityParamListSyntax` represents a collection of `DifferentiabilityParamSyntax` extension DifferentiabilityParamListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) @@ -161,7 +161,7 @@ extension EnumCaseElementListSyntax: ExpressibleByArrayLiteral { } } -/// `EnumCaseParameterList` represents a collection of `EnumCaseParameterSyntax` +/// `EnumCaseParameterListSyntax` represents a collection of `EnumCaseParameterSyntax` extension EnumCaseParameterListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) @@ -181,112 +181,112 @@ extension ExprListSyntax: ExpressibleByArrayLiteral { } } -/// `FunctionParameterList` represents a collection of `FunctionParameterSyntax` +/// `FunctionParameterListSyntax` represents a collection of `FunctionParameterSyntax` extension FunctionParameterListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `GenericArgumentList` represents a collection of `GenericArgumentSyntax` +/// `GenericArgumentListSyntax` represents a collection of `GenericArgumentSyntax` extension GenericArgumentListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `GenericParameterList` represents a collection of `GenericParameterSyntax` +/// `GenericParameterListSyntax` represents a collection of `GenericParameterSyntax` extension GenericParameterListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `GenericRequirementList` represents a collection of `GenericRequirementSyntax` +/// `GenericRequirementListSyntax` represents a collection of `GenericRequirementSyntax` extension GenericRequirementListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `IfConfigClauseList` represents a collection of `IfConfigClauseSyntax` +/// `IfConfigClauseListSyntax` represents a collection of `IfConfigClauseSyntax` extension IfConfigClauseListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `ImportPath` represents a collection of `ImportPathComponentSyntax` +/// `ImportPathSyntax` represents a collection of `ImportPathComponentSyntax` extension ImportPathSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `InheritedTypeList` represents a collection of `InheritedTypeSyntax` +/// `InheritedTypeListSyntax` represents a collection of `InheritedTypeSyntax` extension InheritedTypeListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `KeyPathComponentList` represents a collection of `KeyPathComponentSyntax` +/// `KeyPathComponentListSyntax` represents a collection of `KeyPathComponentSyntax` extension KeyPathComponentListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `MemberDeclList` represents a collection of `MemberDeclListItemSyntax` +/// `MemberDeclListSyntax` represents a collection of `MemberDeclListItemSyntax` extension MemberDeclListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `ModifierList` represents a collection of `DeclModifierSyntax` +/// `ModifierListSyntax` represents a collection of `DeclModifierSyntax` extension ModifierListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `MultipleTrailingClosureElementList` represents a collection of `MultipleTrailingClosureElementSyntax` +/// `MultipleTrailingClosureElementListSyntax` represents a collection of `MultipleTrailingClosureElementSyntax` extension MultipleTrailingClosureElementListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `ObjCSelector` represents a collection of `ObjCSelectorPieceSyntax` +/// `ObjCSelectorSyntax` represents a collection of `ObjCSelectorPieceSyntax` extension ObjCSelectorSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `PatternBindingList` represents a collection of `PatternBindingSyntax` +/// `PatternBindingListSyntax` represents a collection of `PatternBindingSyntax` extension PatternBindingListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `PrecedenceGroupAttributeList` represents a collection of `Syntax` +/// `PrecedenceGroupAttributeListSyntax` represents a collection of `Syntax` extension PrecedenceGroupAttributeListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `PrecedenceGroupNameList` represents a collection of `PrecedenceGroupNameElementSyntax` +/// `PrecedenceGroupNameListSyntax` represents a collection of `PrecedenceGroupNameElementSyntax` extension PrecedenceGroupNameListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `PrimaryAssociatedTypeList` represents a collection of `PrimaryAssociatedTypeSyntax` +/// `PrimaryAssociatedTypeListSyntax` represents a collection of `PrimaryAssociatedTypeSyntax` extension PrimaryAssociatedTypeListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) @@ -300,35 +300,35 @@ extension SpecializeAttributeSpecListSyntax: ExpressibleByArrayLiteral { } } -/// `StringLiteralSegments` represents a collection of `Syntax` +/// `StringLiteralSegmentsSyntax` represents a collection of `Syntax` extension StringLiteralSegmentsSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `SwitchCaseList` represents a collection of `Syntax` +/// `SwitchCaseListSyntax` represents a collection of `Syntax` extension SwitchCaseListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `TupleExprElementList` represents a collection of `TupleExprElementSyntax` +/// `TupleExprElementListSyntax` represents a collection of `TupleExprElementSyntax` extension TupleExprElementListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `TuplePatternElementList` represents a collection of `TuplePatternElementSyntax` +/// `TuplePatternElementListSyntax` represents a collection of `TuplePatternElementSyntax` extension TuplePatternElementListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `TupleTypeElementList` represents a collection of `TupleTypeElementSyntax` +/// `TupleTypeElementListSyntax` represents a collection of `TupleTypeElementSyntax` extension TupleTypeElementListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) @@ -348,14 +348,14 @@ extension UnexpectedNodesSyntax: ExpressibleByArrayLiteral { } } -/// `VersionComponentList` represents a collection of `VersionComponentSyntax` +/// `VersionComponentListSyntax` represents a collection of `VersionComponentSyntax` extension VersionComponentListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements) } } -/// `YieldExprList` represents a collection of `YieldExprListElementSyntax` +/// `YieldExprListSyntax` represents a collection of `YieldExprListElementSyntax` extension YieldExprListSyntax: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.init(elements)