Skip to content

Commit 7f1f40f

Browse files
authored
Merge pull request #1484 from kimdv/kimdv/add-diagnostic-for-dictionary
Add diagnostic for dictionary
2 parents 05b52f6 + 4fd49a8 commit 7f1f40f

File tree

2 files changed

+88
-13
lines changed

2 files changed

+88
-13
lines changed

Sources/SwiftParser/Types.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,6 +1081,30 @@ extension Parser {
10811081
arena: self.arena
10821082
)
10831083
)
1084+
} else if self.at(.colon) {
1085+
var lookahead = self.lookahead()
1086+
1087+
// We only want to continue with a dictionary if we can parse a colon and a simpletype.
1088+
// Otherwise we can get a wrong diagnostic if we get a Python-style function declaration.
1089+
guard lookahead.consume(if: .colon) != nil && lookahead.canParseSimpleType() else {
1090+
return result
1091+
}
1092+
1093+
let (unexpectedBeforeColon, colon) = self.expect(.colon)
1094+
let secondType = self.parseSimpleType()
1095+
let rightSquareBracket = self.consume(if: .rightSquareBracket) ?? self.missingToken(.rightSquareBracket)
1096+
1097+
result = RawTypeSyntax(
1098+
RawDictionaryTypeSyntax(
1099+
leftSquareBracket: self.missingToken(.leftSquareBracket),
1100+
keyType: result,
1101+
unexpectedBeforeColon,
1102+
colon: colon,
1103+
valueType: secondType,
1104+
rightSquareBracket: rightSquareBracket,
1105+
arena: self.arena
1106+
)
1107+
)
10841108
}
10851109

10861110
var loopProgress = LoopProgressCondition()

Tests/SwiftParserTest/translated/RecoveryTests.swift

Lines changed: 64 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,22 +1204,63 @@ final class RecoveryTests: XCTestCase {
12041204
"""
12051205
struct ErrorTypeInVarDeclDictionaryType {
12061206
let a1: String1️⃣:
1207-
let a2: String2️⃣: Int]
1208-
let a3: String3️⃣: [Int]
1209-
let a4: String4️⃣: Int
1207+
let a2: 2️⃣String: Int]
1208+
let a3: 3️⃣String: [Int]4️⃣
1209+
let a4: 5️⃣String: Int6️⃣
1210+
let a4: 7️⃣String: Int]??
12101211
}
12111212
""",
12121213
diagnostics: [
1213-
// TODO: Old parser expected error on line 2: unexpected ':' in type; did you mean to write a dictionary type?, Fix-It replacements: 11 - 11 = '['
1214-
DiagnosticSpec(locationMarker: "1️⃣", message: "consecutive declarations on a line must be separated by ';'", fixIts: ["insert ';'"]),
1215-
DiagnosticSpec(locationMarker: "1️⃣", message: "unexpected code ':' before variable"),
1216-
// TODO: Old parser expected error on line 3: unexpected ':' in type; did you mean to write a dictionary type?, Fix-It replacements: 11 - 11 = '['
1217-
DiagnosticSpec(locationMarker: "2️⃣", message: "unexpected code ': Int]' before variable"),
1218-
// TODO: Old parser expected error on line 4: unexpected ':' in type; did you mean to write a dictionary type?, Fix-It replacements: 11 - 11 = '[', 24 - 24 = ']'
1219-
DiagnosticSpec(locationMarker: "3️⃣", message: "unexpected code ': [Int]' before variable"),
1220-
// TODO: Old parser expected error on line 5: unexpected ':' in type; did you mean to write a dictionary type?, Fix-It replacements: 11 - 11 = '[', 22 - 22 = ']'
1221-
DiagnosticSpec(locationMarker: "4️⃣", message: "unexpected code ': Int' in struct"),
1222-
]
1214+
DiagnosticSpec(
1215+
locationMarker: "1️⃣",
1216+
message: "consecutive declarations on a line must be separated by ';'",
1217+
fixIts: ["insert ';'"]
1218+
),
1219+
DiagnosticSpec(
1220+
locationMarker: "1️⃣",
1221+
message: "unexpected code ':' before variable"
1222+
),
1223+
DiagnosticSpec(
1224+
locationMarker: "2️⃣",
1225+
message: "expected '[' to start dictionary type",
1226+
fixIts: ["insert '['"]
1227+
),
1228+
DiagnosticSpec(
1229+
locationMarker: "3️⃣",
1230+
message: "expected '[' to start dictionary type",
1231+
fixIts: ["insert '['"]
1232+
),
1233+
DiagnosticSpec(
1234+
locationMarker: "4️⃣",
1235+
message: "expected ']' to end dictionary type",
1236+
fixIts: ["insert ']'"]
1237+
),
1238+
DiagnosticSpec(
1239+
locationMarker: "5️⃣",
1240+
message: "expected '[' to start dictionary type",
1241+
fixIts: ["insert '['"]
1242+
),
1243+
DiagnosticSpec(
1244+
locationMarker: "6️⃣",
1245+
message: "expected ']' to end dictionary type",
1246+
fixIts: ["insert ']'"]
1247+
),
1248+
DiagnosticSpec(
1249+
locationMarker: "7️⃣",
1250+
message: "expected '[' to start dictionary type",
1251+
fixIts: ["insert '['"]
1252+
),
1253+
1254+
],
1255+
fixedSource: """
1256+
struct ErrorTypeInVarDeclDictionaryType {
1257+
let a1: String;:
1258+
let a2: [String: Int]
1259+
let a3: [String: [Int]]
1260+
let a4: [String: Int]
1261+
let a4: [String: Int]??
1262+
}
1263+
"""
12231264
)
12241265
}
12251266

@@ -2340,4 +2381,14 @@ final class RecoveryTests: XCTestCase {
23402381
"""
23412382
)
23422383
}
2384+
2385+
// https://github.com/apple/swift-syntax/pull/1484/files#r1176740738
2386+
func testRecovery184() {
2387+
assertParse(
2388+
"func foo() -> Int1️⃣:",
2389+
diagnostics: [
2390+
DiagnosticSpec(message: "extraneous code ':' at top level")
2391+
]
2392+
)
2393+
}
23432394
}

0 commit comments

Comments
 (0)