Skip to content

Fix diagnostic of ternary operator missing only colon #1677

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions Sources/SwiftParser/Expressions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -318,10 +318,7 @@ extension Parser {
)

let rhs: RawExprSyntax?
if colon.isMissing {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Contrary to my first comment, I just had a thought. What do we produce if we have the following?

condition ? 1
someOtherVariable

I think in this case we should be suggesting to add : <#expression#> and not just a standalone colon. To achieve that you might need to revert to the old code and just add an additional check for whether the next token is on the same line or a new line.

Copy link
Member Author

@TTOzzi TTOzzi May 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the latest commit of this PR, it returns the diagnostic "expected ':' after '? ...' in ternary expression."
The Swift compiler in Xcode works the same way.
However, as you mentioned, I think it is appropriate to suggest adding : <#expression#> to the code.
I will proceed to work on it further and add a commit in this PR!

// If the colon is missing there's not much more structure we can
// expect out of this expression sequence. Emit a missing expression
// to end the parsing here.
if colon.isMissing, currentToken.isAtStartOfLine {
rhs = RawExprSyntax(RawMissingExprSyntax(arena: self.arena))
} else {
rhs = nil
Expand Down
39 changes: 39 additions & 0 deletions Tests/SwiftParserTest/translated/InvalidIfExprTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,43 @@ final class InvalidIfExprTests: XCTestCase {
)
}

func testInvalidIfExpr5() {
assertParse(
"""
foo ? 1 1️⃣2
""",
diagnostics: [
DiagnosticSpec(message: "expected ':' after '? ...' in ternary expression", fixIts: ["insert ':'"])
],
fixedSource: "foo ? 1 : 2"
)
}

func testInvalidIfExpr6() {
assertParse(
"""
foo ? 1 1️⃣
""",
diagnostics: [
DiagnosticSpec(message: "expected ':' and expression after '? ...' in ternary expression", fixIts: ["insert ':' and expression"])
],
fixedSource: "foo ? 1 : <#expression#>"
)
}

func testInvalidIfExpr7() {
assertParse(
"""
condition ? 1 1️⃣
someOtherVariable
""",
diagnostics: [
DiagnosticSpec(message: "expected ':' and expression after '? ...' in ternary expression", fixIts: ["insert ':' and expression"])
],
fixedSource: """
condition ? 1 : <#expression#>
someOtherVariable
"""
)
}
}