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 = [ syntaxRules = [
PreprocessingRule(), PreprocessingRule(),
CommentRule(), CommentRule(),
RawStringRule(),
MultiLineStringRule(), MultiLineStringRule(),
SingleLineStringRule(), SingleLineStringRule(),
AttributeRule(), 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 { struct MultiLineStringRule: SyntaxRule {
var tokenType: TokenType { return .string } var tokenType: TokenType { return .string }
@ -114,7 +123,7 @@ private extension SwiftGrammar {
var tokenType: TokenType { return .string } var tokenType: TokenType { return .string }
func matches(_ segment: Segment) -> Bool { func matches(_ segment: Segment) -> Bool {
guard segment.isWithinStringLiteral else { guard segment.isWithinStringLiteral(withStart: "\"", end: "\"") else {
return false return false
} }
@ -377,14 +386,12 @@ private extension SwiftGrammar {
} }
private extension Segment { private extension Segment {
var isWithinStringLiteral: Bool { func isWithinStringLiteral(withStart start: String, end: String) -> Bool {
let delimiter = "\"" if tokens.current.hasPrefix(start) {
if tokens.current.hasPrefix(delimiter) {
return true return true
} }
if tokens.current.hasSuffix(delimiter) { if tokens.current.hasSuffix(end) {
return true return true
} }
@ -397,18 +404,20 @@ private extension Segment {
continue continue
} }
if token == delimiter { if token == start {
if markerCounts.start == markerCounts.end { if start != end || markerCounts.start == markerCounts.end {
markerCounts.start += 1 markerCounts.start += 1
} else { } else {
markerCounts.end += 1 markerCounts.end += 1
} }
} else if token == end && start != end {
markerCounts.end += 1
} else { } else {
if token.hasPrefix(delimiter) { if token.hasPrefix(start) {
markerCounts.start += 1 markerCounts.start += 1
} }
if token.hasSuffix(delimiter) { if token.hasSuffix(end) {
markerCounts.end += 1 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() { func testDoubleLiteral() {
let components = highlighter.highlight("let double = 1.13") let components = highlighter.highlight("let double = 1.13")
@ -142,6 +160,7 @@ extension LiteralTests {
("testStringLiteralWithAttribute", testStringLiteralWithAttribute), ("testStringLiteralWithAttribute", testStringLiteralWithAttribute),
("testStringLiteralInterpolation", testStringLiteralInterpolation), ("testStringLiteralInterpolation", testStringLiteralInterpolation),
("testMultiLineStringLiteral", testMultiLineStringLiteral), ("testMultiLineStringLiteral", testMultiLineStringLiteral),
("testSingleLineRawStringLiteral", testSingleLineRawStringLiteral),
("testDoubleLiteral", testDoubleLiteral), ("testDoubleLiteral", testDoubleLiteral),
("testIntegerLiteralWithSeparators", testIntegerLiteralWithSeparators) ("testIntegerLiteralWithSeparators", testIntegerLiteralWithSeparators)
] ]