dsh-plugin-codegraph-tree-sitter 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -102,6 +102,53 @@ export declare const FIRST_CHILD_NAME_FIELD = "@first-child";
102
102
  * of its own.
103
103
  */
104
104
  export declare const PHP_ELEMENT_NAME_FIELD = "@php-element";
105
+ /**
106
+ * Sentinel {@link DefinitionRule.nameField} value for a rule whose name is Kotlin-specific: the bundled
107
+ * `tree-sitter-kotlin` grammar this package loads binds *no* grammar fields at all (verified against a
108
+ * real parse — `Language.fieldCount`/`fieldNameForId` enumerate zero for it), unlike every other grammar
109
+ * this package extracts from, so a plain `childForFieldName` lookup can never work here regardless of
110
+ * which field name is named. A `class_declaration`'s/`function_declaration`'s/`enum_entry`'s declared
111
+ * name is instead the first direct named child typed `type_identifier` (a class/interface/enum name) or
112
+ * `simple_identifier` (a function/enum-entry name) — found by type rather than by position, since an
113
+ * optional leading `modifiers` node (wrapping `private`/`internal`/…) would otherwise sit at index 0
114
+ * ahead of it. See `kotlinDeclaredName` in `extract.ts`, which this sentinel dispatches to.
115
+ */
116
+ export declare const KOTLIN_NAME_FIELD = "@kotlin-name";
117
+ /**
118
+ * Sentinel {@link DefinitionRule.nameField} value for a rule whose name is Swift-specific: a
119
+ * `property_declaration`'s own `name` field points to a `pattern` node (`var x: Int`'s `x` sits behind
120
+ * this wrapper, not bound to a field of `property_declaration` directly), and the actual declared
121
+ * identifier is one level deeper still, bound to that `pattern` node's own `bound_identifier` field.
122
+ * See `swiftPropertyName` in `extract.ts`, which this sentinel dispatches to instead of a flat
123
+ * `childForFieldName` lookup. Verified against a real parse, not guessed.
124
+ */
125
+ export declare const SWIFT_PROPERTY_NAME_FIELD = "@swift-property";
126
+ /**
127
+ * Sentinel {@link DefinitionRule.nameField} value for a rule whose name is Swift-specific in a
128
+ * different way: a `function_declaration`/`protocol_function_declaration` with an explicit return type
129
+ * (`func add() -> Int`) binds *two* nodes to its own `name` field in this grammar build — the declared
130
+ * identifier itself, and (a verified, unguessed quirk of this specific compiled grammar) its
131
+ * `return_type` node as well — so `childrenForFieldName('name')` returns both, failing
132
+ * `soleNamedField`'s "exactly one bound child" uniqueness check the same way Go's genuinely ambiguous
133
+ * `const a, b = 1, 2` does, and silently dropping every such function from this package's graph. Unlike
134
+ * that Go case, this is not a real multi-name ambiguity — the identifier always comes first in document
135
+ * order — so `swiftFunctionName` in `extract.ts` uses `childForFieldName('name')` (first match) instead
136
+ * of `soleNamedField`'s all-matches check.
137
+ */
138
+ export declare const SWIFT_FUNCTION_NAME_FIELD = "@swift-function";
139
+ /**
140
+ * Sentinel {@link DefinitionRule.nameField} value for a rule whose name is Dart-specific: a `declaration`
141
+ * node is how Dart spells both a class/struct field (`int x;`, wrapping an `initialized_identifier_list`
142
+ * of one or more `initialized_identifier` children, itself the same multi-name ambiguity Go's
143
+ * `const_spec`/`var_spec` already reject outright) and a constructor (wrapping a `constructor_signature`
144
+ * instead, handled by its own separate rule matching that inner node type directly, not this one) — with
145
+ * no field of its own binding either shape, so `dartFieldName` in `extract.ts` returns `undefined` for
146
+ * anything but the single-identifier field-list shape, the same "don't guess" precedent this file already
147
+ * follows elsewhere; a `declaration` wrapping a constructor simply fails to match this rule and is left
148
+ * for the dedicated `constructor_signature` rule to capture during the walk's ordinary recursion into it.
149
+ * Verified against a real parse, not guessed.
150
+ */
151
+ export declare const DART_FIELD_NAME_FIELD = "@dart-field";
105
152
  /** One tree-sitter node type recording a relative-import binding, per language family. */
106
153
  export interface ImportRule {
107
154
  /** The tree-sitter node type anchoring one import statement, e.g. `import_statement`. */
package/lib/languages.js CHANGED
@@ -43,6 +43,53 @@ export const FIRST_CHILD_NAME_FIELD = '@first-child';
43
43
  * of its own.
44
44
  */
45
45
  export const PHP_ELEMENT_NAME_FIELD = '@php-element';
46
+ /**
47
+ * Sentinel {@link DefinitionRule.nameField} value for a rule whose name is Kotlin-specific: the bundled
48
+ * `tree-sitter-kotlin` grammar this package loads binds *no* grammar fields at all (verified against a
49
+ * real parse — `Language.fieldCount`/`fieldNameForId` enumerate zero for it), unlike every other grammar
50
+ * this package extracts from, so a plain `childForFieldName` lookup can never work here regardless of
51
+ * which field name is named. A `class_declaration`'s/`function_declaration`'s/`enum_entry`'s declared
52
+ * name is instead the first direct named child typed `type_identifier` (a class/interface/enum name) or
53
+ * `simple_identifier` (a function/enum-entry name) — found by type rather than by position, since an
54
+ * optional leading `modifiers` node (wrapping `private`/`internal`/…) would otherwise sit at index 0
55
+ * ahead of it. See `kotlinDeclaredName` in `extract.ts`, which this sentinel dispatches to.
56
+ */
57
+ export const KOTLIN_NAME_FIELD = '@kotlin-name';
58
+ /**
59
+ * Sentinel {@link DefinitionRule.nameField} value for a rule whose name is Swift-specific: a
60
+ * `property_declaration`'s own `name` field points to a `pattern` node (`var x: Int`'s `x` sits behind
61
+ * this wrapper, not bound to a field of `property_declaration` directly), and the actual declared
62
+ * identifier is one level deeper still, bound to that `pattern` node's own `bound_identifier` field.
63
+ * See `swiftPropertyName` in `extract.ts`, which this sentinel dispatches to instead of a flat
64
+ * `childForFieldName` lookup. Verified against a real parse, not guessed.
65
+ */
66
+ export const SWIFT_PROPERTY_NAME_FIELD = '@swift-property';
67
+ /**
68
+ * Sentinel {@link DefinitionRule.nameField} value for a rule whose name is Swift-specific in a
69
+ * different way: a `function_declaration`/`protocol_function_declaration` with an explicit return type
70
+ * (`func add() -> Int`) binds *two* nodes to its own `name` field in this grammar build — the declared
71
+ * identifier itself, and (a verified, unguessed quirk of this specific compiled grammar) its
72
+ * `return_type` node as well — so `childrenForFieldName('name')` returns both, failing
73
+ * `soleNamedField`'s "exactly one bound child" uniqueness check the same way Go's genuinely ambiguous
74
+ * `const a, b = 1, 2` does, and silently dropping every such function from this package's graph. Unlike
75
+ * that Go case, this is not a real multi-name ambiguity — the identifier always comes first in document
76
+ * order — so `swiftFunctionName` in `extract.ts` uses `childForFieldName('name')` (first match) instead
77
+ * of `soleNamedField`'s all-matches check.
78
+ */
79
+ export const SWIFT_FUNCTION_NAME_FIELD = '@swift-function';
80
+ /**
81
+ * Sentinel {@link DefinitionRule.nameField} value for a rule whose name is Dart-specific: a `declaration`
82
+ * node is how Dart spells both a class/struct field (`int x;`, wrapping an `initialized_identifier_list`
83
+ * of one or more `initialized_identifier` children, itself the same multi-name ambiguity Go's
84
+ * `const_spec`/`var_spec` already reject outright) and a constructor (wrapping a `constructor_signature`
85
+ * instead, handled by its own separate rule matching that inner node type directly, not this one) — with
86
+ * no field of its own binding either shape, so `dartFieldName` in `extract.ts` returns `undefined` for
87
+ * anything but the single-identifier field-list shape, the same "don't guess" precedent this file already
88
+ * follows elsewhere; a `declaration` wrapping a constructor simply fails to match this rule and is left
89
+ * for the dedicated `constructor_signature` rule to capture during the walk's ordinary recursion into it.
90
+ * Verified against a real parse, not guessed.
91
+ */
92
+ export const DART_FIELD_NAME_FIELD = '@dart-field';
46
93
  /** Definitions common to every ECMAScript-family grammar (JavaScript, JSX, TypeScript, TSX). */
47
94
  const ECMASCRIPT_DEFINITIONS = [
48
95
  { nodeType: 'function_declaration', kind: 'function', nameField: 'name' },
@@ -424,6 +471,335 @@ export const LANGUAGE_TABLE = [
424
471
  // real parse, not guessed.
425
472
  bareFunctionScopeTypes: ['closure_expression'],
426
473
  },
474
+ {
475
+ language: 'ruby',
476
+ extensions: ['.rb'],
477
+ wasmFile: 'tree-sitter-ruby.wasm',
478
+ definitions: [
479
+ // Every `def` — top-level, module-level, or inside a class body — defines a method (a top-level
480
+ // `def` becomes a private instance method of `Object`), so this package uses kind `method`
481
+ // uniformly rather than split a `function`/`method` distinction the language itself does not
482
+ // draw; `singleton_method` (`def self.foo`/`def Klass.foo`) is a class/singleton method, same
483
+ // kind. Verified against a real parse, not guessed.
484
+ { nodeType: 'method', kind: 'method', nameField: 'name' },
485
+ { nodeType: 'singleton_method', kind: 'method', nameField: 'name' },
486
+ { nodeType: 'class', kind: 'class', nameField: 'name' },
487
+ // No dedicated `namespace` handling exists elsewhere but Rust's `mod_item`; a Ruby `module` is the
488
+ // closest existing fit — both are a purely lexical/organizational container with no instance
489
+ // semantics of their own, matching that same precedent.
490
+ { nodeType: 'module', kind: 'namespace', nameField: 'name' },
491
+ // `my_lambda = ->(x) { x + 1 }` — the only anonymous-function *literal* shape this grammar has;
492
+ // `proc { ... }`/`Proc.new { ... }` parse as an ordinary `call` with a block argument, structurally
493
+ // indistinguishable from any other block-taking method call, so they are not treated as a
494
+ // function-valued binding — the same "don't guess" precedent this file already follows elsewhere.
495
+ // Tried first, before the unrestricted `variable` rule below falls through to everything else —
496
+ // the same precedent ECMASCRIPT_DEFINITIONS's `variable_declarator` rule follows.
497
+ { nodeType: 'assignment', kind: 'function', nameField: 'left', nameNodeTypes: ['identifier'], value: { field: 'right', types: ['lambda'] } },
498
+ // `CONST = 1` — a bare uppercase-leading `constant` node is Ruby's own real distinction (the
499
+ // grammar itself lexes an uppercase-leading bare word as a distinct `constant` token, not merely an
500
+ // `identifier`), so no `scopeRestricted` is needed: a dynamic constant assignment inside a method
501
+ // body is a Ruby `SyntaxError`, the parser never produces this shape nested in one. Verified
502
+ // against a real parse, not guessed.
503
+ { nodeType: 'assignment', kind: 'constant', nameField: 'left', nameNodeTypes: ['constant'] },
504
+ // A bare lowercase local variable assignment — `nameNodeTypes` rejects Ruby's other `assignment`
505
+ // left-hand shapes (`left_assignment_list` for `a, b = 1, 2`, a `call` for `self.x = 1`, an
506
+ // `element_reference` for `arr[0] = 1`), none of which name a single declared identifier, verified
507
+ // against a real parse, not guessed. An instance variable (`@name = ...`) is deliberately not
508
+ // captured at all — unlike every other language this package extracts a `field` kind from, Ruby has
509
+ // no declarative field syntax; an instance variable is conventionally *assigned* inside `initialize`
510
+ // (method-body scope), and this file's scope model has no way to mark that assignment a class-level
511
+ // symbol without also flooding `resolve.ts`'s name index with every ordinary method-local variable —
512
+ // the same "don't guess" precedent this file already follows for a shape it cannot cleanly resolve.
513
+ { nodeType: 'assignment', kind: 'variable', nameField: 'left', nameNodeTypes: ['identifier'], scopeRestricted: true },
514
+ ],
515
+ // A bare, receiver-less, paren-less, arg-less method call (`other_call`) parses as a plain
516
+ // `identifier` — syntactically identical to a local-variable read — so it is not (and cannot safely
517
+ // be) captured as a call site; only a `call` node (a receiver, an argument list, or a block present)
518
+ // is. Verified against a real parse, not guessed.
519
+ callTypes: ['call'],
520
+ callFunctionField: 'method',
521
+ // Ruby's grammar has no dedicated import-statement node type at all — `require '...'` and
522
+ // `require_relative '...'` are ordinary method calls (see `rubyRequireImport` in extract.ts, wired
523
+ // through a dedicated dispatch branch the same way `commonJsRequireImport` is for CommonJS, rather
524
+ // than through this table, which has no node type to name here).
525
+ importTypes: [],
526
+ // A `{ ... }`/`do ... end` block attached to a call, and a `->() { ... }` lambda's own block body
527
+ // (itself a `block` node), can all contain a statement — a `var`/`local` inside one is still
528
+ // block-local, not a workspace symbol, the same reasoning `ECMASCRIPT_BARE_FUNCTION_SCOPE_TYPES`
529
+ // applies to a callback. Verified against a real parse, not guessed.
530
+ bareFunctionScopeTypes: ['block', 'do_block', 'lambda'],
531
+ },
532
+ {
533
+ language: 'zig',
534
+ extensions: ['.zig'],
535
+ wasmFile: 'tree-sitter-zig.wasm',
536
+ definitions: [
537
+ // A method is a `function_declaration` directly inside a struct/enum/union's own body — the same
538
+ // node type a free function uses (Zig draws no separate node type the way most languages with a
539
+ // dedicated method/function split do), so each container kind gets its own `parentType`-guarded
540
+ // rule, tried before the unrestricted `function` rule below falls through to everything else — the
541
+ // same precedent C++'s method rule follows for its own shared `function_definition` node type.
542
+ // Verified against a real parse, not guessed.
543
+ { nodeType: 'function_declaration', kind: 'method', nameField: 'name', parentType: 'struct_declaration' },
544
+ { nodeType: 'function_declaration', kind: 'method', nameField: 'name', parentType: 'enum_declaration' },
545
+ { nodeType: 'function_declaration', kind: 'method', nameField: 'name', parentType: 'union_declaration' },
546
+ { nodeType: 'function_declaration', kind: 'function', nameField: 'name' },
547
+ // An enum member and a struct/union member share the very same `container_field` node type —
548
+ // unlike every other language's dedicated bare-enum-member shape, Zig draws no grammar-level
549
+ // distinction at all, so this is the one `parentType` this file needs to split them back apart;
550
+ // tried first, before the unrestricted `field` rule below falls through to a struct/union member.
551
+ // Verified against a real parse, not guessed.
552
+ { nodeType: 'container_field', kind: 'enum_member', nameField: 'name', parentType: 'enum_declaration' },
553
+ { nodeType: 'container_field', kind: 'field', nameField: 'name' },
554
+ // Zig has no dedicated struct/enum/union *statement* the way C/C++/Rust/Java do — a named
555
+ // container type is always a plain `const`/`var` declaration whose value happens to be a
556
+ // `struct_declaration`/`enum_declaration`/`union_declaration` literal (`const Point = struct {
557
+ // ... };`), and this same node type is also how Zig spells an ordinary top-level constant, a
558
+ // mutable global, *and* a std-library import (`const std = @import("std");`) — verified against a
559
+ // real parse. `variable_declaration` binds neither its name nor its value to a field at all (both
560
+ // are purely positional children, unlike every other grammar this package extracts a name from),
561
+ // so this uses `FIRST_CHILD_NAME_FIELD` for the name; the reported `kind` (`struct`/`enum`/
562
+ // `constant`/`variable`) is not fixed by this one static rule at all — `DefinitionRule.kind` has no
563
+ // way to vary by a value's shape the way this needs, so `extractFile` computes it per node via
564
+ // `zigDeclarationKind` instead (see there), and an `@import(...)` value is additionally recorded as
565
+ // an import binding via `zigImportBinding`, the same "also captured as an ordinary variable"
566
+ // precedent CommonJS's `require()` already sets. `scopeRestricted` applies uniformly to every kind
567
+ // this rule can produce, including a locally-declared struct/enum/union — unlike a Rust `fn` nested
568
+ // in another `fn` (still captured at any depth, since Rust's grammar gives a nested function its
569
+ // own distinct, unambiguous node type), Zig's local type declaration shares its node type with an
570
+ // ordinary local variable with no structural way to split the two without inspecting the value
571
+ // first, and this file's `scopeRestricted` gate runs before that inspection — a local type
572
+ // declaration inside a function is rare enough in idiomatic Zig that this file accepts missing it,
573
+ // the same "prefer a clean uniform rule over a fiddly special case" precedent already guiding this
574
+ // package's simpler choices elsewhere.
575
+ { nodeType: 'variable_declaration', kind: 'variable', nameField: FIRST_CHILD_NAME_FIELD, scopeRestricted: true },
576
+ ],
577
+ callTypes: ['call_expression'],
578
+ callFunctionField: 'function',
579
+ // No dedicated import-statement node type exists — `@import(...)` is an ordinary builtin-function
580
+ // call bound through the same `variable_declaration` shape the type/constant/variable rule above
581
+ // already matches (see `zigImportBinding` in extract.ts), not a distinct node type this table could
582
+ // name here.
583
+ importTypes: [],
584
+ // `test "name" { ... }` and `comptime { ... }` are Zig's own top-level block constructs — neither is
585
+ // itself captured as a definition (matching this file's existing "block, not a symbol" treatment of
586
+ // an anonymous callback), but a `const`/`var` directly inside either is still block-local, not a
587
+ // workspace symbol, so both push `'other'` scope for their body the same way a callback's function
588
+ // value does elsewhere in this file. Verified against a real parse, not guessed.
589
+ bareFunctionScopeTypes: ['test_declaration', 'comptime_declaration'],
590
+ },
591
+ {
592
+ language: 'kotlin',
593
+ extensions: ['.kt', '.kts'],
594
+ wasmFile: 'tree-sitter-kotlin.wasm',
595
+ definitions: [
596
+ // Kotlin's grammar gives `class`/`interface`/`enum class` the very same `class_declaration` node
597
+ // type, distinguished only by a bare `interface`/`enum` keyword among its own children (`interface
598
+ // Shape {}` carries a bare `interface` token, `enum class Color {}` carries both a bare `enum` and
599
+ // a bare `class` token, a plain `class Foo {}` carries only `class`) — no rule here can vary `kind`
600
+ // by a keyword the way this needs, so `extractFile` computes it via `kotlinClassKind` instead (see
601
+ // there), the same "kind computed per node, not fixed per rule" precedent Zig's `variable_declaration`
602
+ // entry already establishes above. Verified against a real parse, not guessed.
603
+ { nodeType: 'class_declaration', kind: 'class', nameField: KOTLIN_NAME_FIELD },
604
+ // A method is a `function_declaration` directly inside a `class_body` — the same node type a
605
+ // top-level function uses (including one inside a `companion_object`'s own nested `class_body`,
606
+ // still reported as a method of the enclosing type) — tried first, before the unrestricted
607
+ // `function` rule below falls through to everything else. Verified against a real parse.
608
+ { nodeType: 'function_declaration', kind: 'method', nameField: KOTLIN_NAME_FIELD, parentType: 'class_body' },
609
+ { nodeType: 'function_declaration', kind: 'function', nameField: KOTLIN_NAME_FIELD },
610
+ // An enum constant — verified against a real parse, not guessed; can only ever appear directly
611
+ // inside an `enum_class_body`, so — like Go's/Rust's/Zig's own field rules — no
612
+ // `scopeRestricted`/`parentType` guard is needed: the node type itself is unambiguous.
613
+ { nodeType: 'enum_entry', kind: 'enum_member', nameField: KOTLIN_NAME_FIELD },
614
+ // Deliberately no `field`/`property`/`variable`/`constant` kind at all: a `property_declaration`
615
+ // (`val`/`var`, at class-member, top-level, or local scope) binds its declared name two levels
616
+ // down, inside its own nested `variable_declaration` child, itself positioned after an optional
617
+ // leading `modifiers` node the same way a captured declaration is — extracting it cleanly would
618
+ // need its own multi-level, fully positional (there being no fields at all) navigation on top of
619
+ // everything `KOTLIN_NAME_FIELD` already handles, and this file's "don't guess/don't overreach"
620
+ // precedent (already applied to Lua's/Ruby's own locally-bound values) draws the line here instead.
621
+ ],
622
+ // `call_expression`'s callee is never bound to a field either — see `kotlinCallee` in extract.ts,
623
+ // consulted directly by a dedicated dispatch branch in `extractFile` rather than through
624
+ // `callFunctionField`, which (like every other field name) can never resolve anything for this
625
+ // grammar. `function` is kept only as a placeholder so this table entry still type-checks as a
626
+ // normal `LanguageSpec`; it is never actually read for Kotlin.
627
+ callTypes: ['call_expression'],
628
+ callFunctionField: 'function',
629
+ importTypes: ['import_header'],
630
+ // No anonymous-function-literal shape needs special-casing: a lambda's body is a `{ ... }` block
631
+ // that can contain a statement, exactly like every captured `function_declaration`'s own body, but
632
+ // this file already declines to capture any local `val`/`var` at all for Kotlin (see above), so
633
+ // there is currently no scope-restricted rule this could matter to.
634
+ bareFunctionScopeTypes: [],
635
+ },
636
+ {
637
+ language: 'swift',
638
+ extensions: ['.swift'],
639
+ wasmFile: 'tree-sitter-swift.wasm',
640
+ definitions: [
641
+ // `struct`/`class`/`enum` all share this one node type, distinguished by a `declaration_kind`
642
+ // field whose value node's own type is directly `struct`/`class`/`enum` (an unusual but verified
643
+ // shape — no other grammar this package extracts from promotes a bare keyword to its own field
644
+ // value this way) — no rule can vary `kind` by that field's value, so `extractFile` computes it
645
+ // via `swiftDeclarationKind` instead, the same "kind computed per node" precedent Zig's
646
+ // `variable_declaration`/Kotlin's `class_declaration` entries already establish above. A
647
+ // `protocol` is Swift's own separate `protocol_declaration` node type instead — verified against a
648
+ // real parse, not guessed.
649
+ { nodeType: 'class_declaration', kind: 'class', nameField: 'name' },
650
+ { nodeType: 'protocol_declaration', kind: 'interface', nameField: 'name' },
651
+ // A method is a `function_declaration` directly inside a `class_body` — the same node type a
652
+ // top-level function uses — tried first, before the unrestricted `function` rule below falls
653
+ // through to everything else. A protocol's own method *signature* (`func area() -> Double`, no
654
+ // body) is a distinct node type, `protocol_function_declaration`, always directly inside a
655
+ // `protocol_body` — unambiguous, so no `parentType` guard is needed for it. Both use
656
+ // `SWIFT_FUNCTION_NAME_FIELD`, not a plain `'name'` field, because either one with an explicit
657
+ // return type binds two nodes to that field (see `SWIFT_FUNCTION_NAME_FIELD`'s own doc comment) —
658
+ // verified against a real parse, not guessed.
659
+ { nodeType: 'function_declaration', kind: 'method', nameField: SWIFT_FUNCTION_NAME_FIELD, parentType: 'class_body' },
660
+ { nodeType: 'function_declaration', kind: 'function', nameField: SWIFT_FUNCTION_NAME_FIELD },
661
+ { nodeType: 'protocol_function_declaration', kind: 'method', nameField: SWIFT_FUNCTION_NAME_FIELD },
662
+ // An enum case — verified against a real parse, not guessed; can only ever appear directly inside
663
+ // an `enum_class_body`, so — like every other language's own unambiguous member node type — no
664
+ // `scopeRestricted`/`parentType` guard is needed.
665
+ { nodeType: 'enum_entry', kind: 'enum_member', nameField: 'name' },
666
+ // A struct/class stored property (`var x: Int`/`let x: Int` directly inside a `class_body`) —
667
+ // `property_declaration` is also how Swift spells a top-level or function-local `var`/`let`
668
+ // binding (the very same node type, see the fallback rule below), so this is tried first, guarded
669
+ // to only the class-member shape; a property can never legitimately sit anywhere a
670
+ // `scopeRestricted` gate would exclude it (a class/struct body is never treated as `'other'`
671
+ // scope), so this rule itself needs no such gate either.
672
+ { nodeType: 'property_declaration', kind: 'field', nameField: SWIFT_PROPERTY_NAME_FIELD, parentType: 'class_body' },
673
+ // A top-level or function-local `var`/`let` binding — `DefinitionRule.kind` cannot vary by the
674
+ // `value_binding_pattern` child's own keyword the way this needs, so `extractFile` computes
675
+ // `constant`/`variable` via `swiftDeclarationKind` (the same function also reports `field` for the
676
+ // rule above's match, since it inspects the node's actual parent rather than trusting which rule
677
+ // fired — see there). `scopeRestricted` excludes a function-local binding, matching every other
678
+ // language's own local-variable precedent.
679
+ { nodeType: 'property_declaration', kind: 'variable', nameField: SWIFT_PROPERTY_NAME_FIELD, scopeRestricted: true },
680
+ ],
681
+ // `call_expression` binds no field for its callee at all (verified against a real parse) — see
682
+ // `swiftCallee` in extract.ts, consulted directly by a dedicated dispatch branch in `extractFile`
683
+ // rather than through `callFunctionField`, which can never resolve anything for this node type.
684
+ // `target` is kept only as a placeholder so this table entry still type-checks as a normal
685
+ // `LanguageSpec`; it is never actually read for Swift.
686
+ callTypes: ['call_expression'],
687
+ callFunctionField: 'target',
688
+ importTypes: ['import_declaration'],
689
+ // A closure literal (`{ (x: Int) -> Int in ... }`, e.g. a callback argument) is never itself
690
+ // captured as a definition — but a `let`/`var` inside its body is still closure-local, not a
691
+ // workspace symbol, the same reasoning `ECMASCRIPT_BARE_FUNCTION_SCOPE_TYPES` applies to a callback.
692
+ // Verified against a real parse, not guessed.
693
+ bareFunctionScopeTypes: ['lambda_literal'],
694
+ },
695
+ {
696
+ language: 'dart',
697
+ extensions: ['.dart'],
698
+ wasmFile: 'tree-sitter-dart.wasm',
699
+ definitions: [
700
+ { nodeType: 'class_definition', kind: 'class', nameField: 'name' },
701
+ // A method's `function_signature` sits directly inside a `method_signature` wrapper; an abstract
702
+ // method (interface-only) signature (`double area();`, no body) instead sits inside a plain
703
+ // `declaration` whose own parent is the `class_body` — both tried before the unrestricted
704
+ // `function` rule below falls through to a top-level function. Verified against a real parse, not
705
+ // guessed.
706
+ { nodeType: 'function_signature', kind: 'method', nameField: 'name', parentType: 'method_signature' },
707
+ { nodeType: 'function_signature', kind: 'method', nameField: 'name', parentType: 'declaration', grandparentType: 'class_body' },
708
+ { nodeType: 'function_signature', kind: 'function', nameField: 'name' },
709
+ // A constructor (`Point(this.x, this.y);`) is its own node type, `constructor_signature`, wrapped
710
+ // by the very same `declaration` node type a field uses — matched directly here regardless of that
711
+ // wrapper (see `DART_FIELD_NAME_FIELD`'s doc comment). No dedicated `constructor` seam kind exists;
712
+ // a constructor is a method in every way this package's graph cares about, matching Java's/C#'s own
713
+ // constructor→`method` precedent.
714
+ { nodeType: 'constructor_signature', kind: 'method', nameField: 'name' },
715
+ { nodeType: 'enum_declaration', kind: 'enum', nameField: 'name' },
716
+ // An enum case — verified against a real parse, not guessed; can only ever appear directly inside
717
+ // an `enum_body`, so — like every other language's own unambiguous member node type — no
718
+ // `scopeRestricted`/`parentType` guard is needed.
719
+ { nodeType: 'enum_constant', kind: 'enum_member', nameField: 'name' },
720
+ // A class/struct field — see `DART_FIELD_NAME_FIELD`. Restricted to a direct `class_body` child
721
+ // since Dart uses an entirely different, already-unambiguous node type for a local variable
722
+ // (`local_variable_declaration`), so no `scopeRestricted` gate is needed either — this rule simply
723
+ // never matches one. A top-level `declaration` (Dart also allows a bare top-level `var`/`final`)
724
+ // is deliberately not captured at all — same "don't overreach" precedent this file already applies
725
+ // to a comparably rare shape elsewhere.
726
+ { nodeType: 'declaration', kind: 'field', nameField: DART_FIELD_NAME_FIELD, parentType: 'class_body' },
727
+ ],
728
+ // Dart's grammar has no call-expression node type at all — a call is a flat `identifier` followed by
729
+ // zero or more `selector` children, where a call is whichever `selector` happens to be an
730
+ // `argument_part` rather than a `.property` access; resolving its callee means walking backward
731
+ // through preceding siblings, not reading a field off a single call node the way every other
732
+ // language's `RawCall` extraction in this file works. Capturing this would need a structurally new,
733
+ // sibling-walking resolution strategy this package's call model does not support today, so this
734
+ // package captures no call sites for Dart at all — a real, verified limitation, not a guess. `name`
735
+ // is kept only as a placeholder so this table entry still type-checks as a normal `LanguageSpec`; it
736
+ // is never read, since `callTypes` is empty.
737
+ callTypes: [],
738
+ callFunctionField: 'name',
739
+ // Targets `import_specification` directly (nested inside `import_or_export` → `library_import`)
740
+ // rather than either wrapper — the walk reaches it regardless during ordinary recursion. A Dart
741
+ // `export` statement (`import_or_export` → `library_export`) is deliberately not captured: unlike an
742
+ // import, it re-exports the current file's own symbols to *its* importers, a different relationship
743
+ // than the "this file's own binding" every other `RawImport` in this package represents.
744
+ importTypes: ['import_specification'],
745
+ bareFunctionScopeTypes: [],
746
+ },
747
+ {
748
+ language: 'scala',
749
+ extensions: ['.scala', '.sc'],
750
+ wasmFile: 'tree-sitter-scala.wasm',
751
+ definitions: [
752
+ { nodeType: 'class_definition', kind: 'class', nameField: 'name' },
753
+ // A singleton `object` has no dedicated seam kind of its own; `class` is the closest existing fit —
754
+ // it shares `class_definition`'s exact shape (a `template_body`, an optional `extend` clause) and
755
+ // behaves like an ordinary class with a single implicit instance, matching Java's/C#'s own
756
+ // record→`class` precedent for a related-but-distinct construct.
757
+ { nodeType: 'object_definition', kind: 'class', nameField: 'name' },
758
+ { nodeType: 'trait_definition', kind: 'trait', nameField: 'name' },
759
+ // A method is a `function_definition`/`function_declaration` directly inside a `template_body` —
760
+ // the same node type a top-level function uses — tried first, before the unrestricted `function`
761
+ // rule below falls through to everything else. A trait's own method *signature* (`def area():
762
+ // Double`, no body) is `function_declaration`, always directly inside a `template_body` too (a
763
+ // trait's own), so no `parentType` guard is needed for that one — unambiguous by node type alone.
764
+ // Verified against a real parse, not guessed.
765
+ { nodeType: 'function_definition', kind: 'method', nameField: 'name', parentType: 'template_body' },
766
+ { nodeType: 'function_definition', kind: 'function', nameField: 'name' },
767
+ { nodeType: 'function_declaration', kind: 'method', nameField: 'name' },
768
+ // A class/trait/object member (`val x = 1` directly inside a `template_body`) — tried first, since
769
+ // this same node type is also how Scala spells a top-level or function-local immutable binding
770
+ // (the fallback rule below). `nameNodeTypes` rejects a destructuring pattern (`val (a, b) = ...`,
771
+ // `pattern` binds a `tuple_pattern`, not a bare `identifier`) rather than name it after a shape this
772
+ // package does not attempt to resolve, the same "don't guess" precedent `pythonBinding`/
773
+ // `ecmascriptImports` already follow. `var_definition` (a mutable binding) follows the identical
774
+ // split, reporting `variable` instead of `constant` for its own module/local-scope fallback.
775
+ // Verified against a real parse, not guessed.
776
+ { nodeType: 'val_definition', kind: 'field', nameField: 'pattern', nameNodeTypes: ['identifier'], parentType: 'template_body' },
777
+ { nodeType: 'val_definition', kind: 'constant', nameField: 'pattern', nameNodeTypes: ['identifier'], scopeRestricted: true },
778
+ { nodeType: 'var_definition', kind: 'field', nameField: 'pattern', nameNodeTypes: ['identifier'], parentType: 'template_body' },
779
+ { nodeType: 'var_definition', kind: 'variable', nameField: 'pattern', nameNodeTypes: ['identifier'], scopeRestricted: true },
780
+ // A primary constructor parameter (`class Point(val x: Int, val y: Int)`) — a very common Scala
781
+ // idiom for declaring fields directly in the class header instead of the body. Can only ever
782
+ // appear inside a `class_parameters` list, so — like every other language's own unambiguous member
783
+ // node type — no `scopeRestricted`/`parentType` guard is needed. Verified against a real parse,
784
+ // not guessed.
785
+ { nodeType: 'class_parameter', kind: 'field', nameField: 'name' },
786
+ ],
787
+ // `call_expression`'s callee sits in its own `function` field directly — a bare call
788
+ // (`add(1, 2)`)'s field value is a plain `identifier`; a member call (`p.length()`)'s is a
789
+ // `field_expression` instead, whose own `field` field names the callee and whose `value` field holds
790
+ // the receiver — both already handled by this file's existing generic `calleeName`/`isBareCallee`
791
+ // logic (the same `field` fallback Rust's `field_expression` already uses), so this language needs no
792
+ // call-specific dispatch of its own, unlike Kotlin/Swift/Lua/Ruby. Verified against a real parse, not
793
+ // guessed.
794
+ callTypes: ['call_expression'],
795
+ callFunctionField: 'function',
796
+ importTypes: ['import_declaration'],
797
+ // No anonymous-function-literal shape is special-cased here — this file's own attempt to write one
798
+ // parsed ambiguously as an `infix_expression` rather than a dedicated node type, an inconclusive
799
+ // result this package declines to guess a rule from; the practical impact is limited to a `val`/`var`
800
+ // inside a closure literal passed as a module-level argument, a rare pattern in idiomatic Scala.
801
+ bareFunctionScopeTypes: [],
802
+ },
427
803
  ];
428
804
  /**
429
805
  * The grammar for a file extension, or `undefined` when this package indexes nothing for it.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-codegraph-tree-sitter",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Self-built code-graph indexer for DeepSeek Harness — parses a workspace with web-tree-sitter and writes schema version 4 to .codegraph/codegraph.db, the same on-disk format the codegraph CLI writes, so no external indexer is required",
5
5
  "keywords": [
6
6
  "dsh",
@@ -51,7 +51,7 @@
51
51
  "@deepseek-ai/schemastery": "^3.18.1",
52
52
  "tree-sitter-wasms": "^0.1.13",
53
53
  "web-tree-sitter": "^0.25.10",
54
- "dsh-plugin-codegraph-service": "^0.1.4"
54
+ "dsh-plugin-codegraph-service": "^0.1.5"
55
55
  },
56
56
  "peerDependencies": {
57
57
  "@deepseek-ai/cordis": ">=4.0.1",