feat(csharp): read union base-property dedupe facts from the IR#17043
Draft
fern-support wants to merge 1 commit into
Draft
feat(csharp): read union base-property dedupe facts from the IR#17043fern-support wants to merge 1 commit into
fern-support wants to merge 1 commit into
Conversation
Add an opt-in `dedupe-union-base-properties` C# config flag that stops duplicating a discriminated union's base properties on its `samePropertiesAsObject` variant leaves. The decision is read from the IR fact `ObjectTypeDeclaration.deferredUnionBaseProperties` (computed once in the IR with structural type equality and an exclusive-variant guard) via a new `GeneratorContext.getBasePropertyWireNamesToOmitForType` — the generator never re-derives it. Model policy (envelope owns the base props; variant leaves + their example initializers omit them; the union JSON reader strips union-owned properties per-variant before deserializing) lives in ObjectGenerator/UnionGenerator. Written fresh rather than stacking on #16975 (which will be closed). Incorporates that PR's review feedback: reading the structural IR fact removes the differently-typed-field data-corruption footgun and the cross-union accumulation concern by construction; base-property naming goes through the shared `getGeneratedPropertyName` helper; config key is kebab-case per convention. BLOCKED / DRAFT: stacks on the IR PR (#17041). Does not compile until `@fern-fern/ir-sdk` publishes 67.12 with `deferredUnionBaseProperties` and csharp moves to irVersion 67 (declared in versions.yml). Verified the rest type-checks by temporarily stubbing the one field access (all 17 csharp packages compiled). Not included: the C# dynamic-snippets leaf omission (needs @fern-api/dynamic-ir-sdk republished; snippet tests stay disabled on the fixture until then) and the regenerated seed output for the new fixture. Co-Authored-By: Claude <noreply@anthropic.com>
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.
Description
Linear ticket: Refs
PR 3 of 3 (stacked on the IR PR #17041). Adds the opt-in C# discriminated-union base-property dedupe, reading the decision from the IR (
ObjectTypeDeclaration.deferredUnionBaseProperties) instead of computing it in the generator.Written fresh (not stacked on #16975, which will be closed), but incorporating #16975's review feedback — see below.
Changes Made
base/src/context/GeneratorContext.ts: newgetBasePropertyWireNamesToOmitForType(typeId)that returnsir.types[typeId].deferredUnionBasePropertieswire names, gated on the flag. No computation, no reference-graph analysis, no caches.codegen/.../CsharpConfigSchema.ts+generation-info.ts: opt-indedupe-union-base-propertiesflag (kebab-case, default off).model/src/generateFields.ts: extracted sharedgetGeneratedPropertyNamehelper (single source of truth for property naming).model/src/object/ObjectGenerator.ts: variant-leaf classes + their example initializers omit the deferred base properties.model/src/union/UnionGenerator.ts: generated example sets base properties on the envelope; the union JSON reader strips union-owned properties per-variant (never aggregated) before deserializing a variant.getGeneratedPropertyName;versions.ymlentries (csharp-sdk + csharp-model,irVersion: 67); seed fixturecsharp-union-base-properties.Learnings applied from #16975's review
deferredUnionBasePropertiesis computed with structural type equality, so a same-named-but-differently-typed field is never dropped.getGeneratedPropertyName.dedupe-union-base-properties, matching every other C# config key.Verification
deferredUnionBasePropertiesaccess (the only line that needs the unpublished SDK field): all 17 csharp packages compile. The lone remaining error is that documented field access.Remaining before this can merge
@fern-fern/ir-sdkpublishes 67.12; bump the csharp@fern-fern/ir-sdkdep and move csharp toirVersion: 67.@fern-api/dynamic-ir-sdkrepublished withdeferredUnionBaseProperties; snippet tests stay disabled on the fixture until then. Not in this PR.pnpm seed test --generator csharp-sdk; the fix(csharp): stop duplicating discriminated-union base properties on variant leaves #16975 baseline was onlyserver-sent-events-openapichanging, plus this new fixture). Not committed here — no .NET toolchain in the authoring environment.Testing
getGeneratedPropertyNameunit test added (compiles; runs in CI once unblocked).Generated with Claude Code