Skip to content

[Variadic Generics] Add a new type syntax node and parsing support for explicit pack references. #1134

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

Merged
merged 4 commits into from
Dec 13, 2022
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,19 @@ public let TYPE_NODES: [Node] = [
])
]),

Node(name: "PackReferenceType",
nameForDiagnostics: "pack reference",
kind: "Type",
children: [
Child(name: "EachKeyword",
kind: "ContextualKeyworkToken",
textChoices: [
"each"
]),
Child(name: "PackType",
kind: "Type")
]),

Node(name: "TupleTypeElement",
nameForDiagnostics: nil,
kind: "Syntax",
Expand Down
3 changes: 2 additions & 1 deletion Sources/SwiftParser/Patterns.swift
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,8 @@ extension Parser.Lookahead {
// If the first name wasn't "isolated", we're done.
if !self.atContextualKeyword("isolated") &&
!self.atContextualKeyword("some") &&
!self.atContextualKeyword("any") {
!self.atContextualKeyword("any") &&
!self.atContextualKeyword("each") {
return true
}

Expand Down
7 changes: 7 additions & 0 deletions Sources/SwiftParser/Types.swift
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,13 @@ extension Parser {
/// protocol-composition-continuation → type-identifier | protocol-composition-type
@_spi(RawSyntax)
public mutating func parseSimpleOrCompositionType() -> RawTypeSyntax {
// 'each' is a contextual keyword for a pack reference.
if let each = consume(ifAny: [], contextualKeywords: ["each"]) {
let packType = parseSimpleType()
return RawTypeSyntax(RawPackReferenceTypeSyntax(
eachKeyword: each, packType: packType, arena: self.arena))
}

let someOrAny = self.consume(ifAny: [], contextualKeywords: ["some", "any"])

var base = self.parseSimpleType()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ allows Swift tools to parse, inspect, generate, and transform Swift source code.
- <doc:SwiftSyntax/ImplicitlyUnwrappedOptionalTypeSyntax>
- <doc:SwiftSyntax/CompositionTypeSyntax>
- <doc:SwiftSyntax/PackExpansionTypeSyntax>
- <doc:SwiftSyntax/PackReferenceTypeSyntax>
- <doc:SwiftSyntax/TupleTypeSyntax>
- <doc:SwiftSyntax/FunctionTypeSyntax>
- <doc:SwiftSyntax/AttributedTypeSyntax>
Expand Down
62 changes: 61 additions & 1 deletion Sources/SwiftSyntax/Raw/gyb_generated/RawSyntaxNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public struct RawTypeSyntax: RawTypeSyntaxNodeProtocol {

public static func isKindOf(_ raw: RawSyntax) -> Bool {
switch raw.kind {
case .missingType, .simpleTypeIdentifier, .memberTypeIdentifier, .classRestrictionType, .arrayType, .dictionaryType, .metatypeType, .optionalType, .constrainedSugarType, .implicitlyUnwrappedOptionalType, .compositionType, .packExpansionType, .tupleType, .functionType, .attributedType, .namedOpaqueReturnType: return true
case .missingType, .simpleTypeIdentifier, .memberTypeIdentifier, .classRestrictionType, .arrayType, .dictionaryType, .metatypeType, .optionalType, .constrainedSugarType, .implicitlyUnwrappedOptionalType, .compositionType, .packExpansionType, .packReferenceType, .tupleType, .functionType, .attributedType, .namedOpaqueReturnType: return true
default: return false
}
}
Expand Down Expand Up @@ -16736,6 +16736,66 @@ public struct RawPackExpansionTypeSyntax: RawTypeSyntaxNodeProtocol {
}
}

@_spi(RawSyntax)
public struct RawPackReferenceTypeSyntax: RawTypeSyntaxNodeProtocol {

@_spi(RawSyntax)
public var layoutView: RawSyntaxLayoutView {
return raw.layoutView!
}

public static func isKindOf(_ raw: RawSyntax) -> Bool {
return raw.kind == .packReferenceType
}

public var raw: RawSyntax
init(raw: RawSyntax) {
assert(Self.isKindOf(raw))
self.raw = raw
}

public init?<Node: RawSyntaxNodeProtocol>(_ other: Node) {
guard Self.isKindOf(other.raw) else { return nil }
self.init(raw: other.raw)
}

public init(
_ unexpectedBeforeEachKeyword: RawUnexpectedNodesSyntax? = nil,
eachKeyword: RawTokenSyntax,
_ unexpectedBetweenEachKeywordAndPackType: RawUnexpectedNodesSyntax? = nil,
packType: RawTypeSyntax,
_ unexpectedAfterPackType: RawUnexpectedNodesSyntax? = nil,
arena: __shared SyntaxArena
) {
let raw = RawSyntax.makeLayout(
kind: .packReferenceType, uninitializedCount: 5, arena: arena) { layout in
layout.initialize(repeating: nil)
layout[0] = unexpectedBeforeEachKeyword?.raw
layout[1] = eachKeyword.raw
layout[2] = unexpectedBetweenEachKeywordAndPackType?.raw
layout[3] = packType.raw
layout[4] = unexpectedAfterPackType?.raw
}
self.init(raw: raw)
}

public var unexpectedBeforeEachKeyword: RawUnexpectedNodesSyntax? {
layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:))
}
public var eachKeyword: RawTokenSyntax {
layoutView.children[1].map(RawTokenSyntax.init(raw:))!
}
public var unexpectedBetweenEachKeywordAndPackType: RawUnexpectedNodesSyntax? {
layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:))
}
public var packType: RawTypeSyntax {
layoutView.children[3].map(RawTypeSyntax.init(raw:))!
}
public var unexpectedAfterPackType: RawUnexpectedNodesSyntax? {
layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:))
}
}

@_spi(RawSyntax)
public struct RawTupleTypeElementSyntax: RawSyntaxNodeProtocol {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2438,6 +2438,14 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) {
assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax.self))
assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self))
break
case .packReferenceType:
assert(layout.count == 5)
assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self))
assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 3, verify(layout[3], as: RawTypeSyntax.self))
assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self))
break
case .tupleTypeElement:
assert(layout.count == 17)
assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self))
Expand Down
5 changes: 5 additions & 0 deletions Sources/SwiftSyntax/generated/Misc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ extension Syntax {
.node(OptionalPatternSyntax.self),
.node(OptionalTypeSyntax.self),
.node(PackExpansionTypeSyntax.self),
.node(PackReferenceTypeSyntax.self),
.node(ParameterClauseSyntax.self),
.node(PatternBindingListSyntax.self),
.node(PatternBindingSyntax.self),
Expand Down Expand Up @@ -646,6 +647,8 @@ extension SyntaxKind {
return OptionalTypeSyntax.self
case .packExpansionType:
return PackExpansionTypeSyntax.self
case .packReferenceType:
return PackReferenceTypeSyntax.self
case .parameterClause:
return ParameterClauseSyntax.self
case .patternBindingList:
Expand Down Expand Up @@ -1175,6 +1178,8 @@ extension SyntaxKind {
return "optional type"
case .packExpansionType:
return "variadic expansion"
case .packReferenceType:
return "pack reference"
case .parameterClause:
return "parameter clause"
case .patternBindingList:
Expand Down
7 changes: 7 additions & 0 deletions Sources/SwiftSyntax/gyb_generated/SyntaxAnyVisitor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1698,6 +1698,13 @@ open class SyntaxAnyVisitor: SyntaxVisitor {
override open func visitPost(_ node: PackExpansionTypeSyntax) {
visitAnyPost(node._syntaxNode)
}
override open func visit(_ node: PackReferenceTypeSyntax) -> SyntaxVisitorContinueKind {
return visitAny(node._syntaxNode)
}

override open func visitPost(_ node: PackReferenceTypeSyntax) {
visitAnyPost(node._syntaxNode)
}
override open func visit(_ node: TupleTypeElementSyntax) -> SyntaxVisitorContinueKind {
return visitAny(node._syntaxNode)
}
Expand Down
5 changes: 3 additions & 2 deletions Sources/SwiftSyntax/gyb_generated/SyntaxBaseNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ public struct TypeSyntax: TypeSyntaxProtocol, SyntaxHashable {

public init?<S: SyntaxProtocol>(_ node: S) {
switch node.raw.kind {
case .missingType, .simpleTypeIdentifier, .memberTypeIdentifier, .classRestrictionType, .arrayType, .dictionaryType, .metatypeType, .optionalType, .constrainedSugarType, .implicitlyUnwrappedOptionalType, .compositionType, .packExpansionType, .tupleType, .functionType, .attributedType, .namedOpaqueReturnType:
case .missingType, .simpleTypeIdentifier, .memberTypeIdentifier, .classRestrictionType, .arrayType, .dictionaryType, .metatypeType, .optionalType, .constrainedSugarType, .implicitlyUnwrappedOptionalType, .compositionType, .packExpansionType, .packReferenceType, .tupleType, .functionType, .attributedType, .namedOpaqueReturnType:
self._syntaxNode = node._syntaxNode
default:
return nil
Expand All @@ -539,7 +539,7 @@ public struct TypeSyntax: TypeSyntaxProtocol, SyntaxHashable {
// Assert that the kind of the given data matches in debug builds.
#if DEBUG
switch data.raw.kind {
case .missingType, .simpleTypeIdentifier, .memberTypeIdentifier, .classRestrictionType, .arrayType, .dictionaryType, .metatypeType, .optionalType, .constrainedSugarType, .implicitlyUnwrappedOptionalType, .compositionType, .packExpansionType, .tupleType, .functionType, .attributedType, .namedOpaqueReturnType:
case .missingType, .simpleTypeIdentifier, .memberTypeIdentifier, .classRestrictionType, .arrayType, .dictionaryType, .metatypeType, .optionalType, .constrainedSugarType, .implicitlyUnwrappedOptionalType, .compositionType, .packExpansionType, .packReferenceType, .tupleType, .functionType, .attributedType, .namedOpaqueReturnType:
break
default:
fatalError("Unable to create TypeSyntax from \(data.raw.kind)")
Expand Down Expand Up @@ -589,6 +589,7 @@ public struct TypeSyntax: TypeSyntaxProtocol, SyntaxHashable {
.node(ImplicitlyUnwrappedOptionalTypeSyntax.self),
.node(CompositionTypeSyntax.self),
.node(PackExpansionTypeSyntax.self),
.node(PackReferenceTypeSyntax.self),
.node(TupleTypeSyntax.self),
.node(FunctionTypeSyntax.self),
.node(AttributedTypeSyntax.self),
Expand Down
3 changes: 3 additions & 0 deletions Sources/SwiftSyntax/gyb_generated/SyntaxEnum.swift
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ public enum SyntaxEnum {
case compositionTypeElementList(CompositionTypeElementListSyntax)
case compositionType(CompositionTypeSyntax)
case packExpansionType(PackExpansionTypeSyntax)
case packReferenceType(PackReferenceTypeSyntax)
case tupleTypeElement(TupleTypeElementSyntax)
case tupleTypeElementList(TupleTypeElementListSyntax)
case tupleType(TupleTypeSyntax)
Expand Down Expand Up @@ -755,6 +756,8 @@ public extension Syntax {
return .compositionType(CompositionTypeSyntax(self)!)
case .packExpansionType:
return .packExpansionType(PackExpansionTypeSyntax(self)!)
case .packReferenceType:
return .packReferenceType(PackReferenceTypeSyntax(self)!)
case .tupleTypeElement:
return .tupleTypeElement(TupleTypeElementSyntax(self)!)
case .tupleTypeElementList:
Expand Down
31 changes: 31 additions & 0 deletions Sources/SwiftSyntax/gyb_generated/SyntaxFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7826,6 +7826,37 @@ public enum SyntaxFactory {
return PackExpansionTypeSyntax(data)
}
}
@available(*, deprecated, message: "Use initializer on PackReferenceTypeSyntax")
public static func makePackReferenceType(_ unexpectedBeforeEachKeyword: UnexpectedNodesSyntax? = nil, eachKeyword: TokenSyntax, _ unexpectedBetweenEachKeywordAndPackType: UnexpectedNodesSyntax? = nil, packType: TypeSyntax, _ unexpectedAfterPackType: UnexpectedNodesSyntax? = nil) -> PackReferenceTypeSyntax {
let layout: [RawSyntax?] = [
unexpectedBeforeEachKeyword?.raw,
eachKeyword.raw,
unexpectedBetweenEachKeywordAndPackType?.raw,
packType.raw,
unexpectedAfterPackType?.raw,
]
return withExtendedLifetime(SyntaxArena()) { arena in
let raw = RawSyntax.makeLayout(kind: SyntaxKind.packReferenceType,
from: layout, arena: arena)
let data = SyntaxData.forRoot(raw)
return PackReferenceTypeSyntax(data)
}
}

@available(*, deprecated, message: "Use initializer on PackReferenceTypeSyntax")
public static func makeBlankPackReferenceType(presence: SourcePresence = .present) -> PackReferenceTypeSyntax {
return withExtendedLifetime(SyntaxArena()) { arena in
let data = SyntaxData.forRoot(RawSyntax.makeLayout(kind: .packReferenceType,
from: [
nil,
RawSyntax.makeMissingToken(kind: TokenKind.unknown(""), arena: arena),
nil,
RawSyntax.makeEmptyLayout(kind: SyntaxKind.missingType, arena: arena),
nil,
], arena: arena))
return PackReferenceTypeSyntax(data)
}
}
@available(*, deprecated, message: "Use initializer on TupleTypeElementSyntax")
public static func makeTupleTypeElement(_ unexpectedBeforeInOut: UnexpectedNodesSyntax? = nil, inOut: TokenSyntax?, _ unexpectedBetweenInOutAndName: UnexpectedNodesSyntax? = nil, name: TokenSyntax?, _ unexpectedBetweenNameAndSecondName: UnexpectedNodesSyntax? = nil, secondName: TokenSyntax?, _ unexpectedBetweenSecondNameAndColon: UnexpectedNodesSyntax? = nil, colon: TokenSyntax?, _ unexpectedBetweenColonAndType: UnexpectedNodesSyntax? = nil, type: TypeSyntax, _ unexpectedBetweenTypeAndEllipsis: UnexpectedNodesSyntax? = nil, ellipsis: TokenSyntax?, _ unexpectedBetweenEllipsisAndInitializer: UnexpectedNodesSyntax? = nil, initializer: InitializerClauseSyntax?, _ unexpectedBetweenInitializerAndTrailingComma: UnexpectedNodesSyntax? = nil, trailingComma: TokenSyntax?, _ unexpectedAfterTrailingComma: UnexpectedNodesSyntax? = nil) -> TupleTypeElementSyntax {
let layout: [RawSyntax?] = [
Expand Down
1 change: 1 addition & 0 deletions Sources/SwiftSyntax/gyb_generated/SyntaxKind.swift
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ public enum SyntaxKind {
case compositionTypeElementList
case compositionType
case packExpansionType
case packReferenceType
case tupleTypeElement
case tupleTypeElementList
case tupleType
Expand Down
21 changes: 21 additions & 0 deletions Sources/SwiftSyntax/gyb_generated/SyntaxRewriter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1668,6 +1668,13 @@ open class SyntaxRewriter {
return TypeSyntax(visitChildren(node))
}

/// Visit a `PackReferenceTypeSyntax`.
/// - Parameter node: the node that is being visited
/// - Returns: the rewritten node
open func visit(_ node: PackReferenceTypeSyntax) -> TypeSyntax {
return TypeSyntax(visitChildren(node))
}

/// Visit a `TupleTypeElementSyntax`.
/// - Parameter node: the node that is being visited
/// - Returns: the rewritten node
Expand Down Expand Up @@ -4274,6 +4281,16 @@ open class SyntaxRewriter {
return Syntax(visit(node))
}

/// Implementation detail of visit(_:). Do not call directly.
private func visitImplPackReferenceTypeSyntax(_ data: SyntaxData) -> Syntax {
let node = PackReferenceTypeSyntax(data)
// Accessing _syntaxNode directly is faster than calling Syntax(node)
visitPre(node._syntaxNode)
defer { visitPost(node._syntaxNode) }
if let newNode = visitAny(node._syntaxNode) { return newNode }
return Syntax(visit(node))
}

/// Implementation detail of visit(_:). Do not call directly.
private func visitImplTupleTypeElementSyntax(_ data: SyntaxData) -> Syntax {
let node = TupleTypeElementSyntax(data)
Expand Down Expand Up @@ -5044,6 +5061,8 @@ open class SyntaxRewriter {
return visitImplCompositionTypeSyntax
case .packExpansionType:
return visitImplPackExpansionTypeSyntax
case .packReferenceType:
return visitImplPackReferenceTypeSyntax
case .tupleTypeElement:
return visitImplTupleTypeElementSyntax
case .tupleTypeElementList:
Expand Down Expand Up @@ -5579,6 +5598,8 @@ open class SyntaxRewriter {
return visitImplCompositionTypeSyntax(data)
case .packExpansionType:
return visitImplPackExpansionTypeSyntax(data)
case .packReferenceType:
return visitImplPackReferenceTypeSyntax(data)
case .tupleTypeElement:
return visitImplTupleTypeElementSyntax(data)
case .tupleTypeElementList:
Expand Down
12 changes: 12 additions & 0 deletions Sources/SwiftSyntax/gyb_generated/SyntaxTransform.swift
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,10 @@ public protocol SyntaxTransformVisitor {
/// - Parameter node: the node we are visiting.
/// - Returns: the sum of whatever the child visitors return.
func visit(_ node: PackExpansionTypeSyntax) -> ResultType
/// Visiting `PackReferenceTypeSyntax` specifically.
/// - Parameter node: the node we are visiting.
/// - Returns: the sum of whatever the child visitors return.
func visit(_ node: PackReferenceTypeSyntax) -> ResultType
/// Visiting `TupleTypeElementSyntax` specifically.
/// - Parameter node: the node we are visiting.
/// - Returns: the sum of whatever the child visitors return.
Expand Down Expand Up @@ -2480,6 +2484,12 @@ extension SyntaxTransformVisitor {
public func visit(_ node: PackExpansionTypeSyntax) -> ResultType {
visitAny(Syntax(node))
}
/// Visiting `PackReferenceTypeSyntax` specifically.
/// - Parameter node: the node we are visiting.
/// - Returns: nil by default.
public func visit(_ node: PackReferenceTypeSyntax) -> ResultType {
visitAny(Syntax(node))
}
/// Visiting `TupleTypeElementSyntax` specifically.
/// - Parameter node: the node we are visiting.
/// - Returns: nil by default.
Expand Down Expand Up @@ -3111,6 +3121,8 @@ extension SyntaxTransformVisitor {
return visit(derived)
case .packExpansionType(let derived):
return visit(derived)
case .packReferenceType(let derived):
return visit(derived)
case .tupleTypeElement(let derived):
return visit(derived)
case .tupleTypeElementList(let derived):
Expand Down
23 changes: 23 additions & 0 deletions Sources/SwiftSyntax/gyb_generated/SyntaxVisitor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2391,6 +2391,16 @@ open class SyntaxVisitor {
/// The function called after visiting `PackExpansionTypeSyntax` and its descendents.
/// - node: the node we just finished visiting.
open func visitPost(_ node: PackExpansionTypeSyntax) {}
/// Visiting `PackReferenceTypeSyntax` specifically.
/// - Parameter node: the node we are visiting.
/// - Returns: how should we continue visiting.
open func visit(_ node: PackReferenceTypeSyntax) -> SyntaxVisitorContinueKind {
return .visitChildren
}

/// The function called after visiting `PackReferenceTypeSyntax` and its descendents.
/// - node: the node we just finished visiting.
open func visitPost(_ node: PackReferenceTypeSyntax) {}
/// Visiting `TupleTypeElementSyntax` specifically.
/// - Parameter node: the node we are visiting.
/// - Returns: how should we continue visiting.
Expand Down Expand Up @@ -5248,6 +5258,17 @@ open class SyntaxVisitor {
visitPost(node)
}

/// Implementation detail of doVisit(_:_:). Do not call directly.
private func visitImplPackReferenceTypeSyntax(_ data: SyntaxData) {
let node = PackReferenceTypeSyntax(data)
let needsChildren = (visit(node) == .visitChildren)
// Avoid calling into visitChildren if possible.
if needsChildren && !node.raw.layoutView!.children.isEmpty {
visitChildren(node)
}
visitPost(node)
}

/// Implementation detail of doVisit(_:_:). Do not call directly.
private func visitImplTupleTypeElementSyntax(_ data: SyntaxData) {
let node = TupleTypeElementSyntax(data)
Expand Down Expand Up @@ -6016,6 +6037,8 @@ open class SyntaxVisitor {
visitImplCompositionTypeSyntax(data)
case .packExpansionType:
visitImplPackExpansionTypeSyntax(data)
case .packReferenceType:
visitImplPackReferenceTypeSyntax(data)
case .tupleTypeElement:
visitImplTupleTypeElementSyntax(data)
case .tupleTypeElementList:
Expand Down
Loading