@@ -262,48 +262,97 @@ 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
+ for _ in 0 ..< handle. unexpectedTokens {
296
+ unexpectedTokens. append ( RawSyntax ( self . consumeAnyToken ( ) ) )
297
+ }
298
+ }
299
+ return RawVersionTupleSyntax (
300
+ RawUnexpectedNodesSyntax ( unexpectedTokens, arena: self . arena) ,
301
+ major: self . missingToken ( . integerLiteral, text: nil ) ,
302
+ components: nil ,
303
+ arena: self . arena
304
+ )
305
+ }
306
+ }
296
307
297
- return RawVersionTupleSyntax(
298
- major: major,
299
- components: RawVersionComponentListSyntax ( elements: components, arena: self . arena) ,
300
- unexpectedTrailingComponents,
301
- arena: self . arena
302
- )
308
+ var unexpectedTrailingComponents: RawUnexpectedNodesSyntax?
303
309
310
+ if !trailingComponents. isEmpty {
311
+ unexpectedTrailingComponents = RawUnexpectedNodesSyntax ( elements: trailingComponents. compactMap { $0. as ( RawSyntax . self) } , arena: self . arena)
312
+ }
313
+
314
+ return RawVersionTupleSyntax (
315
+ major: major,
316
+ components: RawVersionComponentListSyntax ( elements: components, arena: self . arena) ,
317
+ unexpectedTrailingComponents,
318
+ arena: self . arena
319
+ )
320
+ } else {
321
+ let unexpectedToken = self . eat ( . floatingLiteral)
322
+ return RawVersionTupleSyntax (
323
+ RawUnexpectedNodesSyntax ( [ unexpectedToken] , arena: self . arena) ,
324
+ major: self . missingToken ( . integerLiteral, text: nil ) ,
325
+ components: nil ,
326
+ arena: self . arena
327
+ )
328
+ }
304
329
} else {
305
330
let major = self . expectDecimalIntegerWithoutRecovery ( )
306
- return RawVersionTupleSyntax ( major: major, components: nil , arena: self . arena)
331
+ if major. hasError {
332
+ let unexpectedNodes : RawUnexpectedNodesSyntax ?
333
+ var unexpectedTokens = [ RawSyntax] ( )
334
+ if !major. isEmpty {
335
+ unexpectedTokens. append ( RawSyntax ( major) )
336
+ }
337
+ if let ( _, handle) = self . canRecoverTo ( anyIn: VersionTupleSyntax . EndOfVersionTupleOptions. self) {
338
+ for _ in 0 ..< handle. unexpectedTokens {
339
+ unexpectedTokens. append ( RawSyntax ( self . consumeAnyToken ( ) ) )
340
+ }
341
+ }
342
+ if !unexpectedTokens. isEmpty {
343
+ unexpectedNodes = RawUnexpectedNodesSyntax ( elements: unexpectedTokens, arena: self . arena)
344
+ } else {
345
+ unexpectedNodes = nil
346
+ }
347
+ return RawVersionTupleSyntax (
348
+ unexpectedNodes,
349
+ major: self . missingToken ( . integerLiteral, text: nil ) ,
350
+ components: nil ,
351
+ arena: self . arena
352
+ )
353
+ } else {
354
+ return RawVersionTupleSyntax ( major: major, components: nil , arena: self . arena)
355
+ }
307
356
}
308
357
}
309
358
}
0 commit comments