Language depth: current coverage and remaining edges
This note records the language-depth work completed in 0.6.0 and unchanged in 0.7.0, plus the remaining edge cases. The 0.5.0 provider matrix, indented Sass and method-level depth are now implemented; the sections below describe the final mechanics and what is still intentionally out of scope.
Current provider matrix
| Family | Boundary level | Nested members? |
|---|---|---|
| python | top-level def / class + class methods |
yes — Class.method, nested classes |
| go | top-level func / type |
methods are top-level receiver declarations |
| rust | top-level items + impl/trait methods |
yes — Type::method |
| java | type + constructor/method | yes |
| cpp (C/C++) | namespace/type + methods | yes for class/struct methods |
| csharp | namespace/type + methods/properties | yes |
| ruby | module/class + methods | yes |
| php | namespace/type + methods/functions | yes |
| lua | function declarations | methods via M.foo / M:foo |
| javascript | top-level declarations, React components, class members | yes: Class.method |
| sass | indentation-based selectors / at-rules / mixins | yes — nested selectors |
| html | landmarks / ids / custom elements | n/a |
| css | selectors / at-rules (nested SCSS/Less) | yes |
| sfc (Vue/Svelte/Astro) | delegated template/script/style | follows the block provider |
| sql | CREATE statements |
n/a |
| yaml/hcl/puppet/systemd/shell/markdown | grammar-specific sections/blocks | n/a |
Chunker mechanics
Decl(start, end, label, kind) is a flat boundary hint. Providers may return
overlapping ranges; the chunker sorts by start, extends each declaration to the
next start, and emits the parent header before its children. That is how a class
and its methods coexist without a hierarchy field:
- Java/C#/C++/PHP emit
Type.Method; - Ruby/Lua emit their method forms;
- Python emits
Class.methodandOuter.Inner.method; - Rust emits
Type::methodfromimplandtraitbodies; - JavaScript/TypeScript emit
Class.methodandClass.property.
The doctor coverage metric now merges line intervals as a union, so a parent and
child cannot double-count. tests/test_depth.py checks that parent headers,
qualified children and plan selection survive a small chunk ceiling.
Indented Sass
sass.py parses .sass as an indentation grammar, not as CSS with braces:
- Indentation stack. Spaces and tabs are compared with a fixed tab width
(
TAB_WIDTH = 2); a block ends when indentation returns to its parent. - Selector vs property. A line that has a deeper following code line is a
block opener; a line ending in
:is a property namespace (for examplefont:+ indented properties) and is not a declaration. A selector such as&:hoveris recognised by the deeper block below it. - Multiline selectors. Lines ending in commas are joined until the selector is complete.
- Comments.
//and/* ... */comments are masked while preserving line numbers; block comments can span lines. - Directives and mixins.
@media,@supports,@mixin,@function,@if,@each,@forand@whilebecome at-rule boundaries;=namemixin definitions becomemixin;@include/@extendare statements. - Extents. A block ends at its last nonblank line before dedent, so chunks never claim trailing blank lines.
Fixtures cover nesting, media, mixins, multiline selectors, property namespaces
and block comments. .scss and .less remain on the brace-based css provider.
Still out of scope: SassScript expression semantics, @use/@forward module
resolution, generated selectors, and a true mixed tab/space policy. The parser
treats those as boundary hints and keeps the generic fallback for anything it
cannot classify.
Method-level depth: remaining edges
The recommended order is complete:
- coverage union — done;
- Python class methods — done;
- Rust
impl/traitmethods — done; - JavaScript/TypeScript class members — done;
- chunker invariants and a class-heavy plan check — done.
Remaining, intentionally limited cases:
- JavaScript class expressions assigned to variables
(
const Foo = class { ... }) are not expanded; onlyClassDeclarationemits members. - Python nested functions inside methods are not declarations; only class bodies are walked. This keeps implementation detail out of the map.
- Rust methods inside nested modules are not recursively expanded beyond
impl/trait; a module remains a chunk and its own top-level items are handled. - Go struct fields are not chunks; receiver methods are already top-level.
- Class-heavy header overhead. Parent headers add small chunks. The depth test verifies plan budget fit, but a future packing rule could fold a header into its first child when it contains only annotations/braces.
- Future languages (Kotlin, Swift, Scala, Dart, etc.) still use the generic fixed-window fallback. Adding one remains a provider file plus fixtures.
No Decl schema change is required for the current depth. If the map later needs
an explicit hierarchy, add optional depth and parent fields and carry them
into chunks.jsonl; do that only when a consumer needs them.