Skip to content

Keep the source generator running on [Blocks(null)] and case clashes - #3124

Merged
pournasserian merged 3 commits into
mainfrom
3071-generator-followups
Nov 15, 2026
Merged

pournasserian merged 3 commits into
mainfrom
3071-generator-followups

Conversation

@pournasserian

@pournasserian pournasserian commented Nov 15, 2026 •

Copy link
Copy Markdown
Member

The two inputs from the review of M4 and M6 that stopped the source generator (CS8785) and left a compilation with no builders, plus three follow-ups from the review of this pull request. Each item got a failing test first.

Closes #3071

What changed

  1. [Blocks(null)]. SymbolReader skips an array argument that IsNull, so the field gets no member and no word, its class keeps a builder with its other fields, and the other classes keep theirs. [Blocks] is the only array argument the generator enumerates. The host now refuses [Blocks(null)] with FCMS1211, the code it gives [Blocks] with no types, where it failed with a NullReferenceException. The analyzers report it with FCMS0011, where they reported nothing.
  2. Builder names that differ in case alone. FieldsEmitter compares class names ignoring case, as Roslyn compares hint names and as generate compares its files. x-y and xy give XYFields and XyFields: the first in the emitter's order gets the builder, the second gets none and FCMS0100. Because the tool shares the emitter, generate csharp now writes such a schema, warning FCMS0100 for the second builder, where it refused it with FCMS3380.
  3. A block type with a hyphen takes its name. The emitter now takes the class name before it leaves out a block type with a hyphen (FCMS0104), as the tool's TypeNames gives that type its class. For blocks a-b and ab, ab now gets neither a builder (FCMS0100) nor a class (FCMS3376), where it got the builder AbBlockFields while a-b kept the class ABBlock. The FCMS0100 message is now "because another type takes the name X, in this case or another".
  4. [Select(null)]. The host now refuses it with FCMS1216, where it failed with a NullReferenceException. On an enum it gets the message for a list on an enum, and elsewhere the message for no options. The analyzers report it with the matching rule, FCMS0007 or FCMS0008, where they skipped it. The generator still gives the field its member, as it does for [Select] with no options.

Spec 6.1 and 6.4, docs/analyzers.md (FCMS0007, FCMS0008, FCMS0011) and the tool's README say what was built. No new codes.

Decisions

  • A [Blocks(null)] field is left out on its own and its class keeps its builder. The generator already does this for [Blocks()] and for a blocks field whose types are not blocks.
  • The first name wins, in the emitter's order (group, then name, then namespace, ordinal). That is the order SchemaModel gives the tool's TypeNames, so the tool and the generator keep the same type.
  • For item 3, the emitter takes the name rather than TypeNames skipping the block: a block type with a hyphen still needs its class in a client to read its JSON. In a host, ab beside a-b loses the builder it had, and FCMS0100 says why.
  • [Select(null)] is refused on an enum too, rather than read as [Select] with the enum's members as its options, so null gets no new meaning.

Tests

  • Generator: [Blocks(null)] beside another collection gives every builder, none with Body, and no exception or diagnostic. x-y and xy beside another collection give XYFields and the other builders, one FCMS0100 at the class of xy, and no exception.
  • Emitter: case clashes among collections and among components keep the first of each. Blocks a-b and ab give no builder, with FCMS0104 and FCMS0100.
  • Core: [Blocks(null!)] is FCMS1211, and [Select(null!)] is FCMS1216 on a string and on an enum. Analyzers: they are FCMS0011, FCMS0008 and FCMS0007, and LeftToTheHostTests no longer treats either as unreported.
  • Tool: generate csharp on foo-bar and foobar exits 0, writes FooBar.g.cs and FooBarFields.g.cs, and warns FCMS0100. Blocks a-b and ab give ABBlock.g.cs and no class or builder for ab, in C# and in TypeScript.
  • dotnet build -c Release -warnaserror is clean. The Generators (138), Sdk (148), Core (1572) and Architecture (24) tests and the tool's GenerateTests class (22) pass in Release. Markdown lint is clean.

@pournasserian pournasserian added type:bug Defect area:sdk FluentCMS.Sdk public contract labels Nov 15, 2026
@pournasserian
pournasserian enabled auto-merge (squash) November 15, 2026 15:07
@pournasserian
pournasserian merged commit fba1a44 into main Nov 15, 2026
14 checks passed
@pournasserian
pournasserian deleted the 3071-generator-followups branch November 15, 2026 15:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:sdk FluentCMS.Sdk public contract type:bug Defect

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Source generator follow-ups from the review of M4 and M6

1 participant