Skip to content

What a generated type promises that the type itself cannot say - #46

Merged
matt-edmondson merged 1 commit into
mainfrom
claude/peaceful-mayer-oo6l2u
Sep 10, 2026
Merged

What a generated type promises that the type itself cannot say#46
matt-edmondson merged 1 commit into
mainfrom
claude/peaceful-mayer-oo6l2u

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

The exemplar's first two sections each end with two static_asserts, and both acceptance tests stripped them. The document recorded that as an open question — they are an assertion about a generated type rather than something the schema asked for, and where they belong was undecided.

Both acceptance tests now assert the document's sections in full. That is the point of this change: §1 and §2 are byte-identical to the specification rather than byte-identical to it less two lines each.


Where they belong, and why

The decision turns on something already settled in this AST.

SourceFile.Imports are the one part that does not translate — a C++ include path, a C# namespace and a Python module are different kinds of thing that share a position, so each is carried as text for the language the file is for.

A compile-time predicate is the same shape of problem. std::is_trivially_copyable_v<T> has no equivalent anywhere else, so there is no shared idea underneath it to model. CompileTimeAssertion.Condition is therefore text — which makes it consistent with an existing rule rather than a new special case.

static_assert(std::is_trivially_copyable_v<RigidBody>,
    "RigidBody must be trivially copyable: it crosses the C# boundary and the wire as bytes");

The message goes on its own line. These are long by nature — the predicate says what is false and the message says why anyone cared — and a compiler quoting the whole declaration back reads better as two lines than as one very wide one.

Only C++ has anything checked before the program runs. The other three write a comment saying what was asserted, because a file that quietly loses a guarantee looks exactly like one that still makes it:

// asserted at build time: std::is_standard_layout_v<RigidBody>

One rule needed hoisting

A namespace and a file separated every member unconditionally, which split the two assertions about one type into two paragraphs. They now follow the same rule the members of a type already do, lifted to a virtual on the base:

  • Always separate, unless a language says otherwise.
  • C++ says: two of a kind that say nothing about themselves stay together.

So a struct is separated from the assertions about it, and those assertions are one block.

Verification

  • dotnet build -c Release0 warnings, 0 errors across the solution
  • 485 tests pass (477 before, 8 new), 0 failures

The new tests cover the C++ spelling with and without a message, escaping of a message containing a quote, what the other three languages say instead, the grouping rule, the YAML round trip, cloning, and placing one through the graph.

Each acceptance expectation is still rebuilt from the document's own text. The semantic type's remains the document with exactly one line substituted — the short accessor, which clang-format does not reconcile either way — and the test still names that substitution as the only one.

What is next

The bridge from a ktsu.Schema model to these nodes. It is currently blocked on ktsu.Coder publishing a version containing the node set merged in #45: the newest on NuGet is 3.3.0, which predates that merge, and Schema would need to reference it.

🤖 Generated with Claude Code

https://claude.ai/code/session_01AhoPJ5AbxP8QEBNxPQYEPk


Generated by Claude Code

The exemplar's first two sections each end with two static_asserts, and both
acceptance tests stripped them. The document recorded that as an open question:
they are an assertion about a generated type rather than something the schema
asked for, and where they belong was undecided.

They belong in the AST, and the decision turns on something already settled.
SourceFile.Imports are the one part of the AST that does not translate -- a C++
include path, a C# namespace and a Python module are different kinds of thing
that share a position, so each is carried as text for the language the file is
for. A compile-time predicate is the same shape of problem:
std::is_trivially_copyable_v<T> has no equivalent anywhere else, so there is no
shared idea underneath it to model. CompileTimeAssertion.Condition is therefore
text, which makes it consistent with an existing rule rather than a new special
case.

Only C++ has anything checked before the program runs. The other three write a
comment saying what was asserted, because a file that quietly loses a guarantee
looks exactly like one that still makes it.

The message goes on its own line. These are long by nature -- the predicate says
what is false and the message says why anyone cared -- and a compiler quoting
the whole declaration back is easier to read as two lines than as one very wide
one.

Both acceptance tests now assert the document's sections in full. That is the
point of this change: sections 1 and 2 are byte-identical to the specification
rather than byte-identical to it less two lines each.

Getting there needed the blank-line rule in one more place. A namespace and a
file separated every member unconditionally, which split the two assertions
about one type into two paragraphs. They now follow the same rule the members of
a type do, hoisted to a virtual on the base: always separate, unless a language
says otherwise, and C++ says two of a kind that say nothing about themselves
stay together.

485 tests pass, 477 before and 8 new, with 0 warnings across the solution.

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

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit 026ce76 into main Sep 10, 2026
12 checks passed
@matt-edmondson
matt-edmondson deleted the claude/peaceful-mayer-oo6l2u branch September 10, 2026 11:46
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