@@ -262,48 +262,96 @@ extension Parser {
262
262
/// version-list -> version-tuple-element version-list?
263
263
/// version-tuple-element -> '.' interger-literal
264
264
mutating func parseVersionTuple( maxComponentCount: Int ) -> RawVersionTupleSyntax {
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)
265
+ if self . at ( . floatingLiteral) {
272
266
273
- var components : [ RawVersionComponentSyntax ] = [ ]
274
- var trailingComponents : [ RawVersionComponentSyntax ] = [ ]
267
+ if let periodIndex = self . currentToken. tokenText. firstIndex ( of: UInt8 ( ascii: " . " ) ) ,
268
+ self . currentToken. tokenText [ 0 ..< periodIndex] . allSatisfy ( { Unicode . Scalar ( $0) . isDigit } )
269
+ {
270
+ // The lexer generates a float literal '1.2' for the major and minor version.
271
+ // Split it into two integers if possible
272
+ let major = self . consumePrefix ( SyntaxText ( rebasing: self . currentToken. tokenText [ 0 ..< periodIndex] ) , as: . integerLiteral)
275
273
276
- for i in 1 ... {
277
- guard let period = self . consume ( if: . period) else {
278
- break
279
- }
280
- let version = self . expectDecimalIntegerWithoutRecovery ( )
274
+ var components : [ RawVersionComponentSyntax ] = [ ]
275
+ var trailingComponents : [ RawVersionComponentSyntax ] = [ ]
281
276
282
- let versionComponent = RawVersionComponentSyntax ( period: period, number: version, arena: self . arena)
277
+ for i in 1 ... {
278
+ guard let period = self . consume ( if: . period) else {
279
+ break
280
+ }
281
+ let version = self . expectDecimalIntegerWithoutRecovery ( )
283
282
284
- if i < maxComponentCount {
285
- components. append ( versionComponent)
286
- } else {
287
- trailingComponents. append ( versionComponent)
288
- }
289
- }
283
+ let versionComponent = RawVersionComponentSyntax ( period: period, number: version, arena: self . arena)
290
284
291
- var unexpectedTrailingComponents: RawUnexpectedNodesSyntax?
285
+ if i < maxComponentCount {
286
+ components. append ( versionComponent)
287
+ } else {
288
+ trailingComponents. append ( versionComponent)
289
+ }
292
290
293
- if !trailingComponents . isEmpty {
294
- unexpectedTrailingComponents = RawUnexpectedNodesSyntax ( elements: trailingComponents. compactMap { $0. as ( RawSyntax . self) } , arena: self . arena)
295
- }
291
+ if versionComponent. hasError {
292
+ let unexpectedComponents = components + trailingComponents
293
+ var unexpectedTokens = [ RawSyntax ( major) ] + unexpectedComponents. map ( RawSyntax . init)
294
+ if let ( _, handle) = self . canRecoverTo ( anyIn: VersionTupleSyntax . EndOfVersionTupleOptions. self) ,
295
+ handle. unexpectedTokens > 0
296
+ {
297
+ for _ in 0 ..< handle. unexpectedTokens {
298
+ unexpectedTokens. append ( RawSyntax ( self . consumeAnyToken ( ) ) )
299
+ }
300
+ }
301
+ return RawVersionTupleSyntax (
302
+ RawUnexpectedNodesSyntax ( unexpectedTokens, arena: self . arena) ,
303
+ major: self . missingToken ( . integerLiteral, text: nil ) ,
304
+ components: nil ,
305
+ arena: self . arena
306
+ )
307
+ }
308
+ }
296
309
297
- return RawVersionTupleSyntax(
298
- major: major,
299
- components: RawVersionComponentListSyntax ( elements: components, arena: self . arena) ,
300
- unexpectedTrailingComponents,
301
- arena: self . arena
302
- )
310
+ var unexpectedTrailingComponents: RawUnexpectedNodesSyntax?
311
+
312
+ if !trailingComponents. isEmpty {
313
+ unexpectedTrailingComponents = RawUnexpectedNodesSyntax ( elements: trailingComponents. compactMap { $0. as ( RawSyntax . self) } , arena: self . arena)
314
+ }
303
315
316
+ return RawVersionTupleSyntax (
317
+ major: major,
318
+ components: RawVersionComponentListSyntax ( elements: components, arena: self . arena) ,
319
+ unexpectedTrailingComponents,
320
+ arena: self . arena
321
+ )
322
+ } else {
323
+ let unexpectedToken = self . eat ( . floatingLiteral)
324
+ return RawVersionTupleSyntax (
325
+ RawUnexpectedNodesSyntax ( [ unexpectedToken] , arena: self . arena) ,
326
+ major: self . missingToken ( . integerLiteral, text: nil ) ,
327
+ components: nil ,
328
+ arena: self . arena
329
+ )
330
+ }
304
331
} else {
305
332
let major = self . expectDecimalIntegerWithoutRecovery ( )
306
- return RawVersionTupleSyntax ( major: major, components: nil , arena: self . arena)
333
+ if major. isMissing {
334
+ let unexpectedNodes : RawUnexpectedNodesSyntax ?
335
+ if let ( _, handle) = self . canRecoverTo ( anyIn: VersionTupleSyntax . EndOfVersionTupleOptions. self) ,
336
+ handle. unexpectedTokens > 0
337
+ {
338
+ var unexpectedTokens = [ RawSyntax] ( )
339
+ for _ in 0 ..< handle. unexpectedTokens {
340
+ unexpectedTokens. append ( RawSyntax ( self . consumeAnyToken ( ) ) )
341
+ }
342
+ unexpectedNodes = RawUnexpectedNodesSyntax ( elements: unexpectedTokens, arena: self . arena)
343
+ } else {
344
+ unexpectedNodes = nil
345
+ }
346
+ return RawVersionTupleSyntax (
347
+ unexpectedNodes,
348
+ major: major,
349
+ components: nil ,
350
+ arena: self . arena
351
+ )
352
+ } else {
353
+ return RawVersionTupleSyntax ( major: major, components: nil , arena: self . arena)
354
+ }
307
355
}
308
356
}
309
357
}
0 commit comments