Background
Tree-sitter's highlights.scm query files tag every token in source code with a semantic category — keywords, operators, literals, and crucially, access modifiers and decorators/attributes. Every tree-sitter language package ships highlights.scm with full coverage.
Problem
Currently only Java extracts access modifiers and annotations as node properties (via custom logic in parsers/java/utils.py). For the other 11 languages:
- We can't answer "what are the public methods of this class?"
- We can't filter by visibility (
pub, private, protected, static)
- We can't find decorated functions ("show all
@pytest.mark.parametrize tests", "find all #[test] functions")
- LLM queries about code visibility/access patterns produce incomplete answers
The information exists in the parse tree but we don't extract it.
Approach
Vendor highlights.scm files for all 12 languages (already available in all pip packages) and extract modifier/decorator captures as node properties.
What highlights.scm captures (relevant subset)
@keyword / @keyword.modifier — public, private, protected, static, abstract, final, async, pub, pub(crate)
@attribute / @function.decorator — @decorator (Python), #[attr] (Rust), [[attr]] (C++), @Annotation (Java)
@type.qualifier — const, volatile, mutable, readonly
Example patterns:
; Python
(decorator "@" @attribute)
; Rust
(attribute_item) @attribute
; Java
(modifiers) @keyword.modifier
(marker_annotation) @attribute
; TypeScript
(accessibility_modifier) @keyword.modifier
Implementation
- Create
codebase_rag/queries/highlights/ directory with .scm files per language (or load from pip packages directly since all 12 have them)
- During node property building (in
function_ingest.py and class_ingest/mixin.py), run highlights query on the node's source range
- Collect
@keyword.modifier and @attribute captures that fall within the node's declaration
- Store as node properties:
modifiers: list[str] and decorators: list[str]
- Extend Java's existing
MethodModifiersAndAnnotations pattern to all languages
- Add tests per language verifying modifier and decorator extraction
Property schema additions
Function/Method nodes:
modifiers: ["public", "static", "async"] # access and behavior modifiers
decorators: ["@property", "#[test]"] # decorators/attributes
Class nodes:
modifiers: ["abstract", "final", "pub"]
decorators: ["@dataclass", "#[derive(Debug)]"]
Languages
All 12: Python, JavaScript, TypeScript, Rust, Java, C, C++, Go, Lua, Scala, PHP, C#
References
Background
Tree-sitter's
highlights.scmquery files tag every token in source code with a semantic category — keywords, operators, literals, and crucially, access modifiers and decorators/attributes. Every tree-sitter language package ships highlights.scm with full coverage.Problem
Currently only Java extracts access modifiers and annotations as node properties (via custom logic in
parsers/java/utils.py). For the other 11 languages:pub,private,protected,static)@pytest.mark.parametrizetests", "find all#[test]functions")The information exists in the parse tree but we don't extract it.
Approach
Vendor
highlights.scmfiles for all 12 languages (already available in all pip packages) and extract modifier/decorator captures as node properties.What highlights.scm captures (relevant subset)
@keyword/@keyword.modifier—public,private,protected,static,abstract,final,async,pub,pub(crate)@attribute/@function.decorator—@decorator(Python),#[attr](Rust),[[attr]](C++),@Annotation(Java)@type.qualifier—const,volatile,mutable,readonlyExample patterns:
Implementation
codebase_rag/queries/highlights/directory with .scm files per language (or load from pip packages directly since all 12 have them)function_ingest.pyandclass_ingest/mixin.py), run highlights query on the node's source range@keyword.modifierand@attributecaptures that fall within the node's declarationmodifiers: list[str]anddecorators: list[str]MethodModifiersAndAnnotationspattern to all languagesProperty schema additions
Languages
All 12: Python, JavaScript, TypeScript, Rust, Java, C, C++, Go, Lua, Scala, PHP, C#
References
codebase_rag/parsers/java/utils.py