Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
02045fb
csharp: impact on an interface method finds its callers and implement…
swapnilpaliwal-sd Sep 26, 2026
34fcc80
python: a line inserted after a method's docstring is a change to tha…
swapnilpaliwal-sd Sep 26, 2026
65064cd
Merge pull request #1374 from AxiomCodeAI/fix/1358-python-docstring-i…
swapnilpaliwal-sd Sep 26, 2026
e812066
changed: a removed or new declaration is listed once, and a class by …
swapnilpaliwal-sd Sep 26, 2026
be090ec
python: a script with a python shebang and no .py extension is indexe…
swapnilpaliwal-sd Sep 26, 2026
1e032d8
Merge pull request #1378 from AxiomCodeAI/fix/1377-changed-duplicate-…
swapnilpaliwal-sd Sep 26, 2026
4b7d797
Merge fix/1376-python-shebang-scripts into 0.1.3 (#1376)
swapnilpaliwal-sd Sep 26, 2026
3160944
release 0.1.3: every package, plugin manifest and the parser at 0.1.3
swapnilpaliwal-sd Sep 26, 2026
c7d2e3d
help: --lang and --language list csharp
swapnilpaliwal-sd Sep 26, 2026
2e6214f
index: every language in a repository gets a graph, and queries ask each
swapnilpaliwal-sd Sep 27, 2026
0df257c
Merge fix/mixed-language-index into 0.1.3
swapnilpaliwal-sd Sep 27, 2026
2121512
javascript: a JSX element is an edge to the component it renders
swapnilpaliwal-sd Sep 28, 2026
a055664
typescript: a JSX component tag is a call to the component
swapnilpaliwal-sd Sep 28, 2026
47b5a94
skill: name the MCP tool before the shell verb on the first-call surf…
swapnilpaliwal-sd Sep 28, 2026
7fb4ed6
Merge pull request #1466 from AxiomCodeAI/loop/ja-js-jsx-component-use
swapnilpaliwal-sd Sep 28, 2026
e22cb39
Merge pull request #1541 from AxiomCodeAI/loop/ty-ts-jsx-tags
swapnilpaliwal-sd Sep 28, 2026
9d18792
Merge pull request #1558 from AxiomCodeAI/fix/1425-skill-mcp-first
swapnilpaliwal-sd Sep 28, 2026
879c63e
java: a var local never names an external type called var (#1401)
swapnilpaliwal-sd Sep 28, 2026
a98cacf
python: impact and path read framework_edge (#1509)
swapnilpaliwal-sd Sep 28, 2026
9b5783a
Merge pull request #1563 from AxiomCodeAI/fix/1401-var-local-type
swapnilpaliwal-sd Sep 28, 2026
16a492e
Merge pull request #1564 from AxiomCodeAI/fix/1509-python-framework-edge
swapnilpaliwal-sd Sep 28, 2026
8615740
java: the oracle-agreement golden counts the case added by #1563
swapnilpaliwal-sd Sep 28, 2026
33cc5e4
java: record the three var shapes case 61 leaves untyped as known-mis…
swapnilpaliwal-sd Sep 28, 2026
6ace630
java: case 61 gets its oracle golden
swapnilpaliwal-sd Sep 28, 2026
7a03c15
typescript: a JSX tag through a wrapper, a loader or a prop lands on …
swapnilpaliwal-sd Sep 28, 2026
a85d207
refresh after edit: one engine lookup, no silent fallback, safe swaps…
swapnilpaliwal-sd Sep 28, 2026
976a5e4
Merge pull request #1575 from AxiomCodeAI/fix/1401-oracle-agreement-g…
swapnilpaliwal-sd Sep 28, 2026
18a6cd4
Merge pull request #1577 from AxiomCodeAI/loop/ty-ts-jsx-tags
swapnilpaliwal-sd Sep 28, 2026
dc4c1a1
Merge pull request #1565 from AxiomCodeAI/fix/refresh-after-edit
swapnilpaliwal-sd Sep 28, 2026
e1ef564
Query latency: do once what every query repeated; never hold a call s…
swapnilpaliwal-sd Sep 28, 2026
32eee1f
Merge pull request #1576 from AxiomCodeAI/fix/query-latency
swapnilpaliwal-sd Sep 28, 2026
5a5525a
parser: 0.1.1, the parser's own version (it moves only when the parse…
swapnilpaliwal-sd Sep 28, 2026
ed67b99
Merge pull request #1581 from AxiomCodeAI/release/parser-0.1.1
swapnilpaliwal-sd Sep 28, 2026
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
44 changes: 37 additions & 7 deletions bin/axiomcode
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
# (run.source_version). Defaults to the source's git commit, or
# v1.0.0 outside a checkout.
# --exclude-tests Exclude test code. Included by default.
# --language <L> Restrict the run to one language: java, typescript, python or
# javascript.
# --language <L>[,…] Restrict the run to these languages: java, typescript, python,
# javascript or csharp.
# --debug Also write csv/*.csv and keep raw/ beside each graph.
#
# Engine options:
Expand Down Expand Up @@ -57,7 +57,13 @@ if [ -L "$self" ]; then
fi
self="$r"
fi
ROOT="$(d="$(cd "$(dirname "$self")" && pwd)"; while [ "$d" != / ] && { [ ! -f "$d/package.json" ] || [ ! -d "$d/graph" ]; }; do d="$(dirname "$d")"; done; echo "$d")"
# NO PROGRAM IS STARTED TO FIND IT: the parent of a path is taken by parameter expansion, not `dirname`. Every query goes
# through here, and under Git Bash on Windows each program started is a fork emulation that costs tens of milliseconds
# idle and far more on a busy machine; the walk used to start one per level, the verb check below four more.
case "$self" in */*) d="${self%/*}";; *) d=.;; esac
d="$(cd "${d:-/}" && pwd)"
while [ "$d" != / ] && { [ ! -f "$d/package.json" ] || [ ! -d "$d/graph" ]; }; do d="${d%/*}"; d="${d:-/}"; done
ROOT="$d"
# No marker found means every path built from ROOT is nonsense; say so here rather than fail
# later on a path the user cannot interpret.
[ -d "$ROOT/graph" ] || { echo "axiomcode: cannot locate the package root from $0 (resolved to $self)" >&2; exit 2; }
Expand All @@ -76,8 +82,20 @@ QUERY="$ROOT/plugins/axiomcode/skills/axiomcode/scripts/axiomcode"
# `tests` is the frontend's alias for test-impact; `test` is THIS command's engine suite. One letter
# apart, entirely different jobs, and putting both on one command is a trap — so the alias is not
# routed here, and the name is refused below with both readings spelled out.
query_verbs(){ [ -f "$QUERY" ] && bash "$QUERY" --verbs 2>/dev/null | grep -vx tests || true; }
is_query_verb(){ query_verbs | grep -qx -- "$1"; }
# The list is read from the frontend's own dispatch table, the lines ` <verb>[|<alias>]) exec …` that its `--verbs`
# prints, so the two entry points still cannot drift -- but read here, in this shell, instead of by a second bash, a
# sed, a tr and two greps on every query.
QVERBS=()
load_verbs(){
[ ${#QVERBS[@]} -gt 0 ] && return 0; [ -f "$QUERY" ] || return 0
local l v x re='^ ([a-z|-]*)\) *exec '
while IFS= read -r l || [ -n "$l" ]; do
[[ $l =~ $re ]] || continue; v="${BASH_REMATCH[1]}"
for x in ${v//|/ }; do [ "$x" = tests ] || QVERBS+=("$x"); done
done < "$QUERY"
}
query_verbs(){ load_verbs; [ ${#QVERBS[@]} -gt 0 ] && printf '%s\n' "${QVERBS[@]}"; return 0; }
is_query_verb(){ load_verbs; local x; for x in ${QVERBS[@]+"${QVERBS[@]}"}; do [ "$x" = "$1" ] && return 0; done; return 1; }
usage(){
awk 'NR > 2 && /^# ─/ {exit} NR > 2' "$0" | sed 's/^# \{0,1\}//'
if [ -f "$QUERY" ]; then
Expand Down Expand Up @@ -177,7 +195,11 @@ case "$cmd" in
[ -n "$src" ] || src="${pos[0]:-}"; [ -n "$out" ] || out="${pos[1]:-}"
[ -n "$src" ] && [ -n "$out" ] || die "usage: axiomcode <src-dir> <out-dir> [--library <path>[,…]] [options] (try --help)"
[ -d "$src" ] || die "not a directory: $src"
[ -z "$lang" ] || [ -d "$ROOT/graph/$lang" ] || die "no engine for --language=$lang (have: $(ls -d "$ROOT"/graph/*/engine 2>/dev/null | sed 's#.*/graph/##; s#/engine##' | tr '\n' ' '))"
# --language takes one language or a comma list of them (a repository written in several)
IFS=',' read -ra want <<< "$lang"
for l in ${want[@]+"${want[@]}"}; do
[ -d "$ROOT/graph/$l" ] || die "no engine for --language=$l (have: $(ls -d "$ROOT"/graph/*/engine 2>/dev/null | sed 's#.*/graph/##; s#/engine##' | tr '\n' ' '))"
done
[ -n "$version" ] || version="$(git -C "$src" rev-parse HEAD 2>/dev/null || echo v1.0.0)"
popts+=(--version "$version")
mkdir -p "$out"; out="$(cd "$out" && pwd)"; int="$out/.intermediate"; ir="$int/ir"
Expand Down Expand Up @@ -233,8 +255,16 @@ case "$cmd" in
found=(); for d in "$ir"/*/; do l="$(basename "$d")"; [ -d "$ROOT/graph/$l/engine" ] && found+=("$l"); done
[ ${#found[@]} -gt 0 ] || { echo "❌ no language with an engine in the IR (folders: $(ls "$ir" | tr '\n' ' '))" >&2; exit 1; }
langs=("${found[@]}")
if [ -n "$lang" ]; then
if [ ${#want[@]} -eq 1 ]; then
case " ${found[*]} " in *" $lang "*) langs=("$lang");; *) echo "❌ --language=$lang, but the IR holds only: ${found[*]}" >&2; exit 1;; esac
elif [ ${#want[@]} -gt 1 ]; then
# A LANGUAGE ASKED FOR AND NOT FOUND IS NAMED, NEVER DROPPED IN SILENCE. The caller counted files by
# extension; the parser finds PROJECTS, and a file no project claims is not in the IR. The others are
# still solved, and the caller is told which one is missing.
langs=(); missing=()
for l in "${want[@]}"; do case " ${found[*]} " in *" $l "*) langs+=("$l");; *) missing+=("$l");; esac; done
[ ${#missing[@]} -gt 0 ] && echo "⚠️ asked for ${missing[*]}, but the IR holds no such language (it holds: ${found[*]})" >&2
[ ${#langs[@]} -gt 0 ] || { echo "❌ --language=$lang, but the IR holds only: ${found[*]}" >&2; exit 1; }
fi
echo "▶ languages: ${langs[*]}"
# ONE LANGUAGE'S FAILURE MUST NOT COST THE OTHERS THEIR GRAPHS. Under `set -e` this loop
Expand Down
2 changes: 1 addition & 1 deletion gemini-extension.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "axiomcode",
"version": "0.1.2",
"version": "0.1.3",
"description": "Ask your repository how its code connects: who calls this, what breaks if I change it, which tests an edit reaches, how A reaches B. Answers come from a resolved call graph and are verified against it; nothing is guessed.",
"contextFileName": "plugins/axiomcode/AGENTS.md",
"mcpServers": {
Expand Down
8 changes: 4 additions & 4 deletions graph/bundle/SCHEMA.md
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ THE GRAPH. One row per (site, resolved target). A site with N possible targets h
| `DYNAMIC_IMPORT_CALL` | typescript | `import(…)`. |
| `DECORATOR_CALL` | typescript | A decorator application `@d` / `@d(…)`. |
| `OPTIONAL_CALL` | typescript | `f?.(…)`. |
| `JSX_COMPONENT_CALL` | typescript | `<Component …/>` (reserved by the parser; emitted by nothing yet). |
| `JSX_COMPONENT_CALL` | typescript | `<Component …/>` — a JSX element naming a component; `<div>` emits no site. |
| `PROPERTY_READ` | typescript, javascript | Reading `obj.x` where `x` is a `get` accessor runs the getter (engine-authored). No written call; the site is the property-access expression. A compound assignment or `++` reads before it writes, so it carries this and PROPERTY_WRITE. |
| `PROPERTY_WRITE` | typescript, javascript | Assigning `obj.x = v` where `x` is a `set` accessor runs the setter (engine-authored). No written call; the site is the property-access expression on the left. |
| `FUNCTION_CALL` | javascript | `f(…)` — a bare callee, resolved by the binder. |
Expand All @@ -507,6 +507,7 @@ THE GRAPH. One row per (site, resolved target). A site with N possible targets h
| `TAGGED_TEMPLATE_CALL` | javascript | tag`…`. |
| `DYNAMIC_CODE_CALL` | javascript | `eval(…)` / `new Function(…)` — unknowable by construction. |
| `DYNAMIC_IMPORT_CALL` | javascript | `import(…)` — a module load that is also a site. |
| `JSX_ELEMENT` | javascript | `<Component …/>` — the renderer runs the component (a function component, or a class component's constructor and `render`) with the element's attributes as its props. Engine-authored: no written call; the site is the JSX element expression. An intrinsic tag (`<div/>`) is no site. |
| `SIMPLE_CALL` | python | `f(…)` — a bare name. |
| `METHOD_CALL` | python | `obj.m(…)`. |
| `CHAINED_CALL` | python | `a.b().c(…)` — the receiver is itself a call. |
Expand Down Expand Up @@ -598,7 +599,7 @@ THE DISPATCH ENVELOPE: (base method, method that may run instead) for every call

| value | languages | meaning |
|---|---|---|
| `nominal` | java, typescript | A written extends/implements reaches the candidate's owner from the base's owner. The strongest evidence there is: the author declared the relationship. |
| `nominal` | java, typescript, csharp | A written extends/implements reaches the candidate's owner from the base's owner. The strongest evidence there is: the author declared the relationship. |
| `structural` | typescript | No declaration; the candidate's owner satisfies the base's owner by SHAPE. Emitted only for supertypes with no nominal implementor at all, so it never competes with a declared answer — but it is a heuristic, and a consumer that wants declarations only filters it out. |
| `value` | java, typescript, csharp, python | A function stored in a field, variable or parameter whose type is the base's callable type; a call through that holder may run it. In TypeScript also a function written as an implementation of an interface's member signature: an object-literal member of a literal typed by the interface (#1208), or a function assigned to the member through a property chain, `inst.i.run = (x) => …` (#1283). In C# also what one delegate member is assigned from another (`a.Run = a.Parse`). In Python, a function assigned onto an instance's member from outside its class, which shadows the class's method of that name. The base is the signature the call resolves to (bodiless), so the pair is how a walk over callers reaches the function that runs. Flow-derived rather than declared: a consumer that wants declarations only filters it out. |
| `mro` | python | The subtype's C3 linearisation picks the candidate for that attribute name. Not merely "the subtype declares this name" — a name a sibling base wins is attributed to that sibling. |
Expand All @@ -609,7 +610,7 @@ THE DISPATCH ENVELOPE: (base method, method that may run instead) for every call

### `overrides`

Virtual-dispatch pairs: (base method, overriding method) wherever a call to the base may run the override. Java only, and kept for compatibility — it is exactly `dispatch_candidates` filtered to `basis = nominal`. Prefer `dispatch_candidates`, which is populated in every language.
Virtual-dispatch pairs: (base method, overriding method) wherever a call to the base may run the override. Java and C# only, and kept for compatibility — it is exactly `dispatch_candidates` filtered to `basis = nominal`. Prefer `dispatch_candidates`, which is populated in every language.

| # | column | type | key | null | idx | meaning |
|---|---|---|---|---|---|---|
Expand All @@ -620,7 +621,6 @@ Virtual-dispatch pairs: (base method, overriding method) wherever a call to the

- **typescript** — EMPTY — this table is Java-shaped. The TypeScript dispatch envelope is in dispatch_candidates, with basis `nominal` or `structural`.
- **python** — EMPTY — this table is Java-shaped. The Python dispatch envelope is in dispatch_candidates with basis `mro`, and `value` for a function assigned onto an instance's member; the raw linearisation is in ext_mro_position.
- **csharp** — EMPTY — C# records the dispatch envelope in dispatch_candidates, not as override rows.

### `entry_points`

Expand Down
5 changes: 4 additions & 1 deletion graph/bundle/languages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,10 @@ const CSHARP: LanguageAdapter = {
prefixes: { method: 'CS_METHOD_', type: 'CS_TYPE_', expression: 'CS_EXPRESSION_', module: 'CS_MODULE_' },
raw: {
callEdges: CALL_EDGES,
typeAncestors: { file: 'resolution-type-ancestor.csv', columns: [1, 2] },
// keyed on the declaration, not the partial-type group type_ancestor itself uses,
// so it joins types.id
typeAncestors: { file: 'resolution-type-ancestor-type.csv', columns: [1, 2] },
overrides: { file: 'resolution-virtual-override.csv', columns: [0, 1] },
entryPoints: { file: 'entry-point.csv', columns: [0, 1] },
entryReachable: { file: 'entry-reachable.csv', columns: [0] },
dispatchCandidates: { file: 'dispatch-candidates.csv', columns: [0, 1, 2] },
Expand Down
8 changes: 4 additions & 4 deletions graph/bundle/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export const CORE_TABLES: readonly TableSpec[] = [
},
{
name: 'overrides',
description: 'Virtual-dispatch pairs: (base method, overriding method) wherever a call to the base may run the override. Java only, and kept for compatibility — it is exactly `dispatch_candidates` filtered to `basis = nominal`. Prefer `dispatch_candidates`, which is populated in every language.',
description: 'Virtual-dispatch pairs: (base method, overriding method) wherever a call to the base may run the override. Java and C# only, and kept for compatibility — it is exactly `dispatch_candidates` filtered to `basis = nominal`. Prefer `dispatch_candidates`, which is populated in every language.',
columns: [
{ name: 'method_id', type: 'TEXT', key: true, indexed: true, description: 'FK → methods.id — the base (declared) method.' },
{ name: 'overriding_method_id', type: 'TEXT', key: true, indexed: true, description: 'FK → methods.id — the override in a subtype.' },
Expand Down Expand Up @@ -623,7 +623,7 @@ export const VOCAB: readonly VocabSpec[] = [
{ table: 'call_edges', column: 'kind', value: 'DYNAMIC_IMPORT_CALL', languages: T, meaning: '`import(…)`.' },
{ table: 'call_edges', column: 'kind', value: 'DECORATOR_CALL', languages: T, meaning: 'A decorator application `@d` / `@d(…)`.' },
{ table: 'call_edges', column: 'kind', value: 'OPTIONAL_CALL', languages: T, meaning: '`f?.(…)`.' },
{ table: 'call_edges', column: 'kind', value: 'JSX_COMPONENT_CALL', languages: T, meaning: '`<Component …/>` (reserved by the parser; emitted by nothing yet).' },
{ table: 'call_edges', column: 'kind', value: 'JSX_COMPONENT_CALL', languages: T, meaning: '`<Component …/>` — a JSX element naming a component; `<div>` emits no site.' },
{ table: 'call_edges', column: 'kind', value: 'PROPERTY_READ', languages: ['typescript', 'javascript'], meaning: 'Reading `obj.x` where `x` is a `get` accessor runs the getter (engine-authored). No written call; the site is the property-access expression. A compound assignment or `++` reads before it writes, so it carries this and PROPERTY_WRITE.' },
{ table: 'call_edges', column: 'kind', value: 'PROPERTY_WRITE', languages: ['typescript', 'javascript'], meaning: 'Assigning `obj.x = v` where `x` is a `set` accessor runs the setter (engine-authored). No written call; the site is the property-access expression on the left.' },
// — JavaScript (the parser's JsCallKind)
Expand All @@ -640,6 +640,7 @@ export const VOCAB: readonly VocabSpec[] = [
{ table: 'call_edges', column: 'kind', value: 'TAGGED_TEMPLATE_CALL', languages: S, meaning: 'tag`…`.' },
{ table: 'call_edges', column: 'kind', value: 'DYNAMIC_CODE_CALL', languages: S, meaning: '`eval(…)` / `new Function(…)` — unknowable by construction.' },
{ table: 'call_edges', column: 'kind', value: 'DYNAMIC_IMPORT_CALL', languages: S, meaning: '`import(…)` — a module load that is also a site.' },
{ table: 'call_edges', column: 'kind', value: 'JSX_ELEMENT', languages: S, meaning: '`<Component …/>` — the renderer runs the component (a function component, or a class component\'s constructor and `render`) with the element\'s attributes as its props. Engine-authored: no written call; the site is the JSX element expression. An intrinsic tag (`<div/>`) is no site.' },
// — Python (the parser's callKind, plus engine-authored decorator/metaclass forms)
{ table: 'call_edges', column: 'kind', value: 'SIMPLE_CALL', languages: P, meaning: '`f(…)` — a bare name.' },
{ table: 'call_edges', column: 'kind', value: 'METHOD_CALL', languages: P, meaning: '`obj.m(…)`.' },
Expand Down Expand Up @@ -691,7 +692,7 @@ export const VOCAB: readonly VocabSpec[] = [
{ table: 'entry_points', column: 'reason', value: 'orm_hook', languages: P, meaning: 'A lifecycle or validation hook registered by decoration. The data layer calls it; nothing in the client does.' },

// dispatch_candidates.basis
{ table: 'dispatch_candidates', column: 'basis', value: 'nominal', languages: ['java', 'typescript'], meaning: 'A written extends/implements reaches the candidate\'s owner from the base\'s owner. The strongest evidence there is: the author declared the relationship.' },
{ table: 'dispatch_candidates', column: 'basis', value: 'nominal', languages: ['java', 'typescript', 'csharp'], meaning: 'A written extends/implements reaches the candidate\'s owner from the base\'s owner. The strongest evidence there is: the author declared the relationship.' },
{ table: 'dispatch_candidates', column: 'basis', value: 'structural', languages: T, meaning: 'No declaration; the candidate\'s owner satisfies the base\'s owner by SHAPE. Emitted only for supertypes with no nominal implementor at all, so it never competes with a declared answer — but it is a heuristic, and a consumer that wants declarations only filters it out.' },
{ table: 'dispatch_candidates', column: 'basis', value: 'value', languages: ['java', 'typescript', 'csharp', 'python'], meaning: 'A function stored in a field, variable or parameter whose type is the base\'s callable type; a call through that holder may run it. In TypeScript also a function written as an implementation of an interface\'s member signature: an object-literal member of a literal typed by the interface (#1208), or a function assigned to the member through a property chain, `inst.i.run = (x) => …` (#1283). In C# also what one delegate member is assigned from another (`a.Run = a.Parse`). In Python, a function assigned onto an instance\'s member from outside its class, which shadows the class\'s method of that name. The base is the signature the call resolves to (bodiless), so the pair is how a walk over callers reaches the function that runs. Flow-derived rather than declared: a consumer that wants declarations only filters it out.' },
{ table: 'dispatch_candidates', column: 'basis', value: 'mro', languages: P, meaning: 'The subtype\'s C3 linearisation picks the candidate for that attribute name. Not merely "the subtype declares this name" — a name a sibling base wins is attributed to that sibling.' },
Expand Down Expand Up @@ -764,7 +765,6 @@ export const NOTES: readonly NoteSpec[] = [
{ language: 'csharp', table: 'skipped', note: 'EMPTY — the C# front end writes no skipped-files report. It takes the opposite line: a construct its grammar does not cover fails the run rather than skipping the file, so there is no per-file decision to record. An empty table here is not evidence that every file was read.' },
{ language: 'csharp', table: 'type_instantiated', note: 'EMPTY — the C# engine derives the instantiation set but does not export it. Dispatch in C# is not narrowed by it either (see the README of the C# engine).' },
{ language: 'csharp', table: 'type_use', note: 'EMPTY — the C# front end does not export type uses yet.' },
{ language: 'csharp', table: 'overrides', note: 'EMPTY — C# records the dispatch envelope in dispatch_candidates, not as override rows.' },
{ language: 'javascript', table: 'dispatch_candidates', note: 'EMPTY — JavaScript has no declared dispatch to widen from: a multi_inferred set is already the values the receiver may hold (see call_edges), so there is no envelope to record.' },
{ language: 'javascript', table: 'skipped', note: 'A DIRECTORY_EXCLUDED row\'s file_path is a PRUNED DIRECTORY, not a file, and `detail` carries how many files are behind it; those files have no rows of their own. So `SELECT count(*) FROM skipped` is not the number of files missing, and a join on file_path will not match them. Filter the reason out when you want per-file rows.' },
{ language: 'python', table: 'skipped', note: 'The only front end that positions a skip: a PY2_CONSTRUCT_DETECTED row carries the construct and its line and column, so the file can be triaged without re-running the parser.' },
Expand Down
Loading
Loading