@zuvia-software-solutions/code-mapper 1.4.0 → 2.0.0
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/cli/ai-context.js +1 -1
- package/dist/cli/analyze.d.ts +1 -0
- package/dist/cli/analyze.js +73 -82
- package/dist/cli/augment.js +0 -2
- package/dist/cli/eval-server.d.ts +2 -2
- package/dist/cli/eval-server.js +6 -6
- package/dist/cli/index.js +6 -10
- package/dist/cli/mcp.d.ts +1 -3
- package/dist/cli/mcp.js +3 -3
- package/dist/cli/refresh.d.ts +2 -2
- package/dist/cli/refresh.js +24 -29
- package/dist/cli/status.js +4 -13
- package/dist/cli/tool.d.ts +5 -4
- package/dist/cli/tool.js +8 -10
- package/dist/config/ignore-service.js +14 -34
- package/dist/core/augmentation/engine.js +53 -83
- package/dist/core/db/adapter.d.ts +99 -0
- package/dist/core/db/adapter.js +402 -0
- package/dist/core/db/graph-loader.d.ts +27 -0
- package/dist/core/db/graph-loader.js +148 -0
- package/dist/core/db/queries.d.ts +160 -0
- package/dist/core/db/queries.js +441 -0
- package/dist/core/db/schema.d.ts +108 -0
- package/dist/core/db/schema.js +136 -0
- package/dist/core/embeddings/embedder.d.ts +21 -12
- package/dist/core/embeddings/embedder.js +104 -50
- package/dist/core/embeddings/embedding-pipeline.d.ts +48 -22
- package/dist/core/embeddings/embedding-pipeline.js +220 -262
- package/dist/core/embeddings/text-generator.js +4 -19
- package/dist/core/embeddings/types.d.ts +1 -1
- package/dist/core/graph/graph.d.ts +1 -1
- package/dist/core/graph/graph.js +1 -0
- package/dist/core/graph/types.d.ts +11 -9
- package/dist/core/graph/types.js +4 -1
- package/dist/core/incremental/refresh.d.ts +46 -0
- package/dist/core/incremental/refresh.js +464 -0
- package/dist/core/incremental/types.d.ts +2 -1
- package/dist/core/incremental/types.js +42 -44
- package/dist/core/ingestion/ast-cache.js +1 -0
- package/dist/core/ingestion/call-processor.d.ts +15 -3
- package/dist/core/ingestion/call-processor.js +448 -60
- package/dist/core/ingestion/cluster-enricher.d.ts +1 -1
- package/dist/core/ingestion/cluster-enricher.js +2 -0
- package/dist/core/ingestion/community-processor.d.ts +1 -1
- package/dist/core/ingestion/community-processor.js +8 -3
- package/dist/core/ingestion/export-detection.d.ts +1 -1
- package/dist/core/ingestion/export-detection.js +1 -1
- package/dist/core/ingestion/filesystem-walker.js +1 -1
- package/dist/core/ingestion/heritage-processor.d.ts +2 -2
- package/dist/core/ingestion/heritage-processor.js +22 -11
- package/dist/core/ingestion/import-processor.d.ts +2 -2
- package/dist/core/ingestion/import-processor.js +24 -9
- package/dist/core/ingestion/language-config.js +7 -4
- package/dist/core/ingestion/mro-processor.d.ts +1 -1
- package/dist/core/ingestion/mro-processor.js +23 -11
- package/dist/core/ingestion/named-binding-extraction.js +5 -5
- package/dist/core/ingestion/parsing-processor.d.ts +4 -4
- package/dist/core/ingestion/parsing-processor.js +26 -18
- package/dist/core/ingestion/pipeline.d.ts +4 -2
- package/dist/core/ingestion/pipeline.js +50 -20
- package/dist/core/ingestion/process-processor.d.ts +2 -2
- package/dist/core/ingestion/process-processor.js +28 -14
- package/dist/core/ingestion/resolution-context.d.ts +1 -1
- package/dist/core/ingestion/resolution-context.js +14 -4
- package/dist/core/ingestion/resolvers/csharp.js +4 -3
- package/dist/core/ingestion/resolvers/go.js +3 -1
- package/dist/core/ingestion/resolvers/jvm.js +13 -4
- package/dist/core/ingestion/resolvers/standard.js +2 -2
- package/dist/core/ingestion/resolvers/utils.js +6 -2
- package/dist/core/ingestion/route-stitcher.d.ts +15 -0
- package/dist/core/ingestion/route-stitcher.js +92 -0
- package/dist/core/ingestion/structure-processor.d.ts +1 -1
- package/dist/core/ingestion/structure-processor.js +3 -2
- package/dist/core/ingestion/symbol-table.d.ts +2 -0
- package/dist/core/ingestion/symbol-table.js +5 -1
- package/dist/core/ingestion/tree-sitter-queries.d.ts +2 -2
- package/dist/core/ingestion/tree-sitter-queries.js +177 -0
- package/dist/core/ingestion/type-env.js +20 -0
- package/dist/core/ingestion/type-extractors/csharp.js +4 -3
- package/dist/core/ingestion/type-extractors/go.js +23 -12
- package/dist/core/ingestion/type-extractors/php.js +18 -10
- package/dist/core/ingestion/type-extractors/ruby.js +15 -3
- package/dist/core/ingestion/type-extractors/rust.js +3 -2
- package/dist/core/ingestion/type-extractors/shared.js +3 -2
- package/dist/core/ingestion/type-extractors/typescript.js +11 -5
- package/dist/core/ingestion/utils.d.ts +27 -4
- package/dist/core/ingestion/utils.js +145 -100
- package/dist/core/ingestion/workers/parse-worker.d.ts +1 -0
- package/dist/core/ingestion/workers/parse-worker.js +97 -29
- package/dist/core/ingestion/workers/worker-pool.js +3 -0
- package/dist/core/search/bm25-index.d.ts +15 -8
- package/dist/core/search/bm25-index.js +48 -98
- package/dist/core/search/hybrid-search.d.ts +9 -3
- package/dist/core/search/hybrid-search.js +30 -25
- package/dist/core/search/reranker.js +9 -7
- package/dist/core/search/types.d.ts +0 -4
- package/dist/core/semantic/tsgo-service.d.ts +5 -1
- package/dist/core/semantic/tsgo-service.js +161 -66
- package/dist/lib/tsgo-test.d.ts +2 -0
- package/dist/lib/tsgo-test.js +6 -0
- package/dist/lib/type-utils.d.ts +25 -0
- package/dist/lib/type-utils.js +22 -0
- package/dist/lib/utils.d.ts +3 -2
- package/dist/lib/utils.js +3 -2
- package/dist/mcp/compatible-stdio-transport.js +1 -1
- package/dist/mcp/local/local-backend.d.ts +29 -56
- package/dist/mcp/local/local-backend.js +808 -1118
- package/dist/mcp/resources.js +35 -25
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +5 -5
- package/dist/mcp/tools.js +24 -25
- package/dist/storage/repo-manager.d.ts +2 -12
- package/dist/storage/repo-manager.js +1 -47
- package/dist/types/pipeline.d.ts +8 -5
- package/dist/types/pipeline.js +5 -0
- package/package.json +18 -11
- package/dist/cli/serve.d.ts +0 -5
- package/dist/cli/serve.js +0 -8
- package/dist/core/incremental/child-process.d.ts +0 -8
- package/dist/core/incremental/child-process.js +0 -649
- package/dist/core/incremental/refresh-coordinator.d.ts +0 -32
- package/dist/core/incremental/refresh-coordinator.js +0 -147
- package/dist/core/lbug/csv-generator.d.ts +0 -28
- package/dist/core/lbug/csv-generator.js +0 -355
- package/dist/core/lbug/lbug-adapter.d.ts +0 -96
- package/dist/core/lbug/lbug-adapter.js +0 -753
- package/dist/core/lbug/schema.d.ts +0 -46
- package/dist/core/lbug/schema.js +0 -402
- package/dist/mcp/core/embedder.d.ts +0 -24
- package/dist/mcp/core/embedder.js +0 -168
- package/dist/mcp/core/lbug-adapter.d.ts +0 -29
- package/dist/mcp/core/lbug-adapter.js +0 -330
- package/dist/server/api.d.ts +0 -5
- package/dist/server/api.js +0 -340
- package/dist/server/mcp-http.d.ts +0 -7
- package/dist/server/mcp-http.js +0 -95
- package/models/mlx-embedder.py +0 -185
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** @file cluster-enricher.ts @description LLM-based enrichment for community clusters, generating semantic names, keywords, and descriptions */
|
|
2
|
-
import { CommunityNode } from './community-processor.js';
|
|
2
|
+
import type { CommunityNode } from './community-processor.js';
|
|
3
3
|
export interface ClusterEnrichment {
|
|
4
4
|
name: string;
|
|
5
5
|
keywords: string[];
|
|
@@ -50,6 +50,8 @@ export const enrichClusters = async (communities, memberMap, llmClient, onProgre
|
|
|
50
50
|
let tokensUsed = 0;
|
|
51
51
|
for (let i = 0; i < communities.length; i++) {
|
|
52
52
|
const community = communities[i];
|
|
53
|
+
if (community === undefined)
|
|
54
|
+
continue;
|
|
53
55
|
const members = memberMap.get(community.id) || [];
|
|
54
56
|
onProgress?.(i + 1, communities.length);
|
|
55
57
|
if (members.length === 0) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** @file community-processor.ts @description Detects code communities using the Leiden algorithm on CALLS/EXTENDS/IMPLEMENTS edges, grouping symbols by functional area */
|
|
2
|
-
import { KnowledgeGraph } from '../graph/types.js';
|
|
2
|
+
import type { KnowledgeGraph } from '../graph/types.js';
|
|
3
3
|
export interface CommunityNode {
|
|
4
4
|
id: string;
|
|
5
5
|
label: string;
|
|
@@ -28,7 +28,10 @@ export const COMMUNITY_COLORS = [
|
|
|
28
28
|
'#84cc16', // lime
|
|
29
29
|
];
|
|
30
30
|
export const getCommunityColor = (communityIndex) => {
|
|
31
|
-
|
|
31
|
+
const color = COMMUNITY_COLORS[communityIndex % COMMUNITY_COLORS.length];
|
|
32
|
+
if (color === undefined)
|
|
33
|
+
return '#888888';
|
|
34
|
+
return color;
|
|
32
35
|
};
|
|
33
36
|
/** Detect communities in the knowledge graph using the Leiden algorithm on CALLS/EXTENDS/IMPLEMENTS edges */
|
|
34
37
|
export const processCommunities = async (knowledgeGraph, onProgress) => {
|
|
@@ -149,7 +152,7 @@ const buildGraphologyGraph = (knowledgeGraph, isLarge) => {
|
|
|
149
152
|
return graph;
|
|
150
153
|
};
|
|
151
154
|
/** Create Community nodes with auto-generated labels based on member file paths */
|
|
152
|
-
const createCommunityNodes = (communities,
|
|
155
|
+
const createCommunityNodes = (communities, _communityCount, graph, knowledgeGraph) => {
|
|
153
156
|
// Group node IDs by community number
|
|
154
157
|
const communityMembers = new Map();
|
|
155
158
|
Object.entries(communities).forEach(([nodeId, commNum]) => {
|
|
@@ -195,7 +198,7 @@ const generateHeuristicLabel = (memberIds, nodePathMap, graph, commNum) => {
|
|
|
195
198
|
if (parts.length >= 2) {
|
|
196
199
|
const folder = parts[parts.length - 2];
|
|
197
200
|
// Skip generic folders
|
|
198
|
-
if (!['src', 'lib', 'core', 'utils', 'common', 'shared', 'helpers'].includes(folder.toLowerCase())) {
|
|
201
|
+
if (folder !== undefined && !['src', 'lib', 'core', 'utils', 'common', 'shared', 'helpers'].includes(folder.toLowerCase())) {
|
|
199
202
|
folderCounts.set(folder, (folderCounts.get(folder) || 0) + 1);
|
|
200
203
|
}
|
|
201
204
|
}
|
|
@@ -237,6 +240,8 @@ const findCommonPrefix = (strings) => {
|
|
|
237
240
|
const sorted = strings.slice().sort();
|
|
238
241
|
const first = sorted[0];
|
|
239
242
|
const last = sorted[sorted.length - 1];
|
|
243
|
+
if (first === undefined || last === undefined)
|
|
244
|
+
return '';
|
|
240
245
|
let i = 0;
|
|
241
246
|
while (i < first.length && first[i] === last[i]) {
|
|
242
247
|
i++;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** @file export-detection.ts @description Per-language detection of whether a symbol is exported/public, pure function safe for worker threads */
|
|
2
|
-
import { SyntaxNode } from './utils.js';
|
|
2
|
+
import { type SyntaxNode } from './utils.js';
|
|
3
3
|
import { SupportedLanguages } from '../../config/supported-languages.js';
|
|
4
4
|
/**
|
|
5
5
|
* Check if a tree-sitter node is exported/public in its language
|
|
@@ -74,7 +74,7 @@ const csharpExportChecker = (node, _name) => {
|
|
|
74
74
|
const goExportChecker = (_node, name) => {
|
|
75
75
|
if (name.length === 0)
|
|
76
76
|
return false;
|
|
77
|
-
const first = name
|
|
77
|
+
const first = name.charAt(0);
|
|
78
78
|
return first === first.toUpperCase() && first !== first.toLowerCase();
|
|
79
79
|
};
|
|
80
80
|
// Rust declaration node types for visibility_modifier scanning
|
|
@@ -30,7 +30,7 @@ export const walkRepositoryPaths = async (repoPath, onProgress) => {
|
|
|
30
30
|
onProgress?.(processed, filtered.length, result.value.path);
|
|
31
31
|
}
|
|
32
32
|
else {
|
|
33
|
-
onProgress?.(processed, filtered.length, batch[results.indexOf(result)]);
|
|
33
|
+
onProgress?.(processed, filtered.length, batch[results.indexOf(result)] ?? '');
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** @file heritage-processor.ts @description Extracts class inheritance relationships (EXTENDS/IMPLEMENTS) from AST matches. Resolves the correct edge type via symbol table lookup, falling back to language-gated heuristics for unresolved symbols: C#/Java use I[A-Z] convention, Swift defaults to IMPLEMENTS, all others default to EXTENDS */
|
|
2
|
-
import { KnowledgeGraph } from '../graph/types.js';
|
|
3
|
-
import { ASTCache } from './ast-cache.js';
|
|
2
|
+
import type { KnowledgeGraph } from '../graph/types.js';
|
|
3
|
+
import type { ASTCache } from './ast-cache.js';
|
|
4
4
|
import type { ExtractedHeritage } from './workers/parse-worker.js';
|
|
5
5
|
import type { ResolutionContext } from './resolution-context.js';
|
|
6
6
|
export declare const processHeritage: (graph: KnowledgeGraph, files: {
|
|
@@ -4,6 +4,7 @@ import Parser from 'tree-sitter';
|
|
|
4
4
|
import { isLanguageAvailable, loadParser, loadLanguage } from '../tree-sitter/parser-loader.js';
|
|
5
5
|
import { LANGUAGE_QUERIES } from './tree-sitter-queries.js';
|
|
6
6
|
import { generateId } from '../../lib/utils.js';
|
|
7
|
+
import { toNodeId, toEdgeId } from '../db/schema.js';
|
|
7
8
|
import { getLanguageFromFilename, isVerboseIngestionEnabled, yieldToEventLoop } from './utils.js';
|
|
8
9
|
import { SupportedLanguages } from '../../config/supported-languages.js';
|
|
9
10
|
import { getTreeSitterBufferSize } from './constants.js';
|
|
@@ -18,7 +19,10 @@ const INTERFACE_NAME_RE = /^I[A-Z]/;
|
|
|
18
19
|
const resolveExtendsType = (parentName, currentFilePath, ctx, language) => {
|
|
19
20
|
const resolved = ctx.resolve(parentName, currentFilePath);
|
|
20
21
|
if (resolved && resolved.candidates.length > 0) {
|
|
21
|
-
const
|
|
22
|
+
const topCandidate = resolved.candidates[0];
|
|
23
|
+
if (!topCandidate)
|
|
24
|
+
return { type: 'EXTENDS', idPrefix: 'Class' };
|
|
25
|
+
const isInterface = topCandidate.type === 'Interface';
|
|
22
26
|
return isInterface
|
|
23
27
|
? { type: 'IMPLEMENTS', idPrefix: 'Interface' }
|
|
24
28
|
: { type: 'EXTENDS', idPrefix: 'Class' };
|
|
@@ -47,7 +51,10 @@ const resolveHeritageId = (name, filePath, ctx, fallbackLabel, fallbackKey) => {
|
|
|
47
51
|
if (resolved.tier === 'global' && resolved.candidates.length > 1) {
|
|
48
52
|
return generateId(fallbackLabel, fallbackKey ?? name);
|
|
49
53
|
}
|
|
50
|
-
|
|
54
|
+
const topCandidate = resolved.candidates[0];
|
|
55
|
+
if (!topCandidate)
|
|
56
|
+
return generateId(fallbackLabel, fallbackKey ?? name);
|
|
57
|
+
return toNodeId(topCandidate.nodeId);
|
|
51
58
|
}
|
|
52
59
|
return generateId(fallbackLabel, fallbackKey ?? name);
|
|
53
60
|
};
|
|
@@ -57,6 +64,8 @@ export const processHeritage = async (graph, files, astCache, ctx, onProgress) =
|
|
|
57
64
|
const skippedByLang = logSkipped ? new Map() : null;
|
|
58
65
|
for (let i = 0; i < files.length; i++) {
|
|
59
66
|
const file = files[i];
|
|
67
|
+
if (!file)
|
|
68
|
+
continue;
|
|
60
69
|
onProgress?.(i + 1, files.length);
|
|
61
70
|
if (i % 20 === 0)
|
|
62
71
|
await yieldToEventLoop();
|
|
@@ -81,7 +90,7 @@ export const processHeritage = async (graph, files, astCache, ctx, onProgress) =
|
|
|
81
90
|
try {
|
|
82
91
|
tree = parser.parse(file.content, undefined, { bufferSize: getTreeSitterBufferSize(file.content.length) });
|
|
83
92
|
}
|
|
84
|
-
catch
|
|
93
|
+
catch {
|
|
85
94
|
// Skip files that can't be parsed
|
|
86
95
|
continue;
|
|
87
96
|
}
|
|
@@ -91,8 +100,8 @@ export const processHeritage = async (graph, files, astCache, ctx, onProgress) =
|
|
|
91
100
|
let query;
|
|
92
101
|
let matches;
|
|
93
102
|
try {
|
|
94
|
-
const
|
|
95
|
-
query = new Parser.Query(
|
|
103
|
+
const tsLang = parser.getLanguage();
|
|
104
|
+
query = new Parser.Query(tsLang, queryStr);
|
|
96
105
|
matches = query.matches(tree.rootNode);
|
|
97
106
|
}
|
|
98
107
|
catch (queryError) {
|
|
@@ -121,7 +130,7 @@ export const processHeritage = async (graph, files, astCache, ctx, onProgress) =
|
|
|
121
130
|
const parentId = resolveHeritageId(parentClassName, file.path, ctx, idPrefix);
|
|
122
131
|
if (childId && parentId && childId !== parentId) {
|
|
123
132
|
graph.addRelationship({
|
|
124
|
-
id:
|
|
133
|
+
id: toEdgeId(`${relType}:${childId}->${parentId}`),
|
|
125
134
|
sourceId: childId,
|
|
126
135
|
targetId: parentId,
|
|
127
136
|
type: relType,
|
|
@@ -138,7 +147,7 @@ export const processHeritage = async (graph, files, astCache, ctx, onProgress) =
|
|
|
138
147
|
const interfaceId = resolveHeritageId(interfaceName, file.path, ctx, 'Interface');
|
|
139
148
|
if (classId && interfaceId) {
|
|
140
149
|
graph.addRelationship({
|
|
141
|
-
id:
|
|
150
|
+
id: toEdgeId(`IMPLEMENTS:${classId}->${interfaceId}`),
|
|
142
151
|
sourceId: classId,
|
|
143
152
|
targetId: interfaceId,
|
|
144
153
|
type: 'IMPLEMENTS',
|
|
@@ -155,7 +164,7 @@ export const processHeritage = async (graph, files, astCache, ctx, onProgress) =
|
|
|
155
164
|
const traitId = resolveHeritageId(traitName, file.path, ctx, 'Trait');
|
|
156
165
|
if (structId && traitId) {
|
|
157
166
|
graph.addRelationship({
|
|
158
|
-
id:
|
|
167
|
+
id: toEdgeId(`IMPLEMENTS:${structId}->${traitId}`),
|
|
159
168
|
sourceId: structId,
|
|
160
169
|
targetId: traitId,
|
|
161
170
|
type: 'IMPLEMENTS',
|
|
@@ -186,6 +195,8 @@ export const processHeritageFromExtracted = async (graph, extractedHeritage, ctx
|
|
|
186
195
|
await yieldToEventLoop();
|
|
187
196
|
}
|
|
188
197
|
const h = extractedHeritage[i];
|
|
198
|
+
if (!h)
|
|
199
|
+
continue;
|
|
189
200
|
if (h.kind === 'extends') {
|
|
190
201
|
const fileLanguage = getLanguageFromFilename(h.filePath);
|
|
191
202
|
if (!fileLanguage)
|
|
@@ -195,7 +206,7 @@ export const processHeritageFromExtracted = async (graph, extractedHeritage, ctx
|
|
|
195
206
|
const parentId = resolveHeritageId(h.parentName, h.filePath, ctx, idPrefix);
|
|
196
207
|
if (childId && parentId && childId !== parentId) {
|
|
197
208
|
graph.addRelationship({
|
|
198
|
-
id:
|
|
209
|
+
id: toEdgeId(`${relType}:${childId}->${parentId}`),
|
|
199
210
|
sourceId: childId,
|
|
200
211
|
targetId: parentId,
|
|
201
212
|
type: relType,
|
|
@@ -209,7 +220,7 @@ export const processHeritageFromExtracted = async (graph, extractedHeritage, ctx
|
|
|
209
220
|
const interfaceId = resolveHeritageId(h.parentName, h.filePath, ctx, 'Interface');
|
|
210
221
|
if (classId && interfaceId) {
|
|
211
222
|
graph.addRelationship({
|
|
212
|
-
id:
|
|
223
|
+
id: toEdgeId(`IMPLEMENTS:${classId}->${interfaceId}`),
|
|
213
224
|
sourceId: classId,
|
|
214
225
|
targetId: interfaceId,
|
|
215
226
|
type: 'IMPLEMENTS',
|
|
@@ -223,7 +234,7 @@ export const processHeritageFromExtracted = async (graph, extractedHeritage, ctx
|
|
|
223
234
|
const traitId = resolveHeritageId(h.parentName, h.filePath, ctx, 'Trait');
|
|
224
235
|
if (structId && traitId) {
|
|
225
236
|
graph.addRelationship({
|
|
226
|
-
id:
|
|
237
|
+
id: toEdgeId(`IMPLEMENTS:${structId}->${traitId}:${h.kind}`),
|
|
227
238
|
sourceId: structId,
|
|
228
239
|
targetId: traitId,
|
|
229
240
|
type: 'IMPLEMENTS',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** @file import-processor.ts @description Resolves import statements across all supported languages, builds the ImportMap/PackageMap/NamedImportMap, and emits IMPORTS graph edges. Supports language-specific resolution for TS, Go, C#, PHP, Swift, Ruby, Rust, and JVM languages */
|
|
2
|
-
import { KnowledgeGraph } from '../graph/types.js';
|
|
3
|
-
import { ASTCache } from './ast-cache.js';
|
|
2
|
+
import type { KnowledgeGraph } from '../graph/types.js';
|
|
3
|
+
import type { ASTCache } from './ast-cache.js';
|
|
4
4
|
import type { ExtractedImport } from './workers/parse-worker.js';
|
|
5
5
|
import type { ResolutionContext } from './resolution-context.js';
|
|
6
6
|
import type { SuffixIndex } from './resolvers/index.js';
|
|
@@ -4,6 +4,7 @@ import Parser from 'tree-sitter';
|
|
|
4
4
|
import { isLanguageAvailable, loadParser, loadLanguage } from '../tree-sitter/parser-loader.js';
|
|
5
5
|
import { LANGUAGE_QUERIES } from './tree-sitter-queries.js';
|
|
6
6
|
import { generateId } from '../../lib/utils.js';
|
|
7
|
+
import { toEdgeId } from '../db/schema.js';
|
|
7
8
|
import { getLanguageFromFilename, isVerboseIngestionEnabled, yieldToEventLoop } from './utils.js';
|
|
8
9
|
import { SupportedLanguages } from '../../config/supported-languages.js';
|
|
9
10
|
import { extractNamedBindings } from './named-binding-extraction.js';
|
|
@@ -11,7 +12,7 @@ import { getTreeSitterBufferSize } from './constants.js';
|
|
|
11
12
|
import { loadTsconfigPaths, loadGoModulePath, loadComposerConfig, loadCSharpProjectConfig, loadSwiftPackageConfig, } from './language-config.js';
|
|
12
13
|
import { buildSuffixIndex, resolveImportPath, appendKotlinWildcard, KOTLIN_EXTENSIONS, resolveJvmWildcard, resolveJvmMemberImport, resolveGoPackageDir, resolveGoPackage, resolveCSharpImport, resolveCSharpNamespaceDir, resolvePhpImport, resolveRustImport, resolveRubyImport, } from './resolvers/index.js';
|
|
13
14
|
import { callRouters } from './call-routing.js';
|
|
14
|
-
const isDev = process.env
|
|
15
|
+
const isDev = process.env['NODE_ENV'] === 'development';
|
|
15
16
|
/** Check if a file path is directly inside a package directory identified by its suffix */
|
|
16
17
|
export function isFileInPackageDir(filePath, dirSuffix) {
|
|
17
18
|
// Prepend '/' so paths like "internal/auth/service.go" match suffix "/internal/auth/"
|
|
@@ -92,8 +93,10 @@ function resolveLanguageImport(filePath, rawImportPath, language, configs, ctx)
|
|
|
92
93
|
const dirPrefix = targetDir + '/';
|
|
93
94
|
const files = [];
|
|
94
95
|
for (let i = 0; i < normalizedFileList.length; i++) {
|
|
95
|
-
|
|
96
|
-
|
|
96
|
+
const normalizedPath = normalizedFileList[i];
|
|
97
|
+
const originalPath = allFileList[i];
|
|
98
|
+
if (normalizedPath && originalPath && normalizedPath.startsWith(dirPrefix) && normalizedPath.endsWith('.swift')) {
|
|
99
|
+
files.push(originalPath);
|
|
97
100
|
}
|
|
98
101
|
}
|
|
99
102
|
if (files.length > 0)
|
|
@@ -123,7 +126,7 @@ function resolveLanguageImport(filePath, rawImportPath, language, configs, ctx)
|
|
|
123
126
|
return resolvedPath ? { kind: 'files', files: [resolvedPath] } : null;
|
|
124
127
|
}
|
|
125
128
|
/** Apply an ImportResult — emit graph edges, update ImportMap/PackageMap and NamedImportMap */
|
|
126
|
-
function applyImportResult(result, filePath,
|
|
129
|
+
function applyImportResult(result, filePath, _importMap, packageMap, addImportEdge, addImportGraphEdge, namedBindings, namedImportMap) {
|
|
127
130
|
if (!result)
|
|
128
131
|
return;
|
|
129
132
|
if (result.kind === 'package' && packageMap) {
|
|
@@ -133,7 +136,9 @@ function applyImportResult(result, filePath, importMap, packageMap, addImportEdg
|
|
|
133
136
|
}
|
|
134
137
|
if (!packageMap.has(filePath))
|
|
135
138
|
packageMap.set(filePath, new Set());
|
|
136
|
-
packageMap.get(filePath)
|
|
139
|
+
const pkgSet = packageMap.get(filePath);
|
|
140
|
+
if (pkgSet)
|
|
141
|
+
pkgSet.add(result.dirSuffix);
|
|
137
142
|
}
|
|
138
143
|
else {
|
|
139
144
|
// 'files' kind or 'package' without PackageMap — use ImportMap directly
|
|
@@ -144,9 +149,13 @@ function applyImportResult(result, filePath, importMap, packageMap, addImportEdg
|
|
|
144
149
|
// Record named bindings for precise Tier 2a resolution
|
|
145
150
|
if (namedBindings && namedImportMap && files.length === 1) {
|
|
146
151
|
const resolvedFile = files[0];
|
|
152
|
+
if (!resolvedFile)
|
|
153
|
+
return;
|
|
147
154
|
if (!namedImportMap.has(filePath))
|
|
148
155
|
namedImportMap.set(filePath, new Map());
|
|
149
156
|
const fileBindings = namedImportMap.get(filePath);
|
|
157
|
+
if (!fileBindings)
|
|
158
|
+
return;
|
|
150
159
|
for (const binding of namedBindings) {
|
|
151
160
|
fileBindings.set(binding.local, { sourcePath: resolvedFile, exportedName: binding.exported });
|
|
152
161
|
}
|
|
@@ -220,7 +229,7 @@ export const processImports = async (graph, files, astCache, ctx, onProgress, re
|
|
|
220
229
|
const addImportGraphEdge = (filePath, resolvedPath) => {
|
|
221
230
|
const sourceId = generateId('File', filePath);
|
|
222
231
|
const targetId = generateId('File', resolvedPath);
|
|
223
|
-
const relId =
|
|
232
|
+
const relId = toEdgeId(`IMPORTS:${filePath}->${resolvedPath}`);
|
|
224
233
|
totalImportsResolved++;
|
|
225
234
|
graph.addRelationship({
|
|
226
235
|
id: relId,
|
|
@@ -237,10 +246,14 @@ export const processImports = async (graph, files, astCache, ctx, onProgress, re
|
|
|
237
246
|
if (!importMap.has(filePath)) {
|
|
238
247
|
importMap.set(filePath, new Set());
|
|
239
248
|
}
|
|
240
|
-
importMap.get(filePath)
|
|
249
|
+
const fileImports = importMap.get(filePath);
|
|
250
|
+
if (fileImports)
|
|
251
|
+
fileImports.add(resolvedPath);
|
|
241
252
|
};
|
|
242
253
|
for (let i = 0; i < files.length; i++) {
|
|
243
254
|
const file = files[i];
|
|
255
|
+
if (!file)
|
|
256
|
+
continue;
|
|
244
257
|
onProgress?.(i + 1, files.length);
|
|
245
258
|
if (i % 20 === 0)
|
|
246
259
|
await yieldToEventLoop();
|
|
@@ -364,7 +377,7 @@ export const processImportsFromExtracted = async (graph, files, extractedImports
|
|
|
364
377
|
const addImportGraphEdge = (filePath, resolvedPath) => {
|
|
365
378
|
const sourceId = generateId('File', filePath);
|
|
366
379
|
const targetId = generateId('File', resolvedPath);
|
|
367
|
-
const relId =
|
|
380
|
+
const relId = toEdgeId(`IMPORTS:${filePath}->${resolvedPath}`);
|
|
368
381
|
totalImportsResolved++;
|
|
369
382
|
graph.addRelationship({
|
|
370
383
|
id: relId,
|
|
@@ -381,7 +394,9 @@ export const processImportsFromExtracted = async (graph, files, extractedImports
|
|
|
381
394
|
if (!importMap.has(filePath)) {
|
|
382
395
|
importMap.set(filePath, new Set());
|
|
383
396
|
}
|
|
384
|
-
importMap.get(filePath)
|
|
397
|
+
const fileImports = importMap.get(filePath);
|
|
398
|
+
if (fileImports)
|
|
399
|
+
fileImports.add(resolvedPath);
|
|
385
400
|
};
|
|
386
401
|
// Group by file for progress reporting
|
|
387
402
|
const importsByFile = new Map();
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/** @file language-config.ts @description Loads language-specific project configuration (tsconfig.json, go.mod, composer.json, .csproj, Package.swift) for import path resolution */
|
|
3
3
|
import fs from 'fs/promises';
|
|
4
4
|
import path from 'path';
|
|
5
|
-
const isDev = process.env
|
|
5
|
+
const isDev = process.env['NODE_ENV'] === 'development';
|
|
6
6
|
/**
|
|
7
7
|
* Parse tsconfig.json to extract path aliases
|
|
8
8
|
*
|
|
@@ -50,7 +50,7 @@ export async function loadGoModulePath(repoRoot) {
|
|
|
50
50
|
const goModPath = path.join(repoRoot, 'go.mod');
|
|
51
51
|
const content = await fs.readFile(goModPath, 'utf-8');
|
|
52
52
|
const match = content.match(/^module\s+(\S+)/m);
|
|
53
|
-
if (match) {
|
|
53
|
+
if (match && match[1]) {
|
|
54
54
|
if (isDev) {
|
|
55
55
|
console.log(`📦 Loaded Go module path: ${match[1]}`);
|
|
56
56
|
}
|
|
@@ -95,7 +95,10 @@ export async function loadCSharpProjectConfig(repoRoot) {
|
|
|
95
95
|
const maxDirs = 100;
|
|
96
96
|
let dirsScanned = 0;
|
|
97
97
|
while (scanQueue.length > 0 && dirsScanned < maxDirs) {
|
|
98
|
-
const
|
|
98
|
+
const entry = scanQueue.shift();
|
|
99
|
+
if (!entry)
|
|
100
|
+
break;
|
|
101
|
+
const { dir, depth } = entry;
|
|
99
102
|
dirsScanned++;
|
|
100
103
|
try {
|
|
101
104
|
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
@@ -111,7 +114,7 @@ export async function loadCSharpProjectConfig(repoRoot) {
|
|
|
111
114
|
const csprojPath = path.join(dir, entry.name);
|
|
112
115
|
const content = await fs.readFile(csprojPath, 'utf-8');
|
|
113
116
|
const nsMatch = content.match(/<RootNamespace>\s*([^<]+)\s*<\/RootNamespace>/);
|
|
114
|
-
const rootNamespace = nsMatch
|
|
117
|
+
const rootNamespace = nsMatch?.[1]
|
|
115
118
|
? nsMatch[1].trim()
|
|
116
119
|
: entry.name.replace(/\.csproj$/, '');
|
|
117
120
|
const projectDir = path.relative(repoRoot, dir).replace(/\\/g, '/');
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* resolution rules (C++ leftmost base, C#/Java class-over-interface, Python C3 linearization,
|
|
6
6
|
* Rust requires qualified syntax). OVERRIDES edge direction: Class -> winning ancestor Method
|
|
7
7
|
*/
|
|
8
|
-
import { KnowledgeGraph } from '../graph/types.js';
|
|
8
|
+
import type { KnowledgeGraph } from '../graph/types.js';
|
|
9
9
|
import { SupportedLanguages } from '../../config/supported-languages.js';
|
|
10
10
|
export interface MROEntry {
|
|
11
11
|
classId: string;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* resolution rules (C++ leftmost base, C#/Java class-over-interface, Python C3 linearization,
|
|
7
7
|
* Rust requires qualified syntax). OVERRIDES edge direction: Class -> winning ancestor Method
|
|
8
8
|
*/
|
|
9
|
-
import {
|
|
9
|
+
import { toEdgeId } from '../db/schema.js';
|
|
10
10
|
import { SupportedLanguages } from '../../config/supported-languages.js';
|
|
11
11
|
/** Collect EXTENDS, IMPLEMENTS, and HAS_METHOD adjacency from the graph */
|
|
12
12
|
function buildAdjacency(graph) {
|
|
@@ -105,6 +105,8 @@ function c3Linearize(classId, parentMap, cache, inProgress) {
|
|
|
105
105
|
if (seq.length === 0)
|
|
106
106
|
continue;
|
|
107
107
|
const candidate = seq[0];
|
|
108
|
+
if (candidate === undefined)
|
|
109
|
+
continue;
|
|
108
110
|
const inTail = sequences.some(other => other.length > 1 && other.indexOf(candidate, 1) !== -1);
|
|
109
111
|
if (!inTail) {
|
|
110
112
|
head = candidate;
|
|
@@ -140,7 +142,11 @@ function resolveByMroOrder(methodName, defs, mroOrder, reasonPrefix) {
|
|
|
140
142
|
};
|
|
141
143
|
}
|
|
142
144
|
}
|
|
143
|
-
|
|
145
|
+
const first = defs[0];
|
|
146
|
+
if (first === undefined) {
|
|
147
|
+
return { resolvedTo: null, reason: `${reasonPrefix}: no definitions found` };
|
|
148
|
+
}
|
|
149
|
+
return { resolvedTo: first.methodId, reason: `${reasonPrefix} fallback: first definition` };
|
|
144
150
|
}
|
|
145
151
|
function resolveCsharpJava(methodName, defs, parentEdgeTypes) {
|
|
146
152
|
const classDefs = [];
|
|
@@ -155,10 +161,13 @@ function resolveCsharpJava(methodName, defs, parentEdgeTypes) {
|
|
|
155
161
|
}
|
|
156
162
|
}
|
|
157
163
|
if (classDefs.length > 0) {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
164
|
+
const winner = classDefs[0];
|
|
165
|
+
if (winner !== undefined) {
|
|
166
|
+
return {
|
|
167
|
+
resolvedTo: winner.methodId,
|
|
168
|
+
reason: `class method wins: ${winner.className}::${methodName}`,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
162
171
|
}
|
|
163
172
|
if (interfaceDefs.length > 1) {
|
|
164
173
|
return {
|
|
@@ -167,10 +176,13 @@ function resolveCsharpJava(methodName, defs, parentEdgeTypes) {
|
|
|
167
176
|
};
|
|
168
177
|
}
|
|
169
178
|
if (interfaceDefs.length === 1) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
179
|
+
const single = interfaceDefs[0];
|
|
180
|
+
if (single !== undefined) {
|
|
181
|
+
return {
|
|
182
|
+
resolvedTo: single.methodId,
|
|
183
|
+
reason: `single interface default: ${single.className}::${methodName}`,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
174
186
|
}
|
|
175
187
|
return { resolvedTo: null, reason: 'no resolution found' };
|
|
176
188
|
}
|
|
@@ -288,7 +300,7 @@ export function computeMRO(graph) {
|
|
|
288
300
|
// Emit OVERRIDES edge if resolution found
|
|
289
301
|
if (resolution.resolvedTo !== null) {
|
|
290
302
|
graph.addRelationship({
|
|
291
|
-
id:
|
|
303
|
+
id: toEdgeId(`OVERRIDES:${classId}->${resolution.resolvedTo}`),
|
|
292
304
|
sourceId: classId,
|
|
293
305
|
targetId: resolution.resolvedTo,
|
|
294
306
|
type: 'OVERRIDES',
|
|
@@ -84,10 +84,10 @@ export function extractTsNamedBindings(importNode) {
|
|
|
84
84
|
if (child?.type === 'identifier')
|
|
85
85
|
identifiers.push(child.text);
|
|
86
86
|
}
|
|
87
|
-
if (identifiers.length === 1) {
|
|
87
|
+
if (identifiers.length === 1 && identifiers[0] !== undefined) {
|
|
88
88
|
bindings.push({ local: identifiers[0], exported: identifiers[0] });
|
|
89
89
|
}
|
|
90
|
-
else if (identifiers.length === 2) {
|
|
90
|
+
else if (identifiers.length === 2 && identifiers[0] !== undefined && identifiers[1] !== undefined) {
|
|
91
91
|
// import { Foo as Bar } -> exported='Foo', local='Bar'
|
|
92
92
|
bindings.push({ local: identifiers[1], exported: identifiers[0] });
|
|
93
93
|
}
|
|
@@ -108,10 +108,10 @@ export function extractTsNamedBindings(importNode) {
|
|
|
108
108
|
if (child?.type === 'identifier')
|
|
109
109
|
identifiers.push(child.text);
|
|
110
110
|
}
|
|
111
|
-
if (identifiers.length === 1) {
|
|
111
|
+
if (identifiers.length === 1 && identifiers[0] !== undefined) {
|
|
112
112
|
bindings.push({ local: identifiers[0], exported: identifiers[0] });
|
|
113
113
|
}
|
|
114
|
-
else if (identifiers.length === 2) {
|
|
114
|
+
else if (identifiers.length === 2 && identifiers[0] !== undefined && identifiers[1] !== undefined) {
|
|
115
115
|
// export { Repo as Repository } -> first is source name, second is exported alias
|
|
116
116
|
bindings.push({ local: identifiers[1], exported: identifiers[0] });
|
|
117
117
|
}
|
|
@@ -198,7 +198,7 @@ function collectRustBindings(node, bindings) {
|
|
|
198
198
|
idents.push(nameNode.text);
|
|
199
199
|
}
|
|
200
200
|
}
|
|
201
|
-
if (idents.length === 2) {
|
|
201
|
+
if (idents.length === 2 && idents[0] !== undefined && idents[1] !== undefined) {
|
|
202
202
|
bindings.push({ local: idents[1], exported: idents[0] });
|
|
203
203
|
}
|
|
204
204
|
return;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/** @file parsing-processor.ts @description Parses source files via tree-sitter, extracts code structure nodes (classes, functions, methods, etc), populates the symbol table, and emits DEFINES/HAS_METHOD graph relationships. Supports parallel worker pools with sequential fallback */
|
|
2
|
-
import { KnowledgeGraph } from '../graph/types.js';
|
|
3
|
-
import { SymbolTable } from './symbol-table.js';
|
|
4
|
-
import { ASTCache } from './ast-cache.js';
|
|
5
|
-
import { WorkerPool } from './workers/worker-pool.js';
|
|
2
|
+
import type { KnowledgeGraph } from '../graph/types.js';
|
|
3
|
+
import type { SymbolTable } from './symbol-table.js';
|
|
4
|
+
import type { ASTCache } from './ast-cache.js';
|
|
5
|
+
import type { WorkerPool } from './workers/worker-pool.js';
|
|
6
6
|
import type { ExtractedImport, ExtractedCall, ExtractedHeritage, ExtractedRoute, FileConstructorBindings } from './workers/parse-worker.js';
|
|
7
7
|
export type FileProgressCallback = (current: number, total: number, filePath: string) => void;
|
|
8
8
|
export interface WorkerExtractedData {
|
|
@@ -4,6 +4,7 @@ import Parser from 'tree-sitter';
|
|
|
4
4
|
import { loadParser, loadLanguage, isLanguageAvailable } from '../tree-sitter/parser-loader.js';
|
|
5
5
|
import { LANGUAGE_QUERIES } from './tree-sitter-queries.js';
|
|
6
6
|
import { generateId } from '../../lib/utils.js';
|
|
7
|
+
import { toNodeId, toEdgeId } from '../db/schema.js';
|
|
7
8
|
import { getLanguageFromFilename, yieldToEventLoop, getDefinitionNodeFromCaptures, findEnclosingClassId, extractMethodSignature } from './utils.js';
|
|
8
9
|
import { isNodeExported } from './export-detection.js';
|
|
9
10
|
import { detectFrameworkFromAST } from './framework-detection.js';
|
|
@@ -11,7 +12,7 @@ import { typeConfigs } from './type-extractors/index.js';
|
|
|
11
12
|
import { getTreeSitterBufferSize, TREE_SITTER_MAX_BUFFER } from './constants.js';
|
|
12
13
|
export { isNodeExported } from './export-detection.js';
|
|
13
14
|
// Worker-based parallel parsing
|
|
14
|
-
const processParsingWithWorkers = async (graph, files, symbolTable,
|
|
15
|
+
const processParsingWithWorkers = async (graph, files, symbolTable, _astCache, workerPool, onFileProgress) => {
|
|
15
16
|
// Filter to parseable files only
|
|
16
17
|
const parseableFiles = [];
|
|
17
18
|
for (const file of files) {
|
|
@@ -35,20 +36,27 @@ const processParsingWithWorkers = async (graph, files, symbolTable, astCache, wo
|
|
|
35
36
|
for (const result of chunkResults) {
|
|
36
37
|
for (const node of result.nodes) {
|
|
37
38
|
graph.addNode({
|
|
38
|
-
id: node.id,
|
|
39
|
+
id: toNodeId(node.id),
|
|
39
40
|
label: node.label,
|
|
40
41
|
properties: node.properties,
|
|
41
42
|
});
|
|
42
43
|
}
|
|
43
44
|
for (const rel of result.relationships) {
|
|
44
|
-
graph.addRelationship(
|
|
45
|
+
graph.addRelationship({
|
|
46
|
+
id: toEdgeId(rel.id),
|
|
47
|
+
sourceId: toNodeId(rel.sourceId),
|
|
48
|
+
targetId: toNodeId(rel.targetId),
|
|
49
|
+
type: rel.type,
|
|
50
|
+
confidence: rel.confidence,
|
|
51
|
+
reason: rel.reason,
|
|
52
|
+
});
|
|
45
53
|
}
|
|
46
54
|
for (const sym of result.symbols) {
|
|
47
55
|
symbolTable.add(sym.filePath, sym.name, sym.nodeId, sym.type, {
|
|
48
|
-
parameterCount: sym.parameterCount,
|
|
49
|
-
returnType: sym.returnType,
|
|
50
|
-
ownerId: sym.ownerId,
|
|
51
|
-
parameterTypes: sym.parameterTypes,
|
|
56
|
+
...(sym.parameterCount !== undefined ? { parameterCount: sym.parameterCount } : {}),
|
|
57
|
+
...(sym.returnType !== undefined ? { returnType: sym.returnType } : {}),
|
|
58
|
+
...(sym.ownerId !== undefined ? { ownerId: sym.ownerId } : {}),
|
|
59
|
+
...(sym.parameterTypes !== undefined ? { parameterTypes: sym.parameterTypes } : {}),
|
|
52
60
|
});
|
|
53
61
|
}
|
|
54
62
|
allImports.push(...result.imports);
|
|
@@ -81,6 +89,8 @@ const processParsingSequential = async (graph, files, symbolTable, astCache, onF
|
|
|
81
89
|
const skippedLanguages = new Map();
|
|
82
90
|
for (let i = 0; i < files.length; i++) {
|
|
83
91
|
const file = files[i];
|
|
92
|
+
if (!file)
|
|
93
|
+
continue;
|
|
84
94
|
onFileProgress?.(i + 1, total, file.path);
|
|
85
95
|
if (i % 20 === 0)
|
|
86
96
|
await yieldToEventLoop();
|
|
@@ -218,10 +228,8 @@ const processParsingSequential = async (graph, files, symbolTable, astCache, onF
|
|
|
218
228
|
astFrameworkMultiplier: frameworkHint.entryPointMultiplier,
|
|
219
229
|
astFrameworkReason: frameworkHint.reason,
|
|
220
230
|
} : {}),
|
|
221
|
-
...(methodSig ? {
|
|
222
|
-
|
|
223
|
-
returnType: methodSig.returnType,
|
|
224
|
-
} : {}),
|
|
231
|
+
...(methodSig?.parameterCount !== undefined ? { parameterCount: methodSig.parameterCount } : {}),
|
|
232
|
+
...(methodSig?.returnType !== undefined ? { returnType: methodSig.returnType } : {}),
|
|
225
233
|
},
|
|
226
234
|
};
|
|
227
235
|
graph.addNode(node);
|
|
@@ -230,13 +238,13 @@ const processParsingSequential = async (graph, files, symbolTable, astCache, onF
|
|
|
230
238
|
const needsOwner = nodeLabel === 'Method' || nodeLabel === 'Constructor' || nodeLabel === 'Property' || nodeLabel === 'Function';
|
|
231
239
|
const enclosingClassId = needsOwner ? findEnclosingClassId(nameNode || definitionNodeForRange, file.path) : null;
|
|
232
240
|
symbolTable.add(file.path, nodeName, nodeId, nodeLabel, {
|
|
233
|
-
parameterCount: methodSig
|
|
234
|
-
returnType: methodSig
|
|
235
|
-
parameterTypes: methodSig
|
|
236
|
-
ownerId: enclosingClassId
|
|
241
|
+
...(methodSig?.parameterCount !== undefined ? { parameterCount: methodSig.parameterCount } : {}),
|
|
242
|
+
...(methodSig?.returnType !== undefined ? { returnType: methodSig.returnType } : {}),
|
|
243
|
+
...(methodSig?.parameterTypes !== undefined ? { parameterTypes: methodSig.parameterTypes } : {}),
|
|
244
|
+
...(enclosingClassId !== null ? { ownerId: enclosingClassId } : {}),
|
|
237
245
|
});
|
|
238
246
|
const fileId = generateId('File', file.path);
|
|
239
|
-
const relId =
|
|
247
|
+
const relId = toEdgeId(`DEFINES:${fileId}->${nodeId}`);
|
|
240
248
|
const relationship = {
|
|
241
249
|
id: relId,
|
|
242
250
|
sourceId: fileId,
|
|
@@ -249,8 +257,8 @@ const processParsingSequential = async (graph, files, symbolTable, astCache, onF
|
|
|
249
257
|
// HAS_METHOD: link method/constructor/property to enclosing class
|
|
250
258
|
if (enclosingClassId) {
|
|
251
259
|
graph.addRelationship({
|
|
252
|
-
id:
|
|
253
|
-
sourceId: enclosingClassId,
|
|
260
|
+
id: toEdgeId(`HAS_METHOD:${enclosingClassId}->${nodeId}`),
|
|
261
|
+
sourceId: toNodeId(enclosingClassId),
|
|
254
262
|
targetId: nodeId,
|
|
255
263
|
type: 'HAS_METHOD',
|
|
256
264
|
confidence: 1.0,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
/** @file pipeline.ts @description Main ingestion pipeline that orchestrates scanning, parsing, resolution, community detection, and process detection across chunked file batches */
|
|
2
|
-
import { PipelineProgress, PipelineResult } from '../../types/pipeline.js';
|
|
3
|
-
export declare const runPipelineFromRepo: (repoPath: string, onProgress: (progress: PipelineProgress) => void
|
|
2
|
+
import type { PipelineProgress, PipelineResult } from '../../types/pipeline.js';
|
|
3
|
+
export declare const runPipelineFromRepo: (repoPath: string, onProgress: (progress: PipelineProgress) => void, opts?: {
|
|
4
|
+
tsgo?: boolean;
|
|
5
|
+
}) => Promise<PipelineResult>;
|