gitnexus 1.6.6-rc.2 → 1.6.6-rc.21
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.
- package/dist/_shared/index.d.ts +1 -1
- package/dist/_shared/index.d.ts.map +1 -1
- package/dist/_shared/index.js.map +1 -1
- package/dist/_shared/scope-resolution/reference-site.d.ts +8 -0
- package/dist/_shared/scope-resolution/reference-site.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/registries/context.d.ts +18 -1
- package/dist/_shared/scope-resolution/registries/context.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/registries/context.js.map +1 -1
- package/dist/_shared/scope-resolution/registries/lookup-core.d.ts +4 -2
- package/dist/_shared/scope-resolution/registries/lookup-core.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/registries/lookup-core.js +8 -23
- package/dist/_shared/scope-resolution/registries/lookup-core.js.map +1 -1
- package/dist/cli/analyze.js +65 -3
- package/dist/cli/eval-server.d.ts +14 -3
- package/dist/cli/eval-server.js +79 -9
- package/dist/cli/index.js +3 -1
- package/dist/cli/serve.js +6 -1
- package/dist/cli/setup.js +6 -4
- package/dist/cli/wiki.d.ts +1 -0
- package/dist/cli/wiki.js +32 -8
- package/dist/core/ingestion/languages/cpp/captures.js +165 -9
- package/dist/core/ingestion/languages/cpp/constraint-filter.js +102 -32
- package/dist/core/ingestion/languages/cpp/type-classifier.d.ts +9 -9
- package/dist/core/ingestion/languages/cpp/type-classifier.js +12 -8
- package/dist/core/ingestion/languages/java.js +35 -0
- package/dist/core/ingestion/languages/javascript/arity.d.ts +11 -0
- package/dist/core/ingestion/languages/javascript/arity.js +11 -0
- package/dist/core/ingestion/languages/javascript/captures.d.ts +30 -0
- package/dist/core/ingestion/languages/javascript/captures.js +655 -0
- package/dist/core/ingestion/languages/javascript/import-target.d.ts +29 -0
- package/dist/core/ingestion/languages/javascript/import-target.js +53 -0
- package/dist/core/ingestion/languages/javascript/index.d.ts +48 -0
- package/dist/core/ingestion/languages/javascript/index.js +48 -0
- package/dist/core/ingestion/languages/javascript/interpret.d.ts +29 -0
- package/dist/core/ingestion/languages/javascript/interpret.js +41 -0
- package/dist/core/ingestion/languages/javascript/merge-bindings.d.ts +16 -0
- package/dist/core/ingestion/languages/javascript/merge-bindings.js +18 -0
- package/dist/core/ingestion/languages/javascript/query.d.ts +52 -0
- package/dist/core/ingestion/languages/javascript/query.js +413 -0
- package/dist/core/ingestion/languages/javascript/scope-resolver.d.ts +37 -0
- package/dist/core/ingestion/languages/javascript/scope-resolver.js +73 -0
- package/dist/core/ingestion/languages/javascript/simple-hooks.d.ts +32 -0
- package/dist/core/ingestion/languages/javascript/simple-hooks.js +37 -0
- package/dist/core/ingestion/languages/typescript/simple-hooks.d.ts +10 -0
- package/dist/core/ingestion/languages/typescript/simple-hooks.js +4 -1
- package/dist/core/ingestion/languages/typescript.js +15 -0
- package/dist/core/ingestion/model/field-registry.d.ts +17 -3
- package/dist/core/ingestion/model/field-registry.js +19 -4
- package/dist/core/ingestion/model/owned-members-lookup.d.ts +19 -0
- package/dist/core/ingestion/model/owned-members-lookup.js +43 -0
- package/dist/core/ingestion/model/type-registry.d.ts +9 -0
- package/dist/core/ingestion/model/type-registry.js +18 -0
- package/dist/core/ingestion/registry-primary-flag.js +1 -0
- package/dist/core/ingestion/resolve-references.d.ts +3 -1
- package/dist/core/ingestion/resolve-references.js +5 -1
- package/dist/core/ingestion/scope-extractor.js +4 -0
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +1 -0
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +37 -7
- package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.d.ts +2 -0
- package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.js +8 -1
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +2 -0
- package/dist/core/ingestion/scope-resolution/pipeline/reconcile-ownership.d.ts +4 -2
- package/dist/core/ingestion/scope-resolution/pipeline/reconcile-ownership.js +48 -9
- package/dist/core/ingestion/scope-resolution/pipeline/registry.js +2 -0
- package/dist/core/ingestion/scope-resolution/pipeline/run.js +2 -0
- package/dist/core/lbug/lbug-adapter.d.ts +3 -1
- package/dist/core/lbug/lbug-adapter.js +33 -19
- package/dist/core/lbug/lbug-config.d.ts +1 -1
- package/dist/core/lbug/lbug-config.js +1 -1
- package/dist/core/lbug/pool-adapter.d.ts +19 -7
- package/dist/core/lbug/pool-adapter.js +70 -44
- package/dist/core/lbug/query-params.d.ts +1 -0
- package/dist/core/lbug/query-params.js +21 -0
- package/dist/core/search/bm25-index.js +4 -6
- package/dist/core/wiki/generator.d.ts +13 -0
- package/dist/core/wiki/generator.js +45 -4
- package/dist/core/wiki/llm-client.d.ts +1 -1
- package/dist/core/wiki/llm-client.js +23 -6
- package/dist/mcp/local/local-backend.d.ts +18 -3
- package/dist/mcp/local/local-backend.js +127 -11
- package/dist/mcp/tools.js +10 -0
- package/dist/server/api.d.ts +3 -0
- package/dist/server/api.js +58 -30
- package/package.json +3 -3
- package/web/assets/agent-SmDhIVj9.js +608 -0
- package/web/assets/{architectureDiagram-UL44E2DR-DvIkEGkp.js → architectureDiagram-UL44E2DR-ChS6kfgC.js} +1 -1
- package/web/assets/{chunk-LCXTWHL2-CqJ0oo1x.js → chunk-LCXTWHL2-CikfiTEP.js} +1 -1
- package/web/assets/{chunk-RG4AUYOV-D0M6vdq9.js → chunk-RG4AUYOV-D0pH0sP0.js} +1 -1
- package/web/assets/{classDiagram-KGZ6W3CR-BB-saqC1.js → classDiagram-KGZ6W3CR-VJjLBrQ3.js} +1 -1
- package/web/assets/{classDiagram-v2-72OJOZXJ-Bp2bAlS5.js → classDiagram-v2-72OJOZXJ-CL_v399n.js} +1 -1
- package/web/assets/{diagram-3NCE3AQN-BUxnDPOY.js → diagram-3NCE3AQN-DTTuOnDj.js} +1 -1
- package/web/assets/{diagram-GF46GFSD-BJTyqqvI.js → diagram-GF46GFSD-Di3e_png.js} +1 -1
- package/web/assets/{diagram-QXG6HAR7-DilMHamP.js → diagram-QXG6HAR7-CVQY1hhk.js} +1 -1
- package/web/assets/{diagram-WEQXMOUZ-8KUrarg1.js → diagram-WEQXMOUZ-BoxS7CN3.js} +1 -1
- package/web/assets/{erDiagram-L5TCEMPS-Doj9mSiW.js → erDiagram-L5TCEMPS-CLTuHusW.js} +1 -1
- package/web/assets/{flowDiagram-H6V6AXG4-BOSR-i3p.js → flowDiagram-H6V6AXG4-CQfVb2C4.js} +1 -1
- package/web/assets/{index-j4-NuleT.js → index-BuC2I_Cj.js} +5 -5
- package/web/assets/{infoDiagram-3YFTVSEB-Ce_TvtaV.js → infoDiagram-3YFTVSEB-BOk6LlXV.js} +1 -1
- package/web/assets/{ishikawaDiagram-BNXS4ZKH-4MXIDCSF.js → ishikawaDiagram-BNXS4ZKH-C0sASGB6.js} +1 -1
- package/web/assets/{kanban-definition-75IXJCU3-yYdfm8Kk.js → kanban-definition-75IXJCU3-DT9Lizpz.js} +1 -1
- package/web/assets/{mindmap-definition-2TDM6QVE-DFNEKM77.js → mindmap-definition-2TDM6QVE-BEYaB7hb.js} +1 -1
- package/web/assets/{pieDiagram-CU6KROY3-iZAqpvhd.js → pieDiagram-CU6KROY3-DCgHNkyY.js} +1 -1
- package/web/assets/{requirementDiagram-JXO7QTGE-CtDijhnf.js → requirementDiagram-JXO7QTGE-D6vDU9M2.js} +1 -1
- package/web/assets/{sequenceDiagram-VS2MUI6T-BdjvyCHM.js → sequenceDiagram-VS2MUI6T-CJrGCTXy.js} +1 -1
- package/web/assets/{stateDiagram-7D4R322I-e5odN9fG.js → stateDiagram-7D4R322I-BvxQnQyL.js} +1 -1
- package/web/assets/{stateDiagram-v2-36443NZ5-vPsvjR2D.js → stateDiagram-v2-36443NZ5-D8ziO9W2.js} +1 -1
- package/web/assets/{timeline-definition-O6YCAMPW-DPAksNQp.js → timeline-definition-O6YCAMPW-B45j2q3m.js} +1 -1
- package/web/assets/{vennDiagram-MWXL3ELB-Dtlfdt7J.js → vennDiagram-MWXL3ELB-CRkZRDhi.js} +1 -1
- package/web/assets/{wardleyDiagram-CUQ6CDDI-B23uRMUC.js → wardleyDiagram-CUQ6CDDI-BekUytZJ.js} +1 -1
- package/web/assets/{xychartDiagram-N2JHSOCM-DxwHeksW.js → xychartDiagram-N2JHSOCM-BeMqwSgr.js} +1 -1
- package/web/index.html +1 -1
- package/web/assets/agent-D2kLt6Dl.js +0 -597
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tree-sitter query for JavaScript scope captures (RFC §5.1, Ring 3).
|
|
3
|
+
*
|
|
4
|
+
* Subset of the TypeScript scope query (`languages/typescript/query.ts`)
|
|
5
|
+
* compiled against `tree-sitter-javascript`. TypeScript-only node types
|
|
6
|
+
* (`interface_declaration`, `type_alias_declaration`, `enum_declaration`,
|
|
7
|
+
* `internal_module`, `abstract_class_declaration`, `function_signature`,
|
|
8
|
+
* `method_signature`, `abstract_method_signature`, `type_annotation`,
|
|
9
|
+
* `public_field_definition`) are dropped because:
|
|
10
|
+
*
|
|
11
|
+
* 1. The JS grammar doesn't define them — the query compiler would
|
|
12
|
+
* throw `InvalidNodeType` if they were included.
|
|
13
|
+
* 2. JavaScript has no static type annotations, so the `@type-binding.*`
|
|
14
|
+
* patterns derived from TS annotation nodes don't apply.
|
|
15
|
+
*
|
|
16
|
+
* What IS shared with the TypeScript query:
|
|
17
|
+
*
|
|
18
|
+
* - Scope patterns: `program`, `class_declaration`, `(class)` (the JS
|
|
19
|
+
* grammar node for class expressions — NOT `class_expression`, which
|
|
20
|
+
* does not exist in `tree-sitter-javascript`), `function_declaration`,
|
|
21
|
+
* `generator_function_declaration`, `function_expression`,
|
|
22
|
+
* `arrow_function`, `method_definition`.
|
|
23
|
+
* - Declaration patterns for functions, classes, const/let/var,
|
|
24
|
+
* object-property arrows (Zustand, TanStack, etc.), and HOC-wrapped
|
|
25
|
+
* variable declarations (forwardRef / memo / useCallback / useMemo).
|
|
26
|
+
* - Import patterns: `import_statement`, `export_statement` re-exports,
|
|
27
|
+
* and dynamic `import()` (represented as `call_expression(import)` in
|
|
28
|
+
* both grammars — the `import` leaf node exists in tree-sitter-javascript
|
|
29
|
+
* as well as tree-sitter-typescript).
|
|
30
|
+
* - Type-binding patterns that work without static annotations:
|
|
31
|
+
* constructor inference (`new User()`), call-result alias
|
|
32
|
+
* (`const u = getUser()`), member-access alias (`const a = u.addr`),
|
|
33
|
+
* identifier alias, assignment rebind, and for-of element bindings.
|
|
34
|
+
* JSDoc-derived type bindings (`@param {User} u`, `@returns {User}`)
|
|
35
|
+
* are handled separately in `captures.ts` via comment-node scanning.
|
|
36
|
+
* - Reference patterns: free calls, member calls, constructor calls,
|
|
37
|
+
* write-access, read-access, and dynamic import.
|
|
38
|
+
*
|
|
39
|
+
* CJS `require()` is NOT captured here; it is handled in `captures.ts`
|
|
40
|
+
* by scanning parent context (destructured vs. namespace) of `call_expression`
|
|
41
|
+
* nodes whose callee is the identifier `require`.
|
|
42
|
+
*
|
|
43
|
+
* Grammar version: `tree-sitter-javascript` pinned in gitnexus/package.json.
|
|
44
|
+
*
|
|
45
|
+
* Exposes lazy `Parser` and `Query` singletons so callers don't pay
|
|
46
|
+
* tree-sitter init cost per file.
|
|
47
|
+
*/
|
|
48
|
+
import Parser from 'tree-sitter';
|
|
49
|
+
import JS from 'tree-sitter-javascript';
|
|
50
|
+
const JS_GRAMMAR = JS;
|
|
51
|
+
/** True when the file should be parsed with the JSX-extended query. */
|
|
52
|
+
function isJsxFile(filePath) {
|
|
53
|
+
return filePath.endsWith('.jsx');
|
|
54
|
+
}
|
|
55
|
+
const JAVASCRIPT_SCOPE_QUERY = `
|
|
56
|
+
;; Scopes — module / class-likes / function-likes
|
|
57
|
+
(program) @scope.module
|
|
58
|
+
|
|
59
|
+
(class_declaration) @scope.class
|
|
60
|
+
(class) @scope.class
|
|
61
|
+
|
|
62
|
+
(function_declaration) @scope.function
|
|
63
|
+
(generator_function_declaration) @scope.function
|
|
64
|
+
(function_expression) @scope.function
|
|
65
|
+
(arrow_function) @scope.function
|
|
66
|
+
(method_definition) @scope.function
|
|
67
|
+
|
|
68
|
+
;; Declarations — classes
|
|
69
|
+
(class_declaration
|
|
70
|
+
name: (identifier) @declaration.name) @declaration.class
|
|
71
|
+
|
|
72
|
+
;; Declarations — methods (inside class bodies)
|
|
73
|
+
(method_definition
|
|
74
|
+
name: (property_identifier) @declaration.name) @declaration.method
|
|
75
|
+
|
|
76
|
+
;; Declarations — class fields (JS uses field_definition, not public_field_definition)
|
|
77
|
+
(field_definition
|
|
78
|
+
property: (property_identifier) @declaration.name) @declaration.property
|
|
79
|
+
|
|
80
|
+
;; Declarations — free functions
|
|
81
|
+
(function_declaration
|
|
82
|
+
name: (identifier) @declaration.name) @declaration.function
|
|
83
|
+
|
|
84
|
+
(generator_function_declaration
|
|
85
|
+
name: (identifier) @declaration.name) @declaration.function
|
|
86
|
+
|
|
87
|
+
;; Arrow / function-expression assigned to a const/let/var.
|
|
88
|
+
;; Anchor discipline: @declaration.function sits on the INNER arrow or
|
|
89
|
+
;; function_expression, NOT on the lexical_declaration wrapper. This
|
|
90
|
+
;; aligns anchor.range with the @scope.function range so
|
|
91
|
+
;; pass2AttachDeclarations resolves the innermost scope correctly and
|
|
92
|
+
;; resolveCallerGraphId walks up to the right caller anchor.
|
|
93
|
+
(lexical_declaration
|
|
94
|
+
(variable_declarator
|
|
95
|
+
name: (identifier) @declaration.name
|
|
96
|
+
value: (arrow_function) @declaration.function))
|
|
97
|
+
|
|
98
|
+
(lexical_declaration
|
|
99
|
+
(variable_declarator
|
|
100
|
+
name: (identifier) @declaration.name
|
|
101
|
+
value: (function_expression) @declaration.function))
|
|
102
|
+
|
|
103
|
+
(export_statement
|
|
104
|
+
declaration: (lexical_declaration
|
|
105
|
+
(variable_declarator
|
|
106
|
+
name: (identifier) @declaration.name
|
|
107
|
+
value: (arrow_function) @declaration.function)))
|
|
108
|
+
|
|
109
|
+
(export_statement
|
|
110
|
+
declaration: (lexical_declaration
|
|
111
|
+
(variable_declarator
|
|
112
|
+
name: (identifier) @declaration.name
|
|
113
|
+
value: (function_expression) @declaration.function)))
|
|
114
|
+
|
|
115
|
+
(variable_declaration
|
|
116
|
+
(variable_declarator
|
|
117
|
+
name: (identifier) @declaration.name
|
|
118
|
+
value: (arrow_function) @declaration.function))
|
|
119
|
+
|
|
120
|
+
(variable_declaration
|
|
121
|
+
(variable_declarator
|
|
122
|
+
name: (identifier) @declaration.name
|
|
123
|
+
value: (function_expression) @declaration.function))
|
|
124
|
+
|
|
125
|
+
;; Object-property arrows / function expressions named by their pair key.
|
|
126
|
+
;; Same anchor discipline as the lexical_declaration block above: the
|
|
127
|
+
;; @declaration.function capture must sit on the INNER arrow/fn-expression.
|
|
128
|
+
(pair
|
|
129
|
+
key: (property_identifier) @declaration.name
|
|
130
|
+
value: (arrow_function) @declaration.function)
|
|
131
|
+
|
|
132
|
+
(pair
|
|
133
|
+
key: (property_identifier) @declaration.name
|
|
134
|
+
value: (function_expression) @declaration.function)
|
|
135
|
+
|
|
136
|
+
(pair
|
|
137
|
+
key: (string (string_fragment) @declaration.name)
|
|
138
|
+
value: (arrow_function) @declaration.function)
|
|
139
|
+
|
|
140
|
+
(pair
|
|
141
|
+
key: (string (string_fragment) @declaration.name)
|
|
142
|
+
value: (function_expression) @declaration.function)
|
|
143
|
+
|
|
144
|
+
;; HOC-wrapped variable declarations: const X = HOC((args) => { ... }).
|
|
145
|
+
;; Covers React.forwardRef, memo, useCallback, useMemo, observer,
|
|
146
|
+
;; debounce, and any user-defined HOC factory.
|
|
147
|
+
(lexical_declaration
|
|
148
|
+
(variable_declarator
|
|
149
|
+
name: (identifier) @declaration.name
|
|
150
|
+
value: (call_expression
|
|
151
|
+
arguments: (arguments
|
|
152
|
+
(arrow_function) @declaration.function))))
|
|
153
|
+
|
|
154
|
+
(lexical_declaration
|
|
155
|
+
(variable_declarator
|
|
156
|
+
name: (identifier) @declaration.name
|
|
157
|
+
value: (call_expression
|
|
158
|
+
arguments: (arguments
|
|
159
|
+
(function_expression) @declaration.function))))
|
|
160
|
+
|
|
161
|
+
(export_statement
|
|
162
|
+
declaration: (lexical_declaration
|
|
163
|
+
(variable_declarator
|
|
164
|
+
name: (identifier) @declaration.name
|
|
165
|
+
value: (call_expression
|
|
166
|
+
arguments: (arguments
|
|
167
|
+
(arrow_function) @declaration.function)))))
|
|
168
|
+
|
|
169
|
+
(export_statement
|
|
170
|
+
declaration: (lexical_declaration
|
|
171
|
+
(variable_declarator
|
|
172
|
+
name: (identifier) @declaration.name
|
|
173
|
+
value: (call_expression
|
|
174
|
+
arguments: (arguments
|
|
175
|
+
(function_expression) @declaration.function)))))
|
|
176
|
+
|
|
177
|
+
(variable_declaration
|
|
178
|
+
(variable_declarator
|
|
179
|
+
name: (identifier) @declaration.name
|
|
180
|
+
value: (call_expression
|
|
181
|
+
arguments: (arguments
|
|
182
|
+
(arrow_function) @declaration.function))))
|
|
183
|
+
|
|
184
|
+
(variable_declaration
|
|
185
|
+
(variable_declarator
|
|
186
|
+
name: (identifier) @declaration.name
|
|
187
|
+
value: (call_expression
|
|
188
|
+
arguments: (arguments
|
|
189
|
+
(function_expression) @declaration.function))))
|
|
190
|
+
|
|
191
|
+
;; Variable / constant declarations (non-function values).
|
|
192
|
+
(lexical_declaration
|
|
193
|
+
(variable_declarator
|
|
194
|
+
name: (identifier) @declaration.name)) @declaration.const
|
|
195
|
+
|
|
196
|
+
(export_statement
|
|
197
|
+
declaration: (lexical_declaration
|
|
198
|
+
(variable_declarator
|
|
199
|
+
name: (identifier) @declaration.name))) @declaration.const
|
|
200
|
+
|
|
201
|
+
(variable_declaration
|
|
202
|
+
(variable_declarator
|
|
203
|
+
name: (identifier) @declaration.name)) @declaration.variable
|
|
204
|
+
|
|
205
|
+
;; Imports (ESM) — single anchor per statement; decomposer emits per-specifier markers.
|
|
206
|
+
(import_statement) @import.statement
|
|
207
|
+
|
|
208
|
+
;; Re-exports with a source clause.
|
|
209
|
+
(export_statement
|
|
210
|
+
source: (string)) @import.statement
|
|
211
|
+
|
|
212
|
+
;; Dynamic imports: import('./m') — tree-sitter-javascript represents this
|
|
213
|
+
;; as call_expression with a named import leaf as the function field,
|
|
214
|
+
;; identical to tree-sitter-typescript.
|
|
215
|
+
(call_expression
|
|
216
|
+
function: (import)) @import.dynamic
|
|
217
|
+
|
|
218
|
+
;; ── Type bindings (no static annotations in JS; inferred from AST shape) ──
|
|
219
|
+
|
|
220
|
+
;; Constructor-inferred: const u = new User()
|
|
221
|
+
(variable_declarator
|
|
222
|
+
name: (identifier) @type-binding.name
|
|
223
|
+
value: (new_expression
|
|
224
|
+
constructor: (identifier) @type-binding.type)) @type-binding.constructor
|
|
225
|
+
|
|
226
|
+
;; Qualified constructor: const u = new models.User()
|
|
227
|
+
(variable_declarator
|
|
228
|
+
name: (identifier) @type-binding.name
|
|
229
|
+
value: (new_expression
|
|
230
|
+
constructor: (member_expression) @type-binding.type)) @type-binding.constructor
|
|
231
|
+
|
|
232
|
+
;; Call-result alias: const u = getUser()
|
|
233
|
+
(variable_declarator
|
|
234
|
+
name: (identifier) @type-binding.name
|
|
235
|
+
value: (call_expression
|
|
236
|
+
function: (identifier) @type-binding.type)) @type-binding.alias
|
|
237
|
+
|
|
238
|
+
;; Member-call alias: const u = svc.getUser()
|
|
239
|
+
(variable_declarator
|
|
240
|
+
name: (identifier) @type-binding.name
|
|
241
|
+
value: (call_expression
|
|
242
|
+
function: (member_expression) @type-binding.type)) @type-binding.alias
|
|
243
|
+
|
|
244
|
+
;; Await chain: const u = await getUser() / await svc.getUser()
|
|
245
|
+
(variable_declarator
|
|
246
|
+
name: (identifier) @type-binding.name
|
|
247
|
+
value: (await_expression
|
|
248
|
+
(call_expression
|
|
249
|
+
function: (identifier) @type-binding.type))) @type-binding.alias
|
|
250
|
+
|
|
251
|
+
(variable_declarator
|
|
252
|
+
name: (identifier) @type-binding.name
|
|
253
|
+
value: (await_expression
|
|
254
|
+
(call_expression
|
|
255
|
+
function: (member_expression) @type-binding.type))) @type-binding.alias
|
|
256
|
+
|
|
257
|
+
;; Member-access alias: const addr = user.address
|
|
258
|
+
(variable_declarator
|
|
259
|
+
name: (identifier) @type-binding.name
|
|
260
|
+
value: (member_expression) @type-binding.type) @type-binding.member-alias
|
|
261
|
+
|
|
262
|
+
;; Identifier alias: const alias = user
|
|
263
|
+
(variable_declarator
|
|
264
|
+
name: (identifier) @type-binding.name
|
|
265
|
+
value: (identifier) @type-binding.type) @type-binding.alias
|
|
266
|
+
|
|
267
|
+
;; Assignment rebind: u = new User() / u = getUser()
|
|
268
|
+
(assignment_expression
|
|
269
|
+
left: (identifier) @type-binding.name
|
|
270
|
+
right: (new_expression
|
|
271
|
+
constructor: (identifier) @type-binding.type)) @type-binding.constructor
|
|
272
|
+
|
|
273
|
+
(assignment_expression
|
|
274
|
+
left: (identifier) @type-binding.name
|
|
275
|
+
right: (call_expression
|
|
276
|
+
function: (identifier) @type-binding.type)) @type-binding.alias
|
|
277
|
+
|
|
278
|
+
(assignment_expression
|
|
279
|
+
left: (identifier) @type-binding.name
|
|
280
|
+
right: (identifier) @type-binding.type) @type-binding.alias
|
|
281
|
+
|
|
282
|
+
;; For-of element: for (const u of users) / for (const u of getUsers())
|
|
283
|
+
(for_in_statement
|
|
284
|
+
left: (identifier) @type-binding.name
|
|
285
|
+
right: (identifier) @type-binding.type) @type-binding.alias
|
|
286
|
+
|
|
287
|
+
(for_in_statement
|
|
288
|
+
left: (identifier) @type-binding.name
|
|
289
|
+
right: (call_expression
|
|
290
|
+
function: (identifier) @type-binding.type)) @type-binding.alias
|
|
291
|
+
|
|
292
|
+
(for_in_statement
|
|
293
|
+
left: (identifier) @type-binding.name
|
|
294
|
+
right: (call_expression
|
|
295
|
+
function: (member_expression) @type-binding.type)) @type-binding.alias
|
|
296
|
+
|
|
297
|
+
(for_in_statement
|
|
298
|
+
left: (identifier) @type-binding.name
|
|
299
|
+
right: (member_expression
|
|
300
|
+
property: (property_identifier) @type-binding.type)) @type-binding.alias
|
|
301
|
+
|
|
302
|
+
;; ── References ────────────────────────────────────────────────────────────
|
|
303
|
+
|
|
304
|
+
;; Free calls: fn(args). The dynamic-import filter runs in captures.ts.
|
|
305
|
+
(call_expression
|
|
306
|
+
function: (identifier) @reference.name) @reference.call.free
|
|
307
|
+
|
|
308
|
+
;; Awaited free call: await fn<T>(...) re-associated by tree-sitter.
|
|
309
|
+
(call_expression
|
|
310
|
+
function: (await_expression
|
|
311
|
+
(identifier) @reference.name)) @reference.call.free
|
|
312
|
+
|
|
313
|
+
;; Member calls: obj.method() (includes optional chain).
|
|
314
|
+
(call_expression
|
|
315
|
+
function: (member_expression
|
|
316
|
+
object: (_) @reference.receiver
|
|
317
|
+
property: (property_identifier) @reference.name)) @reference.call.member
|
|
318
|
+
|
|
319
|
+
;; Awaited member call: await svc.m<T>(...)
|
|
320
|
+
(call_expression
|
|
321
|
+
function: (await_expression
|
|
322
|
+
(member_expression
|
|
323
|
+
object: (_) @reference.receiver
|
|
324
|
+
property: (property_identifier) @reference.name))) @reference.call.member
|
|
325
|
+
|
|
326
|
+
;; Constructor calls: new User() / new ns.User()
|
|
327
|
+
(new_expression
|
|
328
|
+
constructor: (identifier) @reference.name) @reference.call.constructor
|
|
329
|
+
|
|
330
|
+
(new_expression
|
|
331
|
+
constructor: (member_expression) @reference.call.constructor.qualified) @reference.call.constructor
|
|
332
|
+
|
|
333
|
+
;; Write access: obj.field = value
|
|
334
|
+
(assignment_expression
|
|
335
|
+
left: (member_expression
|
|
336
|
+
object: (_) @reference.receiver
|
|
337
|
+
property: (property_identifier) @reference.name)) @reference.write.member
|
|
338
|
+
|
|
339
|
+
(augmented_assignment_expression
|
|
340
|
+
left: (member_expression
|
|
341
|
+
object: (_) @reference.receiver
|
|
342
|
+
property: (property_identifier) @reference.name)) @reference.write.member
|
|
343
|
+
|
|
344
|
+
;; Read access: obj.field (in read context; captures.ts filters non-reads).
|
|
345
|
+
(member_expression
|
|
346
|
+
object: (_) @reference.receiver
|
|
347
|
+
property: (property_identifier) @reference.name) @reference.read.member
|
|
348
|
+
`;
|
|
349
|
+
/** JSX-only suffix — appended when compiling against the JSX grammar for .jsx files. */
|
|
350
|
+
const JSX_QUERY_SUFFIX = `
|
|
351
|
+
;; <Foo />
|
|
352
|
+
((jsx_self_closing_element
|
|
353
|
+
name: (identifier) @reference.name) @reference.call.free
|
|
354
|
+
(#match? @reference.name "^[A-Z]"))
|
|
355
|
+
|
|
356
|
+
;; <Foo> ... </Foo>
|
|
357
|
+
((jsx_opening_element
|
|
358
|
+
name: (identifier) @reference.name) @reference.call.free
|
|
359
|
+
(#match? @reference.name "^[A-Z]"))
|
|
360
|
+
|
|
361
|
+
;; <Foo.Bar />
|
|
362
|
+
(jsx_self_closing_element
|
|
363
|
+
name: (member_expression
|
|
364
|
+
object: (_) @reference.receiver
|
|
365
|
+
property: (property_identifier) @reference.name)) @reference.call.member
|
|
366
|
+
|
|
367
|
+
(jsx_opening_element
|
|
368
|
+
name: (member_expression
|
|
369
|
+
object: (_) @reference.receiver
|
|
370
|
+
property: (property_identifier) @reference.name)) @reference.call.member
|
|
371
|
+
`;
|
|
372
|
+
let _jsParser = null;
|
|
373
|
+
let _jsQuery = null;
|
|
374
|
+
let _jsxParser = null;
|
|
375
|
+
let _jsxQuery = null;
|
|
376
|
+
export function getJsParser(filePath) {
|
|
377
|
+
// JSX files use the same JavaScript grammar in tree-sitter-javascript;
|
|
378
|
+
// both .js and .jsx parse with the same grammar object. We keep separate
|
|
379
|
+
// singletons only to mirror the TypeScript pattern and in case a future
|
|
380
|
+
// version of the grammar diverges.
|
|
381
|
+
if (filePath !== undefined && isJsxFile(filePath)) {
|
|
382
|
+
if (_jsxParser === null) {
|
|
383
|
+
_jsxParser = new Parser();
|
|
384
|
+
_jsxParser.setLanguage(JS_GRAMMAR);
|
|
385
|
+
}
|
|
386
|
+
return _jsxParser;
|
|
387
|
+
}
|
|
388
|
+
if (_jsParser === null) {
|
|
389
|
+
_jsParser = new Parser();
|
|
390
|
+
_jsParser.setLanguage(JS_GRAMMAR);
|
|
391
|
+
}
|
|
392
|
+
return _jsParser;
|
|
393
|
+
}
|
|
394
|
+
export function getJsScopeQuery(filePath) {
|
|
395
|
+
if (filePath !== undefined && isJsxFile(filePath)) {
|
|
396
|
+
if (_jsxQuery === null) {
|
|
397
|
+
_jsxQuery = new Parser.Query(JS_GRAMMAR, JAVASCRIPT_SCOPE_QUERY + JSX_QUERY_SUFFIX);
|
|
398
|
+
}
|
|
399
|
+
return _jsxQuery;
|
|
400
|
+
}
|
|
401
|
+
if (_jsQuery === null) {
|
|
402
|
+
_jsQuery = new Parser.Query(JS_GRAMMAR, JAVASCRIPT_SCOPE_QUERY);
|
|
403
|
+
}
|
|
404
|
+
return _jsQuery;
|
|
405
|
+
}
|
|
406
|
+
/** Validate that a cached Tree was produced by the JS grammar. */
|
|
407
|
+
export function jsCachedTreeMatchesGrammar(tree) {
|
|
408
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
409
|
+
const lang = tree?.getLanguage?.();
|
|
410
|
+
if (lang === undefined || lang === null)
|
|
411
|
+
return true;
|
|
412
|
+
return lang === JS_GRAMMAR;
|
|
413
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JavaScript `ScopeResolver` registered in `SCOPE_RESOLVERS` and
|
|
3
|
+
* consumed by the generic `runScopeResolution` orchestrator
|
|
4
|
+
* (RFC #909 Ring 3, issue #928).
|
|
5
|
+
*
|
|
6
|
+
* Follows the same minimal wiring-only pattern as TypeScript (the third
|
|
7
|
+
* migration). Per-hook logic lives in sibling modules:
|
|
8
|
+
*
|
|
9
|
+
* - `query.ts` — JS scope query + parser/query singletons
|
|
10
|
+
* - `captures.ts` — `emitJsScopeCaptures` (JS grammar, CJS, JSDoc)
|
|
11
|
+
* - `interpret.ts` — `interpretJsImport` (delegates to TS interpreter)
|
|
12
|
+
* - `simple-hooks.ts` — `jsBindingScopeFor`, `jsImportOwningScope`,
|
|
13
|
+
* `jsReceiverBinding` (all delegate to TS hooks)
|
|
14
|
+
* - `merge-bindings.ts` — `jsMergeBindings` (delegates to TS function)
|
|
15
|
+
* - `arity.ts` — `jsArityCompatibility` (delegates to TS function)
|
|
16
|
+
* - `import-target.ts` — `makeJsResolveImportTarget` (TS resolver, JS extensions)
|
|
17
|
+
*
|
|
18
|
+
* See `./index.ts` for the full per-module rationale.
|
|
19
|
+
*
|
|
20
|
+
* ## Key differences from TypeScript resolver
|
|
21
|
+
*
|
|
22
|
+
* - `fieldFallbackOnMethodLookup: true` — JavaScript is dynamically typed;
|
|
23
|
+
* the field-fallback heuristic is ENABLED (unlike TypeScript, which
|
|
24
|
+
* disables it because the type-binding layer is precise).
|
|
25
|
+
* - `allowGlobalFreeCallFallback: true` — CJS `require` patterns and
|
|
26
|
+
* global helpers (e.g. `process`, `console`) benefit from workspace-
|
|
27
|
+
* wide unique-name fallback. TypeScript uses explicit imports.
|
|
28
|
+
* - `loadResolutionConfig` is omitted — JavaScript projects don't use
|
|
29
|
+
* `tsconfig.json` path aliases in general. `tsconfigPaths: null` is
|
|
30
|
+
* threaded through the resolver adapter.
|
|
31
|
+
* - `hoistTypeBindingsToModule: true` — JSDoc `@returns {T}` bindings are
|
|
32
|
+
* synthesized on the function scope and hoisted, matching TypeScript's
|
|
33
|
+
* method return-type hoisting strategy for cross-file chain resolution.
|
|
34
|
+
*/
|
|
35
|
+
import type { ScopeResolver } from '../../scope-resolution/contract/scope-resolver.js';
|
|
36
|
+
declare const javascriptScopeResolver: ScopeResolver;
|
|
37
|
+
export { javascriptScopeResolver };
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JavaScript `ScopeResolver` registered in `SCOPE_RESOLVERS` and
|
|
3
|
+
* consumed by the generic `runScopeResolution` orchestrator
|
|
4
|
+
* (RFC #909 Ring 3, issue #928).
|
|
5
|
+
*
|
|
6
|
+
* Follows the same minimal wiring-only pattern as TypeScript (the third
|
|
7
|
+
* migration). Per-hook logic lives in sibling modules:
|
|
8
|
+
*
|
|
9
|
+
* - `query.ts` — JS scope query + parser/query singletons
|
|
10
|
+
* - `captures.ts` — `emitJsScopeCaptures` (JS grammar, CJS, JSDoc)
|
|
11
|
+
* - `interpret.ts` — `interpretJsImport` (delegates to TS interpreter)
|
|
12
|
+
* - `simple-hooks.ts` — `jsBindingScopeFor`, `jsImportOwningScope`,
|
|
13
|
+
* `jsReceiverBinding` (all delegate to TS hooks)
|
|
14
|
+
* - `merge-bindings.ts` — `jsMergeBindings` (delegates to TS function)
|
|
15
|
+
* - `arity.ts` — `jsArityCompatibility` (delegates to TS function)
|
|
16
|
+
* - `import-target.ts` — `makeJsResolveImportTarget` (TS resolver, JS extensions)
|
|
17
|
+
*
|
|
18
|
+
* See `./index.ts` for the full per-module rationale.
|
|
19
|
+
*
|
|
20
|
+
* ## Key differences from TypeScript resolver
|
|
21
|
+
*
|
|
22
|
+
* - `fieldFallbackOnMethodLookup: true` — JavaScript is dynamically typed;
|
|
23
|
+
* the field-fallback heuristic is ENABLED (unlike TypeScript, which
|
|
24
|
+
* disables it because the type-binding layer is precise).
|
|
25
|
+
* - `allowGlobalFreeCallFallback: true` — CJS `require` patterns and
|
|
26
|
+
* global helpers (e.g. `process`, `console`) benefit from workspace-
|
|
27
|
+
* wide unique-name fallback. TypeScript uses explicit imports.
|
|
28
|
+
* - `loadResolutionConfig` is omitted — JavaScript projects don't use
|
|
29
|
+
* `tsconfig.json` path aliases in general. `tsconfigPaths: null` is
|
|
30
|
+
* threaded through the resolver adapter.
|
|
31
|
+
* - `hoistTypeBindingsToModule: true` — JSDoc `@returns {T}` bindings are
|
|
32
|
+
* synthesized on the function scope and hoisted, matching TypeScript's
|
|
33
|
+
* method return-type hoisting strategy for cross-file chain resolution.
|
|
34
|
+
*/
|
|
35
|
+
import { SupportedLanguages } from '../../../../_shared/index.js';
|
|
36
|
+
import { buildMro, defaultLinearize } from '../../scope-resolution/passes/mro.js';
|
|
37
|
+
import { populateClassOwnedMembers } from '../../scope-resolution/scope/walkers.js';
|
|
38
|
+
import { javascriptProvider } from '../typescript.js';
|
|
39
|
+
import { jsMergeBindings } from './merge-bindings.js';
|
|
40
|
+
import { jsArityCompatibility } from './arity.js';
|
|
41
|
+
import { makeJsResolveImportTarget } from './import-target.js';
|
|
42
|
+
const javascriptScopeResolver = {
|
|
43
|
+
language: SupportedLanguages.JavaScript,
|
|
44
|
+
languageProvider: javascriptProvider,
|
|
45
|
+
importEdgeReason: 'javascript-scope: import',
|
|
46
|
+
resolveImportTarget: makeJsResolveImportTarget(),
|
|
47
|
+
// JavaScript LEGB — same tier ordering as TypeScript; no declaration-
|
|
48
|
+
// merging across type/value/namespace spaces.
|
|
49
|
+
mergeBindings: (existing, incoming) => [...jsMergeBindings([...existing, ...incoming])],
|
|
50
|
+
// Adapter: jsArityCompatibility uses (def, callsite); contract is (callsite, def).
|
|
51
|
+
arityCompatibility: (callsite, def) => jsArityCompatibility(def, callsite),
|
|
52
|
+
buildMro: (graph, parsedFiles, nodeLookup) => buildMro(graph, parsedFiles, nodeLookup, defaultLinearize),
|
|
53
|
+
populateOwners: (parsed) => populateClassOwnedMembers(parsed),
|
|
54
|
+
// JavaScript `super` keyword: same pattern as TypeScript.
|
|
55
|
+
isSuperReceiver: (text) => /^super(\s*\(|\s*\.|\s*\[|\s*$)/.test(text.trim()),
|
|
56
|
+
// JavaScript is dynamically typed — enable the field-fallback heuristic
|
|
57
|
+
// so member-call receivers without type annotations can still resolve
|
|
58
|
+
// through declared class fields (e.g. JSDoc-typed fields).
|
|
59
|
+
fieldFallbackOnMethodLookup: true,
|
|
60
|
+
// Return-type propagation (across ESM imports) mirrors TypeScript's
|
|
61
|
+
// default behavior. JSDoc @returns bindings are hoisted to Module scope
|
|
62
|
+
// and propagated to importers via the standard mechanism.
|
|
63
|
+
propagatesReturnTypesAcrossImports: true,
|
|
64
|
+
// JSDoc @returns bindings are synthesized on the function/method node
|
|
65
|
+
// and hoisted to Module scope by `jsBindingScopeFor` (identical to the
|
|
66
|
+
// TypeScript `tsBindingScopeFor` `@type-binding.return` branch).
|
|
67
|
+
hoistTypeBindingsToModule: true,
|
|
68
|
+
// CJS-heavy codebases often have utility functions exported without
|
|
69
|
+
// explicit imports at the call site. Workspace-wide unique-name fallback
|
|
70
|
+
// recovers these edges.
|
|
71
|
+
allowGlobalFreeCallFallback: true,
|
|
72
|
+
};
|
|
73
|
+
export { javascriptScopeResolver };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple hooks for the JavaScript scope-resolution provider.
|
|
3
|
+
*
|
|
4
|
+
* `jsBindingScopeFor` wraps `tsBindingScopeFor` and adds the JS-only
|
|
5
|
+
* `@type-binding.class-field` hoisting rule. The other two hooks
|
|
6
|
+
* (`jsImportOwningScope`, `jsReceiverBinding`) are identical to their
|
|
7
|
+
* TypeScript counterparts and are re-exported directly.
|
|
8
|
+
*
|
|
9
|
+
* ## Why class-field hoisting lives here (not in `tsBindingScopeFor`)
|
|
10
|
+
*
|
|
11
|
+
* `@type-binding.class-field` is emitted exclusively by
|
|
12
|
+
* `synthesizeConstructorFieldBindings` in `captures.ts`, which is a
|
|
13
|
+
* JavaScript-only synthesis pass. TypeScript uses
|
|
14
|
+
* `@type-binding.parameter-property` for constructor parameter
|
|
15
|
+
* properties instead. Keeping the JS-only rule in the JS hook file
|
|
16
|
+
* prevents language-specific logic from leaking into shared TypeScript
|
|
17
|
+
* infrastructure (DoD.md §2.2).
|
|
18
|
+
*/
|
|
19
|
+
import type { CaptureMatch, Scope, ScopeId, ScopeTree } from '../../../../_shared/index.js';
|
|
20
|
+
export { tsImportOwningScope as jsImportOwningScope, tsReceiverBinding as jsReceiverBinding, } from '../typescript/simple-hooks.js';
|
|
21
|
+
/**
|
|
22
|
+
* Like `tsBindingScopeFor` but additionally hoists
|
|
23
|
+
* `@type-binding.class-field` captures to the enclosing Class scope.
|
|
24
|
+
*
|
|
25
|
+
* `@type-binding.class-field` is anchored inside the constructor body
|
|
26
|
+
* (by `synthesizeConstructorFieldBindings`) so that `walkToScope` can
|
|
27
|
+
* walk up from the Function (constructor) scope to the Class scope.
|
|
28
|
+
* This puts `User.address → Address` in the class's typeBindings so
|
|
29
|
+
* compound-receiver resolution finds it when resolving
|
|
30
|
+
* `user.address.save()`.
|
|
31
|
+
*/
|
|
32
|
+
export declare function jsBindingScopeFor(decl: CaptureMatch, innermost: Scope, tree: ScopeTree): ScopeId | null;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple hooks for the JavaScript scope-resolution provider.
|
|
3
|
+
*
|
|
4
|
+
* `jsBindingScopeFor` wraps `tsBindingScopeFor` and adds the JS-only
|
|
5
|
+
* `@type-binding.class-field` hoisting rule. The other two hooks
|
|
6
|
+
* (`jsImportOwningScope`, `jsReceiverBinding`) are identical to their
|
|
7
|
+
* TypeScript counterparts and are re-exported directly.
|
|
8
|
+
*
|
|
9
|
+
* ## Why class-field hoisting lives here (not in `tsBindingScopeFor`)
|
|
10
|
+
*
|
|
11
|
+
* `@type-binding.class-field` is emitted exclusively by
|
|
12
|
+
* `synthesizeConstructorFieldBindings` in `captures.ts`, which is a
|
|
13
|
+
* JavaScript-only synthesis pass. TypeScript uses
|
|
14
|
+
* `@type-binding.parameter-property` for constructor parameter
|
|
15
|
+
* properties instead. Keeping the JS-only rule in the JS hook file
|
|
16
|
+
* prevents language-specific logic from leaking into shared TypeScript
|
|
17
|
+
* infrastructure (DoD.md §2.2).
|
|
18
|
+
*/
|
|
19
|
+
import { tsBindingScopeFor, walkToScope } from '../typescript/simple-hooks.js';
|
|
20
|
+
export { tsImportOwningScope as jsImportOwningScope, tsReceiverBinding as jsReceiverBinding, } from '../typescript/simple-hooks.js';
|
|
21
|
+
/**
|
|
22
|
+
* Like `tsBindingScopeFor` but additionally hoists
|
|
23
|
+
* `@type-binding.class-field` captures to the enclosing Class scope.
|
|
24
|
+
*
|
|
25
|
+
* `@type-binding.class-field` is anchored inside the constructor body
|
|
26
|
+
* (by `synthesizeConstructorFieldBindings`) so that `walkToScope` can
|
|
27
|
+
* walk up from the Function (constructor) scope to the Class scope.
|
|
28
|
+
* This puts `User.address → Address` in the class's typeBindings so
|
|
29
|
+
* compound-receiver resolution finds it when resolving
|
|
30
|
+
* `user.address.save()`.
|
|
31
|
+
*/
|
|
32
|
+
export function jsBindingScopeFor(decl, innermost, tree) {
|
|
33
|
+
if (decl['@type-binding.class-field'] !== undefined) {
|
|
34
|
+
return walkToScope(innermost, tree, 'Class');
|
|
35
|
+
}
|
|
36
|
+
return tsBindingScopeFor(decl, innermost, tree);
|
|
37
|
+
}
|
|
@@ -26,6 +26,16 @@ import type { CaptureMatch, ParsedImport, Scope, ScopeId, ScopeTree, TypeRef } f
|
|
|
26
26
|
* propagation.
|
|
27
27
|
*/
|
|
28
28
|
export declare function tsBindingScopeFor(decl: CaptureMatch, innermost: Scope, tree: ScopeTree): ScopeId | null;
|
|
29
|
+
/**
|
|
30
|
+
* Walk up the scope chain to find the first scope whose `kind` matches
|
|
31
|
+
* any of `kinds`. Returns the matching scope's id or `null` when no
|
|
32
|
+
* ancestor matches (e.g., a return type binding emitted outside any
|
|
33
|
+
* Module scope — shouldn't happen in well-formed input).
|
|
34
|
+
*
|
|
35
|
+
* Exported so language-specific hook wrappers (e.g. `jsBindingScopeFor`)
|
|
36
|
+
* can reuse it without duplicating the traversal logic.
|
|
37
|
+
*/
|
|
38
|
+
export declare function walkToScope(from: Scope, tree: ScopeTree, ...kinds: readonly Scope['kind'][]): ScopeId | null;
|
|
29
39
|
/**
|
|
30
40
|
* TypeScript imports are syntactically top-level: `import_statement` is
|
|
31
41
|
* legal only inside `program` (the module root). `namespace X { … }`
|
|
@@ -56,8 +56,11 @@ export function tsBindingScopeFor(decl, innermost, tree) {
|
|
|
56
56
|
* any of `kinds`. Returns the matching scope's id or `null` when no
|
|
57
57
|
* ancestor matches (e.g., a return type binding emitted outside any
|
|
58
58
|
* Module scope — shouldn't happen in well-formed input).
|
|
59
|
+
*
|
|
60
|
+
* Exported so language-specific hook wrappers (e.g. `jsBindingScopeFor`)
|
|
61
|
+
* can reuse it without duplicating the traversal logic.
|
|
59
62
|
*/
|
|
60
|
-
function walkToScope(from, tree, ...kinds) {
|
|
63
|
+
export function walkToScope(from, tree, ...kinds) {
|
|
61
64
|
let cur = from;
|
|
62
65
|
const kindSet = new Set(kinds);
|
|
63
66
|
while (cur !== undefined) {
|
|
@@ -27,6 +27,7 @@ import { createCallExtractor } from '../call-extractors/generic.js';
|
|
|
27
27
|
import { typescriptCallConfig, javascriptCallConfig, } from '../call-extractors/configs/typescript-javascript.js';
|
|
28
28
|
import { createHeritageExtractor } from '../heritage-extractors/generic.js';
|
|
29
29
|
import { emitTsScopeCaptures, interpretTsImport, interpretTsTypeBinding, tsBindingScopeFor, tsImportOwningScope, tsReceiverBinding, typescriptMergeBindings, typescriptArityCompatibility, resolveTsImportTarget, } from './typescript/index.js';
|
|
30
|
+
import { emitJsScopeCaptures, interpretJsImport, interpretJsTypeBinding, jsBindingScopeFor, jsImportOwningScope, jsReceiverBinding, jsMergeBindings, jsArityCompatibility, } from './javascript/index.js';
|
|
30
31
|
/**
|
|
31
32
|
* TypeScript/JavaScript: arrow_function and function_expression are
|
|
32
33
|
* anonymous AST nodes — they take their name from the surrounding
|
|
@@ -321,4 +322,18 @@ export const javascriptProvider = defineLanguage({
|
|
|
321
322
|
classExtractor: createClassExtractor(javascriptClassConfig),
|
|
322
323
|
heritageExtractor: createHeritageExtractor(SupportedLanguages.JavaScript),
|
|
323
324
|
builtInNames: BUILT_INS,
|
|
325
|
+
// ── RFC #909 Ring 3: scope-based resolution hooks (RFC §5) ──────────
|
|
326
|
+
// JavaScript is the fourth migration after Python, C#, and TypeScript.
|
|
327
|
+
// Hooks are thin wrappers over the TypeScript implementations where
|
|
328
|
+
// semantics are identical; JS-specific additions (CJS require(),
|
|
329
|
+
// JSDoc type bindings) live in ./javascript/captures.ts.
|
|
330
|
+
// See ./javascript/index.ts for the full per-module rationale.
|
|
331
|
+
emitScopeCaptures: emitJsScopeCaptures,
|
|
332
|
+
interpretImport: interpretJsImport,
|
|
333
|
+
interpretTypeBinding: interpretJsTypeBinding,
|
|
334
|
+
bindingScopeFor: jsBindingScopeFor,
|
|
335
|
+
importOwningScope: jsImportOwningScope,
|
|
336
|
+
mergeBindings: (_scope, bindings) => jsMergeBindings(bindings),
|
|
337
|
+
receiverBinding: jsReceiverBinding,
|
|
338
|
+
arityCompatibility: jsArityCompatibility,
|
|
324
339
|
});
|