fix(core): stop heuristically merging distinct named top-level classes#3055
fix(core): stop heuristically merging distinct named top-level classes#3055schani wants to merge 6 commits into
Conversation
#1630) When multiple named top-level JSON inputs were structurally similar (one a property subset of another), CombineClasses' similarity-clique heuristic would merge them into a single class, silently dropping one of the named top-level types and misnaming shared descendant types after the wrong survivor. Exclude named top-level classes from the heuristic similarity-merge candidate pool in findSimilarityCliques; exact-duplicate top-levels are still deduplicated during inference as before, and heuristic merging of non-top-level (inferred/nested) classes is unaffected. Added a regression test (test/unit/multiple-json-top-levels.test.ts) using the Plaid API request JSON samples from the issue, asserting AccountsGetRequest stays distinct from AuthGetRequest and that AuthGetRequest's nested options class is named AuthGetRequestOptions rather than AccountsGetRequestOptions. Fixes #1630 Co-Authored-By: gpt-5.6-sol via pi <noreply@openai.com>
|
I’m not sure this is actually a bug. I’ll have to read up on what the semantics of using a JSON directory as input actually is. |
|
On the directory semantics: The collapse comes from The reason I'm confident this is a real bug and not just a debatable heuristic is
The fix is narrow: it only removes |
…age-3055-1784733942
Generated-output differences1 files differ — 0 modified, 1 new, 0 deleted |
Generated-output differences1 files differ — 0 modified, 1 new, 0 deleted |
Bug
When quicktype was run on a directory of JSON samples where two named top-level types were structurally similar (one's properties are a subset of another's), the type-graph rewriting logic could incorrectly merge them into a single class. Reported against C# output in #1630 using the Plaid API's
AccountsGet.Request.json,AuthGet.Request.json, andTransactionsGet.Request.jsonsamples:AccountsGetRequesthasclient_id,secret, andaccess_token.AuthGetRequesthas the same properties plusoptions.AccountsGetRequesthelper whoseFromJsonreturnedAuthGetRequest.AuthGetRequest.Optionswas misnamedAccountsGetRequestOptions.Root cause
CombineClasses' similarity pass considered distinct named top-level classes as merge candidates. Its 3/4 property-overlap heuristic correctly combines structurally similar inferred classes, but it must not erase the distinction between top-level names supplied by separate input files.Fix
Prevent a similarity clique from containing more than one top-level class. A top-level class can still combine with inferred nested classes, preserving existing recursive-type inference, and exact duplicate top levels remain deduplicated earlier during inference.
Fixture coverage
Added the three issue inputs under
test/inputs/json/priority/issue-1630/and a focusedcsharp-multiple-json-top-levelsfixture. It passes the directory as one JSON input—the same multi-source path used by the CLI—and its C# driver:AccountsGetRequest.FromJsonto returnAccountsGetRequest;AuthGetRequest.Optionsto useAuthGetRequestOptions;TransactionsGetRequest.Optionsto retainTransactionsGetRequestOptions;The fixture participates in C#/System.Text.Json CI and generated-output snapshots, so the intended generated-code change is visible in the output-difference report.
Verification
npm run buildnpm run test:unit(218 tests)npm run lint -- --diagnostic-level=errorOUTPUT_SNAPSHOT_DIR=/tmp/pr3055-head-snapshot FIXTURE=csharp-multiple-json-top-levels CPUs=1 npm run test:fixturesThe local environment does not have
dotnet; the fixture's compile/round-trip path runs in C# CI.Fixes #1630