Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CodeGeneration] further unification and fixes across raw and non-raw sides #2841

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 0 additions & 29 deletions CodeGeneration/Sources/SyntaxSupport/AttributeNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
public let ATTRIBUTE_NODES: [Node] = [
Node(
kind: .attributeList,
base: .syntaxCollection,
nameForDiagnostics: "attributes",
documentation: """
A list of attributes that can be attached to a declaration.
Expand All @@ -34,7 +33,6 @@ public let ATTRIBUTE_NODES: [Node] = [

Node(
kind: .attribute,
base: .syntax,
nameForDiagnostics: "attribute",
documentation: "An `@` attribute.",
parserFunction: "parseAttribute",
Expand Down Expand Up @@ -161,7 +159,6 @@ public let ATTRIBUTE_NODES: [Node] = [

Node(
kind: .specializeAvailabilityArgument,
base: .syntax,
nameForDiagnostics: "availability entry",
documentation: "The availability argument for the _specialize attribute",
children: [
Expand Down Expand Up @@ -195,7 +192,6 @@ public let ATTRIBUTE_NODES: [Node] = [

Node(
kind: .platformVersionItem,
base: .syntax,
nameForDiagnostics: "version",
documentation: "A single platform/version pair in an attribute, e.g. `iOS 10.1`.",
traits: ["WithTrailingComma"],
Expand All @@ -217,14 +213,12 @@ public let ATTRIBUTE_NODES: [Node] = [

Node(
kind: .platformVersionItemList,
base: .syntaxCollection,
nameForDiagnostics: "version list",
elementChoices: [.platformVersionItem]
),

Node(
kind: .backDeployedAttributeArguments,
base: .syntax,
nameForDiagnostics: "'@backDeployed' arguments",
documentation: "A collection of arguments for the `@backDeployed` attribute",
children: [
Expand Down Expand Up @@ -253,7 +247,6 @@ public let ATTRIBUTE_NODES: [Node] = [

Node(
kind: .conventionAttributeArguments,
base: .syntax,
nameForDiagnostics: "@convention(...) arguments",
documentation: "The arguments for the '@convention(...)'.",
children: [
Expand Down Expand Up @@ -287,7 +280,6 @@ public let ATTRIBUTE_NODES: [Node] = [

Node(
kind: .conventionWitnessMethodAttributeArguments,
base: .syntax,
nameForDiagnostics: "@convention(...) arguments for witness methods",
documentation: "The arguments for the '@convention(witness_method: ...)'.",
children: [
Expand All @@ -312,7 +304,6 @@ public let ATTRIBUTE_NODES: [Node] = [

Node(
kind: .derivativeAttributeArguments,
base: .syntax,
nameForDiagnostics: "attribute arguments",
documentation:
"The arguments for the '@derivative(of:)' and '@transpose(of:)' attributes: the 'of:' label, the original declaration name, and an optional differentiability parameter list.",
Expand Down Expand Up @@ -361,14 +352,12 @@ public let ATTRIBUTE_NODES: [Node] = [

Node(
kind: .differentiabilityArgumentList,
base: .syntaxCollection,
nameForDiagnostics: "differentiability parameters",
elementChoices: [.differentiabilityArgument]
),

Node(
kind: .differentiabilityArgument,
base: .syntax,
nameForDiagnostics: "differentiability argument",
documentation:
"A differentiability argument: either the \"self\" identifier, a function parameter name, or a function parameter index.",
Expand All @@ -391,7 +380,6 @@ public let ATTRIBUTE_NODES: [Node] = [

Node(
kind: .differentiabilityWithRespectToArgument,
base: .syntax,
nameForDiagnostics: "'@differentiable' argument",
documentation: "A clause containing differentiability parameters.",
children: [
Expand Down Expand Up @@ -427,7 +415,6 @@ public let ATTRIBUTE_NODES: [Node] = [

Node(
kind: .differentiabilityArguments,
base: .syntax,
nameForDiagnostics: "differentiability arguments",
documentation: "The differentiability arguments.",
children: [
Expand All @@ -450,7 +437,6 @@ public let ATTRIBUTE_NODES: [Node] = [

Node(
kind: .differentiableAttributeArguments,
base: .syntax,
nameForDiagnostics: "'@differentiable' arguments",
documentation:
"The arguments for the `@differentiable` attribute: an optional differentiability kind, an optional differentiability parameter clause, and an optional 'where' clause.",
Expand Down Expand Up @@ -496,7 +482,6 @@ public let ATTRIBUTE_NODES: [Node] = [

Node(
kind: .documentationAttributeArgument,
base: .syntax,
nameForDiagnostics: "@_documentation argument",
traits: [
"WithTrailingComma"
Expand Down Expand Up @@ -542,15 +527,13 @@ public let ATTRIBUTE_NODES: [Node] = [

Node(
kind: .documentationAttributeArgumentList,
base: .syntaxCollection,
nameForDiagnostics: "@_documentation arguments",
documentation: "The arguments of the '@_documentation' attribute",
elementChoices: [.documentationAttributeArgument]
),

Node(
kind: .dynamicReplacementAttributeArguments,
base: .syntax,
nameForDiagnostics: "@_dynamicReplacement argument",
documentation: "The arguments for the '@_dynamicReplacement' attribute",
children: [
Expand All @@ -572,15 +555,13 @@ public let ATTRIBUTE_NODES: [Node] = [

Node(
kind: .effectsAttributeArgumentList,
base: .syntaxCollection,
nameForDiagnostics: "@_effects arguments",
documentation: "The arguments of the '@_effects' attribute. These will be parsed during the SIL stage.",
elementChoices: [.token]
),

Node(
kind: .exposeAttributeArguments,
base: .syntax,
nameForDiagnostics: "@_expose arguments",
documentation: "The arguments for the '@_expose' attribute",
children: [
Expand All @@ -603,7 +584,6 @@ public let ATTRIBUTE_NODES: [Node] = [

Node(
kind: .implementsAttributeArguments,
base: .syntax,
nameForDiagnostics: "@_implements arguemnts",
documentation:
"The arguments for the `@_implements` attribute of the form `Type, methodName(arg1Label:arg2Label:)`",
Expand Down Expand Up @@ -631,7 +611,6 @@ public let ATTRIBUTE_NODES: [Node] = [

Node(
kind: .labeledSpecializeArgument,
base: .syntax,
nameForDiagnostics: "attribute argument",
documentation: "A labeled argument for the `@_specialize` attribute like `exported: true`",
traits: [
Expand Down Expand Up @@ -673,7 +652,6 @@ public let ATTRIBUTE_NODES: [Node] = [

Node(
kind: .objCSelectorPiece,
base: .syntax,
nameForDiagnostics: "Objective-C selector piece",
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",
Expand All @@ -696,14 +674,12 @@ public let ATTRIBUTE_NODES: [Node] = [

Node(
kind: .objCSelectorPieceList,
base: .syntaxCollection,
nameForDiagnostics: "Objective-C selector",
elementChoices: [.objCSelectorPiece]
),

Node(
kind: .opaqueReturnTypeOfAttributeArguments,
base: .syntax,
nameForDiagnostics: "opaque return type arguments",
documentation: "The arguments for the '@_opaqueReturnTypeOf()'.",
children: [
Expand All @@ -726,7 +702,6 @@ public let ATTRIBUTE_NODES: [Node] = [

Node(
kind: .originallyDefinedInAttributeArguments,
base: .syntax,
nameForDiagnostics: "@_originallyDefinedIn arguments",
documentation: "The arguments for the '@_originallyDefinedIn' attribute",
children: [
Expand Down Expand Up @@ -755,7 +730,6 @@ public let ATTRIBUTE_NODES: [Node] = [

Node(
kind: .specializeAttributeArgumentList,
base: .syntaxCollection,
nameForDiagnostics: "argument to '@_specialize",
documentation: "A collection of arguments for the `@_specialize` attribute",
elementChoices: [
Expand All @@ -766,7 +740,6 @@ public let ATTRIBUTE_NODES: [Node] = [

Node(
kind: .specializeTargetFunctionArgument,
base: .syntax,
nameForDiagnostics: "attribute argument",
documentation:
"A labeled argument for the `@_specialize` attribute with a function decl value like `target: myFunc(_:)`",
Expand Down Expand Up @@ -804,7 +777,6 @@ public let ATTRIBUTE_NODES: [Node] = [

Node(
kind: .unavailableFromAsyncAttributeArguments,
base: .syntax,
nameForDiagnostics: "@_unavailableFromAsync argument",
documentation: "The arguments for the '@_unavailableFromAsync' attribute",
children: [
Expand All @@ -825,7 +797,6 @@ public let ATTRIBUTE_NODES: [Node] = [

Node(
kind: .underscorePrivateAttributeArguments,
base: .syntax,
nameForDiagnostics: "@_private argument",
documentation: "The arguments for the '@_private' attribute",
children: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
public let AVAILABILITY_NODES: [Node] = [
Node(
kind: .availabilityArgument,
base: .syntax,
nameForDiagnostics: "availability argument",
documentation:
"A single argument to an `@available` argument like `*`, `iOS 10.1`, or `message: \"This has been deprecated\"`.",
Expand Down Expand Up @@ -53,7 +52,6 @@ public let AVAILABILITY_NODES: [Node] = [

Node(
kind: .availabilityLabeledArgument,
base: .syntax,
nameForDiagnostics: "availability argument",
documentation:
"An argument to an `@available` attribute that consists of a label and a value, e.g. `message: \"This has been deprecated\"`.",
Expand Down Expand Up @@ -95,14 +93,12 @@ public let AVAILABILITY_NODES: [Node] = [

Node(
kind: .availabilityArgumentList,
base: .syntaxCollection,
nameForDiagnostics: "'@availability' arguments",
elementChoices: [.availabilityArgument]
),

Node(
kind: .platformVersion,
base: .syntax,
nameForDiagnostics: "version restriction",
documentation:
"An argument to `@available` that restricts the availability on a certain platform to a version, e.g. `iOS 10` or `swift 3.4`.",
Expand Down Expand Up @@ -132,7 +128,6 @@ public let AVAILABILITY_NODES: [Node] = [

Node(
kind: .versionComponent,
base: .syntax,
nameForDiagnostics: nil,
documentation: "An element to represent a single component in a version, like `.1`.",
children: [
Expand All @@ -151,14 +146,12 @@ public let AVAILABILITY_NODES: [Node] = [

Node(
kind: .versionComponentList,
base: .syntaxCollection,
nameForDiagnostics: nil,
elementChoices: [.versionComponent]
),

Node(
kind: .versionTuple,
base: .syntax,
nameForDiagnostics: "version tuple",
documentation:
"A version number like `1.2.0`. Only the first version component is required. There might be an arbitrary number of following components.",
Expand Down
88 changes: 85 additions & 3 deletions CodeGeneration/Sources/SyntaxSupport/Child.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public enum ChildKind {

/// A child of a node, that may be declared optional or a token with a
/// restricted subset of acceptable kinds or texts.
public class Child: NodeChoiceConvertible {
public class Child: SyntaxNodeConvertible, NodeChoiceConvertible, ParameterConvertible {
/// The name of the child.
///
/// The first character of the name is always uppercase.
Expand Down Expand Up @@ -227,9 +227,9 @@ public class Child: NodeChoiceConvertible {
case .nodeChoices(let choices):
return choices.isEmpty
case .node(let kind):
return kind.isBase
return kind.isBaseType
case .collection(kind: let kind, _, _, _):
return kind.isBase
return kind.isBaseType
case .token:
return false
}
Expand All @@ -244,6 +244,11 @@ public class Child: NodeChoiceConvertible {
return AttributeListSyntax("@_spi(ExperimentalLanguageFeatures)").with(\.trailingTrivia, .newline)
}

/// The ``Node`` representation of this child, if any.
public var node: Node? {
self.syntaxNodeKind.node
}

/// If a classification is passed, it specifies the color identifiers in
/// that subtree should inherit for syntax coloring. Must be a member of
/// ``SyntaxClassification``.
Expand Down Expand Up @@ -273,3 +278,80 @@ public class Child: NodeChoiceConvertible {
self.isOptional = isOptional
}
}

// MARK: SyntaxNodeConvertible
public extension Child {
var isNode: Bool {
switch self.kind {
case .node, .collection:
return true
default:
return false
}
}

var syntaxType: TypeSyntax {
switch self.kind {
case .node(let kind), .collection(let kind, _, _, _):
return kind.syntaxType
case .nodeChoices:
return self.syntaxChoicesType
case .token:
return "TokenSyntax"
}
}
}

// MARK: ParameterConvertible
extension Child {
public var parameterAnyType: TypeSyntax {
self.parameterType(specifier: "any")
}

public var parameterSomeType: TypeSyntax {
self.parameterType(specifier: "some")
}

func parameterType(
specifier: TokenSyntax,
protocolType: TypeSyntax? = nil,
syntaxType: TypeSyntax? = nil
) -> TypeSyntax {
let type: TypeSyntax
if self.isBaseNode {
type = "\(specifier) \(protocolType ?? self.protocolType)"
} else {
type = syntaxType ?? self.syntaxType
}
return self.isOptional ? type.optionalWrapped : type
}

func defaultValue(syntaxType: TypeSyntax) -> ExprSyntax? {
guard !self.isOptional else {
if self.isBaseNode {
return "\(syntaxType.optionalWrapped).none"
} else {
return "nil"
}
}
if case .collection(_, _, defaultsToEmpty: true, _) = self.kind {
return "[]"
}
guard let token else {
return self.isOptional ? "nil" : nil
}
guard token.text == nil else {
return ".\(token.identifier)Token()"
}
guard case .token(let choices, _, _) = self.kind,
case .keyword(let keyword) = choices.only
else {
return nil
}
return ".\(token.memberCallName)(.\(keyword.spec.memberCallName))"
}

public var defaultValue: ExprSyntax? {
self.defaultValue(syntaxType: self.syntaxType)
}
}
Loading