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:
parent
d1dd1acda0
commit
dddf418cea
|
@ -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(" .")
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
|
|
Loading…
Reference in New Issue