Tweaks to how dot syntax is highlighted (#78)
- Don’t highlight what *could* be a static method call using the `dotAccess` style, only highlight tokens that are either value-less enum cases or static properties. - The exception to the above rule is within `switch` statements, in which even call-like tokens are assumed to be enum cases. - Highlight calls to `.init()` as keywords, for consistency with other `init` usages.
This commit is contained in:
parent
e107609b00
commit
367b8408b1
|
@ -186,6 +186,7 @@ private extension SwiftGrammar {
|
|||
|
||||
var callLikeKeywords = accessControlKeywords
|
||||
callLikeKeywords.insert("subscript")
|
||||
callLikeKeywords.insert("init")
|
||||
self.callLikeKeywords = callLikeKeywords
|
||||
}
|
||||
|
||||
|
@ -213,8 +214,22 @@ private extension SwiftGrammar {
|
|||
}
|
||||
|
||||
// Don't treat enums with associated values as function calls
|
||||
guard !segment.prefixedByDotAccess else {
|
||||
return false
|
||||
// when they appear within a switch statement
|
||||
if previousToken == "." {
|
||||
let previousTokens = segment.tokens.onSameLine
|
||||
|
||||
if previousTokens.count > 1 {
|
||||
let lastToken = previousTokens[previousTokens.count - 2]
|
||||
|
||||
guard lastToken != "case" else {
|
||||
return false
|
||||
}
|
||||
|
||||
// Multiple expressions can be matched within a single case
|
||||
guard !lastToken.hasSuffix(",") else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,13 +246,6 @@ private extension SwiftGrammar {
|
|||
return !segment.tokens.onSameLine.contains(anyOf: controlFlowTokens)
|
||||
}
|
||||
|
||||
// Check so that this is an initializer call, not the declaration
|
||||
if segment.tokens.current == "init" {
|
||||
guard segment.tokens.previous == "." else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return segment.tokens.next?.starts(with: "(") ?? false
|
||||
}
|
||||
}
|
||||
|
@ -417,6 +425,12 @@ private extension SwiftGrammar {
|
|||
return false
|
||||
}
|
||||
|
||||
if let next = segment.tokens.next {
|
||||
guard !next.hasPrefix("(") else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return segment.tokens.onSameLine.first != "import"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -452,7 +452,7 @@ final class DeclarationTests: SyntaxHighlighterTestCase {
|
|||
.whitespace(" "),
|
||||
.token("self", .keyword),
|
||||
.plainText("."),
|
||||
.token("init", .call),
|
||||
.token("init", .keyword),
|
||||
.plainText("()"),
|
||||
.whitespace(" "),
|
||||
.plainText("}"),
|
||||
|
|
|
@ -37,13 +37,13 @@ final class EnumTests: SyntaxHighlighterTestCase {
|
|||
])
|
||||
}
|
||||
|
||||
func testEnumDotSyntaxWithAssociatedValue() {
|
||||
func testEnumDotSyntaxWithAssociatedValueTreatedAsCall() {
|
||||
let components = highlighter.highlight("call(.error(error))")
|
||||
|
||||
XCTAssertEqual(components, [
|
||||
.token("call", .call),
|
||||
.plainText("(."),
|
||||
.token("error", .dotAccess),
|
||||
.token("error", .call),
|
||||
.plainText("(error))")
|
||||
])
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ extension EnumTests {
|
|||
return [
|
||||
("testEnumDotSyntaxInAssignment", testEnumDotSyntaxInAssignment),
|
||||
("testEnumDotSyntaxAsArgument", testEnumDotSyntaxAsArgument),
|
||||
("testEnumDotSyntaxWithAssociatedValue", testEnumDotSyntaxWithAssociatedValue),
|
||||
("testEnumDotSyntaxWithAssociatedValueTreatedAsCall", testEnumDotSyntaxWithAssociatedValueTreatedAsCall),
|
||||
("testUsingEnumInSubscript", testUsingEnumInSubscript)
|
||||
]
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ final class FunctionCallTests: SyntaxHighlighterTestCase {
|
|||
.whitespace(" "),
|
||||
.token("String", .type),
|
||||
.plainText("."),
|
||||
.token("init", .call),
|
||||
.token("init", .keyword),
|
||||
.plainText("()")
|
||||
])
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ final class StatementTests: SyntaxHighlighterTestCase {
|
|||
])
|
||||
}
|
||||
|
||||
func testSwitchStatementWithAssociatedValues() {
|
||||
func testSwitchStatementWithSingleAssociatedValue() {
|
||||
let components = highlighter.highlight("""
|
||||
switch value {
|
||||
case .one(let a): break
|
||||
|
@ -135,6 +135,42 @@ final class StatementTests: SyntaxHighlighterTestCase {
|
|||
])
|
||||
}
|
||||
|
||||
func testSwitchStatementWithMultipleAssociatedValues() {
|
||||
let components = highlighter.highlight("""
|
||||
switch value {
|
||||
case .one(let a), .two(let b): break
|
||||
}
|
||||
""")
|
||||
|
||||
XCTAssertEqual(components, [
|
||||
.token("switch", .keyword),
|
||||
.whitespace(" "),
|
||||
.plainText("value"),
|
||||
.whitespace(" "),
|
||||
.plainText("{"),
|
||||
.whitespace("\n"),
|
||||
.token("case", .keyword),
|
||||
.whitespace(" "),
|
||||
.plainText("."),
|
||||
.token("one", .dotAccess),
|
||||
.plainText("("),
|
||||
.token("let", .keyword),
|
||||
.whitespace(" "),
|
||||
.plainText("a),"),
|
||||
.whitespace(" "),
|
||||
.plainText("."),
|
||||
.token("two", .dotAccess),
|
||||
.plainText("("),
|
||||
.token("let", .keyword),
|
||||
.whitespace(" "),
|
||||
.plainText("b):"),
|
||||
.whitespace(" "),
|
||||
.token("break", .keyword),
|
||||
.whitespace("\n"),
|
||||
.plainText("}")
|
||||
])
|
||||
}
|
||||
|
||||
func testSwitchStatementWithFallthrough() {
|
||||
let components = highlighter.highlight("""
|
||||
switch variable {
|
||||
|
@ -360,7 +396,8 @@ extension StatementTests {
|
|||
("testImportStatementWithSubmodule", testImportStatementWithSubmodule),
|
||||
("testChainedIfElseStatements", testChainedIfElseStatements),
|
||||
("testSwitchStatement", testSwitchStatement),
|
||||
("testSwitchStatementWithAssociatedValues", testSwitchStatementWithAssociatedValues),
|
||||
("testSwitchStatementWithSingleAssociatedValue", testSwitchStatementWithSingleAssociatedValue),
|
||||
("testSwitchStatementWithMultipleAssociatedValues", testSwitchStatementWithMultipleAssociatedValues),
|
||||
("testSwitchStatementWithFallthrough", testSwitchStatementWithFallthrough),
|
||||
("testSwitchStatementWithTypePatternMatching", testSwitchStatementWithTypePatternMatching),
|
||||
("testSwitchStatementWithOptional", testSwitchStatementWithOptional),
|
||||
|
|
Loading…
Reference in New Issue