Correctly highlight types conforming to multiple protocols

Previously, the last protocol would be treated as a function call (Splash
thought it was a call with trailing closure syntax, rather than the opening
of a type definition). This patch fixes that by verifying that the code
checking for constraints inside a generic type definition is in fact looking
at a generic, rather than something else.
This commit is contained in:
John Sundell 2019-03-08 18:20:36 +01:00
parent ddd2bf9020
commit 7f2421cd99
2 changed files with 27 additions and 1 deletions

View File

@ -257,11 +257,19 @@ private extension SwiftGrammar {
// In a generic declaration, only highlight constraints
if segment.tokens.previous.isAny(of: "<", ",") {
var foundOpeningBracket = false
// Since the declaration might be on another line, we have to walk
// backwards through all tokens until we've found enough information.
for token in segment.tokens.all.reversed() {
if !foundOpeningBracket && token == "<" {
foundOpeningBracket = true
}
guard !declarationKeywords.contains(token) else {
return false
// If it turns out that we weren't in fact inside of a generic
// declaration, (lacking "<"), then highlight the type as normal.
return !foundOpeningBracket
}
guard !keywords.contains(token) else {

View File

@ -221,6 +221,23 @@ final class DeclarationTests: SyntaxHighlighterTestCase {
])
}
func testClassDeclarationWithMultipleProtocolConformances() {
let components = highlighter.highlight("class MyClass: ProtocolA, ProtocolB {}")
XCTAssertEqual(components, [
.token("class", .keyword),
.whitespace(" "),
.plainText("MyClass:"),
.whitespace(" "),
.token("ProtocolA", .type),
.plainText(","),
.whitespace(" "),
.token("ProtocolB", .type),
.whitespace(" "),
.plainText("{}")
])
}
func testSubclassDeclaration() {
let components = highlighter.highlight("class ViewController: UIViewController { }")
@ -616,6 +633,7 @@ extension DeclarationTests {
("testGenericStructDeclaration", testGenericStructDeclaration),
("testClassDeclaration", testClassDeclaration),
("testCompactClassDeclarationWithInitializer", testCompactClassDeclarationWithInitializer),
("testClassDeclarationWithMultipleProtocolConformances", testClassDeclarationWithMultipleProtocolConformances),
("testSubclassDeclaration", testSubclassDeclaration),
("testProtocolDeclaration", testProtocolDeclaration),
("testExtensionDeclaration", testExtensionDeclaration),