diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 72267a9bbe7..09fa81ac036 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -8,9 +8,6 @@ jobs: tests: name: Test uses: swiftlang/github-workflows/.github/workflows/swift_package_test.yml@main - with: - # https://github.com/swiftlang/swift-syntax/issues/2992 - enable_windows_checks: false soundness: name: Soundness uses: swiftlang/github-workflows/.github/workflows/soundness.yml@main diff --git a/Sources/SwiftParser/Lexer/Cursor.swift b/Sources/SwiftParser/Lexer/Cursor.swift index 28ed57f8947..bb947d80ecf 100644 --- a/Sources/SwiftParser/Lexer/Cursor.swift +++ b/Sources/SwiftParser/Lexer/Cursor.swift @@ -1594,7 +1594,7 @@ extension Lexer.Cursor { // MARK: Lexing a character in a string literal extension Lexer.Cursor { - enum CharacterLex { + enum CharacterLex: Equatable { /// A normal character as it occurs in the source file case success(Unicode.Scalar) diff --git a/Sources/SwiftParser/StringLiteralRepresentedLiteralValue.swift b/Sources/SwiftParser/StringLiteralRepresentedLiteralValue.swift index 084538b128e..ad7c9d6e944 100644 --- a/Sources/SwiftParser/StringLiteralRepresentedLiteralValue.swift +++ b/Sources/SwiftParser/StringLiteralRepresentedLiteralValue.swift @@ -83,8 +83,8 @@ extension StringSegmentSyntax { precondition(!hasError, "appendUnescapedLiteralValue relies on properly parsed literals") let rawText = content.rawText - if !rawText.contains("\\") { - // Fast path. No escape sequence. + if !rawText.contains(where: { $0 == "\\" || $0 == "\r" }) { + // Fast path. No escape sequence that need to be interpreted or line endings that need to be normalized to \n. output.append(String(syntaxText: rawText)) return } @@ -105,6 +105,18 @@ extension StringSegmentSyntax { ) switch lex { + case .success(Unicode.Scalar("\r")): + // Line endings in multi-line string literals are normalized to line feeds even if the source file has a + // different encoding for new lines. + output.append("\n") + if cursor.peek() == "\n" { + // If we have \r\n, eat the \n as well and leave + let consumed = cursor.lexCharacterInStringLiteral( + stringLiteralKind: stringLiteralKind, + delimiterLength: delimiterLength + ) + assert(consumed == .success(Unicode.Scalar("\n"))) + } case .success(let scalar), .validatedEscapeSequence(let scalar): output.append(Character(scalar))