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
package/dist/cli/wiki.js
CHANGED
|
@@ -14,6 +14,19 @@ import { WikiGenerator } from '../core/wiki/generator.js';
|
|
|
14
14
|
import { resolveLLMConfig } from '../core/wiki/llm-client.js';
|
|
15
15
|
import { detectCursorCLI } from '../core/wiki/cursor-client.js';
|
|
16
16
|
import { logger } from '../core/logger.js';
|
|
17
|
+
function parsePositiveIntegerOption(value, flag, multiplier = 1) {
|
|
18
|
+
if (value === undefined)
|
|
19
|
+
return undefined;
|
|
20
|
+
const trimmed = value.trim();
|
|
21
|
+
if (!/^[1-9]\d*$/.test(trimmed)) {
|
|
22
|
+
throw new Error(`${flag} must be a positive integer`);
|
|
23
|
+
}
|
|
24
|
+
const parsed = parseInt(trimmed, 10);
|
|
25
|
+
if (parsed > Math.floor(Number.MAX_SAFE_INTEGER / multiplier)) {
|
|
26
|
+
throw new Error(`${flag} is too large`);
|
|
27
|
+
}
|
|
28
|
+
return parsed;
|
|
29
|
+
}
|
|
17
30
|
/**
|
|
18
31
|
* Prompt the user for input via stdin.
|
|
19
32
|
*/
|
|
@@ -100,6 +113,17 @@ export const wikiCommand = async (inputPath, options) => {
|
|
|
100
113
|
process.exitCode = 1;
|
|
101
114
|
return;
|
|
102
115
|
}
|
|
116
|
+
let timeoutSeconds;
|
|
117
|
+
let retries;
|
|
118
|
+
try {
|
|
119
|
+
timeoutSeconds = parsePositiveIntegerOption(options?.timeout, '--timeout', 1000);
|
|
120
|
+
retries = parsePositiveIntegerOption(options?.retries, '--retries');
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
console.log(` Error: ${error.message}\n`);
|
|
124
|
+
process.exitCode = 1;
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
103
127
|
// ── Resolve LLM config (with interactive fallback) ─────────────────
|
|
104
128
|
// Save any CLI overrides immediately
|
|
105
129
|
if (options?.apiKey ||
|
|
@@ -305,15 +329,11 @@ export const wikiCommand = async (inputPath, options) => {
|
|
|
305
329
|
}
|
|
306
330
|
}
|
|
307
331
|
// ── Apply per-run overrides not saved to config ────────────────────
|
|
308
|
-
if (
|
|
309
|
-
|
|
310
|
-
if (!isNaN(secs) && secs > 0)
|
|
311
|
-
llmConfig.requestTimeoutMs = secs * 1000;
|
|
332
|
+
if (timeoutSeconds !== undefined) {
|
|
333
|
+
llmConfig.requestTimeoutMs = timeoutSeconds * 1000;
|
|
312
334
|
}
|
|
313
|
-
if (
|
|
314
|
-
|
|
315
|
-
if (!isNaN(n) && n > 0)
|
|
316
|
-
llmConfig.maxAttempts = n;
|
|
335
|
+
if (retries !== undefined) {
|
|
336
|
+
llmConfig.maxAttempts = retries;
|
|
317
337
|
}
|
|
318
338
|
// ── Setup progress bar with elapsed timer ──────────────────────────
|
|
319
339
|
const bar = new cliProgress.SingleBar({
|
|
@@ -344,6 +364,7 @@ export const wikiCommand = async (inputPath, options) => {
|
|
|
344
364
|
force: options?.force,
|
|
345
365
|
concurrency: options?.concurrency ? parseInt(options.concurrency, 10) : undefined,
|
|
346
366
|
reviewOnly: options?.review,
|
|
367
|
+
lang: options?.lang,
|
|
347
368
|
};
|
|
348
369
|
const generator = new WikiGenerator(repoPath, storagePath, lbugPath, llmConfig, wikiOptions, (phase, percent, detail) => {
|
|
349
370
|
const label = detail || phase;
|
|
@@ -473,6 +494,9 @@ export const wikiCommand = async (inputPath, options) => {
|
|
|
473
494
|
if (err.message?.includes('No source files')) {
|
|
474
495
|
console.log(`\n ${err.message}\n`);
|
|
475
496
|
}
|
|
497
|
+
else if (err.message?.includes('LLM request timed out after')) {
|
|
498
|
+
console.log(`\n Timeout: ${err.message}\n`);
|
|
499
|
+
}
|
|
476
500
|
else if (err.message?.includes('content filter')) {
|
|
477
501
|
// Content filter block — actionable message
|
|
478
502
|
console.log(`\n Content Filter: ${err.message}\n`);
|
|
@@ -3,7 +3,7 @@ import { getCppParser, getCppScopeQuery } from './query.js';
|
|
|
3
3
|
import { getTreeSitterBufferSize } from '../../constants.js';
|
|
4
4
|
import { parseSourceSafe } from '../../../tree-sitter/safe-parse.js';
|
|
5
5
|
import { splitCppInclude, splitCppUsingDecl } from './import-decomposer.js';
|
|
6
|
-
import { computeCppDeclarationArity, computeCppCallArity } from './arity-metadata.js';
|
|
6
|
+
import { classifyCppParameterType, computeCppDeclarationArity, computeCppCallArity, } from './arity-metadata.js';
|
|
7
7
|
import { markCppAnonymousNamespaceRange, markFileLocal } from './file-local-linkage.js';
|
|
8
8
|
import { markCppDependentBase } from './two-phase-lookup.js';
|
|
9
9
|
import { markCppAdlSiteArgs, markCppAdlSiteNoAdl } from './adl.js';
|
|
@@ -159,6 +159,10 @@ export function emitCppScopeCaptures(sourceText, filePath, cachedTree) {
|
|
|
159
159
|
if (argTypes !== undefined && argTypes.length > 0) {
|
|
160
160
|
grouped['@reference.parameter-types'] = syntheticCapture('@reference.parameter-types', cNode, JSON.stringify(argTypes));
|
|
161
161
|
}
|
|
162
|
+
const argTypeClasses = inferCppCallArgTypeClasses(cNode);
|
|
163
|
+
if (argTypeClasses !== undefined && argTypeClasses.length > 0) {
|
|
164
|
+
grouped['@reference.parameter-type-classes'] = syntheticCapture('@reference.parameter-type-classes', cNode, JSON.stringify(argTypeClasses));
|
|
165
|
+
}
|
|
162
166
|
}
|
|
163
167
|
}
|
|
164
168
|
// ── Inline namespace detection ──────────────────────────────────
|
|
@@ -612,6 +616,36 @@ function inferCppCallArgTypes(node) {
|
|
|
612
616
|
}
|
|
613
617
|
return types.length > 0 ? types : undefined;
|
|
614
618
|
}
|
|
619
|
+
function inferCppCallArgTypeClasses(node) {
|
|
620
|
+
const argList = node.childForFieldName('arguments');
|
|
621
|
+
if (argList === null)
|
|
622
|
+
return undefined;
|
|
623
|
+
const classes = [];
|
|
624
|
+
for (let i = 0; i < argList.childCount; i++) {
|
|
625
|
+
const child = argList.child(i);
|
|
626
|
+
if (child === null)
|
|
627
|
+
continue;
|
|
628
|
+
if (child.type === ',' || child.type === '(' || child.type === ')')
|
|
629
|
+
continue;
|
|
630
|
+
const litType = inferCppLiteralType(child);
|
|
631
|
+
if (litType !== '') {
|
|
632
|
+
classes.push(valueTypeClass(litType));
|
|
633
|
+
}
|
|
634
|
+
else if (child.type === 'identifier') {
|
|
635
|
+
classes.push(lookupDeclaredTypeClassForIdentifier(child));
|
|
636
|
+
}
|
|
637
|
+
else {
|
|
638
|
+
classes.push(unknownTypeClass('unknown'));
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
return classes.length > 0 ? classes : undefined;
|
|
642
|
+
}
|
|
643
|
+
function valueTypeClass(base) {
|
|
644
|
+
return { base, cv: 'none', indirection: 'value', pointerDepth: 0 };
|
|
645
|
+
}
|
|
646
|
+
function unknownTypeClass(base) {
|
|
647
|
+
return { base, cv: 'unknown', indirection: 'unknown', pointerDepth: 0 };
|
|
648
|
+
}
|
|
615
649
|
/**
|
|
616
650
|
* Infer the canonical type name of a C++ literal AST node.
|
|
617
651
|
* Returns empty string for non-literal / unknown nodes.
|
|
@@ -674,6 +708,9 @@ function lookupDeclaredTypeForIdentifier(identNode) {
|
|
|
674
708
|
}
|
|
675
709
|
if (scope === null)
|
|
676
710
|
return '';
|
|
711
|
+
const paramType = lookupFunctionParameterType(scope, varName);
|
|
712
|
+
if (paramType !== '')
|
|
713
|
+
return paramType;
|
|
677
714
|
// Scan declarations in the scope for a matching variable name
|
|
678
715
|
for (let i = 0; i < scope.childCount; i++) {
|
|
679
716
|
const stmt = scope.child(i);
|
|
@@ -689,18 +726,113 @@ function lookupDeclaredTypeForIdentifier(identNode) {
|
|
|
689
726
|
const declarator = stmt.childForFieldName('declarator');
|
|
690
727
|
if (declarator === null)
|
|
691
728
|
continue;
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
if (nameChild !== null && nameChild.text === varName) {
|
|
695
|
-
return normalizeCppTypeText(typeNode.text);
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
else if (declarator.text === varName) {
|
|
729
|
+
const nameChild = declaredNameNode(declarator);
|
|
730
|
+
if (nameChild !== null && extractDeclaratorLeafName(nameChild) === varName) {
|
|
699
731
|
return normalizeCppTypeText(typeNode.text);
|
|
700
732
|
}
|
|
701
733
|
}
|
|
702
734
|
return '';
|
|
703
735
|
}
|
|
736
|
+
function lookupDeclaredTypeClassForIdentifier(identNode) {
|
|
737
|
+
const varName = identNode.text;
|
|
738
|
+
let scope = identNode.parent;
|
|
739
|
+
while (scope !== null &&
|
|
740
|
+
scope.type !== 'compound_statement' &&
|
|
741
|
+
scope.type !== 'translation_unit') {
|
|
742
|
+
scope = scope.parent;
|
|
743
|
+
}
|
|
744
|
+
if (scope === null)
|
|
745
|
+
return unknownTypeClass('unknown');
|
|
746
|
+
const paramTypeClass = lookupFunctionParameterTypeClass(scope, varName, identNode);
|
|
747
|
+
if (paramTypeClass !== undefined)
|
|
748
|
+
return paramTypeClass;
|
|
749
|
+
for (let i = 0; i < scope.childCount; i++) {
|
|
750
|
+
const stmt = scope.child(i);
|
|
751
|
+
if (stmt === null || stmt.type !== 'declaration')
|
|
752
|
+
continue;
|
|
753
|
+
const typeNode = stmt.childForFieldName('type');
|
|
754
|
+
if (typeNode === null)
|
|
755
|
+
continue;
|
|
756
|
+
if (typeNode.type === 'placeholder_type_specifier')
|
|
757
|
+
continue;
|
|
758
|
+
const declarator = stmt.childForFieldName('declarator');
|
|
759
|
+
if (declarator === null)
|
|
760
|
+
continue;
|
|
761
|
+
const nameChild = declaredNameNode(declarator);
|
|
762
|
+
if (nameChild === null || extractDeclaratorLeafName(nameChild) !== varName)
|
|
763
|
+
continue;
|
|
764
|
+
const typeClass = classifyCppParameterType(typeNode.text, nameChild.text, stmt.text.replace(/;\s*$/, ''));
|
|
765
|
+
if (isKnownEnumName(identNode, typeClass.base)) {
|
|
766
|
+
return { ...typeClass, base: `enum:${typeClass.base}` };
|
|
767
|
+
}
|
|
768
|
+
return typeClass;
|
|
769
|
+
}
|
|
770
|
+
return unknownTypeClass('unknown');
|
|
771
|
+
}
|
|
772
|
+
function lookupFunctionParameterType(scope, varName) {
|
|
773
|
+
const param = findEnclosingFunctionParameter(scope, varName);
|
|
774
|
+
if (param === null)
|
|
775
|
+
return '';
|
|
776
|
+
const typeNode = param.childForFieldName('type');
|
|
777
|
+
if (typeNode === null)
|
|
778
|
+
return '';
|
|
779
|
+
return normalizeCppTypeText(typeNode.text);
|
|
780
|
+
}
|
|
781
|
+
function lookupFunctionParameterTypeClass(scope, varName, identNode) {
|
|
782
|
+
const param = findEnclosingFunctionParameter(scope, varName);
|
|
783
|
+
if (param === null)
|
|
784
|
+
return undefined;
|
|
785
|
+
const typeNode = param.childForFieldName('type');
|
|
786
|
+
if (typeNode === null)
|
|
787
|
+
return undefined;
|
|
788
|
+
const declarator = param.childForFieldName('declarator');
|
|
789
|
+
if (declarator === null)
|
|
790
|
+
return undefined;
|
|
791
|
+
const typeClass = classifyCppParameterType(typeNode.text, declarator.text, param.text);
|
|
792
|
+
if (isKnownEnumName(identNode, typeClass.base)) {
|
|
793
|
+
return { ...typeClass, base: `enum:${typeClass.base}` };
|
|
794
|
+
}
|
|
795
|
+
return typeClass;
|
|
796
|
+
}
|
|
797
|
+
function findEnclosingFunctionParameter(scope, varName) {
|
|
798
|
+
let node = scope.parent;
|
|
799
|
+
while (node !== null) {
|
|
800
|
+
if (node.type === 'function_definition' || node.type === 'function_declarator') {
|
|
801
|
+
const fnDecl = node.type === 'function_declarator'
|
|
802
|
+
? node
|
|
803
|
+
: findFirstDescendantOfType(node, 'function_declarator');
|
|
804
|
+
const params = fnDecl?.childForFieldName('parameters') ?? null;
|
|
805
|
+
if (params !== null) {
|
|
806
|
+
for (let i = 0; i < params.namedChildCount; i++) {
|
|
807
|
+
const param = params.namedChild(i);
|
|
808
|
+
if (param === null || param.type !== 'parameter_declaration')
|
|
809
|
+
continue;
|
|
810
|
+
const declarator = param.childForFieldName('declarator');
|
|
811
|
+
if (declarator !== null && extractDeclaratorLeafName(declarator) === varName) {
|
|
812
|
+
return param;
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
return null;
|
|
817
|
+
}
|
|
818
|
+
node = node.parent;
|
|
819
|
+
}
|
|
820
|
+
return null;
|
|
821
|
+
}
|
|
822
|
+
function declaredNameNode(declarator) {
|
|
823
|
+
if (declarator.type !== 'init_declarator')
|
|
824
|
+
return declarator;
|
|
825
|
+
for (let i = 0; i < declarator.namedChildCount; i++) {
|
|
826
|
+
const child = declarator.namedChild(i);
|
|
827
|
+
if (child === null)
|
|
828
|
+
continue;
|
|
829
|
+
if (child.type === 'identifier')
|
|
830
|
+
return child;
|
|
831
|
+
if (child.type.endsWith('_declarator'))
|
|
832
|
+
return child;
|
|
833
|
+
}
|
|
834
|
+
return declarator.childForFieldName('declarator');
|
|
835
|
+
}
|
|
704
836
|
/** Normalize a type-specifier text for argument type matching.
|
|
705
837
|
* Strips qualifiers (const, volatile), namespace prefixes (std::),
|
|
706
838
|
* and pointer/reference markers. */
|
|
@@ -711,6 +843,28 @@ function normalizeCppTypeText(text) {
|
|
|
711
843
|
t = t.replace(/[*&]/g, '').trim();
|
|
712
844
|
return t;
|
|
713
845
|
}
|
|
846
|
+
function isKnownEnumName(node, typeName) {
|
|
847
|
+
if (typeName === '' || typeName === 'unknown')
|
|
848
|
+
return false;
|
|
849
|
+
let root = node;
|
|
850
|
+
while (root.parent !== null)
|
|
851
|
+
root = root.parent;
|
|
852
|
+
const stack = [root];
|
|
853
|
+
while (stack.length > 0) {
|
|
854
|
+
const cur = stack.pop();
|
|
855
|
+
if (cur.type === 'enum_specifier') {
|
|
856
|
+
const name = cur.childForFieldName('name');
|
|
857
|
+
if (name?.text === typeName)
|
|
858
|
+
return true;
|
|
859
|
+
}
|
|
860
|
+
for (let i = 0; i < cur.childCount; i++) {
|
|
861
|
+
const child = cur.child(i);
|
|
862
|
+
if (child !== null)
|
|
863
|
+
stack.push(child);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
return false;
|
|
867
|
+
}
|
|
714
868
|
/**
|
|
715
869
|
* Detect whether a `namespace_definition` AST node is inline.
|
|
716
870
|
* Tree-sitter-cpp exposes the `inline` keyword as an anonymous child
|
|
@@ -1166,7 +1320,9 @@ function extractDeclaratorLeafName(node) {
|
|
|
1166
1320
|
// Common wrapper nodes — follow the 'declarator' field when present.
|
|
1167
1321
|
const next = cur.childForFieldName('declarator') ??
|
|
1168
1322
|
// parenthesized_declarator: single named child
|
|
1169
|
-
(cur.type === 'parenthesized_declarator'
|
|
1323
|
+
(cur.type === 'parenthesized_declarator' || cur.type.endsWith('_declarator')
|
|
1324
|
+
? cur.namedChild(0)
|
|
1325
|
+
: null);
|
|
1170
1326
|
if (next === null)
|
|
1171
1327
|
return null;
|
|
1172
1328
|
cur = next;
|
|
@@ -21,13 +21,9 @@
|
|
|
21
21
|
*/
|
|
22
22
|
import { classifyType } from './type-classifier.js';
|
|
23
23
|
/**
|
|
24
|
-
* Curated Tier-A predicate registry
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* Deferred predicates that need a cv/ref/pointer sidecar on
|
|
29
|
-
* `normalizeCppParamType` (today the normalizer strips those markers
|
|
30
|
-
* before storage) live in #1579 as one-line follow-up adds.
|
|
24
|
+
* Curated Tier-A predicate registry. Predicates that depend on pointer,
|
|
25
|
+
* reference, or cv shape consult `ConstraintContext.argumentTypeClasses`.
|
|
26
|
+
* Missing or unsupported shape returns 'unknown' to preserve monotonicity.
|
|
31
27
|
*/
|
|
32
28
|
// ISO `<type_traits>` treats `bool`, `char`, and the signed/unsigned char
|
|
33
29
|
// variants as integral types (§21.3.4 Table 48), so `is_integral_v<bool>`
|
|
@@ -39,40 +35,117 @@ function isIntegralClass(c) {
|
|
|
39
35
|
return c === 'integral' || c === 'bool' || c === 'char';
|
|
40
36
|
}
|
|
41
37
|
const REGISTRY = new Map([
|
|
42
|
-
[
|
|
43
|
-
|
|
38
|
+
[
|
|
39
|
+
'is_void_v',
|
|
40
|
+
(args) => unaryVerdict(args, (arg) => isPlainValue(arg) && arg.typeClass === 'void'),
|
|
41
|
+
],
|
|
42
|
+
[
|
|
43
|
+
'is_integral_v',
|
|
44
|
+
(args) => unaryVerdict(args, (arg) => isPlainValue(arg) && isIntegralClass(arg.typeClass)),
|
|
45
|
+
],
|
|
46
|
+
[
|
|
47
|
+
'is_floating_point_v',
|
|
48
|
+
(args) => unaryVerdict(args, (arg) => isPlainValue(arg) && arg.typeClass === 'floating'),
|
|
49
|
+
],
|
|
44
50
|
[
|
|
45
51
|
'is_arithmetic_v',
|
|
46
|
-
(
|
|
52
|
+
(args) => unaryVerdict(args, (arg) => isPlainValue(arg) && (isIntegralClass(arg.typeClass) || arg.typeClass === 'floating')),
|
|
53
|
+
],
|
|
54
|
+
[
|
|
55
|
+
'is_enum_v',
|
|
56
|
+
(args) => unaryVerdict(args, (arg) => isPlainValue(arg) && arg.typeClass === 'enum'),
|
|
57
|
+
],
|
|
58
|
+
[
|
|
59
|
+
'is_class_v',
|
|
60
|
+
(args) => unaryVerdict(args, (arg) => isPlainValue(arg) && arg.typeClass === 'class'),
|
|
61
|
+
],
|
|
62
|
+
[
|
|
63
|
+
'is_pointer_v',
|
|
64
|
+
(args) => unaryShapeVerdict(args, (shape) => shape.indirection === 'pointer' && shape.pointerDepth > 0),
|
|
65
|
+
],
|
|
66
|
+
[
|
|
67
|
+
'is_reference_v',
|
|
68
|
+
(args) => unaryShapeVerdict(args, (shape) => shape.indirection === 'lvalue-ref' || shape.indirection === 'rvalue-ref'),
|
|
69
|
+
],
|
|
70
|
+
[
|
|
71
|
+
'is_const_v',
|
|
72
|
+
(args) => unaryShapeVerdict(args, (shape) => shape.cv === 'const' || shape.cv === 'const volatile', {
|
|
73
|
+
requireTopLevelCv: true,
|
|
74
|
+
}),
|
|
75
|
+
],
|
|
76
|
+
[
|
|
77
|
+
'is_volatile_v',
|
|
78
|
+
(args) => unaryShapeVerdict(args, (shape) => shape.cv === 'volatile' || shape.cv === 'const volatile', {
|
|
79
|
+
requireTopLevelCv: true,
|
|
80
|
+
}),
|
|
47
81
|
],
|
|
48
|
-
// NOTE: cv-qualifiers are stripped by `normalizeCppParamType` before the
|
|
49
|
-
// type token reaches `classifyType`, so `is_same_v<const T, T>` returns
|
|
50
|
-
// `'compatible'` instead of the ISO-correct `false`. Tracked under the
|
|
51
|
-
// cv-sidecar refactor in #1579's "Out of scope" list; until that lands
|
|
52
|
-
// this approximation matches the common `is_same_v<T, ConcreteType>`
|
|
53
|
-
// dispatch idiom and silently degrades on cv-distinct compares.
|
|
54
82
|
[
|
|
55
83
|
'is_same_v',
|
|
56
|
-
(
|
|
57
|
-
if (
|
|
84
|
+
(args) => {
|
|
85
|
+
if (args.length < 2 || args[0].typeClass === 'unknown' || args[1].typeClass === 'unknown') {
|
|
58
86
|
return 'unknown';
|
|
59
|
-
|
|
87
|
+
}
|
|
88
|
+
return args[0].typeClass === args[1].typeClass ? 'compatible' : 'incompatible';
|
|
60
89
|
},
|
|
61
90
|
],
|
|
62
91
|
]);
|
|
63
|
-
function
|
|
64
|
-
|
|
92
|
+
function unaryVerdict(args, predicate) {
|
|
93
|
+
const arg = args[0];
|
|
94
|
+
if (arg === undefined || arg.typeClass === 'unknown')
|
|
65
95
|
return 'unknown';
|
|
66
|
-
return predicate ? 'compatible' : 'incompatible';
|
|
96
|
+
return predicate(arg) ? 'compatible' : 'incompatible';
|
|
97
|
+
}
|
|
98
|
+
function unaryShapeVerdict(args, predicate, options = {}) {
|
|
99
|
+
const arg = args[0];
|
|
100
|
+
if (arg === undefined || arg.typeClass === 'unknown')
|
|
101
|
+
return 'unknown';
|
|
102
|
+
const shape = arg.shape;
|
|
103
|
+
if (shape === undefined || shape.indirection === 'unknown' || shape.cv === 'unknown') {
|
|
104
|
+
return 'unknown';
|
|
105
|
+
}
|
|
106
|
+
if (options.requireTopLevelCv === true && shape.indirection === 'pointer') {
|
|
107
|
+
return 'unknown';
|
|
108
|
+
}
|
|
109
|
+
return predicate(shape) ? 'compatible' : 'incompatible';
|
|
110
|
+
}
|
|
111
|
+
function isPlainValue(arg) {
|
|
112
|
+
const shape = arg.shape;
|
|
113
|
+
if (shape === undefined)
|
|
114
|
+
return true;
|
|
115
|
+
return shape.indirection === 'value';
|
|
116
|
+
}
|
|
117
|
+
function classifyConstraintArg(token, shape) {
|
|
118
|
+
if (shape !== undefined && shape.base.startsWith('enum:')) {
|
|
119
|
+
return { typeClass: 'enum', shape };
|
|
120
|
+
}
|
|
121
|
+
const typeClass = token === undefined || token === '' ? 'unknown' : classifyType(token);
|
|
122
|
+
return { typeClass, ...(shape !== undefined ? { shape } : {}) };
|
|
123
|
+
}
|
|
124
|
+
function tokenForArg(ctx, argIdx) {
|
|
125
|
+
const shape = ctx.argumentTypeClasses?.[argIdx];
|
|
126
|
+
if (shape?.base.startsWith('enum:'))
|
|
127
|
+
return shape.base;
|
|
128
|
+
return ctx.argumentTypes?.[argIdx];
|
|
129
|
+
}
|
|
130
|
+
function shapeForTemplateParam(ctx, paramName, argIdx, def) {
|
|
131
|
+
const argShape = ctx.argumentTypeClasses?.[argIdx];
|
|
132
|
+
if (argShape === undefined)
|
|
133
|
+
return undefined;
|
|
134
|
+
const paramShape = def?.parameterTypeClasses?.[argIdx];
|
|
135
|
+
if (paramShape === undefined)
|
|
136
|
+
return argShape;
|
|
137
|
+
if (paramShape.base === paramName && paramShape.indirection === 'value')
|
|
138
|
+
return argShape;
|
|
139
|
+
return undefined;
|
|
67
140
|
}
|
|
68
141
|
/** Public surface — registered as `ScopeResolver.constraintCompatibility`. */
|
|
69
142
|
export function cppConstraintCompatibility(_callsite, def, ctx) {
|
|
70
143
|
const payload = def.templateConstraints;
|
|
71
144
|
if (payload === undefined)
|
|
72
145
|
return 'unknown';
|
|
73
|
-
return evaluate(payload.expr, payload, ctx);
|
|
146
|
+
return evaluate(payload.expr, payload, ctx, def);
|
|
74
147
|
}
|
|
75
|
-
function evaluate(expr, payload, ctx) {
|
|
148
|
+
function evaluate(expr, payload, ctx, def) {
|
|
76
149
|
switch (expr.kind) {
|
|
77
150
|
case 'unknown':
|
|
78
151
|
return 'unknown';
|
|
@@ -83,18 +156,15 @@ function evaluate(expr, payload, ctx) {
|
|
|
83
156
|
const classes = expr.args.map((paramName) => {
|
|
84
157
|
const argIdx = payload.paramArgIndex[paramName];
|
|
85
158
|
if (argIdx === undefined)
|
|
86
|
-
return 'unknown';
|
|
87
|
-
|
|
88
|
-
if (token === undefined || token === '')
|
|
89
|
-
return 'unknown';
|
|
90
|
-
return classifyType(token);
|
|
159
|
+
return { typeClass: 'unknown' };
|
|
160
|
+
return classifyConstraintArg(tokenForArg(ctx, argIdx), shapeForTemplateParam(ctx, paramName, argIdx, def));
|
|
91
161
|
});
|
|
92
162
|
return evaluator(classes);
|
|
93
163
|
}
|
|
94
164
|
case 'and': {
|
|
95
165
|
let result = 'compatible';
|
|
96
166
|
for (const child of expr.children) {
|
|
97
|
-
const v = evaluate(child, payload, ctx);
|
|
167
|
+
const v = evaluate(child, payload, ctx, def);
|
|
98
168
|
if (v === 'incompatible')
|
|
99
169
|
return 'incompatible';
|
|
100
170
|
if (v === 'unknown')
|
|
@@ -105,7 +175,7 @@ function evaluate(expr, payload, ctx) {
|
|
|
105
175
|
case 'or': {
|
|
106
176
|
let result = 'incompatible';
|
|
107
177
|
for (const child of expr.children) {
|
|
108
|
-
const v = evaluate(child, payload, ctx);
|
|
178
|
+
const v = evaluate(child, payload, ctx, def);
|
|
109
179
|
if (v === 'compatible')
|
|
110
180
|
return 'compatible';
|
|
111
181
|
if (v === 'unknown')
|
|
@@ -114,7 +184,7 @@ function evaluate(expr, payload, ctx) {
|
|
|
114
184
|
return result;
|
|
115
185
|
}
|
|
116
186
|
case 'not': {
|
|
117
|
-
const v = evaluate(expr.child, payload, ctx);
|
|
187
|
+
const v = evaluate(expr.child, payload, ctx, def);
|
|
118
188
|
if (v === 'compatible')
|
|
119
189
|
return 'incompatible';
|
|
120
190
|
if (v === 'incompatible')
|
|
@@ -7,20 +7,20 @@
|
|
|
7
7
|
* the call-site inference in `captures.ts`) to one of the categories
|
|
8
8
|
* the `<type_traits>` predicate registry uses for SFINAE filtering.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* ("including any cv-qualified variants").
|
|
10
|
+
* `argumentTypes` remain normalized for overload narrowing, while
|
|
11
|
+
* constraint predicates that need cv/ref/pointer shape read the parallel
|
|
12
|
+
* `argumentTypeClasses` sidecar. Unknown shapes must stay unknown rather
|
|
13
|
+
* than being guessed as incompatible.
|
|
15
14
|
*/
|
|
16
|
-
export type TypeClass = 'integral' | 'floating' | 'bool' | 'char' | 'string' | 'null' | 'class' | 'unknown';
|
|
15
|
+
export type TypeClass = 'integral' | 'floating' | 'bool' | 'char' | 'string' | 'null' | 'void' | 'enum' | 'class' | 'pointer' | 'reference' | 'unknown';
|
|
17
16
|
/**
|
|
18
17
|
* Classify a normalized C++ type token. The mapping mirrors the literal-
|
|
19
18
|
* inference table in `captures.ts:inferCppLiteralType` plus the std::
|
|
20
19
|
* normalization in `arity-metadata.ts:normalizeCppParamType`.
|
|
21
20
|
*
|
|
22
|
-
* Caller note: token
|
|
23
|
-
*
|
|
24
|
-
*
|
|
21
|
+
* Caller note: token should be normalized for overload matching. Enum
|
|
22
|
+
* tokens produced by the C++ adapter use the internal `enum:<Name>`
|
|
23
|
+
* prefix so `is_enum_v` does not have to guess that every user token is
|
|
24
|
+
* class-like.
|
|
25
25
|
*/
|
|
26
26
|
export declare function classifyType(token: string): TypeClass;
|
|
@@ -7,25 +7,29 @@
|
|
|
7
7
|
* the call-site inference in `captures.ts`) to one of the categories
|
|
8
8
|
* the `<type_traits>` predicate registry uses for SFINAE filtering.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* ("including any cv-qualified variants").
|
|
10
|
+
* `argumentTypes` remain normalized for overload narrowing, while
|
|
11
|
+
* constraint predicates that need cv/ref/pointer shape read the parallel
|
|
12
|
+
* `argumentTypeClasses` sidecar. Unknown shapes must stay unknown rather
|
|
13
|
+
* than being guessed as incompatible.
|
|
15
14
|
*/
|
|
16
15
|
/**
|
|
17
16
|
* Classify a normalized C++ type token. The mapping mirrors the literal-
|
|
18
17
|
* inference table in `captures.ts:inferCppLiteralType` plus the std::
|
|
19
18
|
* normalization in `arity-metadata.ts:normalizeCppParamType`.
|
|
20
19
|
*
|
|
21
|
-
* Caller note: token
|
|
22
|
-
*
|
|
23
|
-
*
|
|
20
|
+
* Caller note: token should be normalized for overload matching. Enum
|
|
21
|
+
* tokens produced by the C++ adapter use the internal `enum:<Name>`
|
|
22
|
+
* prefix so `is_enum_v` does not have to guess that every user token is
|
|
23
|
+
* class-like.
|
|
24
24
|
*/
|
|
25
25
|
export function classifyType(token) {
|
|
26
26
|
if (token.length === 0)
|
|
27
27
|
return 'unknown';
|
|
28
|
+
if (token.startsWith('enum:'))
|
|
29
|
+
return 'enum';
|
|
28
30
|
switch (token) {
|
|
31
|
+
case 'void':
|
|
32
|
+
return 'void';
|
|
29
33
|
case 'int':
|
|
30
34
|
return 'integral';
|
|
31
35
|
case 'double':
|
|
@@ -26,6 +26,40 @@ import { createVariableExtractor } from '../variable-extractors/generic.js';
|
|
|
26
26
|
import { javaVariableConfig } from '../variable-extractors/configs/jvm.js';
|
|
27
27
|
import { createHeritageExtractor } from '../heritage-extractors/generic.js';
|
|
28
28
|
import { emitJavaScopeCaptures, interpretJavaImport, interpretJavaTypeBinding, javaBindingScopeFor, javaImportOwningScope, javaMergeBindings, javaReceiverBinding, javaArityCompatibility, resolveJavaImportTarget, } from './java/index.js';
|
|
29
|
+
const orderJavaSameNameTypeCandidates = ({ callSiteFilePath, candidates, }) => {
|
|
30
|
+
if (!callSiteFilePath.endsWith('.java'))
|
|
31
|
+
return null;
|
|
32
|
+
if (candidates.length <= 1)
|
|
33
|
+
return null;
|
|
34
|
+
const callerDir = splitDirectorySegments(callSiteFilePath);
|
|
35
|
+
const scored = candidates.map((candidate, index) => ({
|
|
36
|
+
candidate,
|
|
37
|
+
index,
|
|
38
|
+
score: sharedPrefixLength(callerDir, splitDirectorySegments(candidate.filePath)),
|
|
39
|
+
}));
|
|
40
|
+
const bestScore = Math.max(...scored.map((entry) => entry.score));
|
|
41
|
+
// When all candidates tie, we have no structural signal to prefer one path.
|
|
42
|
+
// Returning null keeps downstream ambiguity handling conservative.
|
|
43
|
+
if (scored.every((entry) => entry.score === bestScore))
|
|
44
|
+
return null;
|
|
45
|
+
const ordered = [...scored]
|
|
46
|
+
.sort((a, b) => b.score - a.score || a.index - b.index)
|
|
47
|
+
.map((entry) => entry.candidate);
|
|
48
|
+
return ordered;
|
|
49
|
+
};
|
|
50
|
+
const splitDirectorySegments = (filePath) => {
|
|
51
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
52
|
+
// Remove empty segments from leading/trailing/multiple slashes, then drop filename.
|
|
53
|
+
const segments = normalized.split('/').filter(Boolean);
|
|
54
|
+
return segments.slice(0, -1);
|
|
55
|
+
};
|
|
56
|
+
const sharedPrefixLength = (left, right) => {
|
|
57
|
+
const max = Math.min(left.length, right.length);
|
|
58
|
+
let idx = 0;
|
|
59
|
+
while (idx < max && left[idx] === right[idx])
|
|
60
|
+
idx += 1;
|
|
61
|
+
return idx;
|
|
62
|
+
};
|
|
29
63
|
export const javaProvider = defineLanguage({
|
|
30
64
|
id: SupportedLanguages.Java,
|
|
31
65
|
extensions: ['.java'],
|
|
@@ -73,4 +107,5 @@ export const javaProvider = defineLanguage({
|
|
|
73
107
|
receiverBinding: javaReceiverBinding,
|
|
74
108
|
arityCompatibility: javaArityCompatibility,
|
|
75
109
|
resolveImportTarget: resolveJavaImportTarget,
|
|
110
|
+
orderSameNameTypeCandidates: orderJavaSameNameTypeCandidates,
|
|
76
111
|
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Arity compatibility for JavaScript.
|
|
3
|
+
*
|
|
4
|
+
* Delegates to `typescriptArityCompatibility` unchanged — JavaScript
|
|
5
|
+
* supports the same arity constructs (rest parameters `...args`, default
|
|
6
|
+
* parameters `p = v`) and the metadata shape (`parameterCount`,
|
|
7
|
+
* `requiredParameterCount`, `parameterTypes`) is synthesized by the same
|
|
8
|
+
* `computeTsArityMetadata` function (which understands both TS and JS
|
|
9
|
+
* parameter node types via `extractTsJsParameters`).
|
|
10
|
+
*/
|
|
11
|
+
export { typescriptArityCompatibility as jsArityCompatibility } from '../typescript/arity.js';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Arity compatibility for JavaScript.
|
|
3
|
+
*
|
|
4
|
+
* Delegates to `typescriptArityCompatibility` unchanged — JavaScript
|
|
5
|
+
* supports the same arity constructs (rest parameters `...args`, default
|
|
6
|
+
* parameters `p = v`) and the metadata shape (`parameterCount`,
|
|
7
|
+
* `requiredParameterCount`, `parameterTypes`) is synthesized by the same
|
|
8
|
+
* `computeTsArityMetadata` function (which understands both TS and JS
|
|
9
|
+
* parameter node types via `extractTsJsParameters`).
|
|
10
|
+
*/
|
|
11
|
+
export { typescriptArityCompatibility as jsArityCompatibility } from '../typescript/arity.js';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `emitScopeCaptures` for JavaScript.
|
|
3
|
+
*
|
|
4
|
+
* Adapts `emitTsScopeCaptures` for the JavaScript grammar:
|
|
5
|
+
*
|
|
6
|
+
* 1. **JS grammar** — uses `tree-sitter-javascript` instead of
|
|
7
|
+
* `tree-sitter-typescript`. The JS scope query is a subset of the
|
|
8
|
+
* TypeScript one (TypeScript-only node types dropped).
|
|
9
|
+
*
|
|
10
|
+
* 2. **CJS `require()` decomposition** — `const { X } = require('./m')`
|
|
11
|
+
* and `const X = require('./m')` are walked in a post-query pass and
|
|
12
|
+
* synthesized as `@import.kind/name/alias/source` markers so that
|
|
13
|
+
* `interpretJsImport` can recover a `ParsedImport` using the same
|
|
14
|
+
* shape as the TypeScript ESM decomposer.
|
|
15
|
+
*
|
|
16
|
+
* 3. **JSDoc type bindings** — JavaScript has no static type annotations
|
|
17
|
+
* so `@type-binding.parameter` / `@type-binding.return` must be
|
|
18
|
+
* inferred from leading JSDoc comments. A lightweight regex scanner
|
|
19
|
+
* (`parseJsDocParams` / `parseJsDocReturn`) extracts `@param {T} n`
|
|
20
|
+
* and `@returns {T}` tags and emits synthetic captures positioned on
|
|
21
|
+
* the annotated function node.
|
|
22
|
+
*
|
|
23
|
+
* 4. **Shared synthesis passes** — destructuring, for-of map-tuple, and
|
|
24
|
+
* instanceof narrowing passes are duplicated from `typescript/captures.ts`
|
|
25
|
+
* (they are pure AST operations with no grammar-specific logic).
|
|
26
|
+
*
|
|
27
|
+
* Pure given the input source text. No I/O, no globals consulted.
|
|
28
|
+
*/
|
|
29
|
+
import type { CaptureMatch } from '../../../../_shared/index.js';
|
|
30
|
+
export declare function emitJsScopeCaptures(sourceText: string, filePath: string, cachedTree?: unknown): readonly CaptureMatch[];
|