Skip to content

Commit 81de038

Browse files
authored
Improve highlighting of comments when placed next to symbols (#120)
Especially for multi-line comments placed next to generic type lists.
1 parent 8d83deb commit 81de038

2 files changed

Lines changed: 115 additions & 5 deletions

File tree

Sources/Splash/Grammar/SwiftGrammar.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ public struct SwiftGrammar: Grammar {
5757
return false
5858
case ("{", "/"), ("}", "/"):
5959
return false
60+
case (">", "/"), ("?", "/"):
61+
return false
6062
default:
6163
return true
6264
}
@@ -424,14 +426,14 @@ private extension SwiftGrammar {
424426
}
425427

426428
// In a generic declaration, only highlight constraints
427-
if segment.tokens.previous.isAny(of: "<", ",") {
429+
if segment.tokens.previous.isAny(of: "<", ",", "*/") {
428430
var foundOpeningBracket = false
429431

430432
// Since the declaration might be on another line, we have to walk
431433
// backwards through all tokens until we've found enough information.
432434
for token in segment.tokens.all.reversed() {
433435
// Highlight return type generics as normal
434-
if token == "->" {
436+
if token.isAny(of: "->", ">", ">:") {
435437
return true
436438
}
437439

@@ -441,7 +443,7 @@ private extension SwiftGrammar {
441443

442444
// Handling generic lists for parameters, rather than declarations
443445
if foundOpeningBracket {
444-
if token.isAny(of: ":", ">:") || token.first == "@" {
446+
if token == ":" || token.first == "@" {
445447
return true
446448
}
447449
}
@@ -456,7 +458,7 @@ private extension SwiftGrammar {
456458
return true
457459
}
458460

459-
if token.isAny(of: ">", "=", "==", "(") {
461+
if token.isAny(of: "=", "==", "(") {
460462
return true
461463
}
462464
}

Tests/SplashTests/Tests/CommentTests.swift

Lines changed: 109 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,109 @@ final class CommentTests: SyntaxHighlighterTestCase {
219219
])
220220
}
221221

222+
func testCommentWithinGenericTypeList() {
223+
let components = highlighter.highlight("""
224+
struct Box<One, /*Comment*/Two: Equatable, Three> {}
225+
""")
226+
227+
XCTAssertEqual(components, [
228+
.token("struct", .keyword),
229+
.whitespace(" "),
230+
.plainText("Box<One,"),
231+
.whitespace(" "),
232+
.token("/*Comment*/", .comment),
233+
.plainText("Two:"),
234+
.whitespace(" "),
235+
.token("Equatable", .type),
236+
.plainText(","),
237+
.whitespace(" "),
238+
.plainText("Three>"),
239+
.whitespace(" "),
240+
.plainText("{}")
241+
])
242+
}
243+
244+
func testCommentsNextToGenericTypeList() {
245+
let components = highlighter.highlight("""
246+
struct Box/*Start*/<Content>/*End*/ {}
247+
""")
248+
249+
XCTAssertEqual(components, [
250+
.token("struct", .keyword),
251+
.whitespace(" "),
252+
.plainText("Box"),
253+
.token("/*Start*/", .comment),
254+
.plainText("<Content>"),
255+
.token("/*End*/", .comment),
256+
.whitespace(" "),
257+
.plainText("{}")
258+
])
259+
}
260+
261+
func testCommentsNextToInitialization() {
262+
let components = highlighter.highlight("/*Start*/Object()/*End*/")
263+
264+
XCTAssertEqual(components, [
265+
.token("/*Start*/", .comment),
266+
.token("Object", .type),
267+
.plainText("()"),
268+
.token("/*End*/", .comment)
269+
])
270+
}
271+
272+
func testCommentsNextToProtocolName() {
273+
let components = highlighter.highlight("""
274+
struct Model<Value>: /*Start*/Equatable/*End*/ {}
275+
""")
276+
277+
XCTAssertEqual(components, [
278+
.token("struct", .keyword),
279+
.whitespace(" "),
280+
.plainText("Model<Value>:"),
281+
.whitespace(" "),
282+
.token("/*Start*/", .comment),
283+
.token("Equatable", .type),
284+
.token("/*End*/", .comment),
285+
.whitespace(" "),
286+
.plainText("{}")
287+
])
288+
}
289+
290+
func testCommentsAfterOptionalTypes() {
291+
let components = highlighter.highlight("""
292+
struct Model {
293+
var one: String?//One
294+
var two: String?/*Two*/
295+
}
296+
""")
297+
298+
XCTAssertEqual(components, [
299+
.token("struct", .keyword),
300+
.whitespace(" "),
301+
.plainText("Model"),
302+
.whitespace(" "),
303+
.plainText("{"),
304+
.whitespace("\n "),
305+
.token("var", .keyword),
306+
.whitespace(" "),
307+
.plainText("one:"),
308+
.whitespace(" "),
309+
.token("String", .type),
310+
.plainText("?"),
311+
.token("//One", .comment),
312+
.whitespace("\n "),
313+
.token("var", .keyword),
314+
.whitespace(" "),
315+
.plainText("two:"),
316+
.whitespace(" "),
317+
.token("String", .type),
318+
.plainText("?"),
319+
.token("/*Two*/", .comment),
320+
.whitespace("\n"),
321+
.plainText("}")
322+
])
323+
}
324+
222325
func testAllTestsRunOnLinux() {
223326
XCTAssertTrue(TestCaseVerifier.verifyLinuxTests((type(of: self)).allTests))
224327
}
@@ -236,7 +339,12 @@ extension CommentTests {
236339
("testCommentPrecededByComma", testCommentPrecededByComma),
237340
("testCommentWithNumber", testCommentWithNumber),
238341
("testCommentWithNoWhiteSpaceToPunctuation", testCommentWithNoWhiteSpaceToPunctuation),
239-
("testCommentsNextToCurlyBrackets", testCommentsNextToCurlyBrackets)
342+
("testCommentsNextToCurlyBrackets", testCommentsNextToCurlyBrackets),
343+
("testCommentWithinGenericTypeList", testCommentWithinGenericTypeList),
344+
("testCommentsNextToGenericTypeList", testCommentsNextToGenericTypeList),
345+
("testCommentsNextToInitialization", testCommentsNextToInitialization),
346+
("testCommentsNextToProtocolName", testCommentsNextToProtocolName),
347+
("testCommentsAfterOptionalTypes", testCommentsAfterOptionalTypes)
240348
]
241349
}
242350
}

0 commit comments

Comments
 (0)