Skip to content

0.2.3 - #2013

Merged
swapnilpaliwal-sd merged 16 commits into
devfrom
0.2.3
Nov 4, 2026
Merged

0.2.3#2013
swapnilpaliwal-sd merged 16 commits into
devfrom
0.2.3

Conversation

@swapnilpaliwal-sd

Copy link
Copy Markdown
Contributor

releasing 0.2.3.

swapnilpaliwal-sd and others added 14 commits October 10, 2026 14:36
…not the file's

`Models.Report` written inside namespace P, in a file that also declares
P.Other.Models and Z.Models, bound to all three Report types: the relative
candidate (type_qn_tail + module_ns_chain) is keyed per FILE, so every
namespace the file declares a type in qualified every name in it. C# reads the
first segment from the namespaces enclosing the site, innermost outward, and
the innermost level with a match wins.

- type_name_out_of_scope(ns, name, arity, group): per site namespace and
  dotted written name, candidates are ranked by the prefix they were found
  under; only the longest survives, and a full match survives only when no
  enclosing namespace matched. Demand-driven from names a file writes.
- type_ref_resolves, ref_names_type, expr_new_type and heritage_resolves drop
  what the site's enclosing type's namespace rules out. Prune-only: the
  file-level answer is unchanged and a site with no known enclosing type drops
  nothing.

Case a-relative-name-is-read-from-the-sites-namespace fails 5/6 on the base
(the single-namespace control passes on both) and passes 6/6.

Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…thod callees resolve (#1997, #1998, #1999, #2000, #2001)

Five callee shapes resolved to nothing though the compiler names their
target:

- new C() where C is typed by a construct-signature literal or an alias
  of one: construction read expr_type only, the plain-call side already
  read expr_shape (#1997)
- ns.f() where f is an exported const of a function type whose value is
  not a function literal: the namespace read gave var_type, never
  var_shape (#1998)
- a.b.c.m() through nested inline object types: a shape-typed member
  read off a shape qualifier had no field_shape clause (#1999)
- this.m() in an object literal typed X & ThisType<T>: the marker is
  read through intersections and aliases, with the alias parameter and
  the call's explicit type argument substituted (#2000)
- this.m.bind/call/apply and the bound result's call: the Function
  members attach to a method read as a value (#2001)

Two guards keep sites that were right from hedging: the namespace shape
is not added where the const holds a function literal, and the
construct shape is not added where the callee variable holds a class.

Cases 91 to 95 pin each shape with its controls. Goldens moved in 08,
80 and 83 (see the pull request); 83's known-missing edge now resolves.
… keeps its own version)

0.2.2 is released; this PR ships in 0.2.3. package.json (version and the five @axiomcode/engine-* pins) and the four editor plugin and extension manifests move from 0.2.2 to 0.2.3. The parser is unchanged by this PR and stays at 0.2.1.
… keeps its own version)

0.2.2 is released, so what merges into this branch ships in 0.2.3. package.json (version and the five @axiomcode/engine-* pins) and the four editor plugin and extension manifests move from 0.2.2 to 0.2.3. The parser keeps its own version, 0.2.1.
typescript: construct, namespace, inline-chain, ThisType and bound-method callees resolve (#1997, #1998, #1999, #2000, #2001)
…2006)

A call the CLI could not carry out — bash missing, the verb crashed or was killed, an exit no verb
uses, silence, a timeout with no build running, a refusal (exit 2) — came back as an ordinary result
on both server paths; only schema-invalid arguments were flagged. run() now raises the server's own
ToolError with the same words, which the SDK and the fallback both mark isError, so the model still
reads the correction. An answer, path's "no chain" (exit 1 in words) and the note that a graph is
still being built (exit 2 while the build lock is held) stay ordinary results.

AXIOMCODE_MCP_TIMEOUT (seconds) exists so a test can see the timeout. tests/mcp.py checks nine
cases per launch mode, on the fallback and, with AXIOMCODE_SDK_PYTHON, on the SDK.
mcp: an execution failure is a tool error (isError), not an answer (#2006)
Two links from one call site to two anonymous functions collapsed into one:
every arrow function and lambda shares a placeholder name (`<arrow>`,
`<lambda>`, `Owner.<lambda>`), and adding a link replaced any row at the same
site with the same target name, ignoring the file:line that tells them apart.

- add: a row is replaced only when it names the same declaration (same name
  and target_file, or resolving to the same declaration in the graph), so
  re-linking stays idempotent and a second anonymous target is a second link
- --remove <site> <target>: <target> may be a declaration's file:line; a name
  that covers links to more than one declaration is refused with each one's
  file:line instead of removing them all
- link output and --list print a placeholder target with its declaration

Cases for TypeScript arrows, Python lambdas and C# lambdas, with controls:
idempotent re-link, two named targets at one site, remove by name.

Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…as receivers

Three receiver shapes had no type, so a call on them resolved to nothing even
with the declaration staged:

- Arithmetic: `-`, `*`, `/`, `%`, `**`, bitwise/shift operators and unary
  `-`, `~`, `++`, `--` yield Number (BigInt when an operand is a bigint);
  unary `+` is always Number; `+` is Number only when both operands are.
  Typing these also fixes overload choice where the arithmetic result is an
  argument (a numeric constructor overload, a `number` function overload).
- Defaults: `a ?? b` / `a || b` (and `a && b`'s right side) carry the named
  type of the operand the compiler names, as the shape rule already did.
  An un-annotated field initialised by a generic `new` now passes its type
  arguments on, so `this.byKey.get(k) ?? []` substitutes V.
- Namespace consts: `N.v(...)` and `N.v.m(...)` where `v` is a const
  declared in a namespace (local, nested, ambient, or a global the binder
  left unbound) now take the const's declared type or shape. A const that
  holds a function literal keeps its body as the only answer.

Cases 96-98 cover each with controls: a string `+` stays String, a bigint
result never names Number, an annotated default is unchanged, an untyped
left side does not borrow the right's type, a namespace function and a
parameter shadowing the namespace name are unchanged.

Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…ral nested in a typed literal

`const poll: (ctx: Ctx) => R = async ({ data, utils }) => utils.http(..)` and
`define({ lifecycle: { start: async ({ utils }) => utils.http(..) } })` left every call
on `utils` unresolved, while `ctx.utils.http(..)` on the same arrow resolved.

Two causes:
- a bound name reads its pattern's type through param_type, which only an annotation
  fills; contextual typing (lambda_param_type) typed references to the parameter and
  never the names destructured from it. The bound name now takes the type (and shape)
  of the field it names from the contextual type, typed at its uses beside the plain
  parameter's, not through param_type, which overload rejection reads under negation.
- an object literal written as a property of a typed literal had no scope, so functions
  in a nested slot took no parameter types. It now takes the type of the field it fills.

Case 99 pins both, with controls: an `any` pattern and a parameter typed by an object
type literal stay unresolved. Every other TypeScript case is unchanged (109/109).

On a Deno connector repository (~750 endpoint definitions): known_edge rows 7,410 -> 8,923,
ambiguous_unknown 35,820 -> 34,300, multi_inferred 63 -> 77, no edge lost; 194 of 198
hook calls of the framework's HTTP helper now resolve.

Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
… its member's type

`const { port } = opts` with `opts: { port: Port }`, and `({ port }: Opts)` with
`type Opts = { port: Port }`, left `port` untyped, so `port.execute()` was
unresolved while `opts.port.execute()` beside it resolved. A type literal has no
declaration for param_type / expr_type to name: it is a shape. The destructuring
rules for parameters and variables now read the shape too (a shape is its own
scope), for fields, nested shapes and methods.

Case 100 covers inline and aliased literals, parameters and variables, a nested
shape and a shape method, with controls: an untyped source stays unresolved, and
a look-alike literal resolves to its own method, not to the interface. Case 75:
five destructured-prop calls now resolve to the targets the compiler oracle had
listed as known-missing (the shadowing guard still holds); they still show as
missing+extra only because a destructured caller is labelled once per bound name.

On a 1.9k-file Deno TypeScript repo: known_edge 7,410 -> 7,441, ambiguous_unknown
35,820 -> 35,789, 0 resolved edges lost; spot-checked against the source.

Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
The parser emits a row for a destructuring pattern and one per name it binds, all at
the pattern's position. normalize_edges.py turned each into a parameter, so
`aliasParam({ port, clock }: Opts)` was labelled `aliasParam(Opts,Opts,Opts)` while the
compiler oracle prints `aliasParam(Opts)`: the same edge showed as one missing and
one extra. One row per position, the pattern's when present.

Case 100's three known-missing edges and five of case 75's now agree with the oracle;
both debt lists are trimmed. Suite 110/110.

Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
typescript: a name destructured from a type-literal-typed value takes its member's type
…red-params

typescript: a destructured parameter typed by its context, and a literal nested in a typed literal
csharp: a relative qualified name is read from the site's namespace, not the file's (#1906)
@swapnilpaliwal-sd swapnilpaliwal-sd self-assigned this Nov 4, 2026
…ange

The case landed with four known-missing edges (a destructured parameter's
per-name label and a parameter typed by an object type literal); the change
merged just before it resolves all four, so the suite failed as NOW-FIXED.

Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
@swapnilpaliwal-sd
swapnilpaliwal-sd merged commit 3f3e6d5 into dev Nov 4, 2026
26 checks passed
@swapnilpaliwal-sd
swapnilpaliwal-sd deleted the 0.2.3 branch November 4, 2026 19:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants