Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Large codebases reward familiarity over clarity. Docs drift, static graphs show

## What it does

- **Maps** — Python: high-confidence AST call graphs with McCabe complexity and callers (import-gated / return-type factory edges when unique; ambiguous names omit rather than invent). JavaScript/TypeScript: Node TypeScript AST when available (`*-ast`, `ast-cyclomatic`, same-file + relative imports, re-export barrels, and nearest `package.json` `"exports"` subpaths); otherwise regex fallback. Go: `go/ast` when available; otherwise regex. Java: `javalang` when installed; otherwise regex. Rust: `syn` AST when cargo is available (`rust-ast`, `ast-cyclomatic`); otherwise `rust-best-effort` regex — same-file plus invent-free `mod`/`use` edges for unique scanned targets; **not** rustc typechecked/Python parity. C#: Roslyn AST when a .NET SDK is available (`csharp-ast`, `ast-cyclomatic`); otherwise `csharp-best-effort` regex — **not** typechecked/Python parity. Unsupported languages are counted and skipped (never scanned as Python or empty fake maps).
- **Maps** - Python: high-confidence AST call graphs with McCabe complexity and callers (import-gated / return-type factory edges when unique; ambiguous names omit rather than invent). JavaScript/TypeScript: Node TypeScript AST when available (`*-ast`, `ast-cyclomatic`, same-file + relative imports, re-export barrels, nearest `package.json` `"exports"`/`"imports"`, and nearest `tsconfig`/`jsconfig` `paths` when unique - still not typechecked); otherwise regex fallback. Go: `go/ast` when available; otherwise regex. Java: `javalang` when installed; otherwise regex. Rust: `syn` AST when cargo is available (`rust-ast`, `ast-cyclomatic`); otherwise `rust-best-effort` regex - same-file plus invent-free `mod`/`use` edges for unique scanned targets; **not** rustc typechecked/Python parity. C#: Roslyn AST when a .NET SDK is available (`csharp-ast`, `ast-cyclomatic`); otherwise `csharp-best-effort` regex - **not** typechecked/Python parity. Unsupported languages are counted and skipped (never scanned as Python or empty fake maps).
- **Invariants & effects** — Contract-linked structure and pre/post hints where configured; map `side_effects` tags are AST heuristics on Python, not proven purity (JS maps leave `side_effects` empty).
- **Hot-path fixtures** — Small, runnable scaffolds tied to real execution.
- **Reading plans** — Module-oriented summaries and questions before you edit.
Expand Down
17 changes: 11 additions & 6 deletions cli/ucli/analyzers/js_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
Override with ``UF_JS_ANALYZER=regex|ast|auto`` (default ``auto``).

Call edges: same-file unique short-name qualification. AST path may also
resolve high-confidence relative imports (``./foo`` / ``../foo``) to unique
exported names — never bare package imports. Ambiguous or dotted callees stay
bare. Not Python-parity (no typed ``obj.method`` resolution).
resolve high-confidence relative imports (``./foo`` / ``../foo``), nearest
``package.json`` ``"exports"`` / ``"imports"``, and nearest ``tsconfig`` /
``jsconfig`` ``paths`` aliases when uniquely mapped — never bare npm packages
or typechecked resolution. Ambiguous or dotted callees stay bare. Not
Python-parity (no typed ``obj.method`` resolution).
"""

from __future__ import annotations
Expand Down Expand Up @@ -723,8 +725,10 @@ def _build_ast_map(
f"Complexity is ast-cyclomatic (structural decision points): {formula}. "
"Call edges: same-file unique names, plus high-confidence relative "
"imports (./ / ../) to unique exports when resolved, including "
"one/two-hop re-export barrels (export { x } from './mod'). "
"No typed obj.method resolution; not Python-parity. "
"one/two-hop re-export barrels (export { x } from './mod'), nearest "
'package.json "exports"/"imports", and nearest tsconfig/jsconfig '
"paths aliases when uniquely mapped. No typed obj.method; no bare npm "
"invent; not typechecked; not Python-parity. "
"Falls back to *-best-effort regex when Node/typescript unavailable."
),
}
Expand Down Expand Up @@ -772,7 +776,8 @@ class JavaScriptAdapter:
"Prefers Node + TypeScript compiler API (javascript-ast, ast-cyclomatic); "
"degrades to regex (javascript-best-effort, keyword-heuristic) if Node or "
"cli/ucli/analyzers/js_ast deps are missing. Same-file call edges; optional "
"relative-import edges on the AST path. TypeScript types are not typechecked."
"relative-import / package.json exports|imports / tsconfig paths edges on "
"the AST path when uniquely resolved. TypeScript types are not typechecked."
)

def build_map(self, root: pathlib.Path) -> dict[str, Any]:
Expand Down
4 changes: 4 additions & 0 deletions cli/ucli/analyzers/js_ast/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ The Python analyzer invokes `parse_worker.mjs` via `node` when
`typescript` package is missing, Understand-First falls back to the
regex adapter (`javascript-best-effort`).

Wave 29 (AST path): nearest `tsconfig.json` / `jsconfig.json` `paths` and
`package.json` `"imports"` (`#…`) resolve only when the mapped file is unique.
Still parse-only — not typechecked; bare npm packages are never invented.

Force paths:

- `UF_JS_ANALYZER=regex` — always regex
Expand Down
Loading
Loading