@optave/codegraph 3.9.0 → 3.9.1

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.
Files changed (104) hide show
  1. package/README.md +7 -6
  2. package/dist/ast-analysis/engine.d.ts.map +1 -1
  3. package/dist/ast-analysis/engine.js +78 -48
  4. package/dist/ast-analysis/engine.js.map +1 -1
  5. package/dist/ast-analysis/visitors/ast-store-visitor.d.ts.map +1 -1
  6. package/dist/ast-analysis/visitors/ast-store-visitor.js +15 -18
  7. package/dist/ast-analysis/visitors/ast-store-visitor.js.map +1 -1
  8. package/dist/db/connection.d.ts +1 -0
  9. package/dist/db/connection.d.ts.map +1 -1
  10. package/dist/db/connection.js +22 -4
  11. package/dist/db/connection.js.map +1 -1
  12. package/dist/db/repository/base.d.ts +35 -0
  13. package/dist/db/repository/base.d.ts.map +1 -1
  14. package/dist/db/repository/base.js +8 -0
  15. package/dist/db/repository/base.js.map +1 -1
  16. package/dist/db/repository/index.d.ts +1 -0
  17. package/dist/db/repository/index.d.ts.map +1 -1
  18. package/dist/db/repository/index.js.map +1 -1
  19. package/dist/db/repository/native-repository.d.ts +7 -1
  20. package/dist/db/repository/native-repository.d.ts.map +1 -1
  21. package/dist/db/repository/native-repository.js +46 -1
  22. package/dist/db/repository/native-repository.js.map +1 -1
  23. package/dist/domain/analysis/dependencies.d.ts +1 -28
  24. package/dist/domain/analysis/dependencies.d.ts.map +1 -1
  25. package/dist/domain/analysis/dependencies.js +12 -0
  26. package/dist/domain/analysis/dependencies.js.map +1 -1
  27. package/dist/domain/graph/builder/incremental.d.ts.map +1 -1
  28. package/dist/domain/graph/builder/incremental.js +18 -0
  29. package/dist/domain/graph/builder/incremental.js.map +1 -1
  30. package/dist/domain/graph/builder/pipeline.d.ts.map +1 -1
  31. package/dist/domain/graph/builder/pipeline.js +293 -296
  32. package/dist/domain/graph/builder/pipeline.js.map +1 -1
  33. package/dist/domain/graph/builder/stages/build-edges.d.ts.map +1 -1
  34. package/dist/domain/graph/builder/stages/build-edges.js +29 -2
  35. package/dist/domain/graph/builder/stages/build-edges.js.map +1 -1
  36. package/dist/domain/graph/builder/stages/resolve-imports.d.ts.map +1 -1
  37. package/dist/domain/graph/builder/stages/resolve-imports.js +19 -23
  38. package/dist/domain/graph/builder/stages/resolve-imports.js.map +1 -1
  39. package/dist/domain/graph/watcher.d.ts.map +1 -1
  40. package/dist/domain/graph/watcher.js +99 -95
  41. package/dist/domain/graph/watcher.js.map +1 -1
  42. package/dist/domain/parser.d.ts.map +1 -1
  43. package/dist/domain/parser.js +2 -0
  44. package/dist/domain/parser.js.map +1 -1
  45. package/dist/extractors/go.js +53 -35
  46. package/dist/extractors/go.js.map +1 -1
  47. package/dist/extractors/javascript.js +66 -27
  48. package/dist/extractors/javascript.js.map +1 -1
  49. package/dist/features/complexity.d.ts.map +1 -1
  50. package/dist/features/complexity.js +78 -58
  51. package/dist/features/complexity.js.map +1 -1
  52. package/dist/features/dataflow.d.ts.map +1 -1
  53. package/dist/features/dataflow.js +109 -118
  54. package/dist/features/dataflow.js.map +1 -1
  55. package/dist/features/structure.d.ts.map +1 -1
  56. package/dist/features/structure.js +147 -97
  57. package/dist/features/structure.js.map +1 -1
  58. package/dist/graph/algorithms/louvain.d.ts.map +1 -1
  59. package/dist/graph/algorithms/louvain.js +4 -2
  60. package/dist/graph/algorithms/louvain.js.map +1 -1
  61. package/dist/graph/classifiers/roles.d.ts +2 -0
  62. package/dist/graph/classifiers/roles.d.ts.map +1 -1
  63. package/dist/graph/classifiers/roles.js +13 -5
  64. package/dist/graph/classifiers/roles.js.map +1 -1
  65. package/dist/presentation/communities.d.ts.map +1 -1
  66. package/dist/presentation/communities.js +38 -34
  67. package/dist/presentation/communities.js.map +1 -1
  68. package/dist/presentation/manifesto.d.ts.map +1 -1
  69. package/dist/presentation/manifesto.js +31 -33
  70. package/dist/presentation/manifesto.js.map +1 -1
  71. package/dist/presentation/queries-cli/inspect.d.ts.map +1 -1
  72. package/dist/presentation/queries-cli/inspect.js +47 -46
  73. package/dist/presentation/queries-cli/inspect.js.map +1 -1
  74. package/dist/shared/file-utils.d.ts.map +1 -1
  75. package/dist/shared/file-utils.js +94 -72
  76. package/dist/shared/file-utils.js.map +1 -1
  77. package/dist/types.d.ts +81 -1
  78. package/dist/types.d.ts.map +1 -1
  79. package/package.json +7 -7
  80. package/src/ast-analysis/engine.ts +99 -55
  81. package/src/ast-analysis/visitors/ast-store-visitor.ts +19 -21
  82. package/src/db/connection.ts +24 -5
  83. package/src/db/repository/base.ts +43 -0
  84. package/src/db/repository/index.ts +1 -0
  85. package/src/db/repository/native-repository.ts +67 -1
  86. package/src/domain/analysis/dependencies.ts +13 -0
  87. package/src/domain/graph/builder/incremental.ts +21 -0
  88. package/src/domain/graph/builder/pipeline.ts +392 -362
  89. package/src/domain/graph/builder/stages/build-edges.ts +30 -1
  90. package/src/domain/graph/builder/stages/resolve-imports.ts +20 -20
  91. package/src/domain/graph/watcher.ts +118 -98
  92. package/src/domain/parser.ts +2 -0
  93. package/src/extractors/go.ts +57 -32
  94. package/src/extractors/javascript.ts +67 -27
  95. package/src/features/complexity.ts +94 -58
  96. package/src/features/dataflow.ts +153 -132
  97. package/src/features/structure.ts +167 -95
  98. package/src/graph/algorithms/louvain.ts +5 -2
  99. package/src/graph/classifiers/roles.ts +14 -5
  100. package/src/presentation/communities.ts +44 -39
  101. package/src/presentation/manifesto.ts +35 -38
  102. package/src/presentation/queries-cli/inspect.ts +48 -46
  103. package/src/shared/file-utils.ts +116 -77
  104. package/src/types.ts +85 -0
@@ -535,75 +535,97 @@ function upsertAstComplexity(
535
535
  return 1;
536
536
  }
537
537
 
538
- export async function buildComplexityMetrics(
538
+ /** Collect native bulk-insert rows from precomputed complexity data.
539
+ * Returns the rows array, or null if any definition is missing complexity
540
+ * (signalling that JS fallback is needed). */
541
+ function collectNativeBulkRows(
542
+ db: BetterSqlite3Database,
543
+ fileSymbols: Map<string, FileSymbols>,
544
+ ): Array<Record<string, unknown>> | null {
545
+ const rows: Array<Record<string, unknown>> = [];
546
+
547
+ for (const [relPath, symbols] of fileSymbols) {
548
+ for (const def of symbols.definitions) {
549
+ if (def.kind !== 'function' && def.kind !== 'method') continue;
550
+ if (!def.line) continue;
551
+ // Interface/type property signatures and single-line stubs are extracted
552
+ // as methods but the native engine correctly never assigns complexity.
553
+ // Mirror the leniency in initWasmParsersIfNeeded to avoid bailing out
554
+ // of the native bulk-insert path for every TypeScript codebase (#846).
555
+ if (!def.complexity) {
556
+ if (def.name.includes('.') || !def.endLine || def.endLine <= def.line) continue;
557
+ return null; // genuine function body missing complexity — needs JS fallback
558
+ }
559
+ const nodeId = getFunctionNodeId(db, def.name, relPath, def.line);
560
+ if (!nodeId) continue;
561
+ const ch = def.complexity.halstead;
562
+ const cl = def.complexity.loc;
563
+ rows.push({
564
+ nodeId,
565
+ cognitive: def.complexity.cognitive ?? 0,
566
+ cyclomatic: def.complexity.cyclomatic ?? 0,
567
+ maxNesting: def.complexity.maxNesting ?? 0,
568
+ loc: cl ? cl.loc : 0,
569
+ sloc: cl ? cl.sloc : 0,
570
+ commentLines: cl ? cl.commentLines : 0,
571
+ halsteadN1: ch ? ch.n1 : 0,
572
+ halsteadN2: ch ? ch.n2 : 0,
573
+ halsteadBigN1: ch ? ch.bigN1 : 0,
574
+ halsteadBigN2: ch ? ch.bigN2 : 0,
575
+ halsteadVocabulary: ch ? ch.vocabulary : 0,
576
+ halsteadLength: ch ? ch.length : 0,
577
+ halsteadVolume: ch ? ch.volume : 0,
578
+ halsteadDifficulty: ch ? ch.difficulty : 0,
579
+ halsteadEffort: ch ? ch.effort : 0,
580
+ halsteadBugs: ch ? ch.bugs : 0,
581
+ maintainabilityIndex: def.complexity.maintainabilityIndex ?? 0,
582
+ });
583
+ }
584
+ }
585
+
586
+ return rows;
587
+ }
588
+
589
+ /** Try the native bulk-insert fast path. Returns true if all rows were
590
+ * inserted successfully (caller can return early). */
591
+ function tryNativeBulkInsert(
539
592
  db: BetterSqlite3Database,
540
593
  fileSymbols: Map<string, FileSymbols>,
541
- rootDir: string,
542
594
  engineOpts?: {
543
595
  nativeDb?: { bulkInsertComplexity?(rows: Array<Record<string, unknown>>): number };
544
596
  suspendJsDb?: () => void;
545
597
  resumeJsDb?: () => void;
546
598
  },
547
- ): Promise<void> {
548
- // ── Native bulk-insert fast path ──────────────────────────────────────
599
+ ): boolean {
549
600
  const nativeDb = engineOpts?.nativeDb;
550
- if (nativeDb?.bulkInsertComplexity) {
551
- const rows: Array<Record<string, unknown>> = [];
552
- let needsJsFallback = false;
553
-
554
- for (const [relPath, symbols] of fileSymbols) {
555
- for (const def of symbols.definitions) {
556
- if (def.kind !== 'function' && def.kind !== 'method') continue;
557
- if (!def.line) continue;
558
- if (!def.complexity) {
559
- needsJsFallback = true;
560
- break;
561
- }
562
- const nodeId = getFunctionNodeId(db, def.name, relPath, def.line);
563
- if (!nodeId) continue;
564
- const ch = def.complexity.halstead;
565
- const cl = def.complexity.loc;
566
- rows.push({
567
- nodeId,
568
- cognitive: def.complexity.cognitive ?? 0,
569
- cyclomatic: def.complexity.cyclomatic ?? 0,
570
- maxNesting: def.complexity.maxNesting ?? 0,
571
- loc: cl ? cl.loc : 0,
572
- sloc: cl ? cl.sloc : 0,
573
- commentLines: cl ? cl.commentLines : 0,
574
- halsteadN1: ch ? ch.n1 : 0,
575
- halsteadN2: ch ? ch.n2 : 0,
576
- halsteadBigN1: ch ? ch.bigN1 : 0,
577
- halsteadBigN2: ch ? ch.bigN2 : 0,
578
- halsteadVocabulary: ch ? ch.vocabulary : 0,
579
- halsteadLength: ch ? ch.length : 0,
580
- halsteadVolume: ch ? ch.volume : 0,
581
- halsteadDifficulty: ch ? ch.difficulty : 0,
582
- halsteadEffort: ch ? ch.effort : 0,
583
- halsteadBugs: ch ? ch.bugs : 0,
584
- maintainabilityIndex: def.complexity.maintainabilityIndex ?? 0,
585
- });
586
- }
587
- if (needsJsFallback) break;
588
- }
601
+ if (!nativeDb?.bulkInsertComplexity) return false;
602
+
603
+ const rows = collectNativeBulkRows(db, fileSymbols);
604
+ if (rows === null) return false; // missing complexity — needs JS fallback
605
+ if (rows.length === 0) return true; // nothing to insert — native path done
606
+
607
+ let inserted: number;
608
+ try {
609
+ engineOpts?.suspendJsDb?.();
610
+ inserted = nativeDb.bulkInsertComplexity(rows);
611
+ } finally {
612
+ engineOpts?.resumeJsDb?.();
613
+ }
589
614
 
590
- if (!needsJsFallback && rows.length > 0) {
591
- let inserted: number;
592
- try {
593
- engineOpts?.suspendJsDb?.();
594
- inserted = nativeDb.bulkInsertComplexity(rows);
595
- } finally {
596
- engineOpts?.resumeJsDb?.();
597
- }
598
- if (inserted === rows.length) {
599
- info(`Complexity (native bulk): ${inserted} functions analyzed`);
600
- return;
601
- }
602
- debug(`Native bulkInsertComplexity partial: ${inserted}/${rows.length} — falling back to JS`);
603
- }
615
+ if (inserted === rows.length) {
616
+ info(`Complexity (native bulk): ${inserted} functions analyzed`);
617
+ return true;
604
618
  }
619
+ debug(`Native bulkInsertComplexity partial: ${inserted}/${rows.length} — falling back to JS`);
620
+ return false;
621
+ }
605
622
 
606
- // ── JS fallback path ─────────────────────────────────────────────────
623
+ /** JS/WASM fallback: parse files and compute metrics via AST traversal. */
624
+ async function computeJsFallbackMetrics(
625
+ db: BetterSqlite3Database,
626
+ fileSymbols: Map<string, FileSymbols>,
627
+ rootDir: string,
628
+ ): Promise<void> {
607
629
  const { parsers, extToLang } = await initWasmParsersIfNeeded(fileSymbols);
608
630
  const { getParser } = await import('../domain/parser.js');
609
631
 
@@ -649,6 +671,20 @@ export async function buildComplexityMetrics(
649
671
  }
650
672
  }
651
673
 
674
+ export async function buildComplexityMetrics(
675
+ db: BetterSqlite3Database,
676
+ fileSymbols: Map<string, FileSymbols>,
677
+ rootDir: string,
678
+ engineOpts?: {
679
+ nativeDb?: { bulkInsertComplexity?(rows: Array<Record<string, unknown>>): number };
680
+ suspendJsDb?: () => void;
681
+ resumeJsDb?: () => void;
682
+ },
683
+ ): Promise<void> {
684
+ if (tryNativeBulkInsert(db, fileSymbols, engineOpts)) return;
685
+ await computeJsFallbackMetrics(db, fileSymbols, rootDir);
686
+ }
687
+
652
688
  // ─── Query-Time Functions (re-exported from complexity-query.ts) ──────────
653
689
  // Split to separate query-time concerns (DB reads, filtering, pagination)
654
690
  // from compute-time concerns (AST traversal, metric algorithms).
@@ -23,6 +23,7 @@ import { hasDataflowTable, openReadonlyOrFail, openReadonlyWithNative } from '..
23
23
  import { ALL_SYMBOL_KINDS, normalizeSymbol } from '../domain/queries.js';
24
24
  import { debug, info } from '../infrastructure/logger.js';
25
25
  import { isTestFile } from '../infrastructure/test-filter.js';
26
+ import type { NormalizedSymbol } from '../shared/normalize.js';
26
27
  import { paginateResult } from '../shared/paginate.js';
27
28
  import type { BetterSqlite3Database, NativeDatabase, NodeRow, TreeSitterNode } from '../types.js';
28
29
  import { findNodes } from './shared/find-nodes.js';
@@ -438,85 +439,126 @@ function prepareDataflowStmts(db: BetterSqlite3Database): DataflowStmts {
438
439
  };
439
440
  }
440
441
 
441
- function buildNodeDataflowResult(
442
- node: NodeRow,
443
- stmts: DataflowStmts,
444
- db: BetterSqlite3Database,
445
- hc: Map<string, string | null>,
442
+ // ─── Shared dataflow result builder ──────────────────────────────────
443
+
444
+ /** Pre-mapped raw dataflow edge arrays shared between SQL and native paths. */
445
+ interface RawDataflowEdges {
446
+ flowsTo: {
447
+ target: string;
448
+ kind: string;
449
+ file: string;
450
+ line: number;
451
+ paramIndex: number;
452
+ expression: string;
453
+ confidence: number;
454
+ }[];
455
+ flowsFrom: {
456
+ source: string;
457
+ kind: string;
458
+ file: string;
459
+ line: number;
460
+ paramIndex: number;
461
+ expression: string;
462
+ confidence: number;
463
+ }[];
464
+ returnConsumers: {
465
+ consumer: string;
466
+ kind: string;
467
+ file: string;
468
+ line: number;
469
+ expression: string;
470
+ }[];
471
+ returnedBy: { producer: string; kind: string; file: string; line: number; expression: string }[];
472
+ mutatesTargets: { target: string; expression: string; line: number }[];
473
+ mutatedBy: { source: string; expression: string; line: number }[];
474
+ }
475
+
476
+ /**
477
+ * Build a unified dataflow result from pre-mapped edge data.
478
+ * Shared between the SQL and native code paths.
479
+ */
480
+ function buildDataflowResult(
481
+ sym: NormalizedSymbol,
482
+ edges: RawDataflowEdges,
446
483
  noTests: boolean,
447
484
  ): Record<string, unknown> {
448
- const sym = normalizeSymbol(node, db, hc);
449
-
450
- const flowsTo = stmts.flowsToOut.all(node.id).map((r: any) => ({
451
- target: r.target_name,
452
- kind: r.target_kind,
453
- file: r.target_file,
454
- line: r.line,
455
- paramIndex: r.param_index,
456
- expression: r.expression,
457
- confidence: r.confidence,
458
- }));
459
-
460
- const flowsFrom = stmts.flowsToIn.all(node.id).map((r: any) => ({
461
- source: r.source_name,
462
- kind: r.source_kind,
463
- file: r.source_file,
464
- line: r.line,
465
- paramIndex: r.param_index,
466
- expression: r.expression,
467
- confidence: r.confidence,
468
- }));
469
-
470
- const returnConsumers = stmts.returnsOut.all(node.id).map((r: any) => ({
471
- consumer: r.target_name,
472
- kind: r.target_kind,
473
- file: r.target_file,
474
- line: r.line,
475
- expression: r.expression,
476
- }));
477
-
478
- const returnedBy = stmts.returnsIn.all(node.id).map((r: any) => ({
479
- producer: r.source_name,
480
- kind: r.source_kind,
481
- file: r.source_file,
482
- line: r.line,
483
- expression: r.expression,
484
- }));
485
-
486
- const mutatesTargets = stmts.mutatesOut.all(node.id).map((r: any) => ({
487
- target: r.target_name,
488
- expression: r.expression,
489
- line: r.line,
490
- }));
491
-
492
- const mutatedBy = stmts.mutatesIn.all(node.id).map((r: any) => ({
493
- source: r.source_name,
494
- expression: r.expression,
495
- line: r.line,
496
- }));
497
-
498
485
  if (noTests) {
499
486
  const filter = (arr: any[]) => arr.filter((r: any) => !isTestFile(r.file));
500
487
  return {
501
488
  ...sym,
502
- flowsTo: filter(flowsTo),
503
- flowsFrom: filter(flowsFrom),
504
- returns: returnConsumers.filter((r) => !isTestFile(r.file)),
505
- returnedBy: returnedBy.filter((r) => !isTestFile(r.file)),
506
- mutates: mutatesTargets,
507
- mutatedBy,
489
+ flowsTo: filter(edges.flowsTo),
490
+ flowsFrom: filter(edges.flowsFrom),
491
+ returns: edges.returnConsumers.filter((r: any) => !isTestFile(r.file)),
492
+ returnedBy: edges.returnedBy.filter((r: any) => !isTestFile(r.file)),
493
+ mutates: edges.mutatesTargets,
494
+ mutatedBy: edges.mutatedBy,
508
495
  };
509
496
  }
510
497
 
511
498
  return {
512
499
  ...sym,
513
- flowsTo,
514
- flowsFrom,
515
- returns: returnConsumers,
516
- returnedBy,
517
- mutates: mutatesTargets,
518
- mutatedBy,
500
+ flowsTo: edges.flowsTo,
501
+ flowsFrom: edges.flowsFrom,
502
+ returns: edges.returnConsumers,
503
+ returnedBy: edges.returnedBy,
504
+ mutates: edges.mutatesTargets,
505
+ mutatedBy: edges.mutatedBy,
506
+ };
507
+ }
508
+
509
+ function buildNodeDataflowResult(
510
+ node: NodeRow,
511
+ stmts: DataflowStmts,
512
+ db: BetterSqlite3Database,
513
+ hc: Map<string, string | null>,
514
+ noTests: boolean,
515
+ ): Record<string, unknown> {
516
+ const sym = normalizeSymbol(node, db, hc);
517
+ const edges: RawDataflowEdges = {
518
+ flowsTo: stmts.flowsToOut.all(node.id).map((r: any) => ({
519
+ target: r.target_name,
520
+ kind: r.target_kind,
521
+ file: r.target_file,
522
+ line: r.line,
523
+ paramIndex: r.param_index,
524
+ expression: r.expression,
525
+ confidence: r.confidence,
526
+ })),
527
+ flowsFrom: stmts.flowsToIn.all(node.id).map((r: any) => ({
528
+ source: r.source_name,
529
+ kind: r.source_kind,
530
+ file: r.source_file,
531
+ line: r.line,
532
+ paramIndex: r.param_index,
533
+ expression: r.expression,
534
+ confidence: r.confidence,
535
+ })),
536
+ returnConsumers: stmts.returnsOut.all(node.id).map((r: any) => ({
537
+ consumer: r.target_name,
538
+ kind: r.target_kind,
539
+ file: r.target_file,
540
+ line: r.line,
541
+ expression: r.expression,
542
+ })),
543
+ returnedBy: stmts.returnsIn.all(node.id).map((r: any) => ({
544
+ producer: r.source_name,
545
+ kind: r.source_kind,
546
+ file: r.source_file,
547
+ line: r.line,
548
+ expression: r.expression,
549
+ })),
550
+ mutatesTargets: stmts.mutatesOut.all(node.id).map((r: any) => ({
551
+ target: r.target_name,
552
+ expression: r.expression,
553
+ line: r.line,
554
+ })),
555
+ mutatedBy: stmts.mutatesIn.all(node.id).map((r: any) => ({
556
+ source: r.source_name,
557
+ expression: r.expression,
558
+ line: r.line,
559
+ })),
519
560
  };
561
+ return buildDataflowResult(sym, edges, noTests);
520
562
  }
521
563
 
522
564
  function buildNativeDataflowResult(
@@ -528,72 +570,51 @@ function buildNativeDataflowResult(
528
570
  ): Record<string, unknown> {
529
571
  const sym = normalizeSymbol(node, db, hc);
530
572
  const d = nativeDb.getDataflowEdges!(node.id);
531
-
532
- const flowsTo = d.flowsToOut.map((r: any) => ({
533
- target: r.name,
534
- kind: r.kind,
535
- file: r.file,
536
- line: r.line,
537
- paramIndex: r.paramIndex,
538
- expression: r.expression,
539
- confidence: r.confidence,
540
- }));
541
- const flowsFrom = d.flowsToIn.map((r: any) => ({
542
- source: r.name,
543
- kind: r.kind,
544
- file: r.file,
545
- line: r.line,
546
- paramIndex: r.paramIndex,
547
- expression: r.expression,
548
- confidence: r.confidence,
549
- }));
550
- const returnConsumers = d.returnsOut.map((r: any) => ({
551
- consumer: r.name,
552
- kind: r.kind,
553
- file: r.file,
554
- line: r.line,
555
- expression: r.expression,
556
- }));
557
- const returnedBy = d.returnsIn.map((r: any) => ({
558
- producer: r.name,
559
- kind: r.kind,
560
- file: r.file,
561
- line: r.line,
562
- expression: r.expression,
563
- }));
564
- const mutatesTargets = d.mutatesOut.map((r: any) => ({
565
- target: r.name,
566
- expression: r.expression,
567
- line: r.line,
568
- }));
569
- const mutatedBy = d.mutatesIn.map((r: any) => ({
570
- source: r.name,
571
- expression: r.expression,
572
- line: r.line,
573
- }));
574
-
575
- if (noTests) {
576
- const filter = (arr: any[]) => arr.filter((r: any) => !isTestFile(r.file));
577
- return {
578
- ...sym,
579
- flowsTo: filter(flowsTo),
580
- flowsFrom: filter(flowsFrom),
581
- returns: returnConsumers.filter((r: any) => !isTestFile(r.file)),
582
- returnedBy: returnedBy.filter((r: any) => !isTestFile(r.file)),
583
- mutates: mutatesTargets,
584
- mutatedBy,
585
- };
586
- }
587
-
588
- return {
589
- ...sym,
590
- flowsTo,
591
- flowsFrom,
592
- returns: returnConsumers,
593
- returnedBy,
594
- mutates: mutatesTargets,
595
- mutatedBy,
573
+ const edges: RawDataflowEdges = {
574
+ flowsTo: d.flowsToOut.map((r: any) => ({
575
+ target: r.name,
576
+ kind: r.kind,
577
+ file: r.file,
578
+ line: r.line,
579
+ paramIndex: r.paramIndex,
580
+ expression: r.expression,
581
+ confidence: r.confidence,
582
+ })),
583
+ flowsFrom: d.flowsToIn.map((r: any) => ({
584
+ source: r.name,
585
+ kind: r.kind,
586
+ file: r.file,
587
+ line: r.line,
588
+ paramIndex: r.paramIndex,
589
+ expression: r.expression,
590
+ confidence: r.confidence,
591
+ })),
592
+ returnConsumers: d.returnsOut.map((r: any) => ({
593
+ consumer: r.name,
594
+ kind: r.kind,
595
+ file: r.file,
596
+ line: r.line,
597
+ expression: r.expression,
598
+ })),
599
+ returnedBy: d.returnsIn.map((r: any) => ({
600
+ producer: r.name,
601
+ kind: r.kind,
602
+ file: r.file,
603
+ line: r.line,
604
+ expression: r.expression,
605
+ })),
606
+ mutatesTargets: d.mutatesOut.map((r: any) => ({
607
+ target: r.name,
608
+ expression: r.expression,
609
+ line: r.line,
610
+ })),
611
+ mutatedBy: d.mutatesIn.map((r: any) => ({
612
+ source: r.name,
613
+ expression: r.expression,
614
+ line: r.line,
615
+ })),
596
616
  };
617
+ return buildDataflowResult(sym, edges, noTests);
597
618
  }
598
619
 
599
620
  export function dataflowData(