Skip to content

Add space on leading and trailing equal #1456

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
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
18 changes: 17 additions & 1 deletion Sources/SwiftParser/Lexer/Cursor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1967,7 +1967,23 @@ extension Lexer.Cursor {
if self.input.baseAddress! - tokStart.input.baseAddress! == 1 {
switch tokStart.peek() {
case UInt8(ascii: "="):
return Lexer.Result(.equal)
if leftBound != rightBound {
var errorPos = tokStart

if rightBound {
_ = errorPos.advance()
}

return Lexer.Result(
.equal,
error: LexingDiagnostic(
.equalMustHaveConsistentWhitespaceOnBothSides,
position: errorPos
)
)
} else {
return Lexer.Result(.equal)
}
case UInt8(ascii: "&"):
if leftBound == rightBound || leftBound {
break
Expand Down
22 changes: 22 additions & 0 deletions Sources/SwiftParserDiagnostics/LexerDiagnosticMessages.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public extension TokenError {
/// Please order the cases in this enum alphabetically by case name.
public enum StaticTokenError: String, DiagnosticMessage {
case editorPlaceholder = "editor placeholder in source file"
case equalMustHaveConsistentWhitespaceOnBothSides = "'=' must have consistent whitespace on both sides"
case expectedBinaryExponentInHexFloatLiteral = "hexadecimal floating point literal must end with an exponent"
case expectedClosingBraceInUnicodeEscape = #"expected '}' in \u{...} escape sequence"#
case expectedDigitInFloatLiteral = "expected a digit in floating point exponent"
Expand Down Expand Up @@ -134,6 +135,7 @@ public extension SwiftSyntax.TokenDiagnostic {

switch self.kind {
case .editorPlaceholder: return StaticTokenError.editorPlaceholder
case .equalMustHaveConsistentWhitespaceOnBothSides: return StaticTokenError.equalMustHaveConsistentWhitespaceOnBothSides
case .expectedBinaryExponentInHexFloatLiteral: return StaticTokenError.expectedBinaryExponentInHexFloatLiteral
case .expectedClosingBraceInUnicodeEscape: return StaticTokenError.expectedClosingBraceInUnicodeEscape
case .expectedDigitInFloatLiteral: return StaticTokenError.expectedDigitInFloatLiteral
Expand Down Expand Up @@ -200,6 +202,26 @@ public extension SwiftSyntax.TokenDiagnostic {
return [
FixIt(message: .replaceCurlyQuoteByNormalQuote, changes: [[.replace(oldNode: Syntax(token), newNode: Syntax(fixedToken))]])
]
case .equalMustHaveConsistentWhitespaceOnBothSides:
let hasLeadingSpace = token.previousToken(viewMode: .all)?.trailingTrivia.contains(where: { $0.isSpaceOrTab }) ?? false
let hasTrailingSpace = token.trailingTrivia.contains { $0.isSpaceOrTab }
var changes: [FixIt.Change] = []

if !hasLeadingSpace {
changes += [
.replaceLeadingTrivia(token: token, newTrivia: .space)
]
}

if !hasTrailingSpace {
changes += [
.replaceTrailingTrivia(token: token, newTrivia: .space)
]
}

return [
FixIt(message: .insertWhitespace, changes: FixIt.Changes(changes: changes))
]
default:
return []
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,9 @@ extension FixItMessage where Self == StaticParserFixIt {
public static var insertNewline: Self {
.init("insert newline")
}
public static var insertWhitespace: Self {
.init("insert whitespace")
}
public static var joinIdentifiers: Self {
.init("join the identifiers together")
}
Expand Down
2 changes: 2 additions & 0 deletions Sources/SwiftSyntax/TokenDiagnostic.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public struct TokenDiagnostic: Hashable {
// Please order these alphabetically

case editorPlaceholder
case equalMustHaveConsistentWhitespaceOnBothSides
case expectedBinaryExponentInHexFloatLiteral
case expectedClosingBraceInUnicodeEscape
case expectedDigitInFloatLiteral
Expand Down Expand Up @@ -96,6 +97,7 @@ public struct TokenDiagnostic: Hashable {
public var severity: Severity {
switch kind {
case .editorPlaceholder: return .error
case .equalMustHaveConsistentWhitespaceOnBothSides: return .error
case .expectedBinaryExponentInHexFloatLiteral: return .error
case .expectedClosingBraceInUnicodeEscape: return .error
case .expectedDigitInFloatLiteral: return .error
Expand Down
36 changes: 24 additions & 12 deletions Tests/SwiftParserTest/translated/RecoveryTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1958,34 +1958,46 @@ final class RecoveryTests: XCTestCase {
}

func testRecovery163() {
// <rdar://problem/22387625> QoI: Common errors: 'let x= 5' and 'let x =5' could use Fix-its
assertParse(
"""
// <rdar://problem/22387625> QoI: Common errors: 'let x= 5' and 'let x =5' could use Fix-its
func r22387625() {
let _= 5
let _ =5
let _1️⃣= 5
let _ =2️⃣5
}
""",
diagnostics: [
// TODO: Old parser expected error on line 3: '=' must have consistent whitespace on both sides, Fix-It replacements: 8 - 8 = ' '
// TODO: Old parser expected error on line 4: '=' must have consistent whitespace on both sides, Fix-It replacements: 10 - 10 = ' '
]
DiagnosticSpec(locationMarker: "1️⃣", message: "'=' must have consistent whitespace on both sides", fixIts: ["insert whitespace"]),
DiagnosticSpec(locationMarker: "2️⃣", message: "'=' must have consistent whitespace on both sides", fixIts: ["insert whitespace"]),
],
fixedSource: """
func r22387625() {
let _ = 5
let _ = 5
}
"""
)
}

func testRecovery164() {
// https://github.com/apple/swift/issues/45723
assertParse(
"""
// https://github.com/apple/swift/issues/45723
do {
let _: Int= 5
let _: Array<Int>= []
let _: Int1️⃣= 5
let _: Array<Int>2️⃣= []
}
""",
diagnostics: [
// TODO: Old parser expected error on line 3: '=' must have consistent whitespace on both sides, Fix-It replacements: 13 - 13 = ' '
// TODO: Old parser expected error on line 4: '=' must have consistent whitespace on both sides, Fix-It replacements: 20 - 20 = ' '
]
DiagnosticSpec(locationMarker: "1️⃣", message: "'=' must have consistent whitespace on both sides", fixIts: ["insert whitespace"]),
DiagnosticSpec(locationMarker: "2️⃣", message: "'=' must have consistent whitespace on both sides", fixIts: ["insert whitespace"]),
],
fixedSource: """
do {
let _: Int = 5
let _: Array<Int> = []
}
"""
)
}

Expand Down