Skip to content

Commit 4e85fa4

Browse files
committed
Diagnose || being used to join platforms in an availability condition
1 parent 042d723 commit 4e85fa4

File tree

5 files changed

+34
-5
lines changed

5 files changed

+34
-5
lines changed

Sources/SwiftParser/Availability.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,18 @@ extension Parser {
3232
entry = self.parseAvailabilitySpec()
3333
}
3434

35+
let unexpectedBeforeKeepGoing: RawUnexpectedNodesSyntax?
3536
keepGoing = self.consume(if: .comma)
37+
if keepGoing == nil, let orOperator = self.consume(if: .spacedBinaryOperator, where: { $0.tokenText == "||" }) {
38+
unexpectedBeforeKeepGoing = RawUnexpectedNodesSyntax([orOperator], arena: self.arena)
39+
keepGoing = missingToken(.comma)
40+
} else {
41+
unexpectedBeforeKeepGoing = nil
42+
}
3643
elements.append(
3744
RawAvailabilityArgumentSyntax(
3845
entry: entry,
46+
unexpectedBeforeKeepGoing,
3947
trailingComma: keepGoing,
4048
arena: self.arena
4149
)

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: AvailabilityArgumentSyntax) -> SyntaxVisitorContinueKind {
316+
if shouldSkip(node) {
317+
return .skipChildren
318+
}
319+
if let trailingComma = node.trailingComma {
320+
exchangeTokens(
321+
unexpected: node.unexpectedBetweenEntryAndTrailingComma,
322+
unexpectedTokenCondition: { $0.text == "||" },
323+
correctTokens: [node.trailingComma],
324+
message: { _ in .joinPlatformsUsingComma },
325+
moveFixIt: { ReplaceTokensFixIt(replaceTokens: $0, replacement: trailingComma) }
326+
)
327+
}
328+
return .visitChildren
329+
}
330+
315331
public override func visit(_ node: ConditionElementSyntax) -> 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
@@ -137,6 +137,9 @@ extension DiagnosticMessage where Self == StaticParserError {
137137
public static var joinConditionsUsingComma: Self {
138138
.init("expected ',' joining parts of a multi-clause condition")
139139
}
140+
public static var joinPlatformsUsingComma: Self {
141+
.init("expected ',' joining platforms in availability condition")
142+
}
140143
public static var missingColonAndExprInTernaryExpr: Self {
141144
.init("expected ':' and expression after '? ...' in ternary expression")
142145
}

Tests/SwiftParserTest/translated/AvailabilityQueryTests.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -389,9 +389,12 @@ final class AvailabilityQueryTests: XCTestCase {
389389
}
390390
""",
391391
diagnostics: [
392-
// TODO: Old parser expected error on line 1: '||' cannot be used in an availability condition
393-
DiagnosticSpec(message: "unexpected code '|| iOS 8.0' in availability condition")
394-
]
392+
DiagnosticSpec(message: "expected ',' joining platforms in availability condition", fixIts: ["replace '||' by ','"])
393+
],
394+
fixedSource: """
395+
if #available(OSX 10.51 , iOS 8.0) {
396+
}
397+
"""
395398
)
396399
}
397400

Tests/SwiftParserTest/translated/AvailabilityQueryUnavailabilityTests.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,8 +360,7 @@ final class AvailabilityQueryUnavailabilityTests: XCTestCase {
360360
}
361361
""",
362362
diagnostics: [
363-
// TODO: Old parser expected error on line 1: '||' cannot be used in an availability condition
364-
DiagnosticSpec(message: "unexpected code '|| iOS 8.0' in availability condition")
363+
DiagnosticSpec(message: "expected ',' joining platforms in availability condition")
365364
]
366365
)
367366
}

0 commit comments

Comments
 (0)