Let a construction hold a designated initialiser in the graph - #62
Merged
Merged
Conversation
…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
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Closes #52.
ConstructionExpression.Argumentswas declaredAstSlotKind.Expression, and aMemberInitialiseris not an expression — it names the member a value is for rather than evaluating to one. SoAcceptsrefused it, which made the handling two cases further down unreachable. That case is written with nowhen child is Expressionguard, unlike all five of its neighbours, andArgumentsis typedCollection<AstNode>rather thanCollection<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
MemberInitialiserthrough theExpressionarm. That would be wrong, and checking why was the useful part of this:The slot is shared with
CallExpression.Arguments. Every generator readsconstruction.Argumentsfor 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.Elementis 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, becauseAstGraph.ValidateConnectionis 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
Elementarm reverted toIsExpression(candidate), the schema test fails onAcceptsand the graph test onresult.Success.850/850 tests pass.
🤖 Generated with Claude Code
https://claude.ai/code/session_01QGCMUrT3jBgmANHNHcPmBf
Generated by Claude Code