File tree Expand file tree Collapse file tree 5 files changed +84
-4
lines changed
Tests/SwiftParserTest/translated Expand file tree Collapse file tree 5 files changed +84
-4
lines changed Original file line number Diff line number Diff line change @@ -1263,6 +1263,29 @@ extension Parser {
1263
1263
return RawExprSyntax ( self . parseClosureExpression ( ) )
1264
1264
case ( . period, let handle) ? : // .foo
1265
1265
let dot = self . eat ( handle)
1266
+
1267
+ // Special case ".<integer_literal>" like ".4". This isn't valid, but the
1268
+ // developer almost certainly meant to use "0.4". Diagnose this, and
1269
+ // recover as if they wrote that.
1270
+ if let integerLiteral = self . consume ( if: . integerLiteral) {
1271
+ return RawExprSyntax (
1272
+ RawFloatLiteralExprSyntax (
1273
+ floatingDigits: RawTokenSyntax (
1274
+ missing: . floatingLiteral,
1275
+ arena: self . arena
1276
+ ) ,
1277
+ RawUnexpectedNodesSyntax (
1278
+ elements: [
1279
+ RawSyntax ( dot) ,
1280
+ RawSyntax ( integerLiteral) ,
1281
+ ] ,
1282
+ arena: self . arena
1283
+ ) ,
1284
+ arena: self . arena
1285
+ )
1286
+ )
1287
+ }
1288
+
1266
1289
let ( name, args) = self . parseDeclNameRef ( [ . keywords, . compoundNames] )
1267
1290
return RawExprSyntax (
1268
1291
RawMemberAccessExprSyntax (
Original file line number Diff line number Diff line change @@ -678,6 +678,39 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor {
678
678
return . visitChildren
679
679
}
680
680
681
+ public override func visit( _ node: FloatLiteralExprSyntax ) -> SyntaxVisitorContinueKind {
682
+ if shouldSkip ( node) {
683
+ return . skipChildren
684
+ }
685
+ if node. floatingDigits. presence == . missing,
686
+ let tokens = node. unexpectedAfterFloatingDigits? . onlyTokens ( satisfying: { $0. tokenKind == . period || $0. tokenKind. isIntegerLiteral } )
687
+ {
688
+ addDiagnostic (
689
+ node,
690
+ InvalidFloatLiteralMissingLeadingZero ( integerLiteral: tokens [ 1 ] ) ,
691
+ fixIts: [
692
+ FixIt (
693
+ message: InsertFixIt ( tokenToBeInserted: . integerLiteral( " 0 " ) ) ,
694
+ changes: [
695
+ FixIt . MultiNodeChange (
696
+ FixIt . Change. replace (
697
+ oldNode: Syntax ( node. floatingDigits) ,
698
+ newNode: Syntax (
699
+ FloatLiteralExprSyntax (
700
+ floatingDigits: . floatingLiteral( " 0. \( tokens [ 1 ] . text) " )
701
+ )
702
+ )
703
+ )
704
+ )
705
+ ] + tokens. map { FixIt . MultiNodeChange. makeMissing ( $0) }
706
+ )
707
+ ] ,
708
+ handledNodes: [ node. floatingDigits. id] + tokens. map { $0. id }
709
+ )
710
+ }
711
+ return . visitChildren
712
+ }
713
+
681
714
public override func visit( _ node: ForInStmtSyntax ) -> SyntaxVisitorContinueKind {
682
715
if shouldSkip ( node) {
683
716
return . skipChildren
Original file line number Diff line number Diff line change @@ -306,6 +306,14 @@ public struct IdentifierNotAllowedInOperatorName: ParserError {
306
306
}
307
307
}
308
308
309
+ public struct InvalidFloatLiteralMissingLeadingZero : ParserError {
310
+ public let integerLiteral : TokenSyntax
311
+
312
+ public var message : String {
313
+ return " '. \( integerLiteral. text) ' is not a valid floating point literal; it must be written '0. \( integerLiteral. text) ' "
314
+ }
315
+ }
316
+
309
317
public struct InvalidIdentifierError : ParserError {
310
318
public let invalidIdentifier : TokenSyntax
311
319
public let missingIdentifier : TokenSyntax
Original file line number Diff line number Diff line change @@ -149,6 +149,15 @@ extension TokenKind {
149
149
return false
150
150
}
151
151
}
152
+
153
+ var isIntegerLiteral : Bool {
154
+ switch self {
155
+ case . integerLiteral:
156
+ return true
157
+ default :
158
+ return false
159
+ }
160
+ }
152
161
}
153
162
154
163
public extension TriviaPiece {
Original file line number Diff line number Diff line change @@ -1372,13 +1372,20 @@ final class RecoveryTests: XCTestCase {
1372
1372
assertParse (
1373
1373
"""
1374
1374
func exprPostfix2() {
1375
- _ = .1️⃣42
1375
+ _ = 1️⃣.42
1376
1376
}
1377
1377
""" ,
1378
1378
diagnostics: [
1379
- // TODO: Old parser expected error on line 2: '.42' is not a valid floating point literal; it must be written '0.42', Fix-It replacements: 7 - 7 = '0'
1380
- DiagnosticSpec ( message: " expected name in member access " , fixIts: [ " insert name " ] )
1381
- ]
1379
+ DiagnosticSpec (
1380
+ message: " '.42' is not a valid floating point literal; it must be written '0.42' " ,
1381
+ fixIts: [ " insert '0' " ]
1382
+ )
1383
+ ] ,
1384
+ fixedSource: """
1385
+ func exprPostfix2() {
1386
+ _ = 0.42
1387
+ }
1388
+ """
1382
1389
)
1383
1390
}
1384
1391
You can’t perform that action at this time.
0 commit comments