Update tree-sitter-kotlin and adapt the queries - #111
Merged
MrSubidubi merged 2 commits intoAug 7, 2026
Conversation
The pinned revision mis-parses a class carrying two or more annotations when
another declaration follows it: `class` and the class name come out as
`simple_identifier`s and the body as a `lambda_literal`, so the tree holds no
`class_declaration` at all. No `ERROR` node is produced, so the file looks
healthy while the class name is highlighted as a variable and the class is
missing from the outline and breadcrumbs. Spring-style code triggers it
readily:
@component
@ConfigurationProperties(prefix = "app")
class Config {
var url: String? = null
}
class Other
That is fixed upstream, 185 commits after the pinned revision.
Four node changes since then need the queries to follow:
- `property_declaration` holds `binding_pattern_kind` instead of the bare
"val"/"var" tokens, which made the `["val" "var"]` alternation an
impossible pattern and stopped `outline.scm` compiling entirely;
- "null" is the named `null_literal`;
- "!is" and "!in" are no longer single tokens — the grammar builds them as an
optional "!" followed by "is"/"in", both of which the query already covers;
- string interpolation exposes `interpolation_identifier_start`,
`interpolation_expression_start` and `interpolation_expression_end` in place
of the "$", "${" and "}" tokens.
`c8ac3d2` predates two fixes for the case this PR is about. fwcd/tree-sitter-kotlin#278 stopped a modifier-led `class` before an adjacent declaration from parsing as an infix expression, and #280 did the same for `object`, which #278 did not cover. Both landed 2026-08-01 and `1852ea1` is the tip carrying them. Verified against the new grammar: a file with an annotated class, an `internal open class` followed by an `object`, and a `sealed interface` parses with three `class_declaration`s and one `object_declaration`, no `ERROR` and no `infix_expression`. All seven query files still compile against it, and the annotated class appears in the outline again.
Contributor
Author
|
Moved the pin from
Re-verified against the new grammar with the CLI upstream uses, cache cleared: @Configuration
@EnableConfigurationProperties
class DataSourceConfig(private val url: String) { ... }
internal open class Other
object Registry { ... }
sealed interface Shapeparses as three |
tree-sitter-kotlin and adapt the queries
MrSubidubi
approved these changes
Aug 7, 2026
MrSubidubi
left a comment
Contributor
There was a problem hiding this comment.
Thank you once again!
MrSubidubi
pushed a commit
that referenced
this pull request
Aug 7, 2026
Zed themes style `comment.doc` apart from `comment`, and every other bundled language that has doc comments captures it. Kotlin captured both `line_comment` and `multiline_comment` as plain `comment`, so a KDoc block was indistinguishable from any other comment. ```kotlin /** * Real KDoc, now `comment.doc`. */ class A /* Plain block comment, still `comment`. */ class B ``` tree-sitter-kotlin has no doc-comment node, unlike tree-sitter-rust which captures `(block_comment (doc_comment))`, so the opening delimiter is what distinguishes them. `#match?` predicates are already used for this kind of thing in the bash, c, cpp and css queries Zed bundles. Three lines, kept separate from #111 so the grammar bump is not held up by it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The pinned grammar revision (
4e909d6) mis-parses a class carrying two or more annotations when another declaration follows it.classand the class name come out assimple_identifiers and the body as alambda_literal, so the tree contains noclass_declarationat all — and noERRORnode, so the file looks healthy.Visible effects: the class name is highlighted as a variable rather than a type, and the class is missing from the outline and from breadcrumbs while its own properties still show. Spring-shaped code hits this constantly.
This is already fixed upstream, 185 commits past the pinned revision.
Query changes
Four node changes since then need the queries to follow. The first one is not cosmetic — it stops
outline.scmcompiling at all against the newer grammar, so the bump cannot land without it:property_declarationholdsbinding_pattern_kindinstead of bare"val"/"var"tokensoutline.scm— the["val" "var"]alternation became an impossible pattern"null"is now the namednull_literalhighlights.scm— was invalid node type"!is"/"!in"are no longer single tokens (optional"!"+"is"/"in")highlights.scm— dropped;"!","is"and"in"are all already in the operator listinterpolation_identifier_start,interpolation_expression_start,interpolation_expression_end(upstream #270)highlights.scm— replaces the"$","${","}"tokensVerification
Every query was run against both grammar revisions over a real 21-file Kotlin project (Spring, Gradle) and the capture counts compared, to catch patterns that still compile but silently stop matching:
outlinehighlightsbracketsindentsinjectionsoverridesrunnablesBreaking the highlight delta down by capture kind, it is
punctuation.delimiter(−619) andpunctuation.bracket(−13); everything else moves by at most ±4, in the positive direction.The
punctuation.delimiterdrop is the dots insideimportstatements: the newer grammar builds the import path as one token, so its dots are no longer separately addressable and no query can colour them independently. Dots inpackageheaders and in navigation expressions are unaffected. This is a deliberate upstream change, not something the queries can restore.Known remaining case
The same family of mis-parse still affects declarations led by two or more plain modifiers (
internal open class First {}followed by another declaration) — upstream issue fwcd/tree-sitter-kotlin#277, with a fix proposed in fwcd/tree-sitter-kotlin#280. That one is independent of this bump; the annotation case above is fixed by the revision this PR moves to.