From f8e8fa5f7a4900339e0486439f9fd80f15288427 Mon Sep 17 00:00:00 2001 From: Hamish Knight Date: Sun, 7 Dec 2025 20:56:16 +0000 Subject: [PATCH] Check for delimiter before lookahead in `advanceIfMultilineStringDelimiter` Avoid doing an unnecessary lookahead if we're not even at a multiline delimiter. This also fixes an issue where we'd scan ahead on the next line for `#"\n`, although this was benign in practice since the delimiter check would have previously then failed afterwards. --- Sources/SwiftParser/Lexer/Cursor.swift | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/Sources/SwiftParser/Lexer/Cursor.swift b/Sources/SwiftParser/Lexer/Cursor.swift index d55f6024068..007b7894270 100644 --- a/Sources/SwiftParser/Lexer/Cursor.swift +++ b/Sources/SwiftParser/Lexer/Cursor.swift @@ -814,11 +814,19 @@ extension Lexer.Cursor { openingRawStringDelimiters: Int? ) -> Bool { precondition(self.previous == #"""#) + + var delimEnd = self + guard delimEnd.advance(matching: #"""#), + case let delimLast = delimEnd, + delimEnd.advance(matching: #"""#) + else { + return false + } + // Test for single-line string literals that resemble multiline delimiter. - var sameLineCloseCheck = self - _ = sameLineCloseCheck.advance() if let openingRawStringDelimiters, openingRawStringDelimiters != 0 { // Scan if the current line contains `"` followed by `openingRawStringDelimiters` `#` characters + var sameLineCloseCheck = delimLast while sameLineCloseCheck.is(notAt: "\r", "\n") { if sameLineCloseCheck.advance(matching: #"""#) { if sameLineCloseCheck.advanceIfStringDelimiter(delimiterLength: openingRawStringDelimiters) { @@ -831,13 +839,8 @@ extension Lexer.Cursor { } } - var tmp = self - if tmp.advance(matching: #"""#) && tmp.advance(matching: #"""#) { - self = tmp - return true - } - - return false + self = delimEnd + return true } /// Read a single UTF-8 scalar, which may span multiple bytes.