Skip to content

Check a class's members before writing any of it [patch] - #169

Merged
matt-edmondson merged 2 commits into
mainfrom
claude/issue-164-validate-class-before-writing
Nov 4, 2026
Merged

matt-edmondson merged 2 commits into
mainfrom
claude/issue-164-validate-class-before-writing

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #164

Summary

ClassTemplate.WriteTo opened the body with using Scope scope = new(codeBlocker); and then wrote its members one at a time. When a member failed its own check, for example a property with no accessors, the Scope still wrote } as the exception unwound. The result was a class that parses cleanly but is silently missing three things:

  • the failing member
  • every member sorted after it
  • every nested class

AddSourceFile and AddClasses did the same one level up.

Changes

  • TemplateBase gets an internal virtual void Validate(), a no-op by default, matching the existing AccessorTemplate.Validate.
  • PropertyTemplate and OperatorTemplate move their existing up-front checks into Validate(), and WriteTo still calls it first. The messages are unchanged and still name the member.
  • ClassTemplate.Validate() checks its own kind, then calls Validate() on every member and every nested class, recursively. WriteTo calls it before writing anything.
  • AddSourceFile validates every class before writing the file header. AddClasses validates every class before writing the first one.

Exception types are unchanged: InvalidOperationException for an invalid member or operator kind, and ArgumentOutOfRangeException for an unknown type kind.

The checks run before writing starts, so an exception thrown by a user BodyFactory while writing can still leave partial output. That is outside what this issue covers.

Tests

  • Six new tests fail on main and pass with the fix (checked by reverting the library and running them again):
    • the issue's repro leaves the buffer empty, and the message names 'P'
    • a nested class with an invalid member leaves the outer class unwritten
    • a nested class of unknown kind leaves the outer class unwritten
    • an operator of unknown kind leaves its class unwritten
    • AddSourceFile with an invalid class writes nothing
    • AddClasses with an invalid class writes nothing
  • One guard test checks that a class whose members are all valid still renders.
  • Full suite: 256/256.

Generated by Claude Code

ClassTemplate wrote its members one at a time inside a Scope, so a member
that failed its check threw mid-body, and the Scope still wrote the
closing brace on the way out. The buffer was left with a class that
parses cleanly but silently lacks the failing member, everything sorted
after it, and every nested class. AddSourceFile and AddClasses did the
same one level up.

Each template's up-front checks now live in an internal Validate().
ClassTemplate validates its kind, its members and its nested classes,
recursively, before writing anything, and AddSourceFile and AddClasses
validate every class before writing the header or the first type. The
exception still names the offending member.

Fixes #164

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

sonarqubecloud Bot commented Nov 3, 2026

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit 86c1ffa into main Nov 4, 2026
15 checks passed
@matt-edmondson
matt-edmondson deleted the claude/issue-164-validate-class-before-writing branch November 4, 2026 00:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants