diff --git a/CHANGELOG.md b/CHANGELOG.md index 4573de3..3770c71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,16 @@ All notable changes to this project will be documented in this file. See [commit ## [3.0.3](https://github.com/optave/codegraph/compare/v3.0.2...v3.0.3) (2026-03-04) +> **Note:** 3.0.2 was an internal/unpublished version used during development. + ### Performance * **ast:** use single transaction for AST node insertion — astMs drops from ~3600ms to ~350ms (native) and ~547ms (WASM), reducing overall native build from 24.9 to 8.5 ms/file ([#333](https://github.com/optave/codegraph/pull/333)) +* **builder:** skip `ensureWasmTrees` when native engine provides complete CFG + dataflow data ([#344](https://github.com/optave/codegraph/pull/344)) + +### Bug Fixes + +* **native:** fix function-scoped `const` declarations being incorrectly extracted as top-level constants ([#344](https://github.com/optave/codegraph/pull/344)) ## [3.0.2](https://github.com/optave/codegraph/compare/v3.0.1...v3.0.2) (2026-03-04) diff --git a/src/builder.js b/src/builder.js index c5019b4..5eb48d7 100644 --- a/src/builder.js +++ b/src/builder.js @@ -1317,16 +1317,47 @@ export async function buildGraph(rootDir, opts = {}) { _t.complexityMs = performance.now() - _t.complexity0; // Pre-parse files missing WASM trees (native builds) so CFG + dataflow - // share a single parse pass instead of each creating parsers independently + // share a single parse pass instead of each creating parsers independently. + // Skip entirely when native engine already provides CFG + dataflow data. if (opts.cfg !== false || opts.dataflow !== false) { - _t.wasmPre0 = performance.now(); - try { - const { ensureWasmTrees } = await import('./parser.js'); - await ensureWasmTrees(astComplexitySymbols, rootDir); - } catch (err) { - debug(`WASM pre-parse failed: ${err.message}`); + const needsCfg = opts.cfg !== false; + const needsDataflow = opts.dataflow !== false; + + let needsWasmTrees = false; + for (const [, symbols] of astComplexitySymbols) { + if (symbols._tree) continue; // already has a tree + // CFG: need tree if any function/method def lacks native CFG + if (needsCfg) { + const fnDefs = (symbols.definitions || []).filter( + (d) => (d.kind === 'function' || d.kind === 'method') && d.line, + ); + if ( + fnDefs.length > 0 && + !fnDefs.every((d) => d.cfg === null || Array.isArray(d.cfg?.blocks)) + ) { + needsWasmTrees = true; + break; + } + } + // Dataflow: need tree if file lacks native dataflow + if (needsDataflow && !symbols.dataflow) { + needsWasmTrees = true; + break; + } + } + + if (needsWasmTrees) { + _t.wasmPre0 = performance.now(); + try { + const { ensureWasmTrees } = await import('./parser.js'); + await ensureWasmTrees(astComplexitySymbols, rootDir); + } catch (err) { + debug(`WASM pre-parse failed: ${err.message}`); + } + _t.wasmPreMs = performance.now() - _t.wasmPre0; + } else { + _t.wasmPreMs = 0; } - _t.wasmPreMs = performance.now() - _t.wasmPre0; } // CFG analysis (skip with --no-cfg) diff --git a/tests/integration/build-parity.test.js b/tests/integration/build-parity.test.js index 566d201..d2f2e8a 100644 --- a/tests/integration/build-parity.test.js +++ b/tests/integration/build-parity.test.js @@ -35,6 +35,8 @@ function readGraph(dbPath) { // Exclude constant nodes — the native engine has a known scope bug where it // extracts local `const` variables inside functions as top-level constants, // while WASM correctly limits constant extraction to program-level declarations. + // TODO: Remove kind != 'constant' exclusion once native binary >= 3.0.4 ships + // Fix: crates/codegraph-core/src/extractors/javascript.rs (find_parent_of_types guard) const nodes = db .prepare( "SELECT name, kind, file, line FROM nodes WHERE kind != 'constant' ORDER BY name, kind, file, line",