Skip to content

Commit

Permalink
Ensure there are no optional syntax collection in the syntax tree
Browse files Browse the repository at this point in the history
All syntax collections should be non-optional, which makes it easier to work with them. Also, the semantics of what an empty collection vs. a `nil` collection have not been clear.
  • Loading branch information
ahoppen committed Aug 9, 2023
1 parent ad6817e commit b3f3692
Show file tree
Hide file tree
Showing 14 changed files with 75 additions and 61 deletions.
3 changes: 1 addition & 2 deletions CodeGeneration/Sources/SyntaxSupport/AvailabilityNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,7 @@ public let AVAILABILITY_NODES: [Node] = [
Child(
name: "Components",
kind: .collection(kind: .versionComponentList, collectionElementName: "VersionComponent"),
documentation: "Any version components that are not the major version . For example, for `1.2.0`, this will contain `.2.0`",
isOptional: true
documentation: "Any version components that are not the major version . For example, for `1.2.0`, this will contain `.2.0`"
),
]
),
Expand Down
3 changes: 1 addition & 2 deletions CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -354,8 +354,7 @@ public let EXPR_NODES: [Node] = [
),
Child(
name: "Items",
kind: .collection(kind: .closureCaptureList, collectionElementName: "Item"),
isOptional: true
kind: .collection(kind: .closureCaptureList, collectionElementName: "Item")
),
Child(
name: "RightSquare",
Expand Down
6 changes: 2 additions & 4 deletions CodeGeneration/Sources/SyntaxSupport/StmtNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ public let STMT_NODES: [Node] = [
),
Child(
name: "CatchItems",
kind: .collection(kind: .catchItemList, collectionElementName: "CatchItem"),
isOptional: true
kind: .collection(kind: .catchItemList, collectionElementName: "CatchItem", defaultsToEmpty: true)
),
Child(
name: "Body",
Expand Down Expand Up @@ -240,8 +239,7 @@ public let STMT_NODES: [Node] = [
),
Child(
name: "CatchClauses",
kind: .collection(kind: .catchClauseList, collectionElementName: "CatchClause"),
isOptional: true
kind: .collection(kind: .catchClauseList, collectionElementName: "CatchClause", defaultsToEmpty: true)
),
]
),
Expand Down
19 changes: 19 additions & 0 deletions CodeGeneration/Tests/ValidateSyntaxNodes/ValidateSyntaxNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -760,4 +760,23 @@ class ValidateSyntaxNodes: XCTestCase {

assertFailuresMatchXFails(failures, expectedFailures: [])
}

func testNoOptionalSyntaxCollections() {
var failures: [ValidationFailure] = []

for node in SYNTAX_NODES.compactMap(\.layoutNode) {
for child in node.children {
if case .collection = child.kind, child.isOptional, !child.isUnexpectedNodes {
failures.append(
ValidationFailure(
node: node.kind,
message: "child '\(child.name)' is an optional syntax collection. All syntax collections should be non-optional."
)
)
}
}
}

assertFailuresMatchXFails(failures, expectedFailures: [])
}
}
2 changes: 1 addition & 1 deletion Sources/SwiftParser/Availability.swift
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ extension Parser {
let unexpectedAfterComponents = self.parseUnexpectedVersionTokens()
return RawVersionTupleSyntax(
major: major,
components: nil,
components: RawVersionComponentListSyntax(elements: [], arena: self.arena),
unexpectedAfterComponents,
arena: self.arena
)
Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftParser/Expressions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1733,7 +1733,7 @@ extension Parser {

captures = RawClosureCaptureClauseSyntax(
leftSquare: lsquare,
items: elements.isEmpty ? nil : RawClosureCaptureListSyntax(elements: elements, arena: self.arena),
items: RawClosureCaptureListSyntax(elements: elements, arena: self.arena),
RawUnexpectedNodesSyntax(unexpectedNodes, arena: self.arena),
rightSquare: rsquare,
arena: self.arena
Expand Down
4 changes: 2 additions & 2 deletions Sources/SwiftParser/Statements.swift
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ extension Parser {
unexpectedBeforeDoKeyword,
doKeyword: doKeyword,
body: body,
catchClauses: elements.isEmpty ? nil : RawCatchClauseListSyntax(elements: elements, arena: self.arena),
catchClauses: RawCatchClauseListSyntax(elements: elements, arena: self.arena),
arena: self.arena
)
}
Expand Down Expand Up @@ -416,7 +416,7 @@ extension Parser {
return RawCatchClauseSyntax(
unexpectedBeforeCatchKeyword,
catchKeyword: catchKeyword,
catchItems: catchItems.isEmpty ? nil : RawCatchItemListSyntax(elements: catchItems, arena: self.arena),
catchItems: RawCatchItemListSyntax(elements: catchItems, arena: self.arena),
body: body,
arena: self.arena
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1936,19 +1936,17 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor {
}

if let unexpectedAfterComponents = node.unexpectedAfterComponents {
if let components = node.components,
unexpectedAfterComponents.allSatisfy({ $0.is(VersionComponentSyntax.self) })
{
if unexpectedAfterComponents.allSatisfy({ $0.is(VersionComponentSyntax.self) }) {
addDiagnostic(
unexpectedAfterComponents,
TrailingVersionAreIgnored(major: node.major, components: components),
TrailingVersionAreIgnored(major: node.major, components: node.components),
handledNodes: [unexpectedAfterComponents.id]
)
} else {
addDiagnostic(
unexpectedAfterComponents,
CannotParseVersionTuple(versionTuple: unexpectedAfterComponents),
handledNodes: [node.major.id, node.components?.id, unexpectedAfterComponents.id].compactMap { $0 }
handledNodes: [node.major.id, node.components.id, unexpectedAfterComponents.id]
)
}
}
Expand Down
32 changes: 16 additions & 16 deletions Sources/SwiftSyntax/generated/raw/RawSyntaxNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2715,7 +2715,7 @@ public struct RawCatchClauseSyntax: RawSyntaxNodeProtocol {
_ unexpectedBeforeCatchKeyword: RawUnexpectedNodesSyntax? = nil,
catchKeyword: RawTokenSyntax,
_ unexpectedBetweenCatchKeywordAndCatchItems: RawUnexpectedNodesSyntax? = nil,
catchItems: RawCatchItemListSyntax?,
catchItems: RawCatchItemListSyntax,
_ unexpectedBetweenCatchItemsAndBody: RawUnexpectedNodesSyntax? = nil,
body: RawCodeBlockSyntax,
_ unexpectedAfterBody: RawUnexpectedNodesSyntax? = nil,
Expand All @@ -2727,7 +2727,7 @@ public struct RawCatchClauseSyntax: RawSyntaxNodeProtocol {
layout[0] = unexpectedBeforeCatchKeyword?.raw
layout[1] = catchKeyword.raw
layout[2] = unexpectedBetweenCatchKeywordAndCatchItems?.raw
layout[3] = catchItems?.raw
layout[3] = catchItems.raw
layout[4] = unexpectedBetweenCatchItemsAndBody?.raw
layout[5] = body.raw
layout[6] = unexpectedAfterBody?.raw
Expand All @@ -2747,8 +2747,8 @@ public struct RawCatchClauseSyntax: RawSyntaxNodeProtocol {
layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:))
}

public var catchItems: RawCatchItemListSyntax? {
layoutView.children[3].map(RawCatchItemListSyntax.init(raw:))
public var catchItems: RawCatchItemListSyntax {
layoutView.children[3].map(RawCatchItemListSyntax.init(raw:))!
}

public var unexpectedBetweenCatchItemsAndBody: RawUnexpectedNodesSyntax? {
Expand Down Expand Up @@ -3129,7 +3129,7 @@ public struct RawClosureCaptureClauseSyntax: RawSyntaxNodeProtocol {
_ unexpectedBeforeLeftSquare: RawUnexpectedNodesSyntax? = nil,
leftSquare: RawTokenSyntax,
_ unexpectedBetweenLeftSquareAndItems: RawUnexpectedNodesSyntax? = nil,
items: RawClosureCaptureListSyntax?,
items: RawClosureCaptureListSyntax,
_ unexpectedBetweenItemsAndRightSquare: RawUnexpectedNodesSyntax? = nil,
rightSquare: RawTokenSyntax,
_ unexpectedAfterRightSquare: RawUnexpectedNodesSyntax? = nil,
Expand All @@ -3141,7 +3141,7 @@ public struct RawClosureCaptureClauseSyntax: RawSyntaxNodeProtocol {
layout[0] = unexpectedBeforeLeftSquare?.raw
layout[1] = leftSquare.raw
layout[2] = unexpectedBetweenLeftSquareAndItems?.raw
layout[3] = items?.raw
layout[3] = items.raw
layout[4] = unexpectedBetweenItemsAndRightSquare?.raw
layout[5] = rightSquare.raw
layout[6] = unexpectedAfterRightSquare?.raw
Expand All @@ -3161,8 +3161,8 @@ public struct RawClosureCaptureClauseSyntax: RawSyntaxNodeProtocol {
layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:))
}

public var items: RawClosureCaptureListSyntax? {
layoutView.children[3].map(RawClosureCaptureListSyntax.init(raw:))
public var items: RawClosureCaptureListSyntax {
layoutView.children[3].map(RawClosureCaptureListSyntax.init(raw:))!
}

public var unexpectedBetweenItemsAndRightSquare: RawUnexpectedNodesSyntax? {
Expand Down Expand Up @@ -7067,7 +7067,7 @@ public struct RawDoStmtSyntax: RawStmtSyntaxNodeProtocol {
_ unexpectedBetweenDoKeywordAndBody: RawUnexpectedNodesSyntax? = nil,
body: RawCodeBlockSyntax,
_ unexpectedBetweenBodyAndCatchClauses: RawUnexpectedNodesSyntax? = nil,
catchClauses: RawCatchClauseListSyntax?,
catchClauses: RawCatchClauseListSyntax,
_ unexpectedAfterCatchClauses: RawUnexpectedNodesSyntax? = nil,
arena: __shared SyntaxArena
) {
Expand All @@ -7079,7 +7079,7 @@ public struct RawDoStmtSyntax: RawStmtSyntaxNodeProtocol {
layout[2] = unexpectedBetweenDoKeywordAndBody?.raw
layout[3] = body.raw
layout[4] = unexpectedBetweenBodyAndCatchClauses?.raw
layout[5] = catchClauses?.raw
layout[5] = catchClauses.raw
layout[6] = unexpectedAfterCatchClauses?.raw
}
self.init(unchecked: raw)
Expand All @@ -7105,8 +7105,8 @@ public struct RawDoStmtSyntax: RawStmtSyntaxNodeProtocol {
layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:))
}

public var catchClauses: RawCatchClauseListSyntax? {
layoutView.children[5].map(RawCatchClauseListSyntax.init(raw:))
public var catchClauses: RawCatchClauseListSyntax {
layoutView.children[5].map(RawCatchClauseListSyntax.init(raw:))!
}

public var unexpectedAfterCatchClauses: RawUnexpectedNodesSyntax? {
Expand Down Expand Up @@ -22129,7 +22129,7 @@ public struct RawVersionTupleSyntax: RawSyntaxNodeProtocol {
_ unexpectedBeforeMajor: RawUnexpectedNodesSyntax? = nil,
major: RawTokenSyntax,
_ unexpectedBetweenMajorAndComponents: RawUnexpectedNodesSyntax? = nil,
components: RawVersionComponentListSyntax?,
components: RawVersionComponentListSyntax,
_ unexpectedAfterComponents: RawUnexpectedNodesSyntax? = nil,
arena: __shared SyntaxArena
) {
Expand All @@ -22139,7 +22139,7 @@ public struct RawVersionTupleSyntax: RawSyntaxNodeProtocol {
layout[0] = unexpectedBeforeMajor?.raw
layout[1] = major.raw
layout[2] = unexpectedBetweenMajorAndComponents?.raw
layout[3] = components?.raw
layout[3] = components.raw
layout[4] = unexpectedAfterComponents?.raw
}
self.init(unchecked: raw)
Expand All @@ -22157,8 +22157,8 @@ public struct RawVersionTupleSyntax: RawSyntaxNodeProtocol {
layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:))
}

public var components: RawVersionComponentListSyntax? {
layoutView.children[3].map(RawVersionComponentListSyntax.init(raw:))
public var components: RawVersionComponentListSyntax {
layoutView.children[3].map(RawVersionComponentListSyntax.init(raw:))!
}

public var unexpectedAfterComponents: RawUnexpectedNodesSyntax? {
Expand Down
8 changes: 4 additions & 4 deletions Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) {
assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [.keyword("catch")]))
assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 3, verify(layout[3], as: RawCatchItemListSyntax?.self))
assertNoError(kind, 3, verify(layout[3], as: RawCatchItemListSyntax.self))
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))
Expand Down Expand Up @@ -547,7 +547,7 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) {
assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.leftSquare)]))
assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 3, verify(layout[3], as: RawClosureCaptureListSyntax?.self))
assertNoError(kind, 3, verify(layout[3], as: RawClosureCaptureListSyntax.self))
assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 5, verify(layout[5], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.rightSquare)]))
assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self))
Expand Down Expand Up @@ -994,7 +994,7 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) {
assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 3, verify(layout[3], as: RawCodeBlockSyntax.self))
assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 5, verify(layout[5], as: RawCatchClauseListSyntax?.self))
assertNoError(kind, 5, verify(layout[5], as: RawCatchClauseListSyntax.self))
assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self))
case .documentationAttributeArgumentList:
for (index, element) in layout.enumerated() {
Expand Down Expand Up @@ -2638,7 +2638,7 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) {
assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.integerLiteral)]))
assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 3, verify(layout[3], as: RawVersionComponentListSyntax?.self))
assertNoError(kind, 3, verify(layout[3], as: RawVersionComponentListSyntax.self))
assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self))
case .whereClause:
assert(layout.count == 5)
Expand Down
30 changes: 15 additions & 15 deletions Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1925,7 +1925,7 @@ public struct CatchClauseSyntax: SyntaxProtocol, SyntaxHashable {
_ unexpectedBeforeCatchKeyword: UnexpectedNodesSyntax? = nil,
catchKeyword: TokenSyntax = .keyword(.catch),
_ unexpectedBetweenCatchKeywordAndCatchItems: UnexpectedNodesSyntax? = nil,
catchItems: CatchItemListSyntax? = nil,
catchItems: CatchItemListSyntax = [],
_ unexpectedBetweenCatchItemsAndBody: UnexpectedNodesSyntax? = nil,
body: CodeBlockSyntax,
_ unexpectedAfterBody: UnexpectedNodesSyntax? = nil,
Expand All @@ -1947,7 +1947,7 @@ public struct CatchClauseSyntax: SyntaxProtocol, SyntaxHashable {
unexpectedBeforeCatchKeyword?.raw,
catchKeyword.raw,
unexpectedBetweenCatchKeywordAndCatchItems?.raw,
catchItems?.raw,
catchItems.raw,
unexpectedBetweenCatchItemsAndBody?.raw,
body.raw,
unexpectedAfterBody?.raw
Expand Down Expand Up @@ -1992,12 +1992,12 @@ public struct CatchClauseSyntax: SyntaxProtocol, SyntaxHashable {
}
}

public var catchItems: CatchItemListSyntax? {
public var catchItems: CatchItemListSyntax {
get {
return data.child(at: 3, parent: Syntax(self)).map(CatchItemListSyntax.init)
return CatchItemListSyntax(data.child(at: 3, parent: Syntax(self))!)
}
set(value) {
self = CatchClauseSyntax(data.replacingChild(at: 3, with: value?.data, arena: SyntaxArena()))
self = CatchClauseSyntax(data.replacingChild(at: 3, with: value.data, arena: SyntaxArena()))
}
}

Expand Down Expand Up @@ -2259,7 +2259,7 @@ public struct ClosureCaptureClauseSyntax: SyntaxProtocol, SyntaxHashable {
_ unexpectedBeforeLeftSquare: UnexpectedNodesSyntax? = nil,
leftSquare: TokenSyntax = .leftSquareToken(),
_ unexpectedBetweenLeftSquareAndItems: UnexpectedNodesSyntax? = nil,
items: ClosureCaptureListSyntax? = nil,
items: ClosureCaptureListSyntax,
_ unexpectedBetweenItemsAndRightSquare: UnexpectedNodesSyntax? = nil,
rightSquare: TokenSyntax = .rightSquareToken(),
_ unexpectedAfterRightSquare: UnexpectedNodesSyntax? = nil,
Expand All @@ -2281,7 +2281,7 @@ public struct ClosureCaptureClauseSyntax: SyntaxProtocol, SyntaxHashable {
unexpectedBeforeLeftSquare?.raw,
leftSquare.raw,
unexpectedBetweenLeftSquareAndItems?.raw,
items?.raw,
items.raw,
unexpectedBetweenItemsAndRightSquare?.raw,
rightSquare.raw,
unexpectedAfterRightSquare?.raw
Expand Down Expand Up @@ -2326,12 +2326,12 @@ public struct ClosureCaptureClauseSyntax: SyntaxProtocol, SyntaxHashable {
}
}

public var items: ClosureCaptureListSyntax? {
public var items: ClosureCaptureListSyntax {
get {
return data.child(at: 3, parent: Syntax(self)).map(ClosureCaptureListSyntax.init)
return ClosureCaptureListSyntax(data.child(at: 3, parent: Syntax(self))!)
}
set(value) {
self = ClosureCaptureClauseSyntax(data.replacingChild(at: 3, with: value?.data, arena: SyntaxArena()))
self = ClosureCaptureClauseSyntax(data.replacingChild(at: 3, with: value.data, arena: SyntaxArena()))
}
}

Expand Down Expand Up @@ -19002,7 +19002,7 @@ public struct VersionTupleSyntax: SyntaxProtocol, SyntaxHashable {
_ unexpectedBeforeMajor: UnexpectedNodesSyntax? = nil,
major: TokenSyntax,
_ unexpectedBetweenMajorAndComponents: UnexpectedNodesSyntax? = nil,
components: VersionComponentListSyntax? = nil,
components: VersionComponentListSyntax,
_ unexpectedAfterComponents: UnexpectedNodesSyntax? = nil,
trailingTrivia: Trivia? = nil

Expand All @@ -19020,7 +19020,7 @@ public struct VersionTupleSyntax: SyntaxProtocol, SyntaxHashable {
unexpectedBeforeMajor?.raw,
major.raw,
unexpectedBetweenMajorAndComponents?.raw,
components?.raw,
components.raw,
unexpectedAfterComponents?.raw
]
let raw = RawSyntax.makeLayout(
Expand Down Expand Up @@ -19065,12 +19065,12 @@ public struct VersionTupleSyntax: SyntaxProtocol, SyntaxHashable {
}

/// Any version components that are not the major version . For example, for `1.2.0`, this will contain `.2.0`
public var components: VersionComponentListSyntax? {
public var components: VersionComponentListSyntax {
get {
return data.child(at: 3, parent: Syntax(self)).map(VersionComponentListSyntax.init)
return VersionComponentListSyntax(data.child(at: 3, parent: Syntax(self))!)
}
set(value) {
self = VersionTupleSyntax(data.replacingChild(at: 3, with: value?.data, arena: SyntaxArena()))
self = VersionTupleSyntax(data.replacingChild(at: 3, with: value.data, arena: SyntaxArena()))
}
}

Expand Down
Loading

0 comments on commit b3f3692

Please sign in to comment.