annotation highlighting
This commit is contained in:
1 parent
d285335e1c
commit
834f3118c8
9 files changed
+87
-14
No files matched your search
@@ -140,16 +140,22 @@ class SimpleLyngHighlighter : LyngHighlighter {
|
||||
|
||||
for (t in tokens) {
|
||||
val k = kindOf(t.type, t.value) ?: continue
|
||||
val start = src.offsetOf(t.pos)
|
||||
val start0 = src.offsetOf(t.pos)
|
||||
val range = when (t.type) {
|
||||
Type.STRING, Type.STRING2 -> adjustQuoteSpan(start, '"')
|
||||
Type.CHAR -> adjustQuoteSpan(start, '\'')
|
||||
Type.STRING, Type.STRING2 -> adjustQuoteSpan(start0, '"')
|
||||
Type.CHAR -> adjustQuoteSpan(start0, '\'')
|
||||
Type.HEX -> {
|
||||
// Parser returns HEX token value without the leading "0x"; include it in highlight span
|
||||
val end = (start + 2 + t.value.length).coerceAtMost(text.length)
|
||||
TextRange(start, end)
|
||||
val end = (start0 + 2 + t.value.length).coerceAtMost(text.length)
|
||||
TextRange(start0, end)
|
||||
}
|
||||
else -> TextRange(start, (start + t.value.length).coerceAtMost(text.length))
|
||||
Type.ATLABEL -> {
|
||||
// Parser returns value without leading '@'; token pos points at '@'.
|
||||
// So we need to include '@' (1 char) + the identifier length.
|
||||
val end = (start0 + 1 + t.value.length).coerceAtMost(text.length)
|
||||
TextRange(start0, end)
|
||||
}
|
||||
else -> TextRange(start0, (start0 + t.value.length).coerceAtMost(text.length))
|
||||
}
|
||||
if (range.endExclusive > range.start) raw += HighlightSpan(range, k)
|
||||
}
|
||||
|
||||
@@ -81,4 +81,44 @@ class HighlightMappingTest {
|
||||
assertTrue(labeled.any { it.first == "(" && it.second == HighlightKind.Punctuation })
|
||||
assertTrue(labeled.any { it.first == ")" && it.second == HighlightKind.Punctuation })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun annotationsIncludeAtAndFullName() {
|
||||
// Simple standalone annotation must include full token including '@'
|
||||
run {
|
||||
val text = "@Ann"
|
||||
val spans = SimpleLyngHighlighter().highlight(text)
|
||||
val annSpans = spans.filter { it.kind == HighlightKind.Label }
|
||||
assertTrue(annSpans.size == 1)
|
||||
val frag = text.substring(annSpans[0].range.start, annSpans[0].range.endExclusive)
|
||||
assertTrue(frag == "@Ann")
|
||||
}
|
||||
// Qualified name: we at least must not drop the last character of the @segment
|
||||
run {
|
||||
val text = "@Qualified.Name"
|
||||
val spans = SimpleLyngHighlighter().highlight(text)
|
||||
val annSpans = spans.filter { it.kind == HighlightKind.Label }
|
||||
assertTrue(annSpans.size == 1)
|
||||
val s = annSpans[0]
|
||||
val frag = text.substring(s.range.start, s.range.endExclusive)
|
||||
assertTrue(frag.startsWith("@Qualified"))
|
||||
// Ensure we did not miss the last char of this segment
|
||||
assertTrue(frag.last() == 'd')
|
||||
// Next token after the span should be '.'
|
||||
assertTrue(text.getOrNull(s.range.endExclusive) == '.')
|
||||
}
|
||||
// Multiple annotations: every Label span must include '@' and end on an identifier boundary
|
||||
run {
|
||||
val text = "@Ann @Another(1) fun x() {}"
|
||||
val spans = SimpleLyngHighlighter().highlight(text)
|
||||
val annSpans = spans.filter { it.kind == HighlightKind.Label }
|
||||
assertTrue(annSpans.size >= 2)
|
||||
for (s in annSpans) {
|
||||
val frag = text.substring(s.range.start, s.range.endExclusive)
|
||||
assertTrue(frag.startsWith("@"))
|
||||
// last char must be letter/digit/underscore/tilde/dollar per idNextChars
|
||||
assertTrue(frag.last().isLetterOrDigit() || frag.last() == '_' || frag.last() == '$' || frag.last() == '~')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user