Add support for Swift 5 single-line raw strings (#52)

This change makes Splash capable of highlighting Swift 5 raw strings,
although it’s currently limited to single line string literals. Support
for multi-line literals will be added in a future commit.
This commit is contained in:
John Sundell 2019-03-12 00:21:25 +01:00 committed by GitHub
parent 9a7fdefab4
commit 6a75ec4491
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 10 deletions

View File

@ -22,6 +22,7 @@ public struct SwiftGrammar: Grammar {
syntaxRules = [
PreprocessingRule(),
CommentRule(),
RawStringRule(),
MultiLineStringRule(),
SingleLineStringRule(),
AttributeRule(),
@ -98,6 +99,14 @@ private extension SwiftGrammar {
}
}
struct RawStringRule: SyntaxRule {
var tokenType: TokenType { return .string }
func matches(_ segment: Segment) -> Bool {
return segment.isWithinStringLiteral(withStart: "#\"", end: "\"#")
}
}
struct MultiLineStringRule: SyntaxRule {
var tokenType: TokenType { return .string }
@ -114,7 +123,7 @@ private extension SwiftGrammar {
var tokenType: TokenType { return .string }
func matches(_ segment: Segment) -> Bool {
guard segment.isWithinStringLiteral else {
guard segment.isWithinStringLiteral(withStart: "\"", end: "\"") else {
return false
}
@ -377,14 +386,12 @@ private extension SwiftGrammar {
}
private extension Segment {
var isWithinStringLiteral: Bool {
let delimiter = "\""
if tokens.current.hasPrefix(delimiter) {
func isWithinStringLiteral(withStart start: String, end: String) -> Bool {
if tokens.current.hasPrefix(start) {
return true
}
if tokens.current.hasSuffix(delimiter) {
if tokens.current.hasSuffix(end) {
return true
}
@ -397,18 +404,20 @@ private extension Segment {
continue
}
if token == delimiter {
if markerCounts.start == markerCounts.end {
if token == start {
if start != end || markerCounts.start == markerCounts.end {
markerCounts.start += 1
} else {
markerCounts.end += 1
}
} else if token == end && start != end {
markerCounts.end += 1
} else {
if token.hasPrefix(delimiter) {
if token.hasPrefix(start) {
markerCounts.start += 1
}
if token.hasSuffix(delimiter) {
if token.hasSuffix(end) {
markerCounts.end += 1
}
}

View File

@ -100,6 +100,24 @@ final class LiteralTests: SyntaxHighlighterTestCase {
])
}
func testSingleLineRawStringLiteral() {
let components = highlighter.highlight("""
#"A raw string \\(withoutInterpolation) yes"#
""")
XCTAssertEqual(components, [
.token("#\"A", .string),
.whitespace(" "),
.token("raw", .string),
.whitespace(" "),
.token("string", .string),
.whitespace(" "),
.token("\\(withoutInterpolation)", .string),
.whitespace(" "),
.token("yes\"#", .string)
])
}
func testDoubleLiteral() {
let components = highlighter.highlight("let double = 1.13")
@ -142,6 +160,7 @@ extension LiteralTests {
("testStringLiteralWithAttribute", testStringLiteralWithAttribute),
("testStringLiteralInterpolation", testStringLiteralInterpolation),
("testMultiLineStringLiteral", testMultiLineStringLiteral),
("testSingleLineRawStringLiteral", testSingleLineRawStringLiteral),
("testDoubleLiteral", testDoubleLiteral),
("testIntegerLiteralWithSeparators", testIntegerLiteralWithSeparators)
]