Skip to content

Let a construction hold a designated initialiser in the graph - #62

Merged
matt-edmondson merged 1 commit into
mainfrom
claude/bold-planck-mxarux
Sep 13, 2026
Merged

matt-edmondson merged 1 commit into
mainfrom
claude/bold-planck-mxarux

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Closes #52.

ConstructionExpression.Arguments was declared AstSlotKind.Expression, and a MemberInitialiser is not an expression — it names the member a value is for rather than evaluating to one. So Accepts refused it, which made the handling two cases further down unreachable. That case is written with no when child is Expression guard, unlike all five of its neighbours, and Arguments is typed Collection<AstNode> rather than Collection<Expression>: both say the intent was to accept it.

The AST, the serializer and all seven generators handle one in exactly this position — a designated initialiser in C++, an object initialiser in C#, a keyword argument in Python, an object literal in JavaScript. The graph is meant to be the uniform view of the AST, and here it could not express a shape every other projection could.

A kind, not a widening

The obvious fix is to let MemberInitialiser through the Expression arm. That would be wrong, and checking why was the useful part of this:

The slot is shared with CallExpression.Arguments. Every generator reads construction.Arguments for a member initialiser — CSharpGenerator:356, CppGenerator:502, PythonGenerator:228, JavaScriptGenerator:188, RustGenerator:1222, GoGenerator:1603, CGenerator:736 — and none reads a call's. One attached to a call would be written as whatever fell out of the generic dispatch rather than as a named argument.

So AstSlotKind.Element is its own kind and a construction gets its own slot: same name, because the editor labels the pin the same way and the attach cases switch on the name, different rule for what may stand in it. The kinds part exactly where the generators do, and the tests pin both halves — a construction takes one, a call refuses it.

Coverage

  • DeclarationSlotsTests — attach, read back, detach; plus the call refusing it.
  • AstGraphTests — the whole chain rather than the schema's answer alone, because AstGraph.ValidateConnection is where the editor felt this: drag a link, validate against the slot, and the AST ends up holding the node.

Both were checked against the bug rather than written after it was gone. With the Element arm reverted to IsExpression(candidate), the schema test fails on Accepts and the graph test on result.Success.

850/850 tests pass.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QGCMUrT3jBgmANHNHcPmBf


Generated by Claude Code

…52)

`ConstructionExpression.Arguments` was declared `AstSlotKind.Expression`,
and a `MemberInitialiser` is not an expression: it names the member a value
is for rather than evaluating to one. So `Accepts` refused it, and the
handling two cases further down — deliberately written with no `when child
is Expression` guard, unlike its five neighbours — was unreachable.

The AST, the serializer and all seven generators handle one in exactly this
position. The graph is meant to be the uniform view of the AST, and here it
could not express a shape every other projection could.

## A kind rather than a widening

The slot is shared with `CallExpression.Arguments`, and the two should not
be widened together: every generator reads `construction.Arguments` for a
member initialiser and **none** reads a call's. One attached to a call would
be written as whatever fell out rather than as a named argument.

So `AstSlotKind.Element` is its own kind and a construction gets its own
slot, with the same name — the pin reads the same and the attach cases
switch on the name — and a different rule. The kinds part exactly where the
generators do, and a test pins both halves: a construction takes one, a call
refuses it.

The graph-level test goes through the whole chain rather than the schema's
answer alone, because `ValidateConnection` is where the editor felt this.
Both tests were checked against the bug: with the `Element` arm reverted,
the schema test fails on `Accepts` and the graph test on `result.Success`.

850/850 tests pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QGCMUrT3jBgmANHNHcPmBf
@sonarqubecloud

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit 575eafd into main Sep 13, 2026
12 checks passed
@matt-edmondson
matt-edmondson deleted the claude/bold-planck-mxarux branch September 13, 2026 03:02
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.

AstSchema refuses a MemberInitialiser in ConstructionExpression.Arguments, which the AST, serializer and all four generators support

2 participants