@nahisaho/musubix-dfg 1.8.5
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/analyzers/index.d.ts +92 -0
- package/dist/analyzers/index.d.ts.map +1 -0
- package/dist/analyzers/index.js +902 -0
- package/dist/analyzers/index.js.map +1 -0
- package/dist/graph/index.d.ts +192 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +552 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +312 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +29 -0
- package/dist/types/index.js.map +1 -0
- package/dist/yata/index.d.ts +135 -0
- package/dist/yata/index.d.ts.map +1 -0
- package/dist/yata/index.js +557 -0
- package/dist/yata/index.js.map +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1,552 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph data structures for DFG/CFG
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
* @module @nahisaho/musubix-dfg/graph
|
|
6
|
+
*/
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Data Flow Graph Implementation
|
|
9
|
+
// ============================================================================
|
|
10
|
+
/**
|
|
11
|
+
* Data Flow Graph builder and analyzer
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const dfg = new DFGBuilder('module.ts');
|
|
16
|
+
* dfg.addNode({ id: 'n1', type: 'variable', name: 'x', ... });
|
|
17
|
+
* dfg.addEdge({ id: 'e1', type: 'def-use', source: 'n1', target: 'n2', ... });
|
|
18
|
+
* const graph = dfg.build();
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export class DFGBuilder {
|
|
22
|
+
filePath;
|
|
23
|
+
id;
|
|
24
|
+
nodes = new Map();
|
|
25
|
+
edges = new Map();
|
|
26
|
+
entryPoints = [];
|
|
27
|
+
exitPoints = [];
|
|
28
|
+
nodeCounter = 0;
|
|
29
|
+
edgeCounter = 0;
|
|
30
|
+
constructor(filePath, id = `dfg-${Date.now()}`) {
|
|
31
|
+
this.filePath = filePath;
|
|
32
|
+
this.id = id;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Generate unique node ID
|
|
36
|
+
*/
|
|
37
|
+
generateNodeId(prefix = 'n') {
|
|
38
|
+
return `${prefix}_${++this.nodeCounter}`;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Generate unique edge ID
|
|
42
|
+
*/
|
|
43
|
+
generateEdgeId(prefix = 'e') {
|
|
44
|
+
return `${prefix}_${++this.edgeCounter}`;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Add a node to the graph
|
|
48
|
+
*/
|
|
49
|
+
addNode(node) {
|
|
50
|
+
this.nodes.set(node.id, node);
|
|
51
|
+
return this;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Add an edge to the graph
|
|
55
|
+
*/
|
|
56
|
+
addEdge(edge) {
|
|
57
|
+
this.edges.set(edge.id, edge);
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Add entry point
|
|
62
|
+
*/
|
|
63
|
+
addEntryPoint(nodeId) {
|
|
64
|
+
if (!this.entryPoints.includes(nodeId)) {
|
|
65
|
+
this.entryPoints.push(nodeId);
|
|
66
|
+
}
|
|
67
|
+
return this;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Add exit point
|
|
71
|
+
*/
|
|
72
|
+
addExitPoint(nodeId) {
|
|
73
|
+
if (!this.exitPoints.includes(nodeId)) {
|
|
74
|
+
this.exitPoints.push(nodeId);
|
|
75
|
+
}
|
|
76
|
+
return this;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Get node by ID
|
|
80
|
+
*/
|
|
81
|
+
getNode(id) {
|
|
82
|
+
return this.nodes.get(id);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Get edge by ID
|
|
86
|
+
*/
|
|
87
|
+
getEdge(id) {
|
|
88
|
+
return this.edges.get(id);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get outgoing edges from a node
|
|
92
|
+
*/
|
|
93
|
+
getOutgoingEdges(nodeId) {
|
|
94
|
+
return Array.from(this.edges.values()).filter((e) => e.source === nodeId);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get incoming edges to a node
|
|
98
|
+
*/
|
|
99
|
+
getIncomingEdges(nodeId) {
|
|
100
|
+
return Array.from(this.edges.values()).filter((e) => e.target === nodeId);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Build the final DataFlowGraph
|
|
104
|
+
*/
|
|
105
|
+
build() {
|
|
106
|
+
return {
|
|
107
|
+
id: this.id,
|
|
108
|
+
filePath: this.filePath,
|
|
109
|
+
nodes: new Map(this.nodes),
|
|
110
|
+
edges: new Map(this.edges),
|
|
111
|
+
entryPoints: [...this.entryPoints],
|
|
112
|
+
exitPoints: [...this.exitPoints],
|
|
113
|
+
metadata: {
|
|
114
|
+
analyzedAt: new Date(),
|
|
115
|
+
languageVersion: 'TypeScript 5.x',
|
|
116
|
+
nodeCount: this.nodes.size,
|
|
117
|
+
edgeCount: this.edges.size,
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Data Flow Graph query and analysis utilities
|
|
124
|
+
*/
|
|
125
|
+
export class DFGAnalyzer {
|
|
126
|
+
graph;
|
|
127
|
+
constructor(graph) {
|
|
128
|
+
this.graph = graph;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Find all paths from source to target
|
|
132
|
+
*/
|
|
133
|
+
findPaths(sourceId, targetId, maxPaths = 100) {
|
|
134
|
+
const paths = [];
|
|
135
|
+
const visited = new Set();
|
|
136
|
+
const dfs = (current, path) => {
|
|
137
|
+
if (paths.length >= maxPaths)
|
|
138
|
+
return;
|
|
139
|
+
if (current === targetId) {
|
|
140
|
+
const sourceNode = this.graph.nodes.get(sourceId);
|
|
141
|
+
const targetNode = this.graph.nodes.get(targetId);
|
|
142
|
+
if (sourceNode && targetNode) {
|
|
143
|
+
paths.push({
|
|
144
|
+
source: sourceNode,
|
|
145
|
+
chain: [...path],
|
|
146
|
+
target: targetNode,
|
|
147
|
+
length: path.length,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (visited.has(current))
|
|
153
|
+
return;
|
|
154
|
+
visited.add(current);
|
|
155
|
+
const outEdges = this.getOutgoingEdges(current);
|
|
156
|
+
for (const edge of outEdges) {
|
|
157
|
+
dfs(edge.target, [...path, edge]);
|
|
158
|
+
}
|
|
159
|
+
visited.delete(current);
|
|
160
|
+
};
|
|
161
|
+
dfs(sourceId, []);
|
|
162
|
+
return paths;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Get outgoing edges from a node
|
|
166
|
+
*/
|
|
167
|
+
getOutgoingEdges(nodeId) {
|
|
168
|
+
return Array.from(this.graph.edges.values()).filter((e) => e.source === nodeId);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Get incoming edges to a node
|
|
172
|
+
*/
|
|
173
|
+
getIncomingEdges(nodeId) {
|
|
174
|
+
return Array.from(this.graph.edges.values()).filter((e) => e.target === nodeId);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Get all data dependencies for a variable
|
|
178
|
+
*/
|
|
179
|
+
getDataDependencies(variableName) {
|
|
180
|
+
const results = [];
|
|
181
|
+
const definitions = new Map();
|
|
182
|
+
const uses = new Map();
|
|
183
|
+
// Find all definitions
|
|
184
|
+
for (const node of this.graph.nodes.values()) {
|
|
185
|
+
if (node.name === variableName) {
|
|
186
|
+
if (node.type === 'variable' ||
|
|
187
|
+
node.type === 'parameter' ||
|
|
188
|
+
node.type === 'assignment') {
|
|
189
|
+
definitions.set(node.id, node);
|
|
190
|
+
uses.set(node.id, []);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// Find all uses via def-use edges
|
|
195
|
+
for (const edge of this.graph.edges.values()) {
|
|
196
|
+
if (edge.type === 'def-use' && definitions.has(edge.source)) {
|
|
197
|
+
const useNode = this.graph.nodes.get(edge.target);
|
|
198
|
+
if (useNode) {
|
|
199
|
+
uses.get(edge.source)?.push(useNode);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// Build results
|
|
204
|
+
for (const [defId, defNode] of definitions) {
|
|
205
|
+
const nodeUses = uses.get(defId) || [];
|
|
206
|
+
results.push({
|
|
207
|
+
variable: variableName,
|
|
208
|
+
definition: defNode,
|
|
209
|
+
uses: nodeUses,
|
|
210
|
+
isDeadCode: nodeUses.length === 0,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
return results;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Find taint propagation from source
|
|
217
|
+
*/
|
|
218
|
+
findTaintPropagation(sourceId) {
|
|
219
|
+
const tainted = new Set();
|
|
220
|
+
const queue = [sourceId];
|
|
221
|
+
while (queue.length > 0) {
|
|
222
|
+
const current = queue.shift();
|
|
223
|
+
if (tainted.has(current))
|
|
224
|
+
continue;
|
|
225
|
+
tainted.add(current);
|
|
226
|
+
const outEdges = this.getOutgoingEdges(current);
|
|
227
|
+
for (const edge of outEdges) {
|
|
228
|
+
if (edge.type === 'def-use' ||
|
|
229
|
+
edge.type === 'data-dep' ||
|
|
230
|
+
edge.type === 'alias') {
|
|
231
|
+
queue.push(edge.target);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return Array.from(tainted)
|
|
236
|
+
.map((id) => this.graph.nodes.get(id))
|
|
237
|
+
.filter((n) => n !== undefined);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Find dead code (definitions without uses)
|
|
241
|
+
*/
|
|
242
|
+
findDeadCode() {
|
|
243
|
+
const dead = [];
|
|
244
|
+
for (const node of this.graph.nodes.values()) {
|
|
245
|
+
if (node.type === 'variable' ||
|
|
246
|
+
node.type === 'assignment') {
|
|
247
|
+
const outEdges = this.getOutgoingEdges(node.id);
|
|
248
|
+
const hasUse = outEdges.some((e) => e.type === 'def-use');
|
|
249
|
+
if (!hasUse) {
|
|
250
|
+
dead.push(node);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return dead;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Export graph to DOT format for visualization
|
|
258
|
+
*/
|
|
259
|
+
toDot() {
|
|
260
|
+
const lines = ['digraph DFG {', ' rankdir=TB;'];
|
|
261
|
+
// Nodes
|
|
262
|
+
for (const node of this.graph.nodes.values()) {
|
|
263
|
+
const label = `${node.name}\\n(${node.type})`;
|
|
264
|
+
const shape = this.getNodeShape(node.type);
|
|
265
|
+
lines.push(` "${node.id}" [label="${label}" shape=${shape}];`);
|
|
266
|
+
}
|
|
267
|
+
// Edges
|
|
268
|
+
for (const edge of this.graph.edges.values()) {
|
|
269
|
+
const label = edge.label || edge.type;
|
|
270
|
+
const style = edge.type === 'control-dep' ? 'dashed' : 'solid';
|
|
271
|
+
lines.push(` "${edge.source}" -> "${edge.target}" [label="${label}" style=${style}];`);
|
|
272
|
+
}
|
|
273
|
+
lines.push('}');
|
|
274
|
+
return lines.join('\n');
|
|
275
|
+
}
|
|
276
|
+
getNodeShape(type) {
|
|
277
|
+
switch (type) {
|
|
278
|
+
case 'function':
|
|
279
|
+
case 'class':
|
|
280
|
+
return 'box';
|
|
281
|
+
case 'conditional':
|
|
282
|
+
return 'diamond';
|
|
283
|
+
case 'call':
|
|
284
|
+
return 'parallelogram';
|
|
285
|
+
default:
|
|
286
|
+
return 'ellipse';
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
// ============================================================================
|
|
291
|
+
// Control Flow Graph Implementation
|
|
292
|
+
// ============================================================================
|
|
293
|
+
/**
|
|
294
|
+
* Control Flow Graph builder
|
|
295
|
+
*/
|
|
296
|
+
export class CFGBuilder {
|
|
297
|
+
functionName;
|
|
298
|
+
filePath;
|
|
299
|
+
id;
|
|
300
|
+
blocks = new Map();
|
|
301
|
+
edges = new Map();
|
|
302
|
+
entryBlock = '';
|
|
303
|
+
exitBlocks = [];
|
|
304
|
+
blockCounter = 0;
|
|
305
|
+
edgeCounter = 0;
|
|
306
|
+
constructor(functionName, filePath, id = `cfg-${Date.now()}`) {
|
|
307
|
+
this.functionName = functionName;
|
|
308
|
+
this.filePath = filePath;
|
|
309
|
+
this.id = id;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Generate unique block ID
|
|
313
|
+
*/
|
|
314
|
+
generateBlockId(prefix = 'b') {
|
|
315
|
+
return `${prefix}_${++this.blockCounter}`;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Generate unique edge ID
|
|
319
|
+
*/
|
|
320
|
+
generateEdgeId(prefix = 'e') {
|
|
321
|
+
return `${prefix}_${++this.edgeCounter}`;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Add a basic block
|
|
325
|
+
*/
|
|
326
|
+
addBlock(block) {
|
|
327
|
+
this.blocks.set(block.id, block);
|
|
328
|
+
return this;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Add an edge
|
|
332
|
+
*/
|
|
333
|
+
addEdge(edge) {
|
|
334
|
+
this.edges.set(edge.id, edge);
|
|
335
|
+
// Update predecessor/successor
|
|
336
|
+
const sourceBlock = this.blocks.get(edge.source);
|
|
337
|
+
const targetBlock = this.blocks.get(edge.target);
|
|
338
|
+
if (sourceBlock && !sourceBlock.successors.includes(edge.target)) {
|
|
339
|
+
sourceBlock.successors.push(edge.target);
|
|
340
|
+
}
|
|
341
|
+
if (targetBlock && !targetBlock.predecessors.includes(edge.source)) {
|
|
342
|
+
targetBlock.predecessors.push(edge.source);
|
|
343
|
+
}
|
|
344
|
+
return this;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Set entry block
|
|
348
|
+
*/
|
|
349
|
+
setEntryBlock(blockId) {
|
|
350
|
+
this.entryBlock = blockId;
|
|
351
|
+
return this;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Add exit block
|
|
355
|
+
*/
|
|
356
|
+
addExitBlock(blockId) {
|
|
357
|
+
if (!this.exitBlocks.includes(blockId)) {
|
|
358
|
+
this.exitBlocks.push(blockId);
|
|
359
|
+
}
|
|
360
|
+
return this;
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Build the final ControlFlowGraph
|
|
364
|
+
*/
|
|
365
|
+
build() {
|
|
366
|
+
const cyclomaticComplexity = this.computeCyclomaticComplexity();
|
|
367
|
+
const maxLoopDepth = this.computeMaxLoopDepth();
|
|
368
|
+
return {
|
|
369
|
+
id: this.id,
|
|
370
|
+
functionName: this.functionName,
|
|
371
|
+
filePath: this.filePath,
|
|
372
|
+
entryBlock: this.entryBlock,
|
|
373
|
+
exitBlocks: [...this.exitBlocks],
|
|
374
|
+
blocks: new Map(this.blocks),
|
|
375
|
+
edges: new Map(this.edges),
|
|
376
|
+
metadata: {
|
|
377
|
+
analyzedAt: new Date(),
|
|
378
|
+
cyclomaticComplexity,
|
|
379
|
+
maxLoopDepth,
|
|
380
|
+
blockCount: this.blocks.size,
|
|
381
|
+
edgeCount: this.edges.size,
|
|
382
|
+
},
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
computeCyclomaticComplexity() {
|
|
386
|
+
// M = E - N + 2P (for single connected component, P=1)
|
|
387
|
+
return this.edges.size - this.blocks.size + 2;
|
|
388
|
+
}
|
|
389
|
+
computeMaxLoopDepth() {
|
|
390
|
+
let maxDepth = 0;
|
|
391
|
+
for (const block of this.blocks.values()) {
|
|
392
|
+
if (block.loopDepth > maxDepth) {
|
|
393
|
+
maxDepth = block.loopDepth;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
return maxDepth;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Control Flow Graph analyzer
|
|
401
|
+
*/
|
|
402
|
+
export class CFGAnalyzer {
|
|
403
|
+
graph;
|
|
404
|
+
constructor(graph) {
|
|
405
|
+
this.graph = graph;
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Find all execution paths from entry to exit
|
|
409
|
+
*/
|
|
410
|
+
findAllPaths(maxPaths = 100) {
|
|
411
|
+
const paths = [];
|
|
412
|
+
const visited = new Set();
|
|
413
|
+
const dfs = (current, path) => {
|
|
414
|
+
if (paths.length >= maxPaths)
|
|
415
|
+
return;
|
|
416
|
+
const block = this.graph.blocks.get(current);
|
|
417
|
+
if (!block)
|
|
418
|
+
return;
|
|
419
|
+
path.blocks.push(block);
|
|
420
|
+
if (this.graph.exitBlocks.includes(current)) {
|
|
421
|
+
const conditions = path.edges
|
|
422
|
+
.filter((e) => e.condition)
|
|
423
|
+
.map((e) => e.condition);
|
|
424
|
+
paths.push({
|
|
425
|
+
id: `path_${paths.length + 1}`,
|
|
426
|
+
blocks: [...path.blocks],
|
|
427
|
+
edges: [...path.edges],
|
|
428
|
+
conditions,
|
|
429
|
+
isFeasible: true, // Would need SMT solver for actual feasibility
|
|
430
|
+
});
|
|
431
|
+
path.blocks.pop();
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
const pathKey = path.blocks.map((b) => b.id).join(',');
|
|
435
|
+
if (visited.has(pathKey)) {
|
|
436
|
+
path.blocks.pop();
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
visited.add(pathKey);
|
|
440
|
+
const outEdges = this.getOutgoingEdges(current);
|
|
441
|
+
for (const edge of outEdges) {
|
|
442
|
+
if (!edge.isBackEdge) {
|
|
443
|
+
// Skip back edges to avoid infinite loops
|
|
444
|
+
path.edges.push(edge);
|
|
445
|
+
dfs(edge.target, path);
|
|
446
|
+
path.edges.pop();
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
visited.delete(pathKey);
|
|
450
|
+
path.blocks.pop();
|
|
451
|
+
};
|
|
452
|
+
dfs(this.graph.entryBlock, { blocks: [], edges: [] });
|
|
453
|
+
return paths;
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Get outgoing edges from a block
|
|
457
|
+
*/
|
|
458
|
+
getOutgoingEdges(blockId) {
|
|
459
|
+
return Array.from(this.graph.edges.values()).filter((e) => e.source === blockId);
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Get incoming edges to a block
|
|
463
|
+
*/
|
|
464
|
+
getIncomingEdges(blockId) {
|
|
465
|
+
return Array.from(this.graph.edges.values()).filter((e) => e.target === blockId);
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Find all loops (natural loops)
|
|
469
|
+
*/
|
|
470
|
+
findLoops() {
|
|
471
|
+
const loops = [];
|
|
472
|
+
// Find back edges
|
|
473
|
+
const backEdges = Array.from(this.graph.edges.values()).filter((e) => e.isBackEdge);
|
|
474
|
+
for (const backEdge of backEdges) {
|
|
475
|
+
const header = this.graph.blocks.get(backEdge.target);
|
|
476
|
+
if (!header)
|
|
477
|
+
continue;
|
|
478
|
+
// Find loop body via reverse DFS from back edge source
|
|
479
|
+
const body = new Set();
|
|
480
|
+
const stack = [backEdge.source];
|
|
481
|
+
while (stack.length > 0) {
|
|
482
|
+
const current = stack.pop();
|
|
483
|
+
if (current === backEdge.target)
|
|
484
|
+
continue;
|
|
485
|
+
const block = this.graph.blocks.get(current);
|
|
486
|
+
if (!block || body.has(block))
|
|
487
|
+
continue;
|
|
488
|
+
body.add(block);
|
|
489
|
+
for (const predId of block.predecessors) {
|
|
490
|
+
stack.push(predId);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
loops.push({
|
|
494
|
+
header,
|
|
495
|
+
body: Array.from(body),
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
return loops;
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Compute cyclomatic complexity
|
|
502
|
+
*/
|
|
503
|
+
getCyclomaticComplexity() {
|
|
504
|
+
return this.graph.metadata.cyclomaticComplexity;
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Export graph to DOT format
|
|
508
|
+
*/
|
|
509
|
+
toDot() {
|
|
510
|
+
const lines = [
|
|
511
|
+
`digraph CFG_${this.graph.functionName} {`,
|
|
512
|
+
' rankdir=TB;',
|
|
513
|
+
];
|
|
514
|
+
// Blocks
|
|
515
|
+
for (const block of this.graph.blocks.values()) {
|
|
516
|
+
const label = block.statements.length > 0
|
|
517
|
+
? block.statements
|
|
518
|
+
.map((s) => s.text.replace(/"/g, '\\"'))
|
|
519
|
+
.join('\\n')
|
|
520
|
+
: block.label;
|
|
521
|
+
const shape = this.getBlockShape(block.type);
|
|
522
|
+
const color = block.loopDepth > 0 ? 'lightblue' : 'white';
|
|
523
|
+
lines.push(` "${block.id}" [label="${label}" shape=${shape} style=filled fillcolor=${color}];`);
|
|
524
|
+
}
|
|
525
|
+
// Edges
|
|
526
|
+
for (const edge of this.graph.edges.values()) {
|
|
527
|
+
const label = edge.condition || edge.type;
|
|
528
|
+
const style = edge.isBackEdge ? 'dashed' : 'solid';
|
|
529
|
+
const color = edge.isBackEdge ? 'red' : 'black';
|
|
530
|
+
lines.push(` "${edge.source}" -> "${edge.target}" [label="${label}" style=${style} color=${color}];`);
|
|
531
|
+
}
|
|
532
|
+
lines.push('}');
|
|
533
|
+
return lines.join('\n');
|
|
534
|
+
}
|
|
535
|
+
getBlockShape(type) {
|
|
536
|
+
switch (type) {
|
|
537
|
+
case 'entry':
|
|
538
|
+
case 'exit':
|
|
539
|
+
return 'ellipse';
|
|
540
|
+
case 'conditional':
|
|
541
|
+
return 'diamond';
|
|
542
|
+
case 'loop-header':
|
|
543
|
+
return 'hexagon';
|
|
544
|
+
default:
|
|
545
|
+
return 'box';
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
// Re-export
|
|
550
|
+
export { DFGBuilder as DataFlowGraphBuilder };
|
|
551
|
+
export { CFGBuilder as ControlFlowGraphBuilder };
|
|
552
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/graph/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nahisaho/musubix-dfg
|
|
3
|
+
*
|
|
4
|
+
* Data Flow Graph (DFG) and Control Flow Graph (CFG) analysis
|
|
5
|
+
* for MUSUBIX neuro-symbolic code understanding.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
* @module @nahisaho/musubix-dfg
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { DataFlowAnalyzer, ControlFlowAnalyzer } from '@nahisaho/musubix-dfg';
|
|
13
|
+
*
|
|
14
|
+
* // Analyze TypeScript code
|
|
15
|
+
* const dfgAnalyzer = new DataFlowAnalyzer();
|
|
16
|
+
* const dfg = await dfgAnalyzer.analyze('src/user-service.ts');
|
|
17
|
+
*
|
|
18
|
+
* // Get data dependencies
|
|
19
|
+
* const deps = dfg.getDataDependencies('userId');
|
|
20
|
+
*
|
|
21
|
+
* // Analyze control flow
|
|
22
|
+
* const cfgAnalyzer = new ControlFlowAnalyzer();
|
|
23
|
+
* const cfg = await cfgAnalyzer.analyze('src/user-service.ts');
|
|
24
|
+
*
|
|
25
|
+
* // Get all paths from entry to exit
|
|
26
|
+
* const paths = cfg.getAllPaths();
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @traces REQ-DFG-001, REQ-DFG-002, REQ-DFG-003
|
|
30
|
+
*/
|
|
31
|
+
export * from './types/index.js';
|
|
32
|
+
export * from './graph/index.js';
|
|
33
|
+
export * from './analyzers/index.js';
|
|
34
|
+
export * from './yata/index.js';
|
|
35
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAGH,cAAc,kBAAkB,CAAC;AAGjC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,sBAAsB,CAAC;AAGrC,cAAc,iBAAiB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @nahisaho/musubix-dfg
|
|
3
|
+
*
|
|
4
|
+
* Data Flow Graph (DFG) and Control Flow Graph (CFG) analysis
|
|
5
|
+
* for MUSUBIX neuro-symbolic code understanding.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
* @module @nahisaho/musubix-dfg
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { DataFlowAnalyzer, ControlFlowAnalyzer } from '@nahisaho/musubix-dfg';
|
|
13
|
+
*
|
|
14
|
+
* // Analyze TypeScript code
|
|
15
|
+
* const dfgAnalyzer = new DataFlowAnalyzer();
|
|
16
|
+
* const dfg = await dfgAnalyzer.analyze('src/user-service.ts');
|
|
17
|
+
*
|
|
18
|
+
* // Get data dependencies
|
|
19
|
+
* const deps = dfg.getDataDependencies('userId');
|
|
20
|
+
*
|
|
21
|
+
* // Analyze control flow
|
|
22
|
+
* const cfgAnalyzer = new ControlFlowAnalyzer();
|
|
23
|
+
* const cfg = await cfgAnalyzer.analyze('src/user-service.ts');
|
|
24
|
+
*
|
|
25
|
+
* // Get all paths from entry to exit
|
|
26
|
+
* const paths = cfg.getAllPaths();
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @traces REQ-DFG-001, REQ-DFG-002, REQ-DFG-003
|
|
30
|
+
*/
|
|
31
|
+
// Types
|
|
32
|
+
export * from './types/index.js';
|
|
33
|
+
// Graph structures
|
|
34
|
+
export * from './graph/index.js';
|
|
35
|
+
// Analyzers
|
|
36
|
+
export * from './analyzers/index.js';
|
|
37
|
+
// YATA integration
|
|
38
|
+
export * from './yata/index.js';
|
|
39
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,QAAQ;AACR,cAAc,kBAAkB,CAAC;AAEjC,mBAAmB;AACnB,cAAc,kBAAkB,CAAC;AAEjC,YAAY;AACZ,cAAc,sBAAsB,CAAC;AAErC,mBAAmB;AACnB,cAAc,iBAAiB,CAAC"}
|