Support highlighting of setters with an explicit access level
This change makes Splash correctly highlight property setters that have an explicit access level defined — such as `private(set) var`.
This commit is contained in:
parent
9fbdb92edb
commit
c85d8d9d4d
@ -36,12 +36,11 @@ public struct SwiftGrammar: Grammar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private extension SwiftGrammar {
|
private extension SwiftGrammar {
|
||||||
static let keywords: Set<String> = [
|
static let keywords = ([
|
||||||
"final", "class", "struct", "enum", "protocol",
|
"final", "class", "struct", "enum", "protocol",
|
||||||
"extension", "let", "var", "func", "typealias",
|
"extension", "let", "var", "func", "typealias",
|
||||||
"init", "guard", "if", "else", "return", "get",
|
"init", "guard", "if", "else", "return", "get",
|
||||||
"throw", "throws", "for", "in", "open", "weak",
|
"throw", "throws", "for", "in", "open", "weak",
|
||||||
"public", "internal", "private", "fileprivate",
|
|
||||||
"import", "mutating", "associatedtype", "case",
|
"import", "mutating", "associatedtype", "case",
|
||||||
"switch", "static", "do", "try", "catch", "as",
|
"switch", "static", "do", "try", "catch", "as",
|
||||||
"super", "self", "set", "true", "false", "nil",
|
"super", "self", "set", "true", "false", "nil",
|
||||||
@ -49,6 +48,10 @@ private extension SwiftGrammar {
|
|||||||
"#selector", "required", "willSet", "didSet",
|
"#selector", "required", "willSet", "didSet",
|
||||||
"lazy", "subscript", "defer", "inout", "while",
|
"lazy", "subscript", "defer", "inout", "while",
|
||||||
"continue", "fallthrough", "repeat", "indirect"
|
"continue", "fallthrough", "repeat", "indirect"
|
||||||
|
] as Set<String>).union(accessControlKeywords)
|
||||||
|
|
||||||
|
static let accessControlKeywords: Set<String> = [
|
||||||
|
"public", "internal", "fileprivate", "private"
|
||||||
]
|
]
|
||||||
|
|
||||||
struct PreprocessingRule: SyntaxRule {
|
struct PreprocessingRule: SyntaxRule {
|
||||||
@ -147,6 +150,7 @@ private extension SwiftGrammar {
|
|||||||
struct CallRule: SyntaxRule {
|
struct CallRule: SyntaxRule {
|
||||||
var tokenType: TokenType { return .call }
|
var tokenType: TokenType { return .call }
|
||||||
private let keywordsToAvoid: Set<String>
|
private let keywordsToAvoid: Set<String>
|
||||||
|
private let callLikeKeywords: Set<String>
|
||||||
private let controlFlowTokens = ["if", "&&", "||", "for"]
|
private let controlFlowTokens = ["if", "&&", "||", "for"]
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
@ -156,6 +160,10 @@ private extension SwiftGrammar {
|
|||||||
keywordsToAvoid.remove("throw")
|
keywordsToAvoid.remove("throw")
|
||||||
keywordsToAvoid.remove("if")
|
keywordsToAvoid.remove("if")
|
||||||
self.keywordsToAvoid = keywordsToAvoid
|
self.keywordsToAvoid = keywordsToAvoid
|
||||||
|
|
||||||
|
var callLikeKeywords = accessControlKeywords
|
||||||
|
callLikeKeywords.insert("subscript")
|
||||||
|
self.callLikeKeywords = callLikeKeywords
|
||||||
}
|
}
|
||||||
|
|
||||||
func matches(_ segment: Segment) -> Bool {
|
func matches(_ segment: Segment) -> Bool {
|
||||||
@ -163,11 +171,14 @@ private extension SwiftGrammar {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subscripting is a bit of an edge case, since it's the only keyword
|
// There's a few keywords that might look like function calls
|
||||||
// that looks like a function call, so we need to handle it explicitly
|
if callLikeKeywords.contains(segment.tokens.current) {
|
||||||
guard segment.tokens.current != "subscript" else {
|
if let nextToken = segment.tokens.next {
|
||||||
|
guard !nextToken.starts(with: "(") else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let previousToken = segment.tokens.previous {
|
if let previousToken = segment.tokens.previous {
|
||||||
guard !keywordsToAvoid.contains(previousToken) else {
|
guard !keywordsToAvoid.contains(previousToken) else {
|
||||||
@ -215,6 +226,20 @@ private extension SwiftGrammar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let previousToken = segment.tokens.previous {
|
if let previousToken = segment.tokens.previous {
|
||||||
|
// Highlight the '(set)' part of setter access modifiers
|
||||||
|
switch segment.tokens.current {
|
||||||
|
case "(":
|
||||||
|
return accessControlKeywords.contains(previousToken)
|
||||||
|
case "set":
|
||||||
|
if previousToken == "(" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case ")":
|
||||||
|
return previousToken == "set"
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
// Don't highlight most keywords when used as a parameter label
|
// Don't highlight most keywords when used as a parameter label
|
||||||
if !segment.tokens.current.isAny(of: "_", "self", "let", "var", "true", "false") {
|
if !segment.tokens.current.isAny(of: "_", "self", "let", "var", "true", "false") {
|
||||||
guard !previousToken.isAny(of: "(", ",") else {
|
guard !previousToken.isAny(of: "(", ",") else {
|
||||||
|
@ -487,6 +487,32 @@ final class DeclarationTests: SyntaxHighlighterTestCase {
|
|||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testPropertyWithSetterAccessLevel() {
|
||||||
|
let components = highlighter.highlight("""
|
||||||
|
struct Hello {
|
||||||
|
private(set) var property: Int
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
XCTAssertEqual(components, [
|
||||||
|
.token("struct", .keyword),
|
||||||
|
.whitespace(" "),
|
||||||
|
.plainText("Hello"),
|
||||||
|
.whitespace(" "),
|
||||||
|
.plainText("{"),
|
||||||
|
.whitespace("\n "),
|
||||||
|
.token("private(set)", .keyword),
|
||||||
|
.whitespace(" "),
|
||||||
|
.token("var", .keyword),
|
||||||
|
.whitespace(" "),
|
||||||
|
.plainText("property:"),
|
||||||
|
.whitespace(" "),
|
||||||
|
.token("Int", .type),
|
||||||
|
.whitespace("\n"),
|
||||||
|
.plainText("}")
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
func testSubscriptDeclaration() {
|
func testSubscriptDeclaration() {
|
||||||
let components = highlighter.highlight("""
|
let components = highlighter.highlight("""
|
||||||
extension Collection {
|
extension Collection {
|
||||||
@ -674,6 +700,7 @@ extension DeclarationTests {
|
|||||||
("testGenericPropertyDeclaration", testGenericPropertyDeclaration),
|
("testGenericPropertyDeclaration", testGenericPropertyDeclaration),
|
||||||
("testPropertyDeclarationWithWillSet", testPropertyDeclarationWithWillSet),
|
("testPropertyDeclarationWithWillSet", testPropertyDeclarationWithWillSet),
|
||||||
("testPropertyDeclarationWithDidSet", testPropertyDeclarationWithDidSet),
|
("testPropertyDeclarationWithDidSet", testPropertyDeclarationWithDidSet),
|
||||||
|
("testPropertyWithSetterAccessLevel", testPropertyWithSetterAccessLevel),
|
||||||
("testSubscriptDeclaration", testSubscriptDeclaration),
|
("testSubscriptDeclaration", testSubscriptDeclaration),
|
||||||
("testDeferDeclaration", testDeferDeclaration),
|
("testDeferDeclaration", testDeferDeclaration),
|
||||||
("testFunctionDeclarationWithInOutParameter", testFunctionDeclarationWithInOutParameter),
|
("testFunctionDeclarationWithInOutParameter", testFunctionDeclarationWithInOutParameter),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user