Skip to content

Commit 6769bb6

Browse files
committed
Diagnose && used to separte multiple availability conditions
1 parent 240d88f commit 6769bb6

File tree

5 files changed

+34
-5
lines changed

5 files changed

+34
-5
lines changed

Sources/SwiftParser/Statements.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,10 +213,18 @@ extension Parser {
213213
var loopProgress = LoopProgressCondition()
214214
repeat {
215215
let condition = self.parseConditionElement()
216+
let unexpectedBeforeKeepGoing: RawUnexpectedNodesSyntax?
216217
keepGoing = self.consume(if: .comma)
218+
if keepGoing == nil, let andOperator = self.consume(if: .spacedBinaryOperator, where: { $0.tokenText == "&&" }) {
219+
unexpectedBeforeKeepGoing = RawUnexpectedNodesSyntax([andOperator], arena: self.arena)
220+
keepGoing = missingToken(.comma)
221+
} else {
222+
unexpectedBeforeKeepGoing = nil
223+
}
217224
elements.append(
218225
RawConditionElementSyntax(
219226
condition: condition,
227+
unexpectedBeforeKeepGoing,
220228
trailingComma: keepGoing,
221229
arena: self.arena
222230
)

Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,22 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor {
312312
return .visitChildren
313313
}
314314

315+
public override func visit(_ node: ConditionElementSyntax) -> SyntaxVisitorContinueKind {
316+
if shouldSkip(node) {
317+
return .skipChildren
318+
}
319+
if let trailingComma = node.trailingComma {
320+
exchangeTokens(
321+
unexpected: node.unexpectedBetweenConditionAndTrailingComma,
322+
unexpectedTokenCondition: { $0.text == "&&" },
323+
correctTokens: [node.trailingComma],
324+
message: { _ in .joinConditionsUsingComma },
325+
moveFixIt: { ReplaceTokensFixIt(replaceTokens: $0, replacement: trailingComma) }
326+
)
327+
}
328+
return .visitChildren
329+
}
330+
315331
public override func visit(_ node: ClosureExprSyntax) -> SyntaxVisitorContinueKind {
316332
if shouldSkip(node) {
317333
return .skipChildren

Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@ extension DiagnosticMessage where Self == StaticParserError {
134134
public static var invalidWhitespaceAfterPeriod: Self {
135135
.init("extraneous whitespace after '.' is not permitted")
136136
}
137+
public static var joinConditionsUsingComma: Self {
138+
.init("expected ',' joining parts of a multi-clause condition")
139+
}
137140
public static var missingColonAndExprInTernaryExpr: Self {
138141
.init("expected ':' and expression after '? ...' in ternary expression")
139142
}

Tests/SwiftParserTest/translated/AvailabilityQueryTests.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,12 @@ final class AvailabilityQueryTests: XCTestCase {
9393
}
9494
""",
9595
diagnostics: [
96-
// TODO: Old parser expected error on line 1: expected ',' joining parts of a multi-clause condition, Fix-It replacements: 28 - 31 = ','
97-
DiagnosticSpec(message: "unexpected code '&& #available(OSX 10.52, *)' in 'if' statement")
98-
]
96+
DiagnosticSpec(message: "expected ',' joining parts of a multi-clause condition", fixIts: ["replace '&&' by ','"])
97+
],
98+
fixedSource: """
99+
if #available(OSX 10.51, *) , #available(OSX 10.52, *) {
100+
}
101+
"""
99102
)
100103
}
101104

Tests/SwiftParserTest/translated/AvailabilityQueryUnavailabilityTests.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@ final class AvailabilityQueryUnavailabilityTests: XCTestCase {
7878
}
7979
""",
8080
diagnostics: [
81-
// TODO: Old parser expected error on line 1: expected ',' joining parts of a multi-clause condition, Fix-It replacements: 27 - 30 = ','
82-
DiagnosticSpec(message: "unexpected code '&& #unavailable(OSX 10.52)' in 'if' statement")
81+
DiagnosticSpec(message: "expected ',' joining parts of a multi-clause condition", fixIts: ["replace '&&' by ','"])
8382
]
8483
)
8584
}

0 commit comments

Comments
 (0)