@optave/codegraph 3.8.1 → 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.
- package/README.md +12 -7
- package/dist/ast-analysis/engine.d.ts.map +1 -1
- package/dist/ast-analysis/engine.js +121 -48
- package/dist/ast-analysis/engine.js.map +1 -1
- package/dist/ast-analysis/visitors/ast-store-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/ast-store-visitor.js +15 -18
- package/dist/ast-analysis/visitors/ast-store-visitor.js.map +1 -1
- package/dist/ast-analysis/visitors/complexity-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/complexity-visitor.js +50 -1
- package/dist/ast-analysis/visitors/complexity-visitor.js.map +1 -1
- package/dist/cli/commands/branch-compare.d.ts.map +1 -1
- package/dist/cli/commands/branch-compare.js +4 -0
- package/dist/cli/commands/branch-compare.js.map +1 -1
- package/dist/cli/commands/diff-impact.d.ts.map +1 -1
- package/dist/cli/commands/diff-impact.js +2 -1
- package/dist/cli/commands/diff-impact.js.map +1 -1
- package/dist/cli/commands/info.d.ts.map +1 -1
- package/dist/cli/commands/info.js +3 -2
- package/dist/cli/commands/info.js.map +1 -1
- package/dist/db/connection.d.ts +1 -0
- package/dist/db/connection.d.ts.map +1 -1
- package/dist/db/connection.js +22 -4
- package/dist/db/connection.js.map +1 -1
- package/dist/db/repository/base.d.ts +41 -0
- package/dist/db/repository/base.d.ts.map +1 -1
- package/dist/db/repository/base.js +22 -0
- package/dist/db/repository/base.js.map +1 -1
- package/dist/db/repository/index.d.ts +1 -0
- package/dist/db/repository/index.d.ts.map +1 -1
- package/dist/db/repository/index.js.map +1 -1
- package/dist/db/repository/native-repository.d.ts +8 -1
- package/dist/db/repository/native-repository.d.ts.map +1 -1
- package/dist/db/repository/native-repository.js +69 -1
- package/dist/db/repository/native-repository.js.map +1 -1
- package/dist/db/repository/sqlite-repository.d.ts +1 -0
- package/dist/db/repository/sqlite-repository.d.ts.map +1 -1
- package/dist/db/repository/sqlite-repository.js +25 -0
- package/dist/db/repository/sqlite-repository.js.map +1 -1
- package/dist/domain/analysis/dependencies.d.ts +1 -28
- package/dist/domain/analysis/dependencies.d.ts.map +1 -1
- package/dist/domain/analysis/dependencies.js +24 -8
- package/dist/domain/analysis/dependencies.js.map +1 -1
- package/dist/domain/graph/builder/incremental.d.ts.map +1 -1
- package/dist/domain/graph/builder/incremental.js +18 -0
- package/dist/domain/graph/builder/incremental.js.map +1 -1
- package/dist/domain/graph/builder/pipeline.d.ts.map +1 -1
- package/dist/domain/graph/builder/pipeline.js +298 -206
- package/dist/domain/graph/builder/pipeline.js.map +1 -1
- package/dist/domain/graph/builder/stages/build-edges.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/build-edges.js +56 -3
- package/dist/domain/graph/builder/stages/build-edges.js.map +1 -1
- package/dist/domain/graph/builder/stages/resolve-imports.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/resolve-imports.js +19 -23
- package/dist/domain/graph/builder/stages/resolve-imports.js.map +1 -1
- package/dist/domain/graph/watcher.d.ts.map +1 -1
- package/dist/domain/graph/watcher.js +99 -95
- package/dist/domain/graph/watcher.js.map +1 -1
- package/dist/domain/parser.d.ts +4 -0
- package/dist/domain/parser.d.ts.map +1 -1
- package/dist/domain/parser.js +130 -61
- package/dist/domain/parser.js.map +1 -1
- package/dist/domain/search/models.d.ts.map +1 -1
- package/dist/domain/search/models.js +7 -5
- package/dist/domain/search/models.js.map +1 -1
- package/dist/extractors/go.js +53 -35
- package/dist/extractors/go.js.map +1 -1
- package/dist/extractors/javascript.js +85 -36
- package/dist/extractors/javascript.js.map +1 -1
- package/dist/features/complexity.d.ts.map +1 -1
- package/dist/features/complexity.js +78 -58
- package/dist/features/complexity.js.map +1 -1
- package/dist/features/dataflow.d.ts.map +1 -1
- package/dist/features/dataflow.js +109 -118
- package/dist/features/dataflow.js.map +1 -1
- package/dist/features/structure.d.ts.map +1 -1
- package/dist/features/structure.js +147 -97
- package/dist/features/structure.js.map +1 -1
- package/dist/graph/algorithms/louvain.d.ts.map +1 -1
- package/dist/graph/algorithms/louvain.js +4 -2
- package/dist/graph/algorithms/louvain.js.map +1 -1
- package/dist/graph/classifiers/roles.d.ts +2 -0
- package/dist/graph/classifiers/roles.d.ts.map +1 -1
- package/dist/graph/classifiers/roles.js +13 -5
- package/dist/graph/classifiers/roles.js.map +1 -1
- package/dist/presentation/communities.d.ts.map +1 -1
- package/dist/presentation/communities.js +38 -34
- package/dist/presentation/communities.js.map +1 -1
- package/dist/presentation/manifesto.d.ts.map +1 -1
- package/dist/presentation/manifesto.js +31 -33
- package/dist/presentation/manifesto.js.map +1 -1
- package/dist/presentation/queries-cli/inspect.d.ts.map +1 -1
- package/dist/presentation/queries-cli/inspect.js +47 -46
- package/dist/presentation/queries-cli/inspect.js.map +1 -1
- package/dist/shared/file-utils.d.ts.map +1 -1
- package/dist/shared/file-utils.js +94 -72
- package/dist/shared/file-utils.js.map +1 -1
- package/dist/types.d.ts +83 -2
- package/dist/types.d.ts.map +1 -1
- package/grammars/tree-sitter-erlang.wasm +0 -0
- package/grammars/tree-sitter-gleam.wasm +0 -0
- package/package.json +9 -9
- package/src/ast-analysis/engine.ts +150 -55
- package/src/ast-analysis/visitors/ast-store-visitor.ts +19 -21
- package/src/ast-analysis/visitors/complexity-visitor.ts +55 -1
- package/src/cli/commands/branch-compare.ts +4 -0
- package/src/cli/commands/diff-impact.ts +2 -1
- package/src/cli/commands/info.ts +3 -2
- package/src/db/connection.ts +24 -5
- package/src/db/repository/base.ts +57 -0
- package/src/db/repository/index.ts +1 -0
- package/src/db/repository/native-repository.ts +92 -1
- package/src/db/repository/sqlite-repository.ts +26 -0
- package/src/domain/analysis/dependencies.ts +24 -6
- package/src/domain/graph/builder/incremental.ts +21 -0
- package/src/domain/graph/builder/pipeline.ts +396 -245
- package/src/domain/graph/builder/stages/build-edges.ts +53 -2
- package/src/domain/graph/builder/stages/resolve-imports.ts +20 -20
- package/src/domain/graph/watcher.ts +118 -98
- package/src/domain/parser.ts +131 -63
- package/src/domain/search/models.ts +11 -5
- package/src/extractors/go.ts +57 -32
- package/src/extractors/javascript.ts +88 -35
- package/src/features/complexity.ts +94 -58
- package/src/features/dataflow.ts +153 -132
- package/src/features/structure.ts +167 -95
- package/src/graph/algorithms/louvain.ts +5 -2
- package/src/graph/classifiers/roles.ts +14 -5
- package/src/presentation/communities.ts +44 -39
- package/src/presentation/manifesto.ts +35 -38
- package/src/presentation/queries-cli/inspect.ts +48 -46
- package/src/shared/file-utils.ts +116 -77
- package/src/types.ts +87 -1
|
@@ -535,75 +535,97 @@ function upsertAstComplexity(
|
|
|
535
535
|
return 1;
|
|
536
536
|
}
|
|
537
537
|
|
|
538
|
-
|
|
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
|
-
):
|
|
548
|
-
// ── Native bulk-insert fast path ──────────────────────────────────────
|
|
599
|
+
): boolean {
|
|
549
600
|
const nativeDb = engineOpts?.nativeDb;
|
|
550
|
-
if (nativeDb?.bulkInsertComplexity)
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
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
|
-
|
|
591
|
-
|
|
592
|
-
|
|
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
|
-
|
|
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).
|
package/src/features/dataflow.ts
CHANGED
|
@@ -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
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
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
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
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(
|