Skip to content

Parse versions as three integer tokens #1440

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 1 commit into from
Mar 28, 2023
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
20 changes: 16 additions & 4 deletions CodeGeneration/Sources/SyntaxSupport/AvailabilityNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,21 @@ public let AVAILABILITY_NODES: [Node] = [
kind: "Syntax",
children: [
Child(
name: "MajorMinor",
kind: .token(choices: [.token(tokenKind: "IntegerLiteralToken"), .token(tokenKind: "FloatingLiteralToken")]),
description: "In case the version consists only of the major version, an integer literal that specifies the major version. In case the version consists of major and minor version number, a floating literal in which the decimal part is interpreted as the minor version."
name: "Major",
Copy link
Member

@rintaro rintaro Mar 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only "patch" has the name "PatchVersion" we should be consistent

kind: .token(choices: [.token(tokenKind: "IntegerLiteralToken")]),
description: "The major version."
),
Child(
name: "MinorPeriod",
kind: .token(choices: [.token(tokenKind: "PeriodToken")]),
description: "If the version contains a minor number, the period separating the major from the minor number.",
isOptional: true
),
Child(
name: "Minor",
kind: .token(choices: [.token(tokenKind: "IntegerLiteralToken")]),
description: "The minor version if specified.",
isOptional: true
),
Child(
name: "PatchPeriod",
Expand All @@ -139,7 +151,7 @@ public let AVAILABILITY_NODES: [Node] = [
isOptional: true
),
Child(
name: "PatchVersion",
name: "Patch",
kind: .token(choices: [.token(tokenKind: "IntegerLiteralToken")]),
description: "The patch version if specified.",
isOptional: true
Expand Down
66 changes: 45 additions & 21 deletions Sources/SwiftParser/Availability.swift
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,18 @@ extension Parser {
)
}

/// If the next token is an integer literal only consisting of the digits 0-9
/// consume and return it, otherwise return a missing integer token.
private mutating func expectDecimalIntegerWithoutRecovery() -> RawTokenSyntax {
guard self.at(.integerLiteral) else {
return missingToken(.integerLiteral, text: nil)
}
guard self.currentToken.tokenText.allSatisfy({ Unicode.Scalar($0).isDigit }) else {
return missingToken(.integerLiteral, text: nil)
}
return self.consumeAnyToken()
}

/// Parse a dot-separated list of version numbers.
///
/// Grammar
Expand All @@ -250,31 +262,43 @@ extension Parser {
/// platform-version → decimal-digits '.' decimal-digits
/// platform-version → decimal-digits '.' decimal-digits '.' decimal-digits
mutating func parseVersionTuple() -> RawVersionTupleSyntax {
let (unexpectedBeforeMajorMinor, majorMinor) = self.expect(.integerLiteral, .floatingLiteral, default: .integerLiteral)
let patchPeriod: RawTokenSyntax?
let unexpectedBeforePatch: RawUnexpectedNodesSyntax?
let patch: RawTokenSyntax?
if majorMinor.tokenKind == .floatingLiteral {
patchPeriod = self.consume(if: .period)
if patchPeriod != nil {
(unexpectedBeforePatch, patch) = self.expect(.integerLiteral)
if self.at(.floatingLiteral),
let periodIndex = self.currentToken.tokenText.firstIndex(of: UInt8(ascii: ".")),
self.currentToken.tokenText[0..<periodIndex].allSatisfy({ Unicode.Scalar($0).isDigit })
{
// The lexer generates a float literal '1.2' for the major and minor version.
// Split it into two integers if possible
let major = self.consumePrefix(SyntaxText(rebasing: self.currentToken.tokenText[0..<periodIndex]), as: .integerLiteral)
let (unexpectedBeforeMinorPeriod, minorPeriod) = self.expect(.period)
let minor = self.expectDecimalIntegerWithoutRecovery()
let patchPeriod: RawTokenSyntax?
let patch: RawTokenSyntax?
if let period = self.consume(if: .period) {
patchPeriod = period
patch = self.expectDecimalIntegerWithoutRecovery()
} else {
unexpectedBeforePatch = nil
patchPeriod = nil
patch = nil
}
return RawVersionTupleSyntax(
major: major,
unexpectedBeforeMinorPeriod,
minorPeriod: minorPeriod,
minor: minor,
patchPeriod: patchPeriod,
patch: patch,
arena: self.arena
)
} else {
patchPeriod = nil
unexpectedBeforePatch = nil
patch = nil
let major = self.expectDecimalIntegerWithoutRecovery()
return RawVersionTupleSyntax(
major: major,
minorPeriod: nil,
minor: nil,
patchPeriod: nil,
patch: nil,
arena: self.arena
)
}

return RawVersionTupleSyntax(
unexpectedBeforeMajorMinor,
majorMinor: majorMinor,
patchPeriod: patchPeriod,
unexpectedBeforePatch,
patchVersion: patch,
arena: self.arena
)
}
}
66 changes: 45 additions & 21 deletions Sources/SwiftSyntax/generated/raw/RawSyntaxNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21031,56 +21031,80 @@ public struct RawVersionTupleSyntax: RawSyntaxNodeProtocol {
}

public init(
_ unexpectedBeforeMajorMinor: RawUnexpectedNodesSyntax? = nil,
majorMinor: RawTokenSyntax,
_ unexpectedBetweenMajorMinorAndPatchPeriod: RawUnexpectedNodesSyntax? = nil,
_ unexpectedBeforeMajor: RawUnexpectedNodesSyntax? = nil,
major: RawTokenSyntax,
_ unexpectedBetweenMajorAndMinorPeriod: RawUnexpectedNodesSyntax? = nil,
minorPeriod: RawTokenSyntax?,
_ unexpectedBetweenMinorPeriodAndMinor: RawUnexpectedNodesSyntax? = nil,
minor: RawTokenSyntax?,
_ unexpectedBetweenMinorAndPatchPeriod: RawUnexpectedNodesSyntax? = nil,
patchPeriod: RawTokenSyntax?,
_ unexpectedBetweenPatchPeriodAndPatchVersion: RawUnexpectedNodesSyntax? = nil,
patchVersion: RawTokenSyntax?,
_ unexpectedAfterPatchVersion: RawUnexpectedNodesSyntax? = nil,
_ unexpectedBetweenPatchPeriodAndPatch: RawUnexpectedNodesSyntax? = nil,
patch: RawTokenSyntax?,
_ unexpectedAfterPatch: RawUnexpectedNodesSyntax? = nil,
arena: __shared SyntaxArena
) {
let raw = RawSyntax.makeLayout(
kind: .versionTuple, uninitializedCount: 7, arena: arena) { layout in
kind: .versionTuple, uninitializedCount: 11, arena: arena) { layout in
layout.initialize(repeating: nil)
layout[0] = unexpectedBeforeMajorMinor?.raw
layout[1] = majorMinor.raw
layout[2] = unexpectedBetweenMajorMinorAndPatchPeriod?.raw
layout[3] = patchPeriod?.raw
layout[4] = unexpectedBetweenPatchPeriodAndPatchVersion?.raw
layout[5] = patchVersion?.raw
layout[6] = unexpectedAfterPatchVersion?.raw
layout[0] = unexpectedBeforeMajor?.raw
layout[1] = major.raw
layout[2] = unexpectedBetweenMajorAndMinorPeriod?.raw
layout[3] = minorPeriod?.raw
layout[4] = unexpectedBetweenMinorPeriodAndMinor?.raw
layout[5] = minor?.raw
layout[6] = unexpectedBetweenMinorAndPatchPeriod?.raw
layout[7] = patchPeriod?.raw
layout[8] = unexpectedBetweenPatchPeriodAndPatch?.raw
layout[9] = patch?.raw
layout[10] = unexpectedAfterPatch?.raw
}
self.init(unchecked: raw)
}

public var unexpectedBeforeMajorMinor: RawUnexpectedNodesSyntax? {
public var unexpectedBeforeMajor: RawUnexpectedNodesSyntax? {
layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:))
}

public var majorMinor: RawTokenSyntax {
public var major: RawTokenSyntax {
layoutView.children[1].map(RawTokenSyntax.init(raw:))!
}

public var unexpectedBetweenMajorMinorAndPatchPeriod: RawUnexpectedNodesSyntax? {
public var unexpectedBetweenMajorAndMinorPeriod: RawUnexpectedNodesSyntax? {
layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:))
}

public var patchPeriod: RawTokenSyntax? {
public var minorPeriod: RawTokenSyntax? {
layoutView.children[3].map(RawTokenSyntax.init(raw:))
}

public var unexpectedBetweenPatchPeriodAndPatchVersion: RawUnexpectedNodesSyntax? {
public var unexpectedBetweenMinorPeriodAndMinor: RawUnexpectedNodesSyntax? {
layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:))
}

public var patchVersion: RawTokenSyntax? {
public var minor: RawTokenSyntax? {
layoutView.children[5].map(RawTokenSyntax.init(raw:))
}

public var unexpectedAfterPatchVersion: RawUnexpectedNodesSyntax? {
public var unexpectedBetweenMinorAndPatchPeriod: RawUnexpectedNodesSyntax? {
layoutView.children[6].map(RawUnexpectedNodesSyntax.init(raw:))
}

public var patchPeriod: RawTokenSyntax? {
layoutView.children[7].map(RawTokenSyntax.init(raw:))
}

public var unexpectedBetweenPatchPeriodAndPatch: RawUnexpectedNodesSyntax? {
layoutView.children[8].map(RawUnexpectedNodesSyntax.init(raw:))
}

public var patch: RawTokenSyntax? {
layoutView.children[9].map(RawTokenSyntax.init(raw:))
}

public var unexpectedAfterPatch: RawUnexpectedNodesSyntax? {
layoutView.children[10].map(RawUnexpectedNodesSyntax.init(raw:))
}
}

@_spi(RawSyntax)
Expand Down
50 changes: 22 additions & 28 deletions Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -227,12 +227,7 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) {
case .accessPathComponent:
assert(layout.count == 5)
assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [
.tokenKind(.identifier),
.tokenKind(.binaryOperator),
.tokenKind(.prefixOperator),
.tokenKind(.postfixOperator)
]))
assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.identifier)]))
assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.period)]))
assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self))
Expand Down Expand Up @@ -835,13 +830,7 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) {
case .declName:
assert(layout.count == 5)
assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [
.tokenKind(.identifier),
.tokenKind(.binaryOperator),
.keyword("init"),
.keyword("self"),
.keyword("Self")
]))
assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.identifier), .tokenKind(.prefixOperator), .keyword("init")]))
assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 3, verify(layout[3], as: RawDeclNameArgumentsSyntax?.self))
assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self))
Expand Down Expand Up @@ -962,7 +951,7 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) {
case .differentiableAttributeArguments:
assert(layout.count == 11)
assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax?.self, tokenChoices: [.keyword("_forward"), .keyword("reverse"), .keyword("_linear")]))
assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax?.self, tokenChoices: [.keyword("forward"), .keyword("reverse"), .keyword("linear")]))
assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.comma)]))
assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self))
Expand Down Expand Up @@ -1019,12 +1008,7 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) {
case .editorPlaceholderExpr:
assert(layout.count == 3)
assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [
.tokenKind(.identifier),
.keyword("self"),
.keyword("Self"),
.keyword("init")
]))
assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.identifier)]))
assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self))
case .effectsArguments:
for (index, element) in layout.enumerated() {
Expand Down Expand Up @@ -1561,7 +1545,14 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) {
case .labeledSpecializeEntry:
assert(layout.count == 9)
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: [
.tokenKind(.identifier),
.keyword("available"),
.keyword("exported"),
.keyword("kind"),
.keyword("spi"),
.keyword("spiModule")
]))
assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.colon)]))
assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self))
Expand Down Expand Up @@ -1786,7 +1777,7 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) {
case .objCSelectorPiece:
assert(layout.count == 5)
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: [.tokenKind(.identifier)]))
assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.colon)]))
assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self))
Expand Down Expand Up @@ -2077,10 +2068,9 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) {
assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 5, verify(layout[5], as: RawTokenSyntax.self, tokenChoices: [
.tokenKind(.identifier),
.keyword("self"),
.keyword("Self"),
.keyword("init"),
.tokenKind(.binaryOperator)
.tokenKind(.binaryOperator),
.tokenKind(.prefixOperator),
.tokenKind(.postfixOperator)
]))
assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 7, verify(layout[7], as: RawDeclNameArgumentsSyntax?.self))
Expand Down Expand Up @@ -2524,14 +2514,18 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) {
assertNoError(kind, 7, verify(layout[7], as: RawPatternBindingListSyntax.self))
assertNoError(kind, 8, verify(layout[8], as: RawUnexpectedNodesSyntax?.self))
case .versionTuple:
assert(layout.count == 7)
assert(layout.count == 11)
assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.integerLiteral), .tokenKind(.floatingLiteral)]))
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: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.period)]))
assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 5, verify(layout[5], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.integerLiteral)]))
assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 7, verify(layout[7], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.period)]))
assertNoError(kind, 8, verify(layout[8], as: RawUnexpectedNodesSyntax?.self))
assertNoError(kind, 9, verify(layout[9], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.integerLiteral)]))
assertNoError(kind, 10, verify(layout[10], as: RawUnexpectedNodesSyntax?.self))
case .whereClause:
assert(layout.count == 5)
assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self))
Expand Down
Loading