Skip to content

Commit 83c2be9

Browse files
authored
Merge pull request #1530 from kimdv/kimdv/cherry-pick-add-diagnostic-for-testRecovery177
2 parents fa8abec + 8ce0e0d commit 83c2be9

File tree

4 files changed

+53
-4
lines changed

4 files changed

+53
-4
lines changed

Sources/SwiftParser/Declarations.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,9 +776,21 @@ extension Parser {
776776
}
777777

778778
keepGoing = self.consume(if: .comma)
779+
let unexpectedBetweenBodyAndTrailingComma: RawUnexpectedNodesSyntax?
780+
781+
// If there's a comma, keep parsing the list.
782+
// If there's a "&&", diagnose replace with a comma and keep parsing
783+
if let token = self.consumeIfContextualPunctuator("&&") {
784+
keepGoing = self.missingToken(.comma)
785+
unexpectedBetweenBodyAndTrailingComma = RawUnexpectedNodesSyntax([token], arena: self.arena)
786+
} else {
787+
unexpectedBetweenBodyAndTrailingComma = nil
788+
}
789+
779790
elements.append(
780791
RawGenericRequirementSyntax(
781792
body: requirement,
793+
unexpectedBetweenBodyAndTrailingComma,
782794
trailingComma: keepGoing,
783795
arena: self.arena
784796
)

Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,38 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor {
546546
return handleEffectSpecifiers(node)
547547
}
548548

549+
public override func visit(_ node: GenericRequirementSyntax) -> SyntaxVisitorContinueKind {
550+
if shouldSkip(node) {
551+
return .skipChildren
552+
}
553+
554+
if let unexpected = node.unexpectedBetweenBodyAndTrailingComma,
555+
let token = unexpected.tokens(satisfying: { $0.tokenKind == .binaryOperator("&&") }).first,
556+
let trailingComma = node.trailingComma,
557+
trailingComma.presence == .missing,
558+
let previous = node.unexpectedBetweenBodyAndTrailingComma?.previousToken(viewMode: .sourceAccurate)
559+
{
560+
561+
addDiagnostic(
562+
unexpected,
563+
.expectedCommaInWhereClause,
564+
fixIts: [
565+
FixIt(
566+
message: ReplaceTokensFixIt(replaceTokens: [token], replacement: .commaToken()),
567+
changes: [
568+
.makeMissing(token),
569+
.makePresent(trailingComma),
570+
FixIt.MultiNodeChange(.replaceTrailingTrivia(token: previous, newTrivia: [])),
571+
]
572+
)
573+
],
574+
handledNodes: [unexpected.id, trailingComma.id]
575+
)
576+
}
577+
578+
return .visitChildren
579+
}
580+
549581
public override func visit(_ node: DeinitializerDeclSyntax) -> SyntaxVisitorContinueKind {
550582
if shouldSkip(node) {
551583
return .skipChildren

Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ extension DiagnosticMessage where Self == StaticParserError {
131131
public static var expectedAssignmentInsteadOfComparisonOperator: Self {
132132
.init("expected '=' instead of '==' to assign default value for parameter")
133133
}
134+
public static var expectedCommaInWhereClause: Self {
135+
.init("expected ',' to separate the requirements of this 'where' clause")
136+
}
134137
public static var expectedLeftBraceOrIfAfterElse: Self {
135138
.init("expected '{' or 'if' after 'else'")
136139
}

Tests/SwiftParserTest/translated/RecoveryTests.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2209,15 +2209,17 @@ final class RecoveryTests: XCTestCase {
22092209
}
22102210

22112211
func testRecovery177() {
2212+
// rdar://38225184
22122213
assertParse(
22132214
"""
2214-
// rdar://38225184
22152215
extension Collection where Element == Int 1️⃣&& Index == Int {}
22162216
""",
22172217
diagnostics: [
2218-
DiagnosticSpec(message: "unexpected code '&& Index == Int' in extension")
2219-
// TODO: Old parser expected error on line 1: expected ',' to separate the requirements of this 'where' clause, Fix-It replacements: 43 - 45 = ','
2220-
]
2218+
DiagnosticSpec(message: "expected ',' to separate the requirements of this 'where' clause", fixIts: ["replace '&&' with ','"])
2219+
],
2220+
fixedSource: """
2221+
extension Collection where Element == Int, Index == Int {}
2222+
"""
22212223
)
22222224
}
22232225

0 commit comments

Comments
 (0)