Skip to content

Kotlin annotations (e.g. @Composable, @Inject) not preserved on Function/Class nodes #295

@thelord810

Description

@thelord810

Version: code-review-graph 2.3.2 (Python 3.13, Windows 10)

Summary

Kotlin nodes (Function / Class) have modifiers=None and extra={} on every row, even when the source contains annotations like @Composable, @HiltViewModel, @Inject, @Test, etc. This means consumers cannot filter or pivot queries on Kotlin annotation metadata — common Android use cases like "show me only @composable functions" or "show me all @hiltviewmodel classes" aren't expressible.

Reproduction

Test repo: D:\openclaw (mixed monorepo, Kotlin Android app under apps/android/). After code-review-graph build:

-- How many Kotlin nodes have anything in modifiers or extra?
SELECT COUNT(*) FROM nodes
WHERE language='kotlin'
  AND (modifiers IS NOT NULL AND modifiers != '');
-- 0

SELECT COUNT(*) FROM nodes
WHERE language='kotlin'
  AND (extra IS NOT NULL AND extra != '{}' AND extra != '');
-- 0

-- Sanity: they do have signatures
SELECT name, signature FROM nodes
WHERE language='kotlin' AND signature IS NOT NULL
LIMIT 3;
-- CameraHudKind        | class CameraHudKind
-- CameraHudState       | class CameraHudState
-- DeviceNames          | class DeviceNames

The signature column has the bare class X / fun x() text but without annotations or visibility modifiers. The modifiers column (which on Python nodes sometimes carries decorators) is always NULL. The extra JSON blob is {}.

Why this matters

On Android projects, the most common analytical queries are annotation-scoped:

  • "All @composable functions in this module" (UI surface area)
  • "All @hiltviewmodel classes" (DI graph)
  • "All @test or @junitTest functions" (test coverage mapping)
  • "All @RequiresApi(N) callers" (min-SDK impact)

None of these are expressible against the current graph. Users have to either grep source files (bypassing the whole graph) or build a parallel light-weight indexer that re-scans Kotlin for annotation regex — defeating the point of having CRG in the pipeline.

Suggested fix direction

The tree-sitter Kotlin grammar exposes annotation nodes directly on function and class declarations (modifier_listannotation). The Kotlin extractor could collect annotation names (and optionally argument lists) into either:

  1. A string column on nodes: modifiers = "@Composable @RequiresApi(26)" — matches the signature pattern, cheapest fix.
  2. A JSON array in the extra column: extra = {"annotations": ["Composable", "RequiresApi"]} — more structured, easier to filter.

Option 2 lets FTS5 tokenize the annotation names for free, which is probably the nicest integration. Happy to try a patch if you can point me at the Kotlin extractor file.

Scope note

This issue is about Kotlin specifically. I don't know if Swift has the same gap — Swift extraction works differently and I haven't verified annotation handling on Swift nodes. Filing only the Kotlin case for now.

Related: #294 (Kotlin + Swift CALLS edge extraction missing).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions