gitnexus 1.6.2-rc.14 → 1.6.2-rc.16
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/lbug/schema-constants.d.ts +1 -1
- package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
- package/dist/_shared/lbug/schema-constants.js +1 -0
- package/dist/_shared/lbug/schema-constants.js.map +1 -1
- package/dist/core/ingestion/call-extractors/configs/c-cpp.d.ts +3 -0
- package/dist/core/ingestion/call-extractors/configs/c-cpp.js +8 -0
- package/dist/core/ingestion/call-extractors/configs/csharp.d.ts +2 -0
- package/dist/core/ingestion/call-extractors/configs/csharp.js +6 -0
- package/dist/core/ingestion/call-extractors/configs/dart.d.ts +2 -0
- package/dist/core/ingestion/call-extractors/configs/dart.js +5 -0
- package/dist/core/ingestion/call-extractors/configs/go.d.ts +2 -0
- package/dist/core/ingestion/call-extractors/configs/go.js +5 -0
- package/dist/core/ingestion/call-extractors/configs/jvm.d.ts +3 -0
- package/dist/core/ingestion/call-extractors/configs/jvm.js +51 -0
- package/dist/core/ingestion/call-extractors/configs/php.d.ts +2 -0
- package/dist/core/ingestion/call-extractors/configs/php.js +5 -0
- package/dist/core/ingestion/call-extractors/configs/python.d.ts +2 -0
- package/dist/core/ingestion/call-extractors/configs/python.js +5 -0
- package/dist/core/ingestion/call-extractors/configs/ruby.d.ts +2 -0
- package/dist/core/ingestion/call-extractors/configs/ruby.js +5 -0
- package/dist/core/ingestion/call-extractors/configs/rust.d.ts +2 -0
- package/dist/core/ingestion/call-extractors/configs/rust.js +5 -0
- package/dist/core/ingestion/call-extractors/configs/swift.d.ts +2 -0
- package/dist/core/ingestion/call-extractors/configs/swift.js +5 -0
- package/dist/core/ingestion/call-extractors/configs/typescript-javascript.d.ts +3 -0
- package/dist/core/ingestion/call-extractors/configs/typescript-javascript.js +8 -0
- package/dist/core/ingestion/call-extractors/generic.d.ts +5 -0
- package/dist/core/ingestion/call-extractors/generic.js +59 -0
- package/dist/core/ingestion/call-processor.js +48 -45
- package/dist/core/ingestion/call-types.d.ts +60 -0
- package/dist/core/ingestion/call-types.js +2 -0
- package/dist/core/ingestion/language-provider.d.ts +12 -0
- package/dist/core/ingestion/languages/c-cpp.js +8 -0
- package/dist/core/ingestion/languages/csharp.js +6 -0
- package/dist/core/ingestion/languages/dart.js +6 -0
- package/dist/core/ingestion/languages/go.js +6 -0
- package/dist/core/ingestion/languages/java.js +6 -0
- package/dist/core/ingestion/languages/kotlin.js +6 -0
- package/dist/core/ingestion/languages/php.js +6 -0
- package/dist/core/ingestion/languages/python.js +6 -0
- package/dist/core/ingestion/languages/ruby.js +6 -0
- package/dist/core/ingestion/languages/rust.js +6 -0
- package/dist/core/ingestion/languages/swift.js +6 -0
- package/dist/core/ingestion/languages/typescript.js +8 -0
- package/dist/core/ingestion/languages/vue.js +6 -0
- package/dist/core/ingestion/tree-sitter-queries.d.ts +11 -11
- package/dist/core/ingestion/tree-sitter-queries.js +81 -0
- package/dist/core/ingestion/utils/ast-helpers.d.ts +1 -1
- package/dist/core/ingestion/utils/ast-helpers.js +3 -0
- package/dist/core/ingestion/variable-extractors/configs/c-cpp.d.ts +3 -0
- package/dist/core/ingestion/variable-extractors/configs/c-cpp.js +81 -0
- package/dist/core/ingestion/variable-extractors/configs/csharp.d.ts +9 -0
- package/dist/core/ingestion/variable-extractors/configs/csharp.js +63 -0
- package/dist/core/ingestion/variable-extractors/configs/dart.d.ts +2 -0
- package/dist/core/ingestion/variable-extractors/configs/dart.js +94 -0
- package/dist/core/ingestion/variable-extractors/configs/go.d.ts +2 -0
- package/dist/core/ingestion/variable-extractors/configs/go.js +83 -0
- package/dist/core/ingestion/variable-extractors/configs/jvm.d.ts +18 -0
- package/dist/core/ingestion/variable-extractors/configs/jvm.js +115 -0
- package/dist/core/ingestion/variable-extractors/configs/php.d.ts +14 -0
- package/dist/core/ingestion/variable-extractors/configs/php.js +58 -0
- package/dist/core/ingestion/variable-extractors/configs/python.d.ts +2 -0
- package/dist/core/ingestion/variable-extractors/configs/python.js +101 -0
- package/dist/core/ingestion/variable-extractors/configs/ruby.d.ts +11 -0
- package/dist/core/ingestion/variable-extractors/configs/ruby.js +52 -0
- package/dist/core/ingestion/variable-extractors/configs/rust.d.ts +2 -0
- package/dist/core/ingestion/variable-extractors/configs/rust.js +76 -0
- package/dist/core/ingestion/variable-extractors/configs/swift.d.ts +2 -0
- package/dist/core/ingestion/variable-extractors/configs/swift.js +88 -0
- package/dist/core/ingestion/variable-extractors/configs/typescript-javascript.d.ts +3 -0
- package/dist/core/ingestion/variable-extractors/configs/typescript-javascript.js +83 -0
- package/dist/core/ingestion/variable-extractors/generic.d.ts +5 -0
- package/dist/core/ingestion/variable-extractors/generic.js +80 -0
- package/dist/core/ingestion/variable-types.d.ts +82 -0
- package/dist/core/ingestion/variable-types.js +2 -0
- package/dist/core/ingestion/workers/parse-worker.js +196 -166
- package/dist/core/lbug/csv-generator.js +1 -0
- package/dist/core/lbug/schema.d.ts +2 -1
- package/dist/core/lbug/schema.js +5 -0
- package/package.json +1 -1
- package/dist/core/ingestion/call-sites/extract-language-call-site.d.ts +0 -10
- package/dist/core/ingestion/call-sites/extract-language-call-site.js +0 -22
- package/dist/core/ingestion/call-sites/java.d.ts +0 -9
- package/dist/core/ingestion/call-sites/java.js +0 -30
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Full DDL schemas remain in each package's own schema.ts because
|
|
8
8
|
* the CLI uses native LadybugDB and the web uses WASM.
|
|
9
9
|
*/
|
|
10
|
-
export declare const NODE_TABLES: readonly ["File", "Folder", "Function", "Class", "Interface", "Method", "CodeElement", "Community", "Process", "Section", "Struct", "Enum", "Macro", "Typedef", "Union", "Namespace", "Trait", "Impl", "TypeAlias", "Const", "Static", "Property", "Record", "Delegate", "Annotation", "Constructor", "Template", "Module", "Route", "Tool"];
|
|
10
|
+
export declare const NODE_TABLES: readonly ["File", "Folder", "Function", "Class", "Interface", "Method", "CodeElement", "Community", "Process", "Section", "Struct", "Enum", "Macro", "Typedef", "Union", "Namespace", "Trait", "Impl", "TypeAlias", "Const", "Static", "Variable", "Property", "Record", "Delegate", "Annotation", "Constructor", "Template", "Module", "Route", "Tool"];
|
|
11
11
|
export type NodeTableName = (typeof NODE_TABLES)[number];
|
|
12
12
|
export declare const REL_TABLE_NAME = "CodeRelation";
|
|
13
13
|
export declare const REL_TYPES: readonly ["CONTAINS", "DEFINES", "IMPORTS", "CALLS", "EXTENDS", "IMPLEMENTS", "HAS_METHOD", "HAS_PROPERTY", "ACCESSES", "METHOD_OVERRIDES", "OVERRIDES", "METHOD_IMPLEMENTS", "MEMBER_OF", "STEP_IN_PROCESS", "HANDLES_ROUTE", "FETCHES", "HANDLES_TOOL", "ENTRY_POINT_OF", "WRAPS", "QUERIES"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-constants.d.ts","sourceRoot":"","sources":["../../src/lbug/schema-constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"schema-constants.d.ts","sourceRoot":"","sources":["../../src/lbug/schema-constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,eAAO,MAAM,WAAW,0VAgCd,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD,eAAO,MAAM,cAAc,iBAAiB,CAAC;AAE7C,eAAO,MAAM,SAAS,iSAqBZ,CAAC;AAEX,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjD,eAAO,MAAM,oBAAoB,kBAAkB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-constants.js","sourceRoot":"","sources":["../../src/lbug/schema-constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,MAAM;IACN,QAAQ;IACR,UAAU;IACV,OAAO;IACP,WAAW;IACX,QAAQ;IACR,aAAa;IACb,WAAW;IACX,SAAS;IACT,SAAS;IACT,QAAQ;IACR,MAAM;IACN,OAAO;IACP,SAAS;IACT,OAAO;IACP,WAAW;IACX,OAAO;IACP,MAAM;IACN,WAAW;IACX,OAAO;IACP,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,UAAU;IACV,YAAY;IACZ,aAAa;IACb,UAAU;IACV,QAAQ;IACR,OAAO;IACP,MAAM;CACE,CAAC;AAIX,MAAM,CAAC,MAAM,cAAc,GAAG,cAAc,CAAC;AAE7C,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,UAAU;IACV,SAAS;IACT,SAAS;IACT,OAAO;IACP,SAAS;IACT,YAAY;IACZ,YAAY;IACZ,cAAc;IACd,UAAU;IACV,kBAAkB;IAClB,WAAW,EAAE,mEAAmE;IAChF,mBAAmB;IACnB,WAAW;IACX,iBAAiB;IACjB,eAAe;IACf,SAAS;IACT,cAAc;IACd,gBAAgB;IAChB,OAAO;IACP,SAAS;CACD,CAAC;AAIX,MAAM,CAAC,MAAM,oBAAoB,GAAG,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"schema-constants.js","sourceRoot":"","sources":["../../src/lbug/schema-constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,MAAM;IACN,QAAQ;IACR,UAAU;IACV,OAAO;IACP,WAAW;IACX,QAAQ;IACR,aAAa;IACb,WAAW;IACX,SAAS;IACT,SAAS;IACT,QAAQ;IACR,MAAM;IACN,OAAO;IACP,SAAS;IACT,OAAO;IACP,WAAW;IACX,OAAO;IACP,MAAM;IACN,WAAW;IACX,OAAO;IACP,QAAQ;IACR,UAAU;IACV,UAAU;IACV,QAAQ;IACR,UAAU;IACV,YAAY;IACZ,aAAa;IACb,UAAU;IACV,QAAQ;IACR,OAAO;IACP,MAAM;CACE,CAAC;AAIX,MAAM,CAAC,MAAM,cAAc,GAAG,cAAc,CAAC;AAE7C,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,UAAU;IACV,SAAS;IACT,SAAS;IACT,OAAO;IACP,SAAS;IACT,YAAY;IACZ,YAAY;IACZ,cAAc;IACd,UAAU;IACV,kBAAkB;IAClB,WAAW,EAAE,mEAAmE;IAChF,mBAAmB;IACnB,WAAW;IACX,iBAAiB;IACjB,eAAe;IACf,SAAS;IACT,cAAc;IACd,gBAAgB;IAChB,OAAO;IACP,SAAS;CACD,CAAC;AAIX,MAAM,CAAC,MAAM,oBAAoB,GAAG,eAAe,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// gitnexus/src/core/ingestion/call-extractors/configs/c-cpp.ts
|
|
2
|
+
import { SupportedLanguages } from '../../../../_shared/index.js';
|
|
3
|
+
export const cCallConfig = {
|
|
4
|
+
language: SupportedLanguages.C,
|
|
5
|
+
};
|
|
6
|
+
export const cppCallConfig = {
|
|
7
|
+
language: SupportedLanguages.CPlusPlus,
|
|
8
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// gitnexus/src/core/ingestion/call-extractors/configs/jvm.ts
|
|
2
|
+
import { SupportedLanguages } from '../../../../_shared/index.js';
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Java method_reference (::) parsing — absorbs call-sites/java.ts
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
/**
|
|
7
|
+
* Parse Java `method_reference` nodes (`expr::method`, `Type::new`,
|
|
8
|
+
* `this::m`, `super::m`).
|
|
9
|
+
*/
|
|
10
|
+
function parseJavaMethodReference(callNode) {
|
|
11
|
+
if (callNode.type !== 'method_reference')
|
|
12
|
+
return null;
|
|
13
|
+
const recv = callNode.namedChild(0);
|
|
14
|
+
if (!recv)
|
|
15
|
+
return null;
|
|
16
|
+
// Type::new → constructor call
|
|
17
|
+
for (const c of callNode.children) {
|
|
18
|
+
if (c.type === 'new') {
|
|
19
|
+
if (recv.type !== 'identifier')
|
|
20
|
+
return null;
|
|
21
|
+
return { calledName: recv.text, callForm: 'constructor' };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// expr::method → member call with receiver
|
|
25
|
+
const rhs = callNode.child(callNode.childCount - 1);
|
|
26
|
+
if (!rhs || rhs.type !== 'identifier')
|
|
27
|
+
return null;
|
|
28
|
+
const methodName = rhs.text;
|
|
29
|
+
if (recv.type === 'identifier') {
|
|
30
|
+
return { calledName: methodName, callForm: 'member', receiverName: recv.text };
|
|
31
|
+
}
|
|
32
|
+
if (recv.type === 'this') {
|
|
33
|
+
return { calledName: methodName, callForm: 'member', receiverName: 'this' };
|
|
34
|
+
}
|
|
35
|
+
if (recv.type === 'super') {
|
|
36
|
+
return { calledName: methodName, callForm: 'member', receiverName: 'super' };
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// Configs
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
export const javaCallConfig = {
|
|
44
|
+
language: SupportedLanguages.Java,
|
|
45
|
+
extractLanguageCallSite: parseJavaMethodReference,
|
|
46
|
+
typeAsReceiverHeuristic: true,
|
|
47
|
+
};
|
|
48
|
+
export const kotlinCallConfig = {
|
|
49
|
+
language: SupportedLanguages.Kotlin,
|
|
50
|
+
typeAsReceiverHeuristic: true,
|
|
51
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// gitnexus/src/core/ingestion/call-extractors/configs/typescript-javascript.ts
|
|
2
|
+
import { SupportedLanguages } from '../../../../_shared/index.js';
|
|
3
|
+
export const typescriptCallConfig = {
|
|
4
|
+
language: SupportedLanguages.TypeScript,
|
|
5
|
+
};
|
|
6
|
+
export const javascriptCallConfig = {
|
|
7
|
+
language: SupportedLanguages.JavaScript,
|
|
8
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// gitnexus/src/core/ingestion/call-extractors/generic.ts
|
|
2
|
+
import { inferCallForm, extractReceiverName, extractReceiverNode, extractMixedChain, countCallArguments, } from '../utils/call-analysis.js';
|
|
3
|
+
/**
|
|
4
|
+
* Create a CallExtractor from a declarative config.
|
|
5
|
+
*/
|
|
6
|
+
export function createCallExtractor(config) {
|
|
7
|
+
return {
|
|
8
|
+
language: config.language,
|
|
9
|
+
extract(callNode, callNameNode) {
|
|
10
|
+
// ── Path 1: Language-specific call site ──────────────────────────
|
|
11
|
+
// Non-standard call shapes (e.g. Java `::` method references) are
|
|
12
|
+
// handled entirely by the config hook. When it returns a result,
|
|
13
|
+
// the generic path is skipped — no argCount, no mixed chain.
|
|
14
|
+
//
|
|
15
|
+
// Note: `extractLanguageCallSite` is called on every `extract()`
|
|
16
|
+
// invocation — both `extract(callNode, undefined)` (parse-worker
|
|
17
|
+
// Path 1) and `extract(callNode, callNameNode)` (Path 2).
|
|
18
|
+
// Language hooks must therefore be idempotent and cheap (e.g. a
|
|
19
|
+
// single node-type check).
|
|
20
|
+
if (config.extractLanguageCallSite) {
|
|
21
|
+
const seed = config.extractLanguageCallSite(callNode);
|
|
22
|
+
if (seed) {
|
|
23
|
+
return {
|
|
24
|
+
...seed,
|
|
25
|
+
...(config.typeAsReceiverHeuristic ? { typeAsReceiverHeuristic: true } : {}),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// ── Path 2: Generic extraction via @call.name ────────────────────
|
|
30
|
+
if (!callNameNode)
|
|
31
|
+
return null;
|
|
32
|
+
const calledName = callNameNode.text;
|
|
33
|
+
const callForm = inferCallForm(callNode, callNameNode);
|
|
34
|
+
let receiverName = callForm === 'member' ? extractReceiverName(callNameNode) : undefined;
|
|
35
|
+
let receiverMixedChain;
|
|
36
|
+
// When the receiver is a complex expression (call chain, field chain,
|
|
37
|
+
// or mixed), extractReceiverName returns undefined. Walk the receiver
|
|
38
|
+
// node to build a unified mixed chain for deferred resolution.
|
|
39
|
+
if (callForm === 'member' && receiverName === undefined) {
|
|
40
|
+
const receiverNode = extractReceiverNode(callNameNode);
|
|
41
|
+
if (receiverNode) {
|
|
42
|
+
const extracted = extractMixedChain(receiverNode);
|
|
43
|
+
if (extracted && extracted.chain.length > 0) {
|
|
44
|
+
receiverMixedChain = extracted.chain;
|
|
45
|
+
receiverName = extracted.baseReceiverName;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
calledName,
|
|
51
|
+
...(callForm !== undefined ? { callForm } : {}),
|
|
52
|
+
...(receiverName !== undefined ? { receiverName } : {}),
|
|
53
|
+
argCount: countCallArguments(callNode),
|
|
54
|
+
...(receiverMixedChain !== undefined ? { receiverMixedChain } : {}),
|
|
55
|
+
...(config.typeAsReceiverHeuristic ? { typeAsReceiverHeuristic: true } : {}),
|
|
56
|
+
};
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
@@ -15,7 +15,6 @@ import { getTreeSitterBufferSize } from './constants.js';
|
|
|
15
15
|
import { normalizeFetchURL, routeMatches } from './route-extractors/nextjs.js';
|
|
16
16
|
import { extractTemplateComponents } from './vue-sfc-extractor.js';
|
|
17
17
|
import { extractReturnTypeName, stripNullable } from './type-extractors/shared.js';
|
|
18
|
-
import { extractParsedCallSite } from './call-sites/extract-language-call-site.js';
|
|
19
18
|
import { lookupMethodByOwnerWithMRO } from './model/resolve.js';
|
|
20
19
|
/**
|
|
21
20
|
* Type labels treated as class-like **method-dispatch receivers** by the call
|
|
@@ -733,52 +732,56 @@ importedRawReturnTypesMap, heritageMap, bindingAccumulator) => {
|
|
|
733
732
|
if (!captureMap['call'])
|
|
734
733
|
return;
|
|
735
734
|
const callNode = captureMap['call'];
|
|
736
|
-
const
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
(
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
callForm: languageSeed.callForm,
|
|
755
|
-
...(receiverTypeName !== undefined ? { receiverTypeName } : {}),
|
|
756
|
-
...(receiverName !== undefined ? { receiverName } : {}),
|
|
757
|
-
}, file.path, ctx, undefined, widenCache, undefined, heritageMap);
|
|
758
|
-
if (!resolved)
|
|
759
|
-
return;
|
|
760
|
-
graph.addRelationship({
|
|
761
|
-
id: generateId('CALLS', `${sourceId}:${languageSeed.calledName}->${resolved.nodeId}`),
|
|
762
|
-
sourceId,
|
|
763
|
-
targetId: resolved.nodeId,
|
|
764
|
-
type: 'CALLS',
|
|
765
|
-
confidence: resolved.confidence,
|
|
766
|
-
reason: resolved.reason,
|
|
767
|
-
});
|
|
768
|
-
if (heritageMap && languageSeed.callForm === 'member' && receiverTypeName) {
|
|
769
|
-
const implTargets = findInterfaceDispatchTargets(languageSeed.calledName, receiverTypeName, file.path, ctx, heritageMap, resolved.nodeId);
|
|
770
|
-
for (const impl of implTargets) {
|
|
771
|
-
graph.addRelationship({
|
|
772
|
-
id: generateId('CALLS', `${sourceId}:${languageSeed.calledName}->${impl.nodeId}`),
|
|
773
|
-
sourceId,
|
|
774
|
-
targetId: impl.nodeId,
|
|
775
|
-
type: 'CALLS',
|
|
776
|
-
confidence: impl.confidence,
|
|
777
|
-
reason: impl.reason,
|
|
778
|
-
});
|
|
735
|
+
const callExtractor = provider.callExtractor;
|
|
736
|
+
// ── Language-specific call site (e.g. Java :: method references) ──
|
|
737
|
+
if (callExtractor) {
|
|
738
|
+
const langCallSite = callExtractor.extract(callNode, undefined);
|
|
739
|
+
if (langCallSite) {
|
|
740
|
+
if (provider.isBuiltInName(langCallSite.calledName))
|
|
741
|
+
return;
|
|
742
|
+
const sourceId = findEnclosingFunction(callNode, file.path, ctx, provider) ||
|
|
743
|
+
generateId('File', file.path);
|
|
744
|
+
const receiverName = langCallSite.callForm === 'member' ? langCallSite.receiverName : undefined;
|
|
745
|
+
let receiverTypeName = receiverName && typeEnv ? typeEnv.lookup(receiverName, callNode) : undefined;
|
|
746
|
+
if (langCallSite.typeAsReceiverHeuristic &&
|
|
747
|
+
receiverName !== undefined &&
|
|
748
|
+
receiverTypeName === undefined &&
|
|
749
|
+
langCallSite.callForm === 'member') {
|
|
750
|
+
const c0 = receiverName.charCodeAt(0);
|
|
751
|
+
if (c0 >= 65 && c0 <= 90)
|
|
752
|
+
receiverTypeName = receiverName;
|
|
779
753
|
}
|
|
754
|
+
const resolved = resolveCallTarget({
|
|
755
|
+
calledName: langCallSite.calledName,
|
|
756
|
+
callForm: langCallSite.callForm,
|
|
757
|
+
...(receiverTypeName !== undefined ? { receiverTypeName } : {}),
|
|
758
|
+
...(receiverName !== undefined ? { receiverName } : {}),
|
|
759
|
+
}, file.path, ctx, undefined, widenCache, undefined, heritageMap);
|
|
760
|
+
if (!resolved)
|
|
761
|
+
return;
|
|
762
|
+
graph.addRelationship({
|
|
763
|
+
id: generateId('CALLS', `${sourceId}:${langCallSite.calledName}->${resolved.nodeId}`),
|
|
764
|
+
sourceId,
|
|
765
|
+
targetId: resolved.nodeId,
|
|
766
|
+
type: 'CALLS',
|
|
767
|
+
confidence: resolved.confidence,
|
|
768
|
+
reason: resolved.reason,
|
|
769
|
+
});
|
|
770
|
+
if (heritageMap && langCallSite.callForm === 'member' && receiverTypeName) {
|
|
771
|
+
const implTargets = findInterfaceDispatchTargets(langCallSite.calledName, receiverTypeName, file.path, ctx, heritageMap, resolved.nodeId);
|
|
772
|
+
for (const impl of implTargets) {
|
|
773
|
+
graph.addRelationship({
|
|
774
|
+
id: generateId('CALLS', `${sourceId}:${langCallSite.calledName}->${impl.nodeId}`),
|
|
775
|
+
sourceId,
|
|
776
|
+
targetId: impl.nodeId,
|
|
777
|
+
type: 'CALLS',
|
|
778
|
+
confidence: impl.confidence,
|
|
779
|
+
reason: impl.reason,
|
|
780
|
+
});
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
return;
|
|
780
784
|
}
|
|
781
|
-
return;
|
|
782
785
|
}
|
|
783
786
|
const nameNode = captureMap['call.name'];
|
|
784
787
|
if (!nameNode)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for the language-agnostic call extraction pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors method-types.ts / field-types.ts: defines the domain interfaces
|
|
5
|
+
* consumed by createCallExtractor() and the per-language configs.
|
|
6
|
+
*/
|
|
7
|
+
import type { SupportedLanguages } from '../../_shared/index.js';
|
|
8
|
+
import type { SyntaxNode } from './utils/ast-helpers.js';
|
|
9
|
+
import type { MixedChainStep } from './utils/call-analysis.js';
|
|
10
|
+
/**
|
|
11
|
+
* Per-node call extraction result. The parse worker enriches this with
|
|
12
|
+
* file-level context (filePath, sourceId, TypeEnv lookups, arg types) to
|
|
13
|
+
* produce the final `ExtractedCall` that enters the resolution pipeline.
|
|
14
|
+
*/
|
|
15
|
+
export interface ExtractedCallSite {
|
|
16
|
+
calledName: string;
|
|
17
|
+
callForm?: 'free' | 'member' | 'constructor';
|
|
18
|
+
receiverName?: string;
|
|
19
|
+
argCount?: number;
|
|
20
|
+
/** Unified mixed chain for complex receivers (field + call chains). */
|
|
21
|
+
receiverMixedChain?: MixedChainStep[];
|
|
22
|
+
/** When true, the type-as-receiver heuristic applies: if receiverName
|
|
23
|
+
* starts with an uppercase letter and has no TypeEnv binding, treat it
|
|
24
|
+
* as a type name (e.g. Java `User::getName`). */
|
|
25
|
+
typeAsReceiverHeuristic?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export interface CallExtractor {
|
|
28
|
+
readonly language: SupportedLanguages;
|
|
29
|
+
/**
|
|
30
|
+
* Extract a call site from captured AST nodes.
|
|
31
|
+
*
|
|
32
|
+
* @param callNode The @call capture (call_expression, method_invocation, …)
|
|
33
|
+
* @param callNameNode The @call.name capture (identifier inside the call).
|
|
34
|
+
* May be undefined when the call shape has no name capture
|
|
35
|
+
* (e.g. Java method_reference via `::`).
|
|
36
|
+
* @returns Extracted call site, or null when no call can be derived.
|
|
37
|
+
*/
|
|
38
|
+
extract(callNode: SyntaxNode, callNameNode: SyntaxNode | undefined): ExtractedCallSite | null;
|
|
39
|
+
}
|
|
40
|
+
export interface CallExtractionConfig {
|
|
41
|
+
language: SupportedLanguages;
|
|
42
|
+
/**
|
|
43
|
+
* Language-specific call site extraction. Called **before** the generic
|
|
44
|
+
* path. If it returns non-null, the generic `inferCallForm` /
|
|
45
|
+
* `extractReceiverName` path is skipped entirely.
|
|
46
|
+
*
|
|
47
|
+
* Use this for call shapes that don't follow the standard `@call` /
|
|
48
|
+
* `@call.name` pattern (e.g. Java `method_reference` via `::`).
|
|
49
|
+
*/
|
|
50
|
+
extractLanguageCallSite?: (callNode: SyntaxNode) => ExtractedCallSite | null;
|
|
51
|
+
/**
|
|
52
|
+
* Whether the type-as-receiver heuristic applies for this language.
|
|
53
|
+
* When true and the receiver name starts with an uppercase letter,
|
|
54
|
+
* the receiver is treated as a type name when no TypeEnv binding exists.
|
|
55
|
+
*
|
|
56
|
+
* Applies to JVM and C# languages where `Type.method()` and `Type::method`
|
|
57
|
+
* are common patterns.
|
|
58
|
+
*/
|
|
59
|
+
typeAsReceiverHeuristic?: boolean;
|
|
60
|
+
}
|
|
@@ -11,10 +11,12 @@
|
|
|
11
11
|
import type { SupportedLanguages, MroStrategy } from '../../_shared/index.js';
|
|
12
12
|
import type { LanguageTypeConfig } from './type-extractors/types.js';
|
|
13
13
|
import type { CallRouter } from './call-routing.js';
|
|
14
|
+
import type { CallExtractor } from './call-types.js';
|
|
14
15
|
import type { ClassExtractor } from './class-types.js';
|
|
15
16
|
import type { ExportChecker } from './export-detection.js';
|
|
16
17
|
import type { FieldExtractor } from './field-extractor.js';
|
|
17
18
|
import type { MethodExtractor } from './method-types.js';
|
|
19
|
+
import type { VariableExtractor } from './variable-types.js';
|
|
18
20
|
import type { ImportResolverFn } from './import-resolvers/types.js';
|
|
19
21
|
import type { NamedBindingExtractorFn } from './named-bindings/types.js';
|
|
20
22
|
import type { SyntaxNode } from './utils/ast-helpers.js';
|
|
@@ -119,6 +121,12 @@ interface LanguageProviderConfig {
|
|
|
119
121
|
/** MRO strategy for multiple inheritance resolution.
|
|
120
122
|
* Default: 'first-wins'. */
|
|
121
123
|
readonly mroStrategy?: MroStrategy;
|
|
124
|
+
/** Call extractor for extracting call site information (calledName, callForm,
|
|
125
|
+
* receiverName, argCount, mixed chains) from @call / @call.name captures.
|
|
126
|
+
* Produced by createCallExtractor() with a per-language CallExtractionConfig.
|
|
127
|
+
* Default: undefined — if unset, no calls are extracted for this language.
|
|
128
|
+
* All tree-sitter providers MUST supply this. */
|
|
129
|
+
readonly callExtractor?: CallExtractor;
|
|
122
130
|
/** Field extractor for extracting field/property definitions from class/struct
|
|
123
131
|
* declarations. Produces FieldInfo[] with name, type, visibility, static,
|
|
124
132
|
* readonly metadata. Default: undefined (no field extraction). */
|
|
@@ -127,6 +135,10 @@ interface LanguageProviderConfig {
|
|
|
127
135
|
* declarations. Produces MethodInfo[] with name, parameters, visibility, isAbstract,
|
|
128
136
|
* isFinal, annotations metadata. Default: undefined (no method extraction). */
|
|
129
137
|
readonly methodExtractor?: MethodExtractor;
|
|
138
|
+
/** Variable extractor for extracting metadata from module/file-scoped variable,
|
|
139
|
+
* constant, and static declarations. Produces VariableInfo with type, visibility,
|
|
140
|
+
* isConst, isStatic, isMutable metadata. Default: undefined (no variable extraction). */
|
|
141
|
+
readonly variableExtractor?: VariableExtractor;
|
|
130
142
|
/** Class/type extractor for deriving canonical qualified names for class-like symbols.
|
|
131
143
|
* Uses the same provider-driven strategy pattern as method/field extraction so
|
|
132
144
|
* namespace/package/module rules stay language-specific. */
|
|
@@ -30,6 +30,10 @@ import { createFieldExtractor } from '../field-extractors/generic.js';
|
|
|
30
30
|
import { cConfig as cFieldConfig, cppConfig as cppFieldConfig, } from '../field-extractors/configs/c-cpp.js';
|
|
31
31
|
import { createMethodExtractor } from '../method-extractors/generic.js';
|
|
32
32
|
import { cMethodConfig, cppMethodConfig } from '../method-extractors/configs/c-cpp.js';
|
|
33
|
+
import { createVariableExtractor } from '../variable-extractors/generic.js';
|
|
34
|
+
import { cVariableConfig, cppVariableConfig } from '../variable-extractors/configs/c-cpp.js';
|
|
35
|
+
import { createCallExtractor } from '../call-extractors/generic.js';
|
|
36
|
+
import { cCallConfig, cppCallConfig } from '../call-extractors/configs/c-cpp.js';
|
|
33
37
|
const C_BUILT_INS = new Set([
|
|
34
38
|
'printf',
|
|
35
39
|
'fprintf',
|
|
@@ -288,11 +292,13 @@ export const cProvider = defineLanguage({
|
|
|
288
292
|
exportChecker: cCppExportChecker,
|
|
289
293
|
importResolver: resolveCImport,
|
|
290
294
|
importSemantics: 'wildcard-transitive',
|
|
295
|
+
callExtractor: createCallExtractor(cCallConfig),
|
|
291
296
|
fieldExtractor: createFieldExtractor(cFieldConfig),
|
|
292
297
|
methodExtractor: createMethodExtractor({
|
|
293
298
|
...cMethodConfig,
|
|
294
299
|
extractFunctionName: cCppExtractFunctionName,
|
|
295
300
|
}),
|
|
301
|
+
variableExtractor: createVariableExtractor(cVariableConfig),
|
|
296
302
|
classExtractor: cClassExtractor,
|
|
297
303
|
labelOverride: cppLabelOverride,
|
|
298
304
|
builtInNames: C_BUILT_INS,
|
|
@@ -306,11 +312,13 @@ export const cppProvider = defineLanguage({
|
|
|
306
312
|
importResolver: resolveCppImport,
|
|
307
313
|
importSemantics: 'wildcard-transitive',
|
|
308
314
|
mroStrategy: 'leftmost-base',
|
|
315
|
+
callExtractor: createCallExtractor(cppCallConfig),
|
|
309
316
|
fieldExtractor: createFieldExtractor(cppFieldConfig),
|
|
310
317
|
methodExtractor: createMethodExtractor({
|
|
311
318
|
...cppMethodConfig,
|
|
312
319
|
extractFunctionName: cCppExtractFunctionName,
|
|
313
320
|
}),
|
|
321
|
+
variableExtractor: createVariableExtractor(cppVariableConfig),
|
|
314
322
|
classExtractor: cppClassExtractor,
|
|
315
323
|
labelOverride: cppLabelOverride,
|
|
316
324
|
builtInNames: C_BUILT_INS,
|
|
@@ -14,10 +14,14 @@ import { csharpExportChecker } from '../export-detection.js';
|
|
|
14
14
|
import { resolveCSharpImport } from '../import-resolvers/csharp.js';
|
|
15
15
|
import { extractCSharpNamedBindings } from '../named-bindings/csharp.js';
|
|
16
16
|
import { CSHARP_QUERIES } from '../tree-sitter-queries.js';
|
|
17
|
+
import { createCallExtractor } from '../call-extractors/generic.js';
|
|
18
|
+
import { csharpCallConfig } from '../call-extractors/configs/csharp.js';
|
|
17
19
|
import { createFieldExtractor } from '../field-extractors/generic.js';
|
|
18
20
|
import { csharpConfig as csharpFieldConfig } from '../field-extractors/configs/csharp.js';
|
|
19
21
|
import { createMethodExtractor } from '../method-extractors/generic.js';
|
|
20
22
|
import { csharpMethodConfig } from '../method-extractors/configs/csharp.js';
|
|
23
|
+
import { createVariableExtractor } from '../variable-extractors/generic.js';
|
|
24
|
+
import { csharpVariableConfig } from '../variable-extractors/configs/csharp.js';
|
|
21
25
|
const BUILT_INS = new Set([
|
|
22
26
|
'Console',
|
|
23
27
|
'WriteLine',
|
|
@@ -122,8 +126,10 @@ export const csharpProvider = defineLanguage({
|
|
|
122
126
|
namedBindingExtractor: extractCSharpNamedBindings,
|
|
123
127
|
interfaceNamePattern: /^I[A-Z]/,
|
|
124
128
|
mroStrategy: 'implements-split',
|
|
129
|
+
callExtractor: createCallExtractor(csharpCallConfig),
|
|
125
130
|
fieldExtractor: createFieldExtractor(csharpFieldConfig),
|
|
126
131
|
methodExtractor: createMethodExtractor(csharpMethodConfig),
|
|
132
|
+
variableExtractor: createVariableExtractor(csharpVariableConfig),
|
|
127
133
|
classExtractor: createClassExtractor(csharpClassConfig),
|
|
128
134
|
builtInNames: BUILT_INS,
|
|
129
135
|
});
|
|
@@ -22,6 +22,10 @@ import { createFieldExtractor } from '../field-extractors/generic.js';
|
|
|
22
22
|
import { dartConfig as dartFieldConfig } from '../field-extractors/configs/dart.js';
|
|
23
23
|
import { createMethodExtractor } from '../method-extractors/generic.js';
|
|
24
24
|
import { dartMethodConfig } from '../method-extractors/configs/dart.js';
|
|
25
|
+
import { createVariableExtractor } from '../variable-extractors/generic.js';
|
|
26
|
+
import { dartVariableConfig } from '../variable-extractors/configs/dart.js';
|
|
27
|
+
import { createCallExtractor } from '../call-extractors/generic.js';
|
|
28
|
+
import { dartCallConfig } from '../call-extractors/configs/dart.js';
|
|
25
29
|
/**
|
|
26
30
|
* Resolve the enclosing function from a `function_body` node by looking at its
|
|
27
31
|
* previous sibling. In Dart's tree-sitter grammar, function_signature and
|
|
@@ -85,8 +89,10 @@ export const dartProvider = defineLanguage({
|
|
|
85
89
|
exportChecker: dartExportChecker,
|
|
86
90
|
importResolver: resolveDartImport,
|
|
87
91
|
importSemantics: 'wildcard-leaf',
|
|
92
|
+
callExtractor: createCallExtractor(dartCallConfig),
|
|
88
93
|
fieldExtractor: createFieldExtractor(dartFieldConfig),
|
|
89
94
|
methodExtractor: createMethodExtractor(dartMethodConfig),
|
|
95
|
+
variableExtractor: createVariableExtractor(dartVariableConfig),
|
|
90
96
|
classExtractor: createClassExtractor(dartClassConfig),
|
|
91
97
|
enclosingFunctionFinder: dartEnclosingFunctionFinder,
|
|
92
98
|
builtInNames: BUILT_INS,
|
|
@@ -20,6 +20,10 @@ import { createFieldExtractor } from '../field-extractors/generic.js';
|
|
|
20
20
|
import { goConfig as goFieldConfig } from '../field-extractors/configs/go.js';
|
|
21
21
|
import { createMethodExtractor } from '../method-extractors/generic.js';
|
|
22
22
|
import { goMethodConfig } from '../method-extractors/configs/go.js';
|
|
23
|
+
import { createVariableExtractor } from '../variable-extractors/generic.js';
|
|
24
|
+
import { goVariableConfig } from '../variable-extractors/configs/go.js';
|
|
25
|
+
import { createCallExtractor } from '../call-extractors/generic.js';
|
|
26
|
+
import { goCallConfig } from '../call-extractors/configs/go.js';
|
|
23
27
|
export const goProvider = defineLanguage({
|
|
24
28
|
id: SupportedLanguages.Go,
|
|
25
29
|
extensions: ['.go'],
|
|
@@ -28,7 +32,9 @@ export const goProvider = defineLanguage({
|
|
|
28
32
|
exportChecker: goExportChecker,
|
|
29
33
|
importResolver: resolveGoImport,
|
|
30
34
|
importSemantics: 'wildcard-leaf',
|
|
35
|
+
callExtractor: createCallExtractor(goCallConfig),
|
|
31
36
|
fieldExtractor: createFieldExtractor(goFieldConfig),
|
|
32
37
|
methodExtractor: createMethodExtractor(goMethodConfig),
|
|
38
|
+
variableExtractor: createVariableExtractor(goVariableConfig),
|
|
33
39
|
classExtractor: createClassExtractor(goClassConfig),
|
|
34
40
|
});
|
|
@@ -15,10 +15,14 @@ import { javaExportChecker } from '../export-detection.js';
|
|
|
15
15
|
import { resolveJavaImport } from '../import-resolvers/jvm.js';
|
|
16
16
|
import { extractJavaNamedBindings } from '../named-bindings/java.js';
|
|
17
17
|
import { JAVA_QUERIES } from '../tree-sitter-queries.js';
|
|
18
|
+
import { createCallExtractor } from '../call-extractors/generic.js';
|
|
19
|
+
import { javaCallConfig } from '../call-extractors/configs/jvm.js';
|
|
18
20
|
import { createFieldExtractor } from '../field-extractors/generic.js';
|
|
19
21
|
import { javaConfig } from '../field-extractors/configs/jvm.js';
|
|
20
22
|
import { createMethodExtractor } from '../method-extractors/generic.js';
|
|
21
23
|
import { javaMethodConfig } from '../method-extractors/configs/jvm.js';
|
|
24
|
+
import { createVariableExtractor } from '../variable-extractors/generic.js';
|
|
25
|
+
import { javaVariableConfig } from '../variable-extractors/configs/jvm.js';
|
|
22
26
|
export const javaProvider = defineLanguage({
|
|
23
27
|
id: SupportedLanguages.Java,
|
|
24
28
|
extensions: ['.java'],
|
|
@@ -29,7 +33,9 @@ export const javaProvider = defineLanguage({
|
|
|
29
33
|
namedBindingExtractor: extractJavaNamedBindings,
|
|
30
34
|
interfaceNamePattern: /^I[A-Z]/,
|
|
31
35
|
mroStrategy: 'implements-split',
|
|
36
|
+
callExtractor: createCallExtractor(javaCallConfig),
|
|
32
37
|
fieldExtractor: createFieldExtractor(javaConfig),
|
|
33
38
|
methodExtractor: createMethodExtractor(javaMethodConfig),
|
|
39
|
+
variableExtractor: createVariableExtractor(javaVariableConfig),
|
|
34
40
|
classExtractor: createClassExtractor(javaClassConfig),
|
|
35
41
|
});
|