gitnexus 1.6.3-rc.40 → 1.6.3-rc.42
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/README.md +16 -0
- package/dist/_shared/scope-resolution/parsed-file.d.ts +12 -0
- package/dist/_shared/scope-resolution/parsed-file.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/parsed-file.js +12 -0
- package/dist/_shared/scope-resolution/parsed-file.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/cli/index.js +3 -1
- package/dist/config/ignore-service.d.ts +9 -0
- package/dist/config/ignore-service.js +80 -13
- package/dist/core/ingestion/language-provider.d.ts +3 -2
- package/dist/core/ingestion/languages/csharp/accessor-unwrap.d.ts +21 -0
- package/dist/core/ingestion/languages/csharp/accessor-unwrap.js +56 -0
- package/dist/core/ingestion/languages/csharp/arity-metadata.d.ts +26 -0
- package/dist/core/ingestion/languages/csharp/arity-metadata.js +46 -0
- package/dist/core/ingestion/languages/csharp/arity.d.ts +23 -0
- package/dist/core/ingestion/languages/csharp/arity.js +37 -0
- package/dist/core/ingestion/languages/csharp/cache-stats.d.ts +15 -0
- package/dist/core/ingestion/languages/csharp/cache-stats.js +26 -0
- package/dist/core/ingestion/languages/csharp/captures.d.ts +19 -0
- package/dist/core/ingestion/languages/csharp/captures.js +249 -0
- package/dist/core/ingestion/languages/csharp/import-decomposer.d.ts +19 -0
- package/dist/core/ingestion/languages/csharp/import-decomposer.js +93 -0
- package/dist/core/ingestion/languages/csharp/import-target.d.ts +25 -0
- package/dist/core/ingestion/languages/csharp/import-target.js +123 -0
- package/dist/core/ingestion/languages/csharp/index.d.ts +82 -0
- package/dist/core/ingestion/languages/csharp/index.js +82 -0
- package/dist/core/ingestion/languages/csharp/interpret.d.ts +15 -0
- package/dist/core/ingestion/languages/csharp/interpret.js +132 -0
- package/dist/core/ingestion/languages/csharp/merge-bindings.d.ts +27 -0
- package/dist/core/ingestion/languages/csharp/merge-bindings.js +55 -0
- package/dist/core/ingestion/languages/csharp/namespace-siblings.d.ts +50 -0
- package/dist/core/ingestion/languages/csharp/namespace-siblings.js +374 -0
- package/dist/core/ingestion/languages/csharp/query.d.ts +35 -0
- package/dist/core/ingestion/languages/csharp/query.js +515 -0
- package/dist/core/ingestion/languages/csharp/receiver-binding.d.ts +31 -0
- package/dist/core/ingestion/languages/csharp/receiver-binding.js +135 -0
- package/dist/core/ingestion/languages/csharp/scope-resolver.d.ts +10 -0
- package/dist/core/ingestion/languages/csharp/scope-resolver.js +63 -0
- package/dist/core/ingestion/languages/csharp/simple-hooks.d.ts +53 -0
- package/dist/core/ingestion/languages/csharp/simple-hooks.js +76 -0
- package/dist/core/ingestion/languages/csharp.js +14 -0
- package/dist/core/ingestion/languages/python/import-target.d.ts +4 -0
- package/dist/core/ingestion/languages/python/import-target.js +4 -0
- package/dist/core/ingestion/languages/python/merge-bindings.d.ts +2 -2
- package/dist/core/ingestion/languages/python/merge-bindings.js +1 -1
- package/dist/core/ingestion/languages/python/query.d.ts +1 -6
- package/dist/core/ingestion/languages/python/query.js +1 -6
- package/dist/core/ingestion/languages/python/receiver-binding.d.ts +3 -3
- package/dist/core/ingestion/languages/python/receiver-binding.js +3 -3
- package/dist/core/ingestion/languages/python/scope-resolver.js +15 -15
- package/dist/core/ingestion/languages/python.js +2 -2
- package/dist/core/ingestion/model/method-registry.d.ts +9 -0
- package/dist/core/ingestion/model/method-registry.js +4 -0
- package/dist/core/ingestion/model/semantic-model.d.ts +39 -0
- package/dist/core/ingestion/model/semantic-model.js +39 -0
- package/dist/core/ingestion/registry-primary-flag.js +1 -0
- package/dist/core/ingestion/scope-extractor.js +20 -0
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +216 -12
- package/dist/core/ingestion/scope-resolution/contract/scope-resolver.js +149 -12
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.d.ts +1 -1
- package/dist/core/ingestion/scope-resolution/graph-bridge/edges.js +9 -2
- package/dist/core/ingestion/scope-resolution/graph-bridge/ids.d.ts +1 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/ids.js +11 -0
- package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +12 -0
- package/dist/core/ingestion/scope-resolution/passes/compound-receiver.d.ts +10 -0
- package/dist/core/ingestion/scope-resolution/passes/compound-receiver.js +61 -0
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +3 -1
- package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +73 -3
- package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.d.ts +26 -0
- package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.js +61 -0
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +8 -4
- package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +164 -37
- package/dist/core/ingestion/scope-resolution/pipeline/phase.js +8 -1
- package/dist/core/ingestion/scope-resolution/pipeline/reconcile-ownership.d.ts +68 -0
- package/dist/core/ingestion/scope-resolution/pipeline/reconcile-ownership.js +125 -0
- package/dist/core/ingestion/scope-resolution/pipeline/registry.js +5 -1
- package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +11 -0
- package/dist/core/ingestion/scope-resolution/pipeline/run.js +33 -7
- package/dist/core/ingestion/scope-resolution/scope/walkers.d.ts +36 -9
- package/dist/core/ingestion/scope-resolution/scope/walkers.js +86 -24
- package/dist/core/ingestion/scope-resolution/workspace-index.d.ts +39 -33
- package/dist/core/ingestion/scope-resolution/workspace-index.js +39 -87
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -155,6 +155,7 @@ gitnexus analyze --force # Force full re-index
|
|
|
155
155
|
gitnexus analyze --embeddings # Enable embedding generation (slower, better search)
|
|
156
156
|
gitnexus analyze --skip-agents-md # Preserve custom AGENTS.md/CLAUDE.md gitnexus section edits
|
|
157
157
|
gitnexus analyze --verbose # Log skipped files when parsers are unavailable
|
|
158
|
+
gitnexus analyze --max-file-size 1024 # Skip files larger than N KB (default: 512, cap: 32768)
|
|
158
159
|
gitnexus mcp # Start MCP server (stdio) — serves all indexed repos
|
|
159
160
|
gitnexus serve # Start local HTTP server (multi-repo) for web UI
|
|
160
161
|
gitnexus index # Register an existing .gitnexus/ folder into the global registry
|
|
@@ -307,6 +308,21 @@ echo "vendor/" >> .gitnexusignore
|
|
|
307
308
|
echo "dist/" >> .gitnexusignore
|
|
308
309
|
```
|
|
309
310
|
|
|
311
|
+
### Large files are being skipped
|
|
312
|
+
|
|
313
|
+
By default the walker skips files larger than **512 KB** (see log line `Skipped N large files (>512KB)`). Raise the threshold via either the CLI flag or the environment variable — both accept a value in **KB**:
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
# CLI flag (takes precedence over the env var)
|
|
317
|
+
npx gitnexus analyze --max-file-size 2048 # skip only files > 2 MB
|
|
318
|
+
|
|
319
|
+
# Environment variable (persists across commands)
|
|
320
|
+
export GITNEXUS_MAX_FILE_SIZE=2048
|
|
321
|
+
npx gitnexus analyze
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Values above **32768 KB (32 MB)** are clamped to the tree-sitter parser ceiling; invalid values fall back to the 512 KB default with a one-time warning. When an override is active, `analyze` prints the effective threshold in its startup banner (e.g. `GITNEXUS_MAX_FILE_SIZE: effective threshold 2048KB (default 512KB)`).
|
|
325
|
+
|
|
310
326
|
## Privacy
|
|
311
327
|
|
|
312
328
|
- All processing happens locally on your machine
|
|
@@ -37,6 +37,18 @@
|
|
|
37
37
|
* `localDefs`. A `ParsedFile` is trivially convertible to a `FinalizeFile`
|
|
38
38
|
* by picking those four fields, so the finalize orchestrator threads
|
|
39
39
|
* ParsedFile through to the shared algorithm without shape-shifting.
|
|
40
|
+
*
|
|
41
|
+
* ## Source-of-truth invariant
|
|
42
|
+
*
|
|
43
|
+
* `ParsedFile` is the single semantic model consumed by both the legacy
|
|
44
|
+
* DAG (`gitnexus/src/core/ingestion/` outside `scope-resolution/`) and
|
|
45
|
+
* the scope-resolution pipeline (`gitnexus/src/core/ingestion/scope-resolution/`).
|
|
46
|
+
* Downstream passes MUST NOT build a parallel parse representation; if
|
|
47
|
+
* a pass needs AST-level facts that `ParsedFile` doesn't expose, it
|
|
48
|
+
* should reuse the orchestrator's `treeCache` rather than re-invoke
|
|
49
|
+
* `parser.parse(...)` on its own. See the
|
|
50
|
+
* `ScopeResolver` contract (`gitnexus/src/core/ingestion/scope-resolution/contract/scope-resolver.ts`)
|
|
51
|
+
* for the full list of invariants downstream consumers rely on.
|
|
40
52
|
*/
|
|
41
53
|
import type { Scope, ScopeId } from './types.js';
|
|
42
54
|
import type { ParsedImport } from './types.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parsed-file.d.ts","sourceRoot":"","sources":["../../src/scope-resolution/parsed-file.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"parsed-file.d.ts","sourceRoot":"","sources":["../../src/scope-resolution/parsed-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,oDAAoD;IACpD,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC;IAClC,QAAQ,CAAC,aAAa,EAAE,SAAS,YAAY,EAAE,CAAC;IAChD;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAChD,QAAQ,CAAC,cAAc,EAAE,SAAS,aAAa,EAAE,CAAC;CACnD"}
|
|
@@ -37,6 +37,18 @@
|
|
|
37
37
|
* `localDefs`. A `ParsedFile` is trivially convertible to a `FinalizeFile`
|
|
38
38
|
* by picking those four fields, so the finalize orchestrator threads
|
|
39
39
|
* ParsedFile through to the shared algorithm without shape-shifting.
|
|
40
|
+
*
|
|
41
|
+
* ## Source-of-truth invariant
|
|
42
|
+
*
|
|
43
|
+
* `ParsedFile` is the single semantic model consumed by both the legacy
|
|
44
|
+
* DAG (`gitnexus/src/core/ingestion/` outside `scope-resolution/`) and
|
|
45
|
+
* the scope-resolution pipeline (`gitnexus/src/core/ingestion/scope-resolution/`).
|
|
46
|
+
* Downstream passes MUST NOT build a parallel parse representation; if
|
|
47
|
+
* a pass needs AST-level facts that `ParsedFile` doesn't expose, it
|
|
48
|
+
* should reuse the orchestrator's `treeCache` rather than re-invoke
|
|
49
|
+
* `parser.parse(...)` on its own. See the
|
|
50
|
+
* `ScopeResolver` contract (`gitnexus/src/core/ingestion/scope-resolution/contract/scope-resolver.ts`)
|
|
51
|
+
* for the full list of invariants downstream consumers rely on.
|
|
40
52
|
*/
|
|
41
53
|
export {};
|
|
42
54
|
//# sourceMappingURL=parsed-file.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parsed-file.js","sourceRoot":"","sources":["../../src/scope-resolution/parsed-file.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"parsed-file.js","sourceRoot":"","sources":["../../src/scope-resolution/parsed-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG"}
|
|
@@ -63,5 +63,13 @@ export interface ReferenceSite {
|
|
|
63
63
|
};
|
|
64
64
|
/** Argument count at the call site; used by `provider.arityCompatibility`. */
|
|
65
65
|
readonly arity?: number;
|
|
66
|
+
/**
|
|
67
|
+
* Inferred argument types at the call site, one per argument. An
|
|
68
|
+
* empty-string entry means "unknown" — consumers narrowing overload
|
|
69
|
+
* candidates treat unknown as any-match. Populated by languages
|
|
70
|
+
* that can derive types from literals / constructor expressions
|
|
71
|
+
* (C#: `42` → `'int'`, `"alice"` → `'string'`).
|
|
72
|
+
*/
|
|
73
|
+
readonly argumentTypes?: readonly string[];
|
|
66
74
|
}
|
|
67
75
|
//# sourceMappingURL=reference-site.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reference-site.d.ts","sourceRoot":"","sources":["../../src/scope-resolution/reference-site.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GACrB,MAAM,GACN,MAAM,GACN,OAAO,GACP,gBAAgB,GAChB,UAAU,GACV,YAAY,CAAC;AAEjB;;;;;;;;;GASG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,aAAa,GAAG,OAAO,CAAC;AAEnE,MAAM,WAAW,aAAa;IAC5B,uEAAuE;IACvE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,kCAAkC;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACtD,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"reference-site.d.ts","sourceRoot":"","sources":["../../src/scope-resolution/reference-site.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GACrB,MAAM,GACN,MAAM,GACN,OAAO,GACP,gBAAgB,GAChB,UAAU,GACV,YAAY,CAAC;AAEjB;;;;;;;;;GASG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,aAAa,GAAG,OAAO,CAAC;AAEnE,MAAM,WAAW,aAAa;IAC5B,uEAAuE;IACvE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,kCAAkC;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACtD,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5C"}
|
package/dist/cli/index.js
CHANGED
|
@@ -30,7 +30,9 @@ program
|
|
|
30
30
|
.option('--max-file-size <kb>', 'Skip files larger than this (KB). Default: 512. Hard cap: 32768 (tree-sitter limit).')
|
|
31
31
|
.addHelpText('after', '\nEnvironment variables:\n' +
|
|
32
32
|
' GITNEXUS_NO_GITIGNORE=1 Skip .gitignore parsing (still reads .gitnexusignore)\n' +
|
|
33
|
-
' GITNEXUS_MAX_FILE_SIZE=N Override large-file skip threshold (KB). Default 512, max 32768
|
|
33
|
+
' GITNEXUS_MAX_FILE_SIZE=N Override large-file skip threshold (KB). Default 512, max 32768.\n' +
|
|
34
|
+
'\nTip: `.gitnexusignore` supports `.gitignore`-style negation. Add e.g.\n' +
|
|
35
|
+
' `!__tests__/` to index a directory that is auto-filtered by default (#771).')
|
|
34
36
|
.action(createLazyAction(() => import('./analyze.js'), 'analyzeCommand'));
|
|
35
37
|
program
|
|
36
38
|
.command('index [path...]')
|
|
@@ -19,6 +19,15 @@ export declare const loadIgnoreRules: (repoPath: string, options?: IgnoreOptions
|
|
|
19
19
|
*
|
|
20
20
|
* Returns an IgnoreLike object for glob's `ignore` option,
|
|
21
21
|
* enabling directory-level pruning during traversal.
|
|
22
|
+
*
|
|
23
|
+
* Precedence (#771): user's `.gitnexusignore` negation patterns take
|
|
24
|
+
* priority over the hardcoded list, matching `.gitignore` semantics.
|
|
25
|
+
* An explicit `!pattern` rule unignores descendants even when they
|
|
26
|
+
* would otherwise be blocked by DEFAULT_IGNORE_LIST — UNLESS a more
|
|
27
|
+
* specific rule in the same file re-ignores a subset (e.g.
|
|
28
|
+
* `!__tests__/` paired with `__tests__/generated/` blocks the child
|
|
29
|
+
* while leaving the parent negated). Last-match-wins is enforced by
|
|
30
|
+
* consulting `ig.ignores(rel)` after `hasExplicitUnignore`.
|
|
22
31
|
*/
|
|
23
32
|
export declare const createIgnoreFilter: (repoPath: string, options?: IgnoreOptions) => Promise<{
|
|
24
33
|
ignored(p: Path): boolean;
|
|
@@ -245,16 +245,20 @@ const IGNORED_FILES = new Set([
|
|
|
245
245
|
'.env.test',
|
|
246
246
|
'.env.example',
|
|
247
247
|
]);
|
|
248
|
-
//
|
|
249
|
-
//
|
|
250
|
-
//
|
|
251
|
-
//
|
|
248
|
+
// The hardcoded DEFAULT_IGNORE_LIST is the "safety net" default: directories
|
|
249
|
+
// that are almost never source code (node_modules, .git, dist, __tests__,
|
|
250
|
+
// etc.). Users who legitimately need to index one of these can negate the
|
|
251
|
+
// hardcoded rule via a `!pattern` line in `.gitnexusignore` (#771) — same
|
|
252
|
+
// semantics as `.gitignore` negation. That override is applied in
|
|
253
|
+
// `createIgnoreFilter` below; `shouldIgnorePath` itself stays a pure
|
|
254
|
+
// hardcoded-list check so its callers (wiki generator, tests) get
|
|
255
|
+
// deterministic results independent of per-repo config.
|
|
252
256
|
export const shouldIgnorePath = (filePath) => {
|
|
253
257
|
const normalizedPath = filePath.replace(/\\/g, '/');
|
|
254
258
|
const parts = normalizedPath.split('/');
|
|
255
259
|
const fileName = parts[parts.length - 1];
|
|
256
260
|
const fileNameLower = fileName.toLowerCase();
|
|
257
|
-
// Check if any path segment is in ignore list
|
|
261
|
+
// Check if any path segment is in the hardcoded ignore list.
|
|
258
262
|
for (const part of parts) {
|
|
259
263
|
if (DEFAULT_IGNORE_LIST.has(part)) {
|
|
260
264
|
return true;
|
|
@@ -320,6 +324,44 @@ export const loadIgnoreRules = async (repoPath, options) => {
|
|
|
320
324
|
}
|
|
321
325
|
return hasRules ? ig : null;
|
|
322
326
|
};
|
|
327
|
+
/**
|
|
328
|
+
* Walk ancestor segments of `rel` and check whether `.gitnexusignore`
|
|
329
|
+
* (or `.gitignore`) contains an explicit `!pattern` negation that
|
|
330
|
+
* applies. Returns true as soon as any segment — or the path itself —
|
|
331
|
+
* is matched by a negation rule.
|
|
332
|
+
*
|
|
333
|
+
* Why this exists (#771): the hardcoded DEFAULT_IGNORE_LIST would
|
|
334
|
+
* otherwise block indexing of directories like `__tests__/` even when
|
|
335
|
+
* the user has an explicit `!__tests__/` line in `.gitnexusignore`.
|
|
336
|
+
* Mirroring `.gitignore` negation semantics: a user's explicit
|
|
337
|
+
* unignore of a parent directory implicitly unignores everything
|
|
338
|
+
* underneath, so we walk the ancestor chain rather than only testing
|
|
339
|
+
* the leaf.
|
|
340
|
+
*
|
|
341
|
+
* The `ignore` package's `test(path)` returns `{ignored, unignored}`;
|
|
342
|
+
* `unignored: true` is the "a negation rule matched this path"
|
|
343
|
+
* signal. Children of a negated directory return
|
|
344
|
+
* `{ignored: false, unignored: false}` on a direct test, which is why
|
|
345
|
+
* we also walk the ancestors here.
|
|
346
|
+
*/
|
|
347
|
+
const hasExplicitUnignore = (ig, rel) => {
|
|
348
|
+
// Direct match on the path (as a file).
|
|
349
|
+
if (ig.test(rel).unignored)
|
|
350
|
+
return true;
|
|
351
|
+
// Direct match on the path treated as a directory — `!dir/` matches
|
|
352
|
+
// here when rel is the directory itself.
|
|
353
|
+
if (ig.test(rel + '/').unignored)
|
|
354
|
+
return true;
|
|
355
|
+
// Walk ancestor segments. `!parent/` should propagate to every
|
|
356
|
+
// descendant the same way `.gitignore` negation propagates.
|
|
357
|
+
const parts = rel.split('/');
|
|
358
|
+
for (let i = parts.length - 1; i > 0; i--) {
|
|
359
|
+
const ancestor = parts.slice(0, i).join('/') + '/';
|
|
360
|
+
if (ig.test(ancestor).unignored)
|
|
361
|
+
return true;
|
|
362
|
+
}
|
|
363
|
+
return false;
|
|
364
|
+
};
|
|
323
365
|
/**
|
|
324
366
|
* Create a glob-compatible ignore filter combining:
|
|
325
367
|
* - .gitignore / .gitnexusignore patterns (via `ignore` package)
|
|
@@ -327,6 +369,15 @@ export const loadIgnoreRules = async (repoPath, options) => {
|
|
|
327
369
|
*
|
|
328
370
|
* Returns an IgnoreLike object for glob's `ignore` option,
|
|
329
371
|
* enabling directory-level pruning during traversal.
|
|
372
|
+
*
|
|
373
|
+
* Precedence (#771): user's `.gitnexusignore` negation patterns take
|
|
374
|
+
* priority over the hardcoded list, matching `.gitignore` semantics.
|
|
375
|
+
* An explicit `!pattern` rule unignores descendants even when they
|
|
376
|
+
* would otherwise be blocked by DEFAULT_IGNORE_LIST — UNLESS a more
|
|
377
|
+
* specific rule in the same file re-ignores a subset (e.g.
|
|
378
|
+
* `!__tests__/` paired with `__tests__/generated/` blocks the child
|
|
379
|
+
* while leaving the parent negated). Last-match-wins is enforced by
|
|
380
|
+
* consulting `ig.ignores(rel)` after `hasExplicitUnignore`.
|
|
330
381
|
*/
|
|
331
382
|
export const createIgnoreFilter = async (repoPath, options) => {
|
|
332
383
|
const ig = await loadIgnoreRules(repoPath, options);
|
|
@@ -337,6 +388,15 @@ export const createIgnoreFilter = async (repoPath, options) => {
|
|
|
337
388
|
const rel = p.relative();
|
|
338
389
|
if (!rel)
|
|
339
390
|
return false;
|
|
391
|
+
// User's .gitnexusignore negation takes precedence over hardcoded
|
|
392
|
+
// rules (#771). If any ancestor or the path itself was explicitly
|
|
393
|
+
// unignored AND no more-specific rule re-ignores this exact path,
|
|
394
|
+
// allow it through. The `!ig.ignores(rel)` guard matches
|
|
395
|
+
// .gitignore's last-match-wins semantics: `!__tests__/` followed
|
|
396
|
+
// by `__tests__/generated/` negates the parent but still blocks
|
|
397
|
+
// the re-ignored child.
|
|
398
|
+
if (ig && hasExplicitUnignore(ig, rel) && !ig.ignores(rel))
|
|
399
|
+
return false;
|
|
340
400
|
// Check .gitignore / .gitnexusignore patterns
|
|
341
401
|
if (ig && ig.ignores(rel))
|
|
342
402
|
return true;
|
|
@@ -344,10 +404,20 @@ export const createIgnoreFilter = async (repoPath, options) => {
|
|
|
344
404
|
return shouldIgnorePath(rel);
|
|
345
405
|
},
|
|
346
406
|
childrenIgnored(p) {
|
|
347
|
-
// Fast path: check directory name against hardcoded list.
|
|
348
407
|
// Note: dot-directories (.git, .vscode, etc.) are primarily excluded by
|
|
349
|
-
// glob's `dot: false` option in filesystem-walker.ts.
|
|
350
|
-
// defense-in-depth — do not remove `dot: false`
|
|
408
|
+
// glob's `dot: false` option in filesystem-walker.ts. The hardcoded
|
|
409
|
+
// list check below is defense-in-depth — do not remove `dot: false`
|
|
410
|
+
// assuming this covers it.
|
|
411
|
+
const rel = p.relative();
|
|
412
|
+
// User's .gitnexusignore negation takes precedence (#771) — if the
|
|
413
|
+
// user explicitly unignored this directory or any ancestor via a
|
|
414
|
+
// !pattern rule, allow descent even if the directory name is in
|
|
415
|
+
// DEFAULT_IGNORE_LIST. The `!ig.ignores(rel + '/')` guard keeps
|
|
416
|
+
// last-match-wins: `!__tests__/` + `__tests__/generated/` still
|
|
417
|
+
// blocks descent into `__tests__/generated/`.
|
|
418
|
+
if (ig && rel && hasExplicitUnignore(ig, rel) && !ig.ignores(rel + '/'))
|
|
419
|
+
return false;
|
|
420
|
+
// Hardcoded list: block descent into well-known noise directories.
|
|
351
421
|
if (DEFAULT_IGNORE_LIST.has(p.name))
|
|
352
422
|
return true;
|
|
353
423
|
// Check against .gitignore / .gitnexusignore patterns.
|
|
@@ -358,11 +428,8 @@ export const createIgnoreFilter = async (repoPath, options) => {
|
|
|
358
428
|
// Bare-name patterns (e.g. `local`) still match `local/` per gitignore spec:
|
|
359
429
|
// the `ignore` package normalizes `dir` and `dir/` to match directories.
|
|
360
430
|
// See: https://github.com/kaelzhang/node-ignore#2-filenames-and-dirnames
|
|
361
|
-
if (ig)
|
|
362
|
-
|
|
363
|
-
if (rel && ig.ignores(rel + '/'))
|
|
364
|
-
return true;
|
|
365
|
-
}
|
|
431
|
+
if (ig && rel && ig.ignores(rel + '/'))
|
|
432
|
+
return true;
|
|
366
433
|
return false;
|
|
367
434
|
},
|
|
368
435
|
};
|
|
@@ -224,8 +224,9 @@ interface LanguageProviderConfig {
|
|
|
224
224
|
readonly builtInNames?: ReadonlySet<string>;
|
|
225
225
|
/**
|
|
226
226
|
* Emit scope captures from raw source, **pre-grouped per tree-sitter
|
|
227
|
-
* query match**. Tree-sitter-based providers run a
|
|
228
|
-
*
|
|
227
|
+
* query match**. Tree-sitter-based providers run a scope query
|
|
228
|
+
* (embedded as a string constant in each language's `query.ts`) and
|
|
229
|
+
* emit one `CaptureMatch` per query match; standalone providers
|
|
229
230
|
* (COBOL) emit matches from a regex tagger. The return shape is
|
|
230
231
|
* parser-agnostic: the central `ScopeExtractor` consumes
|
|
231
232
|
* `CaptureMatch[]` without knowing which parser produced them.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* C# collection-accessor unwrapping.
|
|
3
|
+
*
|
|
4
|
+
* When the compound-receiver resolver encounters a trailing
|
|
5
|
+
* `.Values` / `.Keys` on a dotted member-access chain, it calls the
|
|
6
|
+
* provider's `unwrapCollectionAccessor` hook to find the element
|
|
7
|
+
* type. This module supplies the C# implementation — recognizing
|
|
8
|
+
* Dictionary-family generics and returning the value or key type.
|
|
9
|
+
*
|
|
10
|
+
* Other languages (Python, Java, TypeScript) use method-call syntax
|
|
11
|
+
* for the same access (`.values()` / `.keys()`), which the compound-
|
|
12
|
+
* receiver's call-expression branch already handles; they leave this
|
|
13
|
+
* hook undefined.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Resolve `data.Values` / `data.Keys` on a Dictionary-like receiver
|
|
17
|
+
* to its element-type simple name. Returns `undefined` for any
|
|
18
|
+
* receiver / accessor combination we don't recognize, letting the
|
|
19
|
+
* compound-receiver pass fall through to the regular field walk.
|
|
20
|
+
*/
|
|
21
|
+
export declare function unwrapCsharpCollectionAccessor(receiverType: string, accessor: string): string | undefined;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* C# collection-accessor unwrapping.
|
|
3
|
+
*
|
|
4
|
+
* When the compound-receiver resolver encounters a trailing
|
|
5
|
+
* `.Values` / `.Keys` on a dotted member-access chain, it calls the
|
|
6
|
+
* provider's `unwrapCollectionAccessor` hook to find the element
|
|
7
|
+
* type. This module supplies the C# implementation — recognizing
|
|
8
|
+
* Dictionary-family generics and returning the value or key type.
|
|
9
|
+
*
|
|
10
|
+
* Other languages (Python, Java, TypeScript) use method-call syntax
|
|
11
|
+
* for the same access (`.values()` / `.keys()`), which the compound-
|
|
12
|
+
* receiver's call-expression branch already handles; they leave this
|
|
13
|
+
* hook undefined.
|
|
14
|
+
*/
|
|
15
|
+
/** Extract (K, V) from `Dictionary<K, V>` / `IDictionary<K, V>` /
|
|
16
|
+
* `IReadOnlyDictionary<K, V>` / `SortedDictionary<K, V>` /
|
|
17
|
+
* `ConcurrentDictionary<K, V>` / `ImmutableDictionary<K, V>`.
|
|
18
|
+
* Returns undefined if the type name doesn't match or the argument
|
|
19
|
+
* list isn't exactly two top-level args. */
|
|
20
|
+
function extractDictionaryArgs(rawName) {
|
|
21
|
+
const match = rawName.match(/^(?:[A-Za-z_][A-Za-z0-9_.]*\.)?(?:Dictionary|IDictionary|IReadOnlyDictionary|SortedDictionary|ConcurrentDictionary|ImmutableDictionary)<(.+)>$/);
|
|
22
|
+
if (match === null)
|
|
23
|
+
return undefined;
|
|
24
|
+
const inner = match[1];
|
|
25
|
+
// Split on the top-level comma (tolerate nested `<...>`).
|
|
26
|
+
let depth = 0;
|
|
27
|
+
let commaIdx = -1;
|
|
28
|
+
for (let i = 0; i < inner.length; i++) {
|
|
29
|
+
const ch = inner[i];
|
|
30
|
+
if (ch === '<')
|
|
31
|
+
depth++;
|
|
32
|
+
else if (ch === '>')
|
|
33
|
+
depth--;
|
|
34
|
+
else if (ch === ',' && depth === 0) {
|
|
35
|
+
commaIdx = i;
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (commaIdx === -1)
|
|
40
|
+
return undefined;
|
|
41
|
+
return { key: inner.slice(0, commaIdx).trim(), value: inner.slice(commaIdx + 1).trim() };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Resolve `data.Values` / `data.Keys` on a Dictionary-like receiver
|
|
45
|
+
* to its element-type simple name. Returns `undefined` for any
|
|
46
|
+
* receiver / accessor combination we don't recognize, letting the
|
|
47
|
+
* compound-receiver pass fall through to the regular field walk.
|
|
48
|
+
*/
|
|
49
|
+
export function unwrapCsharpCollectionAccessor(receiverType, accessor) {
|
|
50
|
+
if (accessor !== 'Values' && accessor !== 'Keys')
|
|
51
|
+
return undefined;
|
|
52
|
+
const args = extractDictionaryArgs(receiverType);
|
|
53
|
+
if (args === undefined)
|
|
54
|
+
return undefined;
|
|
55
|
+
return accessor === 'Values' ? args.value : args.key;
|
|
56
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract C# arity metadata from a method-like tree-sitter node —
|
|
3
|
+
* `method_declaration`, `constructor_declaration`, `destructor_declaration`,
|
|
4
|
+
* `operator_declaration`, `conversion_operator_declaration`, or
|
|
5
|
+
* `local_function_statement`.
|
|
6
|
+
*
|
|
7
|
+
* Reuses `csharpMethodConfig.extractParameters` so scope-extracted defs
|
|
8
|
+
* carry the same arity semantics as the legacy parse-worker path:
|
|
9
|
+
* - `params` variadic collapses `parameterCount` to `undefined`,
|
|
10
|
+
* which `csharpArityCompatibility` then treats as "max unknown" —
|
|
11
|
+
* the candidate stays eligible at `argCount >= required`.
|
|
12
|
+
* - Defaulted parameters (`= expr`) contribute to `optionalCount`;
|
|
13
|
+
* `requiredParameterCount = total − optionalCount`.
|
|
14
|
+
* - `parameterTypes` collects declared type names (with `ref`/`out`/
|
|
15
|
+
* `in` prefix) for overload narrowing; a literal `'params'` marker
|
|
16
|
+
* is appended for variadic methods so `csharpArityCompatibility`
|
|
17
|
+
* can detect them without re-reading the AST.
|
|
18
|
+
*/
|
|
19
|
+
import type { SyntaxNode } from '../../utils/ast-helpers.js';
|
|
20
|
+
interface CsharpArityMetadata {
|
|
21
|
+
readonly parameterCount: number | undefined;
|
|
22
|
+
readonly requiredParameterCount: number | undefined;
|
|
23
|
+
readonly parameterTypes: readonly string[] | undefined;
|
|
24
|
+
}
|
|
25
|
+
export declare function computeCsharpArityMetadata(fnNode: SyntaxNode): CsharpArityMetadata;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract C# arity metadata from a method-like tree-sitter node —
|
|
3
|
+
* `method_declaration`, `constructor_declaration`, `destructor_declaration`,
|
|
4
|
+
* `operator_declaration`, `conversion_operator_declaration`, or
|
|
5
|
+
* `local_function_statement`.
|
|
6
|
+
*
|
|
7
|
+
* Reuses `csharpMethodConfig.extractParameters` so scope-extracted defs
|
|
8
|
+
* carry the same arity semantics as the legacy parse-worker path:
|
|
9
|
+
* - `params` variadic collapses `parameterCount` to `undefined`,
|
|
10
|
+
* which `csharpArityCompatibility` then treats as "max unknown" —
|
|
11
|
+
* the candidate stays eligible at `argCount >= required`.
|
|
12
|
+
* - Defaulted parameters (`= expr`) contribute to `optionalCount`;
|
|
13
|
+
* `requiredParameterCount = total − optionalCount`.
|
|
14
|
+
* - `parameterTypes` collects declared type names (with `ref`/`out`/
|
|
15
|
+
* `in` prefix) for overload narrowing; a literal `'params'` marker
|
|
16
|
+
* is appended for variadic methods so `csharpArityCompatibility`
|
|
17
|
+
* can detect them without re-reading the AST.
|
|
18
|
+
*/
|
|
19
|
+
import { csharpMethodConfig } from '../../method-extractors/configs/csharp.js';
|
|
20
|
+
export function computeCsharpArityMetadata(fnNode) {
|
|
21
|
+
const params = csharpMethodConfig.extractParameters?.(fnNode) ?? [];
|
|
22
|
+
let hasVariadic = false;
|
|
23
|
+
let optionalCount = 0;
|
|
24
|
+
const types = [];
|
|
25
|
+
for (const p of params) {
|
|
26
|
+
if (p.isVariadic)
|
|
27
|
+
hasVariadic = true;
|
|
28
|
+
else if (p.isOptional)
|
|
29
|
+
optionalCount++;
|
|
30
|
+
if (p.type !== null)
|
|
31
|
+
types.push(p.type);
|
|
32
|
+
}
|
|
33
|
+
if (hasVariadic)
|
|
34
|
+
types.push('params');
|
|
35
|
+
const total = params.length;
|
|
36
|
+
// `params int[] args` declares one formal param but accepts any arg
|
|
37
|
+
// count ≥ required — mirror Python's treatment of `*args` and leave
|
|
38
|
+
// `parameterCount` undefined so the registry treats max as unknown.
|
|
39
|
+
const parameterCount = hasVariadic ? undefined : total;
|
|
40
|
+
const requiredParameterCount = hasVariadic ? undefined : total - optionalCount;
|
|
41
|
+
return {
|
|
42
|
+
parameterCount,
|
|
43
|
+
requiredParameterCount,
|
|
44
|
+
parameterTypes: types.length > 0 ? types : undefined,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* C# arity check, accommodating `params` variadic and default parameters.
|
|
3
|
+
*
|
|
4
|
+
* The `def` metadata we care about (synthesized by `arity-metadata.ts`):
|
|
5
|
+
* - `parameterCount` — total formal parameters; `undefined`
|
|
6
|
+
* when the method has `params T[]` variadic.
|
|
7
|
+
* - `requiredParameterCount` — min required (excludes defaulted params
|
|
8
|
+
* and `params` variadic).
|
|
9
|
+
* - `parameterTypes` — declared type strings; contains the
|
|
10
|
+
* literal `'params'` when the method is
|
|
11
|
+
* variadic.
|
|
12
|
+
*
|
|
13
|
+
* Verdicts:
|
|
14
|
+
* - `'compatible'` — `requiredParameterCount <= argCount <= parameterCount`,
|
|
15
|
+
* OR the def takes `params` (then any `argCount >= required`).
|
|
16
|
+
* - `'incompatible'` — argCount is below required, OR above max with no variadic.
|
|
17
|
+
* - `'unknown'` — metadata is absent / incomplete.
|
|
18
|
+
*
|
|
19
|
+
* `'incompatible'` is a soft signal in `Registry.lookup` (penalized but
|
|
20
|
+
* still considered when no compatible candidate exists), per RFC §4.
|
|
21
|
+
*/
|
|
22
|
+
import type { Callsite, SymbolDefinition } from '../../../../_shared/index.js';
|
|
23
|
+
export declare function csharpArityCompatibility(def: SymbolDefinition, callsite: Callsite): 'compatible' | 'unknown' | 'incompatible';
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* C# arity check, accommodating `params` variadic and default parameters.
|
|
3
|
+
*
|
|
4
|
+
* The `def` metadata we care about (synthesized by `arity-metadata.ts`):
|
|
5
|
+
* - `parameterCount` — total formal parameters; `undefined`
|
|
6
|
+
* when the method has `params T[]` variadic.
|
|
7
|
+
* - `requiredParameterCount` — min required (excludes defaulted params
|
|
8
|
+
* and `params` variadic).
|
|
9
|
+
* - `parameterTypes` — declared type strings; contains the
|
|
10
|
+
* literal `'params'` when the method is
|
|
11
|
+
* variadic.
|
|
12
|
+
*
|
|
13
|
+
* Verdicts:
|
|
14
|
+
* - `'compatible'` — `requiredParameterCount <= argCount <= parameterCount`,
|
|
15
|
+
* OR the def takes `params` (then any `argCount >= required`).
|
|
16
|
+
* - `'incompatible'` — argCount is below required, OR above max with no variadic.
|
|
17
|
+
* - `'unknown'` — metadata is absent / incomplete.
|
|
18
|
+
*
|
|
19
|
+
* `'incompatible'` is a soft signal in `Registry.lookup` (penalized but
|
|
20
|
+
* still considered when no compatible candidate exists), per RFC §4.
|
|
21
|
+
*/
|
|
22
|
+
export function csharpArityCompatibility(def, callsite) {
|
|
23
|
+
const max = def.parameterCount;
|
|
24
|
+
const min = def.requiredParameterCount;
|
|
25
|
+
if (max === undefined && min === undefined)
|
|
26
|
+
return 'unknown';
|
|
27
|
+
const argCount = callsite.arity;
|
|
28
|
+
if (!Number.isFinite(argCount) || argCount < 0)
|
|
29
|
+
return 'unknown';
|
|
30
|
+
const hasVarArgs = def.parameterTypes !== undefined &&
|
|
31
|
+
def.parameterTypes.some((t) => t === 'params' || t.startsWith('params '));
|
|
32
|
+
if (min !== undefined && argCount < min)
|
|
33
|
+
return 'incompatible';
|
|
34
|
+
if (max !== undefined && argCount > max && !hasVarArgs)
|
|
35
|
+
return 'incompatible';
|
|
36
|
+
return 'compatible';
|
|
37
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dev-mode counters for the cross-phase scope-captures parse cache
|
|
3
|
+
* (C# mirror of `languages/python/cache-stats.ts`).
|
|
4
|
+
*
|
|
5
|
+
* Gated by `PROF_SCOPE_RESOLUTION=1`. Production builds fold every
|
|
6
|
+
* increment into dead code via the module-level `PROF` constant, so
|
|
7
|
+
* the hot path in `captures.ts` stays branch-free.
|
|
8
|
+
*/
|
|
9
|
+
export declare function recordCacheHit(): void;
|
|
10
|
+
export declare function recordCacheMiss(): void;
|
|
11
|
+
export declare function getCsharpCaptureCacheStats(): {
|
|
12
|
+
hits: number;
|
|
13
|
+
misses: number;
|
|
14
|
+
};
|
|
15
|
+
export declare function resetCsharpCaptureCacheStats(): void;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dev-mode counters for the cross-phase scope-captures parse cache
|
|
3
|
+
* (C# mirror of `languages/python/cache-stats.ts`).
|
|
4
|
+
*
|
|
5
|
+
* Gated by `PROF_SCOPE_RESOLUTION=1`. Production builds fold every
|
|
6
|
+
* increment into dead code via the module-level `PROF` constant, so
|
|
7
|
+
* the hot path in `captures.ts` stays branch-free.
|
|
8
|
+
*/
|
|
9
|
+
const PROF = process.env.PROF_SCOPE_RESOLUTION === '1';
|
|
10
|
+
let CACHE_HITS = 0;
|
|
11
|
+
let CACHE_MISSES = 0;
|
|
12
|
+
export function recordCacheHit() {
|
|
13
|
+
if (PROF)
|
|
14
|
+
CACHE_HITS++;
|
|
15
|
+
}
|
|
16
|
+
export function recordCacheMiss() {
|
|
17
|
+
if (PROF)
|
|
18
|
+
CACHE_MISSES++;
|
|
19
|
+
}
|
|
20
|
+
export function getCsharpCaptureCacheStats() {
|
|
21
|
+
return { hits: CACHE_HITS, misses: CACHE_MISSES };
|
|
22
|
+
}
|
|
23
|
+
export function resetCsharpCaptureCacheStats() {
|
|
24
|
+
CACHE_HITS = 0;
|
|
25
|
+
CACHE_MISSES = 0;
|
|
26
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `emitScopeCaptures` for C#.
|
|
3
|
+
*
|
|
4
|
+
* Drives the C# scope query against tree-sitter-c-sharp and groups raw
|
|
5
|
+
* matches into `CaptureMatch[]` for the central extractor. Layers one
|
|
6
|
+
* synthesized stream on top today:
|
|
7
|
+
*
|
|
8
|
+
* 1. **Decomposed using directives** — each `using_directive` is
|
|
9
|
+
* re-emitted with `@import.kind/source/name/alias` markers so
|
|
10
|
+
* `interpretCsharpImport` can recover the ParsedImport shape
|
|
11
|
+
* without re-parsing raw text (see `import-decomposer.ts`).
|
|
12
|
+
*
|
|
13
|
+
* Receiver-binding synthesis (`this` / `base` type anchors) and arity
|
|
14
|
+
* metadata synthesis (Unit 5) layer on top later.
|
|
15
|
+
*
|
|
16
|
+
* Pure given the input source text. No I/O, no globals consulted.
|
|
17
|
+
*/
|
|
18
|
+
import type { CaptureMatch } from '../../../../_shared/index.js';
|
|
19
|
+
export declare function emitCsharpScopeCaptures(sourceText: string, _filePath: string, cachedTree?: unknown): readonly CaptureMatch[];
|