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:
parent
9a7fdefab4
commit
6a75ec4491
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
]
|
||||
|
Loading…
x
Reference in New Issue
Block a user