Skip to content

Commit c7dd3f4

Browse files
authored
Merge pull request #1440 from ahoppen/ahoppen/version-parsing
Parse versions as three integer tokens
2 parents 94add47 + 47a8dcd commit c7dd3f4

File tree

6 files changed

+307
-88
lines changed

6 files changed

+307
-88
lines changed

CodeGeneration/Sources/SyntaxSupport/AvailabilityNodes.swift

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,21 @@ public let AVAILABILITY_NODES: [Node] = [
128128
kind: "Syntax",
129129
children: [
130130
Child(
131-
name: "MajorMinor",
132-
kind: .token(choices: [.token(tokenKind: "IntegerLiteralToken"), .token(tokenKind: "FloatingLiteralToken")]),
133-
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."
131+
name: "Major",
132+
kind: .token(choices: [.token(tokenKind: "IntegerLiteralToken")]),
133+
description: "The major version."
134+
),
135+
Child(
136+
name: "MinorPeriod",
137+
kind: .token(choices: [.token(tokenKind: "PeriodToken")]),
138+
description: "If the version contains a minor number, the period separating the major from the minor number.",
139+
isOptional: true
140+
),
141+
Child(
142+
name: "Minor",
143+
kind: .token(choices: [.token(tokenKind: "IntegerLiteralToken")]),
144+
description: "The minor version if specified.",
145+
isOptional: true
134146
),
135147
Child(
136148
name: "PatchPeriod",
@@ -139,7 +151,7 @@ public let AVAILABILITY_NODES: [Node] = [
139151
isOptional: true
140152
),
141153
Child(
142-
name: "PatchVersion",
154+
name: "Patch",
143155
kind: .token(choices: [.token(tokenKind: "IntegerLiteralToken")]),
144156
description: "The patch version if specified.",
145157
isOptional: true

Sources/SwiftParser/Availability.swift

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,18 @@ extension Parser {
241241
)
242242
}
243243

244+
/// If the next token is an integer literal only consisting of the digits 0-9
245+
/// consume and return it, otherwise return a missing integer token.
246+
private mutating func expectDecimalIntegerWithoutRecovery() -> RawTokenSyntax {
247+
guard self.at(.integerLiteral) else {
248+
return missingToken(.integerLiteral, text: nil)
249+
}
250+
guard self.currentToken.tokenText.allSatisfy({ Unicode.Scalar($0).isDigit }) else {
251+
return missingToken(.integerLiteral, text: nil)
252+
}
253+
return self.consumeAnyToken()
254+
}
255+
244256
/// Parse a dot-separated list of version numbers.
245257
///
246258
/// Grammar
@@ -250,31 +262,43 @@ extension Parser {
250262
/// platform-version → decimal-digits '.' decimal-digits
251263
/// platform-version → decimal-digits '.' decimal-digits '.' decimal-digits
252264
mutating func parseVersionTuple() -> RawVersionTupleSyntax {
253-
let (unexpectedBeforeMajorMinor, majorMinor) = self.expect(.integerLiteral, .floatingLiteral, default: .integerLiteral)
254-
let patchPeriod: RawTokenSyntax?
255-
let unexpectedBeforePatch: RawUnexpectedNodesSyntax?
256-
let patch: RawTokenSyntax?
257-
if majorMinor.tokenKind == .floatingLiteral {
258-
patchPeriod = self.consume(if: .period)
259-
if patchPeriod != nil {
260-
(unexpectedBeforePatch, patch) = self.expect(.integerLiteral)
265+
if self.at(.floatingLiteral),
266+
let periodIndex = self.currentToken.tokenText.firstIndex(of: UInt8(ascii: ".")),
267+
self.currentToken.tokenText[0..<periodIndex].allSatisfy({ Unicode.Scalar($0).isDigit })
268+
{
269+
// The lexer generates a float literal '1.2' for the major and minor version.
270+
// Split it into two integers if possible
271+
let major = self.consumePrefix(SyntaxText(rebasing: self.currentToken.tokenText[0..<periodIndex]), as: .integerLiteral)
272+
let (unexpectedBeforeMinorPeriod, minorPeriod) = self.expect(.period)
273+
let minor = self.expectDecimalIntegerWithoutRecovery()
274+
let patchPeriod: RawTokenSyntax?
275+
let patch: RawTokenSyntax?
276+
if let period = self.consume(if: .period) {
277+
patchPeriod = period
278+
patch = self.expectDecimalIntegerWithoutRecovery()
261279
} else {
262-
unexpectedBeforePatch = nil
280+
patchPeriod = nil
263281
patch = nil
264282
}
283+
return RawVersionTupleSyntax(
284+
major: major,
285+
unexpectedBeforeMinorPeriod,
286+
minorPeriod: minorPeriod,
287+
minor: minor,
288+
patchPeriod: patchPeriod,
289+
patch: patch,
290+
arena: self.arena
291+
)
265292
} else {
266-
patchPeriod = nil
267-
unexpectedBeforePatch = nil
268-
patch = nil
293+
let major = self.expectDecimalIntegerWithoutRecovery()
294+
return RawVersionTupleSyntax(
295+
major: major,
296+
minorPeriod: nil,
297+
minor: nil,
298+
patchPeriod: nil,
299+
patch: nil,
300+
arena: self.arena
301+
)
269302
}
270-
271-
return RawVersionTupleSyntax(
272-
unexpectedBeforeMajorMinor,
273-
majorMinor: majorMinor,
274-
patchPeriod: patchPeriod,
275-
unexpectedBeforePatch,
276-
patchVersion: patch,
277-
arena: self.arena
278-
)
279303
}
280304
}

Sources/SwiftSyntax/generated/raw/RawSyntaxNodes.swift

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21000,56 +21000,80 @@ public struct RawVersionTupleSyntax: RawSyntaxNodeProtocol {
2100021000
}
2100121001

2100221002
public init(
21003-
_ unexpectedBeforeMajorMinor: RawUnexpectedNodesSyntax? = nil,
21004-
majorMinor: RawTokenSyntax,
21005-
_ unexpectedBetweenMajorMinorAndPatchPeriod: RawUnexpectedNodesSyntax? = nil,
21003+
_ unexpectedBeforeMajor: RawUnexpectedNodesSyntax? = nil,
21004+
major: RawTokenSyntax,
21005+
_ unexpectedBetweenMajorAndMinorPeriod: RawUnexpectedNodesSyntax? = nil,
21006+
minorPeriod: RawTokenSyntax?,
21007+
_ unexpectedBetweenMinorPeriodAndMinor: RawUnexpectedNodesSyntax? = nil,
21008+
minor: RawTokenSyntax?,
21009+
_ unexpectedBetweenMinorAndPatchPeriod: RawUnexpectedNodesSyntax? = nil,
2100621010
patchPeriod: RawTokenSyntax?,
21007-
_ unexpectedBetweenPatchPeriodAndPatchVersion: RawUnexpectedNodesSyntax? = nil,
21008-
patchVersion: RawTokenSyntax?,
21009-
_ unexpectedAfterPatchVersion: RawUnexpectedNodesSyntax? = nil,
21011+
_ unexpectedBetweenPatchPeriodAndPatch: RawUnexpectedNodesSyntax? = nil,
21012+
patch: RawTokenSyntax?,
21013+
_ unexpectedAfterPatch: RawUnexpectedNodesSyntax? = nil,
2101021014
arena: __shared SyntaxArena
2101121015
) {
2101221016
let raw = RawSyntax.makeLayout(
21013-
kind: .versionTuple, uninitializedCount: 7, arena: arena) { layout in
21017+
kind: .versionTuple, uninitializedCount: 11, arena: arena) { layout in
2101421018
layout.initialize(repeating: nil)
21015-
layout[0] = unexpectedBeforeMajorMinor?.raw
21016-
layout[1] = majorMinor.raw
21017-
layout[2] = unexpectedBetweenMajorMinorAndPatchPeriod?.raw
21018-
layout[3] = patchPeriod?.raw
21019-
layout[4] = unexpectedBetweenPatchPeriodAndPatchVersion?.raw
21020-
layout[5] = patchVersion?.raw
21021-
layout[6] = unexpectedAfterPatchVersion?.raw
21019+
layout[0] = unexpectedBeforeMajor?.raw
21020+
layout[1] = major.raw
21021+
layout[2] = unexpectedBetweenMajorAndMinorPeriod?.raw
21022+
layout[3] = minorPeriod?.raw
21023+
layout[4] = unexpectedBetweenMinorPeriodAndMinor?.raw
21024+
layout[5] = minor?.raw
21025+
layout[6] = unexpectedBetweenMinorAndPatchPeriod?.raw
21026+
layout[7] = patchPeriod?.raw
21027+
layout[8] = unexpectedBetweenPatchPeriodAndPatch?.raw
21028+
layout[9] = patch?.raw
21029+
layout[10] = unexpectedAfterPatch?.raw
2102221030
}
2102321031
self.init(unchecked: raw)
2102421032
}
2102521033

21026-
public var unexpectedBeforeMajorMinor: RawUnexpectedNodesSyntax? {
21034+
public var unexpectedBeforeMajor: RawUnexpectedNodesSyntax? {
2102721035
layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:))
2102821036
}
2102921037

21030-
public var majorMinor: RawTokenSyntax {
21038+
public var major: RawTokenSyntax {
2103121039
layoutView.children[1].map(RawTokenSyntax.init(raw:))!
2103221040
}
2103321041

21034-
public var unexpectedBetweenMajorMinorAndPatchPeriod: RawUnexpectedNodesSyntax? {
21042+
public var unexpectedBetweenMajorAndMinorPeriod: RawUnexpectedNodesSyntax? {
2103521043
layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:))
2103621044
}
2103721045

21038-
public var patchPeriod: RawTokenSyntax? {
21046+
public var minorPeriod: RawTokenSyntax? {
2103921047
layoutView.children[3].map(RawTokenSyntax.init(raw:))
2104021048
}
2104121049

21042-
public var unexpectedBetweenPatchPeriodAndPatchVersion: RawUnexpectedNodesSyntax? {
21050+
public var unexpectedBetweenMinorPeriodAndMinor: RawUnexpectedNodesSyntax? {
2104321051
layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:))
2104421052
}
2104521053

21046-
public var patchVersion: RawTokenSyntax? {
21054+
public var minor: RawTokenSyntax? {
2104721055
layoutView.children[5].map(RawTokenSyntax.init(raw:))
2104821056
}
2104921057

21050-
public var unexpectedAfterPatchVersion: RawUnexpectedNodesSyntax? {
21058+
public var unexpectedBetweenMinorAndPatchPeriod: RawUnexpectedNodesSyntax? {
2105121059
layoutView.children[6].map(RawUnexpectedNodesSyntax.init(raw:))
2105221060
}
21061+
21062+
public var patchPeriod: RawTokenSyntax? {
21063+
layoutView.children[7].map(RawTokenSyntax.init(raw:))
21064+
}
21065+
21066+
public var unexpectedBetweenPatchPeriodAndPatch: RawUnexpectedNodesSyntax? {
21067+
layoutView.children[8].map(RawUnexpectedNodesSyntax.init(raw:))
21068+
}
21069+
21070+
public var patch: RawTokenSyntax? {
21071+
layoutView.children[9].map(RawTokenSyntax.init(raw:))
21072+
}
21073+
21074+
public var unexpectedAfterPatch: RawUnexpectedNodesSyntax? {
21075+
layoutView.children[10].map(RawUnexpectedNodesSyntax.init(raw:))
21076+
}
2105321077
}
2105421078

2105521079
@_spi(RawSyntax)

Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2513,14 +2513,18 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) {
25132513
assertNoError(kind, 7, verify(layout[7], as: RawPatternBindingListSyntax.self))
25142514
assertNoError(kind, 8, verify(layout[8], as: RawUnexpectedNodesSyntax?.self))
25152515
case .versionTuple:
2516-
assert(layout.count == 7)
2516+
assert(layout.count == 11)
25172517
assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self))
2518-
assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.integerLiteral), .tokenKind(.floatingLiteral)]))
2518+
assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [.tokenKind(.integerLiteral)]))
25192519
assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self))
25202520
assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.period)]))
25212521
assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self))
25222522
assertNoError(kind, 5, verify(layout[5], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.integerLiteral)]))
25232523
assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self))
2524+
assertNoError(kind, 7, verify(layout[7], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.period)]))
2525+
assertNoError(kind, 8, verify(layout[8], as: RawUnexpectedNodesSyntax?.self))
2526+
assertNoError(kind, 9, verify(layout[9], as: RawTokenSyntax?.self, tokenChoices: [.tokenKind(.integerLiteral)]))
2527+
assertNoError(kind, 10, verify(layout[10], as: RawUnexpectedNodesSyntax?.self))
25242528
case .whereClause:
25252529
assert(layout.count == 5)
25262530
assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self))

0 commit comments

Comments
 (0)