Quick fix for single-expression raw string interpolation (#84)

Raw string interpolation has proven to be a bit trickier to
implement, since we don’t want to treat `#` as a delimiter
(since it’s used in so many other ways in Swift, for example
for `#if`, `#available`, etc.).

This patch contains a “quick fix” for supporting interpolated
raw strings that contain a single expression per interpolation.
A proper fix should be developed as soon as possible, but this
unblocks using Splash to highlight most raw string interpolated
code samples, for now.
This commit is contained in:
John Sundell 2019-09-05 11:59:28 +02:00 committed by GitHub
parent d1dd1acda0
commit dddf418cea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 1 deletions

View File

@ -124,6 +124,10 @@ private extension SwiftGrammar {
var tokenType: TokenType { return .string }
func matches(_ segment: Segment) -> Bool {
guard !segment.isWithinRawStringInterpolation else {
return false
}
if segment.isWithinStringLiteral(withStart: "#\"", end: "\"#") {
return true
}
@ -154,7 +158,8 @@ private extension SwiftGrammar {
return false
}
return !segment.isWithinStringInterpolation
return !segment.isWithinStringInterpolation &&
!segment.isWithinRawStringInterpolation
}
}
@ -534,6 +539,25 @@ private extension Segment {
return true
}
var isWithinRawStringInterpolation: Bool {
// Quick fix for supporting single expressions within raw string
// interpolation, a proper fix should be developed ASAP.
switch tokens.current {
case "\\":
return tokens.previous != "\\" && tokens.next == "#"
case "#":
return tokens.previous == "\\" && tokens.next == "("
case "(":
return tokens.onSameLine.suffix(2) == ["\\", "#"]
case ")":
let suffix = tokens.onSameLine.suffix(4)
return suffix.prefix(3) == ["\\", "#", "("]
default:
let suffix = tokens.onSameLine.suffix(3)
return suffix == ["\\", "#", "("] && tokens.next == ")"
}
}
var prefixedByDotAccess: Bool {
return tokens.previous == "(." || prefix.hasSuffix(" .")
}

View File

@ -207,6 +207,18 @@ final class LiteralTests: SyntaxHighlighterTestCase {
])
}
func testRawStringWithInterpolation() {
let components = highlighter.highlight("#\"Hello \\#(variable) world\"#")
XCTAssertEqual(components, [
.token("#\"Hello", .string),
.whitespace(" "),
.plainText("\\#(variable)"),
.whitespace(" "),
.token("world\"#", .string)
])
}
func testDoubleLiteral() {
let components = highlighter.highlight("let double = 1.13")
@ -291,6 +303,7 @@ extension LiteralTests {
("testMultiLineStringLiteral", testMultiLineStringLiteral),
("testSingleLineRawStringLiteral", testSingleLineRawStringLiteral),
("testMultiLineRawStringLiteral", testMultiLineRawStringLiteral),
("testRawStringWithInterpolation", testRawStringWithInterpolation),
("testDoubleLiteral", testDoubleLiteral),
("testIntegerLiteralWithSeparators", testIntegerLiteralWithSeparators),
("testKeyPathLiteral", testKeyPathLiteral),