graph-indexer 2.1.1 → 3.0.1

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.
Files changed (131) hide show
  1. package/CHANGELOG.md +312 -1
  2. package/README.md +236 -312
  3. package/SECURITY.md +53 -58
  4. package/bin/graph-indexer.mjs +251 -0
  5. package/integrations/claude-code/.claude-plugin/plugin.json +9 -0
  6. package/integrations/claude-code/.mcp.json +8 -0
  7. package/integrations/claude-code/agents/code-structure.md +22 -0
  8. package/integrations/claude-code/hooks/gi-hook.mjs +103 -0
  9. package/integrations/claude-code/hooks/hooks.json +16 -0
  10. package/integrations/opencode/graph-indexer.js +129 -0
  11. package/package.json +32 -109
  12. package/src/cli/helper.mjs +67 -0
  13. package/src/cli/hook.mjs +366 -0
  14. package/src/cli/init.mjs +272 -0
  15. package/src/cli/resident.mjs +185 -0
  16. package/src/index/discover.mjs +128 -0
  17. package/src/index/fingerprint.mjs +30 -0
  18. package/src/index/graph.mjs +61 -0
  19. package/src/index/indexer.mjs +476 -0
  20. package/src/index/modules.mjs +332 -0
  21. package/src/index/resolver.mjs +961 -0
  22. package/src/mcp/render.mjs +60 -0
  23. package/src/mcp/server.mjs +147 -0
  24. package/src/mcp/tools.mjs +974 -0
  25. package/src/parse/arity.mjs +153 -0
  26. package/src/parse/extract.mjs +1038 -0
  27. package/src/parse/lang/csharp.mjs +106 -0
  28. package/src/parse/lang/ecma.mjs +438 -0
  29. package/src/parse/lang/go.mjs +194 -0
  30. package/src/parse/lang/jvm.mjs +118 -0
  31. package/src/parse/lang/kotlin.mjs +97 -0
  32. package/src/parse/lang/misc.mjs +115 -0
  33. package/src/parse/lang/native.mjs +126 -0
  34. package/src/parse/lang/python.mjs +153 -0
  35. package/src/parse/lang/rust.mjs +157 -0
  36. package/src/parse/lang/scripting.mjs +219 -0
  37. package/src/parse/languages.mjs +48 -0
  38. package/src/parse/runtime.mjs +56 -0
  39. package/src/query/check.mjs +345 -0
  40. package/src/query/facts.mjs +323 -0
  41. package/src/query/intel.mjs +683 -0
  42. package/src/query/read.mjs +81 -0
  43. package/src/query/testcmd.mjs +130 -0
  44. package/src/query/textsearch.mjs +178 -0
  45. package/src/search/search.mjs +210 -0
  46. package/src/search/tokenize.mjs +188 -0
  47. package/src/store/db.mjs +169 -0
  48. package/src/util/git.mjs +30 -0
  49. package/src/util/paths.mjs +63 -0
  50. package/src/util/regex.mjs +2 -0
  51. package/vendor/grammars/bash.wasm.gz +0 -0
  52. package/vendor/grammars/c.wasm.gz +0 -0
  53. package/vendor/grammars/c_sharp.wasm.gz +0 -0
  54. package/vendor/grammars/cpp.wasm.gz +0 -0
  55. package/vendor/grammars/css.wasm.gz +0 -0
  56. package/vendor/grammars/go.wasm.gz +0 -0
  57. package/vendor/grammars/java.wasm.gz +0 -0
  58. package/vendor/grammars/javascript.wasm.gz +0 -0
  59. package/vendor/grammars/kotlin.wasm.gz +0 -0
  60. package/vendor/grammars/manifest.json +148 -0
  61. package/vendor/grammars/php.wasm.gz +0 -0
  62. package/vendor/grammars/python.wasm.gz +0 -0
  63. package/vendor/grammars/ruby.wasm.gz +0 -0
  64. package/vendor/grammars/rust.wasm.gz +0 -0
  65. package/vendor/grammars/scala.wasm.gz +0 -0
  66. package/vendor/grammars/tsx.wasm.gz +0 -0
  67. package/vendor/grammars/typescript.wasm.gz +0 -0
  68. package/vendor/web-tree-sitter/web-tree-sitter.js +3980 -0
  69. package/vendor/web-tree-sitter/web-tree-sitter.wasm +0 -0
  70. package/cli-ui.mjs +0 -78
  71. package/colbert.mjs +0 -168
  72. package/config.mjs +0 -494
  73. package/daemon-ctl.mjs +0 -175
  74. package/daemon-lock.mjs +0 -69
  75. package/embedders/python/mlx_embed_server.py +0 -61
  76. package/embedders/python/requirements-mlx.txt +0 -5
  77. package/embedders/setup-mlx.mjs +0 -110
  78. package/embeddings.mjs +0 -571
  79. package/engine/binary.mjs +0 -437
  80. package/engine/memory.mjs +0 -1003
  81. package/engine/sqlite.mjs +0 -1136
  82. package/enrichment.mjs +0 -521
  83. package/git-signals.mjs +0 -248
  84. package/indexer.mjs +0 -546
  85. package/init.mjs +0 -1809
  86. package/layout.mjs +0 -123
  87. package/mcp/centrality.mjs +0 -117
  88. package/mcp/format.mjs +0 -61
  89. package/mcp/resolver.mjs +0 -116
  90. package/mcp/symbolgraph.mjs +0 -137
  91. package/mcp/taint.mjs +0 -225
  92. package/mcp/tools.mjs +0 -1582
  93. package/mcp/topology.mjs +0 -676
  94. package/mcp-server.mjs +0 -197
  95. package/parse/extractor.mjs +0 -628
  96. package/parse/imports.mjs +0 -365
  97. package/parse/interprocedural.mjs +0 -134
  98. package/parse/languages.mjs +0 -253
  99. package/parse/metadata.mjs +0 -701
  100. package/parse/routes.mjs +0 -327
  101. package/parse/scip.mjs +0 -391
  102. package/parse/taint-patterns.mjs +0 -119
  103. package/prompts/CORE.md +0 -91
  104. package/prompts/DOMAIN_TEMPLATE.md +0 -46
  105. package/prompts/INTEGRATION.md +0 -123
  106. package/prompts/frameworks/ANDROID.md +0 -17
  107. package/prompts/frameworks/ASPNET_CORE.md +0 -19
  108. package/prompts/frameworks/FASTAPI_DJANGO.md +0 -20
  109. package/prompts/frameworks/LARAVEL_SYMFONY.md +0 -22
  110. package/prompts/frameworks/NODE_EXPRESS_NESTJS.md +0 -19
  111. package/prompts/frameworks/RAILS.md +0 -20
  112. package/prompts/frameworks/REACT.md +0 -20
  113. package/prompts/frameworks/SPRING_BOOT.md +0 -20
  114. package/prompts/languages/BASH.md +0 -22
  115. package/prompts/languages/C.md +0 -21
  116. package/prompts/languages/CSHARP.md +0 -24
  117. package/prompts/languages/CSS_SCSS.md +0 -22
  118. package/prompts/languages/GO.md +0 -24
  119. package/prompts/languages/JAVA.md +0 -23
  120. package/prompts/languages/JAVASCRIPT_TYPESCRIPT.md +0 -24
  121. package/prompts/languages/KOTLIN.md +0 -24
  122. package/prompts/languages/PHP.md +0 -23
  123. package/prompts/languages/PYTHON.md +0 -23
  124. package/prompts/languages/RUBY.md +0 -23
  125. package/prompts/languages/RUST.md +0 -21
  126. package/prompts/languages/SWIFT.md +0 -21
  127. package/seal.mjs +0 -400
  128. package/search-core.mjs +0 -777
  129. package/search-sparse.mjs +0 -183
  130. package/storage.mjs +0 -73
  131. package/watch-daemon.mjs +0 -289
@@ -0,0 +1,126 @@
1
+ /** C and C++ extraction specs. */
2
+
3
+ const C_DEFS = `
4
+ (function_definition declarator: (function_declarator declarator: (identifier) @name)) @def.function
5
+ (function_definition declarator: (pointer_declarator declarator: (function_declarator declarator: (identifier) @name))) @def.function
6
+ (function_definition declarator: (pointer_declarator declarator: (pointer_declarator declarator: (function_declarator declarator: (identifier) @name)))) @def.function
7
+ (struct_specifier name: (type_identifier) @name body: (_)) @def.struct
8
+ (union_specifier name: (type_identifier) @name body: (_)) @def.struct
9
+ (enum_specifier name: (type_identifier) @name body: (_)) @def.enum
10
+ (type_definition declarator: (type_identifier) @name) @def.type
11
+ (type_definition declarator: (pointer_declarator declarator: (type_identifier) @name)) @def.type
12
+ (type_definition declarator: (function_declarator declarator: (parenthesized_declarator (pointer_declarator declarator: (type_identifier) @name)))) @def.type
13
+ (preproc_function_def name: (identifier) @name) @def.macro
14
+ (preproc_def name: (identifier) @name) @def.constant
15
+ (enumerator name: (identifier) @name) @def.constant
16
+ (field_declaration declarator: (field_identifier) @name) @def.field
17
+ (field_declaration declarator: (pointer_declarator declarator: (field_identifier) @name)) @def.field
18
+ `;
19
+
20
+ const C_REFS = `
21
+ (return_statement (_) @ret)
22
+ (call_expression function: (identifier) @name) @ref.call
23
+ (call_expression function: (field_expression argument: (_) @recv field: (field_identifier) @name)) @ref.call
24
+ (type_identifier) @name @ref.type
25
+ (argument_list (identifier) @name) @ref.value
26
+ (init_declarator value: (identifier) @name) @ref.value
27
+ (initializer_list (identifier) @name) @ref.value
28
+ (preproc_include) @import
29
+ `;
30
+
31
+ const CPP_DEFS = `
32
+ (function_definition declarator: (function_declarator declarator: (identifier) @name)) @def.function
33
+ (function_definition declarator: (function_declarator declarator: (field_identifier) @name)) @def.method
34
+ (function_definition declarator: (function_declarator declarator: (qualified_identifier scope: (_) @owner name: (identifier) @name))) @def.method
35
+ (function_definition declarator: (function_declarator declarator: (qualified_identifier scope: (_) @owner name: (destructor_name) @name))) @def.method
36
+ (function_definition declarator: (pointer_declarator declarator: (function_declarator declarator: (identifier) @name))) @def.function
37
+ (function_definition declarator: (reference_declarator (function_declarator declarator: (identifier) @name))) @def.function
38
+ (field_declaration declarator: (function_declarator declarator: (field_identifier) @name)) @def.method
39
+ (declaration declarator: (function_declarator declarator: (identifier) @name)) @def.function
40
+ (class_specifier name: (type_identifier) @name body: (_)) @def.class
41
+ (struct_specifier name: (type_identifier) @name body: (_)) @def.struct
42
+ (union_specifier name: (type_identifier) @name body: (_)) @def.struct
43
+ (enum_specifier name: (type_identifier) @name body: (_)) @def.enum
44
+ (namespace_definition name: (_) @name) @def.module
45
+ (alias_declaration name: (type_identifier) @name) @def.type
46
+ (type_definition declarator: (type_identifier) @name) @def.type
47
+ (preproc_function_def name: (identifier) @name) @def.macro
48
+ (field_declaration declarator: (field_identifier) @name) @def.field
49
+ (enumerator name: (identifier) @name) @def.constant
50
+ `;
51
+
52
+ const CPP_REFS = `
53
+ (lambda_expression) @scope
54
+ (return_statement (_) @ret)
55
+ (call_expression function: (identifier) @name) @ref.call
56
+ (call_expression function: (field_expression argument: (_) @recv field: (field_identifier) @name)) @ref.call
57
+ (call_expression function: (qualified_identifier scope: (_) @recv name: (identifier) @name)) @ref.call
58
+ (call_expression function: (template_function name: (identifier) @name)) @ref.call
59
+ (new_expression type: (type_identifier) @name) @ref.new
60
+ (base_class_clause (type_identifier) @name) @ref.inherit
61
+ (base_class_clause (qualified_identifier name: (type_identifier) @name)) @ref.inherit
62
+ (type_identifier) @name @ref.type
63
+ (argument_list (identifier) @name) @ref.value
64
+ (preproc_include) @import
65
+ (declaration type: (type_identifier) @bind.type declarator: (identifier) @bind.name) @bind
66
+ (declaration type: (type_identifier) @bind.type declarator: (init_declarator declarator: (identifier) @bind.name)) @bind
67
+ (parameter_declaration type: (type_identifier) @bind.type declarator: [(identifier) @bind.name (pointer_declarator declarator: (identifier) @bind.name) (reference_declarator (identifier) @bind.name)]) @bind
68
+ (field_declaration type: (type_identifier) @field.type declarator: [(field_identifier) @field.name (pointer_declarator declarator: (field_identifier) @field.name)]) @field
69
+ `;
70
+
71
+ const C_BUILTINS = new Set(['printf', 'fprintf', 'sprintf', 'snprintf', 'malloc', 'calloc', 'realloc', 'free', 'memcpy',
72
+ 'memset', 'memmove', 'memcmp', 'strlen', 'strcpy', 'strncpy', 'strcmp', 'strncmp', 'strcat', 'strchr', 'strstr',
73
+ 'assert', 'sizeof', 'exit', 'abort', 'puts', 'putchar', 'fopen', 'fclose', 'fread', 'fwrite', 'fgets', 'fputs',
74
+ 'atoi', 'atof', 'strtol', 'strtod', 'va_start', 'va_end', 'va_arg', 'isdigit', 'isspace', 'isalpha', 'tolower',
75
+ 'toupper', 'abs', 'fabs', 'floor', 'ceil', 'pow', 'sqrt', 'static_cast', 'dynamic_cast', 'reinterpret_cast',
76
+ 'const_cast', 'move', 'forward', 'make_shared', 'make_unique']);
77
+
78
+ function parseInclude(node) {
79
+ const p = node.childForFieldName('path');
80
+ if (!p) return [];
81
+ if (p.type === 'system_lib_string') return [{ source: p.text.replace(/^<|>$/g, ''), imported: '*', local: null, system: true }];
82
+ return [{ source: p.text.replace(/^"|"$/g, ''), imported: '*', local: null }];
83
+ }
84
+
85
+ function cVisibility(node) {
86
+ return node.namedChildren.some(c => c.type === 'storage_class_specifier' && c.text === 'static') ? 'private' : null;
87
+ }
88
+
89
+ const common = {
90
+ implicitThis: false,
91
+ selfNames: ['this'],
92
+ externalReceivers: new Set(['std']),
93
+ builtinCalls: C_BUILTINS,
94
+ testFile: /(^|\/)(tests?|test_\w+)\/|_test\.(c|cc|cpp)$|(^|\/)test_[^/]*\.(c|cc|cpp)$/,
95
+ commentTypes: ['comment'],
96
+ parseImport: parseInclude,
97
+ isExported: (node) => cVisibility(node) !== 'private',
98
+ visibility: cVisibility,
99
+ isPrimitiveType: (t) => /^(int|char|void|float|double|long|short|unsigned|signed|bool|size_t|u?int\d+_t|string|auto)$/.test(t),
100
+ bodyField: 'body',
101
+ };
102
+
103
+ export const c = {
104
+ ...common,
105
+ id: 'c',
106
+ grammar: 'c',
107
+ extensions: ['.c', '.h'],
108
+ family: 'c',
109
+ query: C_DEFS + C_REFS,
110
+ };
111
+
112
+ export const cpp = {
113
+ ...common,
114
+ id: 'cpp',
115
+ grammar: 'cpp',
116
+ extensions: ['.cc', '.cpp', '.cxx', '.hpp', '.hh', '.hxx', '.h++', '.c++', '.ipp', '.inl'],
117
+ family: 'c',
118
+ implicitThis: true,
119
+ query: CPP_DEFS + CPP_REFS,
120
+ cleanType: (t) => t.replace(/\b(std|boost)::/g, ''),
121
+ transparentTypes: new Set(['unique_ptr', 'shared_ptr', 'weak_ptr', 'optional', 'reference_wrapper', 'atomic']),
122
+ elementTypes: new Set(['vector', 'list', 'deque', 'set', 'unordered_set', 'multiset', 'array', 'span', 'forward_list']),
123
+ elementMethods: new Set(['at', 'front', 'back', 'top']),
124
+ mapTypes: new Set(['map', 'unordered_map', 'multimap', 'unordered_multimap']),
125
+ mapMethods: new Set(['at']),
126
+ };
@@ -0,0 +1,153 @@
1
+ /** Python extraction spec. See ../extract.mjs for the capture convention. */
2
+
3
+ const QUERY = `
4
+ (function_definition name: (identifier) @name return_type: (type) @type) @def.function
5
+ (function_definition name: (identifier) @name) @def.function
6
+ (class_definition name: (identifier) @name) @def.class
7
+ (module (expression_statement (assignment left: (identifier) @name)) @def.variable)
8
+ (class_definition body: (block (expression_statement (assignment left: (identifier) @name type: (type) @type)) @def.field))
9
+ (class_definition body: (block (expression_statement (assignment left: (identifier) @name)) @def.field))
10
+ (expression_statement (assignment left: (attribute object: (identifier) @_self attribute: (identifier) @name) (#eq? @_self "self")) @def.field)
11
+
12
+ (call function: (identifier) @name) @ref.call
13
+ (call function: (attribute object: (_) @recv attribute: (identifier) @name)) @ref.call
14
+ (class_definition superclasses: (argument_list (identifier) @name)) @ref.inherit
15
+ (class_definition superclasses: (argument_list (attribute object: (_) @recv attribute: (identifier) @name))) @ref.inherit
16
+ (decorator (identifier) @name) @ref.decorator
17
+ (decorator (attribute object: (_) @recv attribute: (identifier) @name)) @ref.decorator
18
+ (decorator (call function: (identifier) @name)) @ref.decorator
19
+ (decorator (call function: (attribute object: (_) @recv attribute: (identifier) @name))) @ref.decorator
20
+ (type (identifier) @name) @ref.type
21
+ (type (attribute object: (_) @recv attribute: (identifier) @name)) @ref.type
22
+ (type (generic_type (identifier) @name)) @ref.type
23
+ (type (generic_type (type_parameter (type (identifier) @name)))) @ref.type
24
+ (type (string (string_content) @name)) @ref.type
25
+ (argument_list (identifier) @name) @ref.value
26
+ (keyword_argument value: (identifier) @name) @ref.value
27
+ (list (identifier) @name) @ref.value
28
+ (pair value: (identifier) @name) @ref.value
29
+ (assignment right: (identifier) @name) @ref.value
30
+ (attribute object: (_) @recv attribute: (identifier) @name) @ref.read
31
+
32
+ [(lambda) (list_comprehension) (set_comprehension) (dictionary_comprehension) (generator_expression)] @scope
33
+ (return_statement (_) @ret)
34
+ (import_statement) @import
35
+ (import_from_statement) @import
36
+
37
+ (assignment left: (identifier) @bind.name right: (_) @bind.expr) @bind
38
+ (assignment left: (identifier) @bind.name type: (type) @bind.type) @bind
39
+ (typed_parameter (identifier) @bind.name type: (type) @bind.type) @bind
40
+ (typed_default_parameter name: (identifier) @bind.name type: (type) @bind.type) @bind
41
+ (for_statement left: (identifier) @bind.name right: (_) @bind.elem) @bind
42
+ (for_in_clause left: (identifier) @bind.name right: (_) @bind.elem) @bind
43
+ (with_item value: (as_pattern (_) @bind.expr alias: (as_pattern_target (identifier) @bind.name))) @bind
44
+ (assignment left: (attribute object: (identifier) @_self attribute: (identifier) @field.name) right: (_) @field.expr (#eq? @_self "self")) @field
45
+ (assignment left: (attribute object: (identifier) @_self attribute: (identifier) @field.name) type: (type) @field.type (#eq? @_self "self")) @field
46
+ (class_definition body: (block (expression_statement (assignment left: (identifier) @field.name type: (type) @field.type)) @field))
47
+ `;
48
+
49
+ const BUILTIN_CALLS = new Set([
50
+ 'print', 'len', 'range', 'isinstance', 'issubclass', 'hasattr', 'getattr', 'setattr', 'delattr', 'super',
51
+ 'str', 'int', 'float', 'bool', 'list', 'dict', 'set', 'tuple', 'frozenset', 'bytes', 'bytearray', 'type',
52
+ 'object', 'enumerate', 'zip', 'map', 'filter', 'sorted', 'reversed', 'min', 'max', 'sum', 'any', 'all',
53
+ 'abs', 'round', 'repr', 'hash', 'id', 'iter', 'next', 'open', 'callable', 'vars', 'dir', 'format',
54
+ 'staticmethod', 'classmethod', 'property', 'NotImplementedError', 'ValueError', 'TypeError', 'KeyError',
55
+ 'RuntimeError', 'Exception', 'AttributeError', 'IndexError', 'StopIteration', 'AssertionError', 'OSError',
56
+ 'IOError', 'ImportError', 'NameError', 'ZeroDivisionError', 'PermissionError', 'FileNotFoundError',
57
+ ]);
58
+ const EXTERNAL_RECEIVERS = new Set(['os', 'sys', 're', 'json', 'math', 'time', 'datetime', 'logging', 'logger',
59
+ 'log', 'typing', 'collections', 'itertools', 'functools', 'asyncio', 'subprocess', 'shutil', 'pathlib', 'random',
60
+ 'np', 'pd', 'torch', 'tf', 'pytest', 'unittest', 'mock', 'warnings', 'inspect', 'copy', 'pickle', 'uuid', 'base64',
61
+ 'hashlib', 'threading', 'contextlib', 'dataclasses', 'enum', 'abc', 'io', 'tempfile', 'glob', 'string', 'decimal']);
62
+ const PRIMITIVES = new Set(['str', 'int', 'float', 'bool', 'bytes', 'None', 'Any', 'object', 'list', 'dict', 'set',
63
+ 'tuple', 'List', 'Dict', 'Set', 'Tuple', 'Optional', 'Union', 'Callable', 'Iterable', 'Iterator', 'Sequence',
64
+ 'Mapping', 'Type', 'Generator', 'AsyncGenerator', 'Awaitable', 'Coroutine', 'Literal', 'ClassVar', 'Self']);
65
+
66
+ function stripDocString(t) {
67
+ return t.replace(/^[rRbBuUfF]*("""|'''|"|')/, '').replace(/("""|'''|"|')$/, '')
68
+ .split('\n').map(l => l.trim()).filter(Boolean).join(' ');
69
+ }
70
+
71
+ function docOf(defNode) {
72
+ const body = defNode.childForFieldName('body');
73
+ const first = body?.namedChild(0);
74
+ if (first?.type === 'expression_statement') {
75
+ const s = first.namedChild(0);
76
+ if (s?.type === 'string') return stripDocString(s.text);
77
+ }
78
+ return null; // fall back to comments above
79
+ }
80
+
81
+ function dotted(node) { return node ? node.text.replace(/\s+/g, '') : null; }
82
+
83
+ function parseImport(node) {
84
+ const out = [];
85
+ if (node.type === 'import_statement') {
86
+ for (const c of node.namedChildren) {
87
+ if (c.type === 'dotted_name') {
88
+ const mod = dotted(c);
89
+ out.push({ source: mod, imported: '*', local: mod });
90
+ } else if (c.type === 'aliased_import') {
91
+ const mod = dotted(c.childForFieldName('name'));
92
+ out.push({ source: mod, imported: '*', local: c.childForFieldName('alias')?.text || mod });
93
+ }
94
+ }
95
+ } else if (node.type === 'import_from_statement') {
96
+ const modNode = node.childForFieldName('module_name');
97
+ const source = dotted(modNode) || '.';
98
+ let any = false;
99
+ for (const c of node.namedChildren) {
100
+ if (c === modNode || c.id === modNode?.id) continue;
101
+ if (c.type === 'dotted_name') { const n = dotted(c); out.push({ source, imported: n, local: n.split('.').pop() }); any = true; }
102
+ else if (c.type === 'aliased_import') {
103
+ const n = dotted(c.childForFieldName('name'));
104
+ out.push({ source, imported: n, local: c.childForFieldName('alias')?.text || n }); any = true;
105
+ } else if (c.type === 'wildcard_import') { out.push({ source, imported: '*', local: null, wildcard: true }); any = true; }
106
+ }
107
+ if (!any) out.push({ source, imported: null, local: null });
108
+ }
109
+ return out;
110
+ }
111
+
112
+ function isModuleLevel(node) {
113
+ // (module (expression_statement (assignment)))
114
+ return node.parent?.type === 'module';
115
+ }
116
+
117
+ export const python = {
118
+ id: 'python',
119
+ // `self.x = …` inside a method declares an instance attribute of the class (first assignment wins)
120
+ hoistMemberFields: true,
121
+ grammar: 'python',
122
+ extensions: ['.py', '.pyi'],
123
+ family: 'python',
124
+ query: QUERY,
125
+ implicitThis: false,
126
+ selfNames: ['self', 'cls'],
127
+ externalReceivers: EXTERNAL_RECEIVERS,
128
+ builtinCalls: BUILTIN_CALLS,
129
+ testFile: /(^|\/)(tests?|testing)\/|(^|\/)test_[^/]*\.py$|_test\.py$|(^|\/)conftest\.py$/,
130
+ commentTypes: ['comment'],
131
+ docWrappers: new Set(['decorated_definition']),
132
+ docOf,
133
+ parseImport,
134
+ isModuleLevel,
135
+ isExported: (node, name) => !name.startsWith('_') || /^__\w+__$/.test(name),
136
+ visibility: (node, name) => (name && name.startsWith('_') && !/^__\w+__$/.test(name) ? 'private' : null),
137
+ isPrimitiveType: (t) => PRIMITIVES.has(t),
138
+ isStatic: (node) => node.parent?.type === 'decorated_definition' && node.parent.namedChildren.some(c => c.type === 'decorator' && /^@(staticmethod|classmethod)\b/.test(c.text)),
139
+ transparentTypes: new Set(['Optional', 'Final', 'ClassVar', 'Annotated', 'Type', 'type', 'Awaitable', 'Required', 'NotRequired', 'ReadOnly']),
140
+ elementTypes: new Set(['list', 'List', 'Sequence', 'MutableSequence', 'Iterable', 'Iterator', 'AsyncIterable', 'AsyncIterator',
141
+ 'Generator', 'AsyncGenerator', 'set', 'Set', 'frozenset', 'FrozenSet', 'AbstractSet', 'MutableSet', 'Collection', 'Deque', 'deque', 'tuple', 'Tuple']),
142
+ elementMethods: new Set(['pop', 'popleft']),
143
+ mapTypes: new Set(['dict', 'Dict', 'Mapping', 'MutableMapping', 'DefaultDict', 'defaultdict', 'OrderedDict']),
144
+ mapMethods: new Set(['get', 'pop', 'setdefault']),
145
+ mapValueMethods: new Set(['values']),
146
+ decoratorsOf(node) {
147
+ const p = node.parent;
148
+ if (p?.type !== 'decorated_definition') return [];
149
+ return p.namedChildren.filter(c => c.type === 'decorator').map(d => d.text.replace(/^@/, '').split('(')[0].trim()).slice(0, 8);
150
+ },
151
+ bodyField: 'body',
152
+ signatureCleanup: (text) => text.replace(/:$/, ''),
153
+ };
@@ -0,0 +1,157 @@
1
+ /** Rust extraction spec. `impl Type { fn m() }` methods are qualified as Type.m. */
2
+
3
+ const TH = (cap) => `[(type_identifier) @${cap} (generic_type type: (type_identifier) @${cap}) (scoped_type_identifier name: (type_identifier) @${cap}) (reference_type type: (type_identifier) @${cap}) (reference_type type: (generic_type type: (type_identifier) @${cap}))]`;
4
+ // a whole type (normalizeType unwraps references, Box/Rc/Arc/Option/Result, and sees Vec<T> as T[])
5
+ const TW = (cap) => `[(type_identifier) (generic_type) (scoped_type_identifier) (reference_type) (array_type) (pointer_type)] @${cap}`;
6
+
7
+ const QUERY = `
8
+ (function_item name: (identifier) @name return_type: ${TW('type')}) @def.function
9
+ (function_item name: (identifier) @name) @def.function
10
+ (function_signature_item name: (identifier) @name return_type: ${TW('type')}) @def.function
11
+ (function_signature_item name: (identifier) @name) @def.function
12
+ (struct_item name: (type_identifier) @name) @def.struct
13
+ (enum_item name: (type_identifier) @name) @def.enum
14
+ (union_item name: (type_identifier) @name) @def.struct
15
+ (trait_item name: (type_identifier) @name) @def.trait
16
+ (type_item name: (type_identifier) @name) @def.type
17
+ (const_item name: (identifier) @name) @def.constant
18
+ (static_item name: (identifier) @name) @def.constant
19
+ (mod_item name: (identifier) @name body: (_)) @def.module
20
+ (macro_definition name: (identifier) @name) @def.macro
21
+ (field_declaration name: (field_identifier) @name type: ${TW('type')}) @def.field
22
+ (field_declaration name: (field_identifier) @name) @def.field
23
+ (enum_variant name: (identifier) @name) @def.constant
24
+
25
+ (call_expression function: (identifier) @name) @ref.call
26
+ (call_expression function: (field_expression value: (_) @recv field: (field_identifier) @name)) @ref.call
27
+ (call_expression function: (scoped_identifier path: (_) @recv name: (identifier) @name)) @ref.call
28
+ (call_expression function: (generic_function function: (identifier) @name)) @ref.call
29
+ (call_expression function: (generic_function function: (scoped_identifier path: (_) @recv name: (identifier) @name))) @ref.call
30
+ (call_expression function: (generic_function function: (field_expression value: (_) @recv field: (field_identifier) @name))) @ref.call
31
+ (macro_invocation macro: (identifier) @name) @ref.call
32
+ (struct_expression name: (type_identifier) @name) @ref.new
33
+ (struct_expression name: (scoped_type_identifier path: (_) @recv name: (type_identifier) @name)) @ref.new
34
+ (type_identifier) @name @ref.type
35
+ (impl_item trait: ${TH('name')}) @ref.inherit
36
+ (trait_item bounds: (trait_bounds ${TH('name')})) @ref.inherit
37
+ (arguments (identifier) @name) @ref.value
38
+ (arguments (scoped_identifier path: (_) @recv name: (identifier) @name)) @ref.value
39
+
40
+ (closure_expression) @scope
41
+ (return_expression (_) @ret)
42
+ (function_item body: (block [(call_expression) (struct_expression) (field_expression) (identifier) (self) (reference_expression) (try_expression) (scoped_identifier)] @ret .))
43
+ (use_declaration) @import
44
+
45
+ (let_declaration pattern: (identifier) @bind.name type: ${TW('bind.type')}) @bind
46
+ (let_declaration pattern: (mut_pattern (identifier) @bind.name) type: ${TW('bind.type')}) @bind
47
+ (let_declaration pattern: (identifier) @bind.name value: (_) @bind.expr) @bind
48
+ (let_declaration pattern: (mut_pattern (identifier) @bind.name) value: (_) @bind.expr) @bind
49
+ (for_expression pattern: (identifier) @bind.name value: (_) @bind.elem) @bind
50
+ (let_declaration pattern: (identifier) @bind.name value: (struct_expression name: (type_identifier) @bind.new)) @bind
51
+ (let_declaration pattern: (identifier) @bind.name value: (call_expression function: (scoped_identifier path: (identifier) @bind.new name: (identifier) @_ctor))) @bind
52
+ (let_declaration pattern: (mut_pattern (identifier) @bind.name) value: (call_expression function: (scoped_identifier path: (identifier) @bind.new name: (identifier) @_ctor))) @bind
53
+ (let_declaration pattern: (identifier) @bind.name value: (call_expression function: (identifier) @bind.call)) @bind
54
+ (parameter pattern: (identifier) @bind.name type: ${TW('bind.type')}) @bind
55
+ `;
56
+
57
+ const PRIMITIVES = new Set(['i8', 'i16', 'i32', 'i64', 'i128', 'isize', 'u8', 'u16', 'u32', 'u64', 'u128', 'usize',
58
+ 'f32', 'f64', 'bool', 'char', 'str', 'String', 'Option', 'Result', 'Vec', 'Box', 'Rc', 'Arc', 'RefCell',
59
+ 'Cell', 'HashMap', 'HashSet', 'BTreeMap', 'BTreeSet', 'Cow', 'Mutex', 'RwLock', 'Pin', 'PhantomData']);
60
+ const BUILTIN_MACROS = new Set(['println', 'print', 'eprintln', 'eprint', 'format', 'vec', 'panic', 'assert',
61
+ 'assert_eq', 'assert_ne', 'debug_assert', 'debug_assert_eq', 'write', 'writeln', 'unreachable', 'unimplemented',
62
+ 'todo', 'matches', 'include_str', 'include_bytes', 'concat', 'stringify', 'env', 'cfg', 'dbg', 'format_args', 'Ok',
63
+ 'Err', 'Some', 'None', 'Box', 'Default', 'drop', 'Into', 'From']);
64
+
65
+ function implOwner(node) {
66
+ // function_item inside (impl_item body: (declaration_list ...))
67
+ const list = node.parent;
68
+ const impl = list?.parent;
69
+ if (list?.type === 'declaration_list' && impl?.type === 'impl_item') {
70
+ const t = impl.childForFieldName('type');
71
+ if (!t) return null;
72
+ if (t.type === 'type_identifier') return t.text;
73
+ const inner = t.childForFieldName('type') ?? t.childForFieldName('name');
74
+ return inner?.type === 'type_identifier' ? inner.text : t.text.replace(/<.*$/s, '').split('::').pop();
75
+ }
76
+ return null;
77
+ }
78
+
79
+ function flattenUse(node, prefix, out) {
80
+ switch (node.type) {
81
+ case 'scoped_identifier': case 'identifier': case 'crate': case 'self': case 'super': {
82
+ const full = (prefix ? prefix + '::' : '') + node.text;
83
+ const name = full.split('::').pop();
84
+ out.push({ source: full.split('::').slice(0, -1).join('::'), imported: name, local: name === 'self' ? full.split('::').slice(-2, -1)[0] : name });
85
+ break;
86
+ }
87
+ case 'use_as_clause': {
88
+ const p = node.childForFieldName('path');
89
+ const full = (prefix ? prefix + '::' : '') + (p?.text ?? '');
90
+ out.push({ source: full.split('::').slice(0, -1).join('::'), imported: full.split('::').pop(), local: node.childForFieldName('alias')?.text });
91
+ break;
92
+ }
93
+ case 'use_wildcard': {
94
+ const inner = node.namedChildren[0];
95
+ out.push({ source: (prefix ? prefix + '::' : '') + (inner?.text ?? ''), imported: '*', local: null, wildcard: true });
96
+ break;
97
+ }
98
+ case 'scoped_use_list': {
99
+ const p = node.childForFieldName('path');
100
+ const np = (prefix ? prefix + '::' : '') + (p?.text ?? '');
101
+ const list = node.childForFieldName('list');
102
+ for (const c of list?.namedChildren ?? []) flattenUse(c, np, out);
103
+ break;
104
+ }
105
+ case 'use_list':
106
+ for (const c of node.namedChildren) flattenUse(c, prefix, out);
107
+ break;
108
+ default: break;
109
+ }
110
+ }
111
+
112
+ function parseImport(node) {
113
+ const arg = node.childForFieldName('argument');
114
+ const out = [];
115
+ if (arg) flattenUse(arg, '', out);
116
+ return out;
117
+ }
118
+
119
+ function visibility(node) {
120
+ const v = node.namedChildren.find(c => c.type === 'visibility_modifier');
121
+ return v ? 'public' : 'private';
122
+ }
123
+
124
+ export const rust = {
125
+ id: 'rust',
126
+ grammar: 'rust',
127
+ extensions: ['.rs'],
128
+ family: 'rust',
129
+ query: QUERY,
130
+ implicitThis: false,
131
+ selfNames: ['self'],
132
+ externalReceivers: new Set(['std', 'core', 'alloc', 'fmt', 'io', 'mem', 'ptr', 'env', 'fs', 'thread', 'log', 'tracing']),
133
+ builtinCalls: BUILTIN_MACROS,
134
+ testFile: /(^|\/)(tests|benches)\/|_test\.rs$/,
135
+ commentTypes: ['line_comment', 'block_comment'],
136
+ skipBeforeDoc: new Set(['attribute_item', 'inner_attribute_item']),
137
+ parseImport,
138
+ ownerOf: implOwner,
139
+ refineKind(kind, d, parent) {
140
+ if (kind === 'function' && implOwner(d.node)) return 'method';
141
+ return kind;
142
+ },
143
+ isExported: (node) => node.namedChildren.some(c => c.type === 'visibility_modifier') || node.parent?.parent?.type === 'trait_item',
144
+ visibility,
145
+ isPrimitiveType: (t) => PRIMITIVES.has(t),
146
+ transparentTypes: new Set(['Box', 'Rc', 'Arc', 'Cow', 'RefCell', 'Cell', 'Mutex', 'RwLock', 'MutexGuard', 'RwLockReadGuard', 'RwLockWriteGuard', 'Ref', 'RefMut', 'Pin', 'Option', 'Result', 'Weak']),
147
+ elementTypes: new Set(['Vec', 'VecDeque', 'HashSet', 'BTreeSet', 'BinaryHeap', 'LinkedList', 'IntoIter', 'Iter', 'IterMut', 'Drain']),
148
+ elementMethods: new Set(['first', 'last', 'get', 'get_mut', 'first_mut', 'last_mut', 'pop', 'pop_front', 'pop_back', 'front', 'back', 'remove', 'swap_remove', 'next', 'peek', 'find']),
149
+ mapTypes: new Set(['HashMap', 'BTreeMap', 'IndexMap', 'DashMap']),
150
+ mapMethods: new Set(['get', 'get_mut', 'remove', 'insert']),
151
+ mapValueMethods: new Set(['values', 'values_mut', 'into_values']),
152
+ // calls that hand back (a view of) the same value: unwrap, clone, borrow, lock, iter …
153
+ identityMethods: new Set(['unwrap', 'expect', 'unwrap_or_default', 'unwrap_or', 'unwrap_or_else', 'as_ref', 'as_mut', 'as_deref', 'as_deref_mut',
154
+ 'clone', 'borrow', 'borrow_mut', 'lock', 'read', 'write', 'to_owned', 'deref', 'deref_mut', 'cloned', 'copied', 'iter', 'iter_mut', 'into_iter', 'drain', 'upgrade']),
155
+ normalizeRefName: (name, r) => (r.node.type === 'macro_invocation' ? (BUILTIN_MACROS.has(name) ? null : name) : name),
156
+ bodyField: 'body',
157
+ };