Skip to content

Commit 915a166

Browse files
committed
Add diagnostic for dictionary type
1 parent 61cc73e commit 915a166

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
@@ -1069,6 +1069,30 @@ extension Parser {
10691069
arena: self.arena
10701070
)
10711071
)
1072+
} else if self.at(.colon) {
1073+
var lookahead = self.lookahead()
1074+
1075+
// We only want to continue with a dictionary if we can parse a colon and a simpletype.
1076+
// Otherwise we can get a wrong diagnostiv if we get a Python-style function declaration.
1077+
guard lookahead.consume(if: .colon) != nil && lookahead.canParseSimpleType() else {
1078+
return result
1079+
}
1080+
1081+
let (unexpectedBeforeColon, colon) = self.expect(.colon)
1082+
let secondType = self.parseSimpleType()
1083+
let rightSquareBracket = self.consume(if: .rightSquareBracket) ?? self.missingToken(.rightSquareBracket)
1084+
1085+
result = RawTypeSyntax(
1086+
RawDictionaryTypeSyntax(
1087+
leftSquareBracket: self.missingToken(.leftSquareBracket),
1088+
keyType: result,
1089+
unexpectedBeforeColon,
1090+
colon: colon,
1091+
valueType: secondType,
1092+
rightSquareBracket: rightSquareBracket,
1093+
arena: self.arena
1094+
)
1095+
)
10721096
}
10731097

10741098
var loopProgress = LoopProgressCondition()

Tests/SwiftParserTest/translated/RecoveryTests.swift

Lines changed: 64 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,22 +1178,63 @@ final class RecoveryTests: XCTestCase {
11781178
"""
11791179
struct ErrorTypeInVarDeclDictionaryType {
11801180
let a1: String1️⃣:
1181-
let a2: String2️⃣: Int]
1182-
let a3: String3️⃣: [Int]
1183-
let a4: String4️⃣: Int
1181+
let a2: 2️⃣String: Int]
1182+
let a3: 3️⃣String: [Int]4️⃣
1183+
let a4: 5️⃣String: Int6️⃣
1184+
let a4: 7️⃣String: Int]??
11841185
}
11851186
""",
11861187
diagnostics: [
1187-
// TODO: Old parser expected error on line 2: unexpected ':' in type; did you mean to write a dictionary type?, Fix-It replacements: 11 - 11 = '['
1188-
DiagnosticSpec(locationMarker: "1️⃣", message: "consecutive declarations on a line must be separated by ';'", fixIts: ["insert ';'"]),
1189-
DiagnosticSpec(locationMarker: "1️⃣", message: "unexpected code ':' before variable"),
1190-
// TODO: Old parser expected error on line 3: unexpected ':' in type; did you mean to write a dictionary type?, Fix-It replacements: 11 - 11 = '['
1191-
DiagnosticSpec(locationMarker: "2️⃣", message: "unexpected code ': Int]' before variable"),
1192-
// 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 = ']'
1193-
DiagnosticSpec(locationMarker: "3️⃣", message: "unexpected code ': [Int]' before variable"),
1194-
// 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 = ']'
1195-
DiagnosticSpec(locationMarker: "4️⃣", message: "unexpected code ': Int' in struct"),
1196-
]
1188+
DiagnosticSpec(
1189+
locationMarker: "1️⃣",
1190+
message: "consecutive declarations on a line must be separated by ';'",
1191+
fixIts: ["insert ';'"]
1192+
),
1193+
DiagnosticSpec(
1194+
locationMarker: "1️⃣",
1195+
message: "unexpected code ':' before variable"
1196+
),
1197+
DiagnosticSpec(
1198+
locationMarker: "2️⃣",
1199+
message: "expected '[' to start dictionary type",
1200+
fixIts: ["insert '['"]
1201+
),
1202+
DiagnosticSpec(
1203+
locationMarker: "3️⃣",
1204+
message: "expected '[' to start dictionary type",
1205+
fixIts: ["insert '['"]
1206+
),
1207+
DiagnosticSpec(
1208+
locationMarker: "4️⃣",
1209+
message: "expected ']' to end dictionary type",
1210+
fixIts: ["insert ']'"]
1211+
),
1212+
DiagnosticSpec(
1213+
locationMarker: "5️⃣",
1214+
message: "expected '[' to start dictionary type",
1215+
fixIts: ["insert '['"]
1216+
),
1217+
DiagnosticSpec(
1218+
locationMarker: "6️⃣",
1219+
message: "expected ']' to end dictionary type",
1220+
fixIts: ["insert ']'"]
1221+
),
1222+
DiagnosticSpec(
1223+
locationMarker: "7️⃣",
1224+
message: "expected '[' to start dictionary type",
1225+
fixIts: ["insert '['"]
1226+
),
1227+
1228+
],
1229+
fixedSource: """
1230+
struct ErrorTypeInVarDeclDictionaryType {
1231+
let a1: String;:
1232+
let a2: [String: Int]
1233+
let a3: [String: [Int]]
1234+
let a4: [String: Int]
1235+
let a4: [String: Int]??
1236+
}
1237+
"""
11971238
)
11981239
}
11991240

@@ -2314,4 +2355,14 @@ final class RecoveryTests: XCTestCase {
23142355
"""
23152356
)
23162357
}
2358+
2359+
// https://github.com/apple/swift-syntax/pull/1484/files#r1176740738
2360+
func testRecovery184() {
2361+
assertParse(
2362+
"func foo() -> Int1️⃣:",
2363+
diagnostics: [
2364+
DiagnosticSpec(message: "extraneous code ':' at top level")
2365+
]
2366+
)
2367+
}
23172368
}

0 commit comments

Comments
 (0)