feat(core): nest inline types in their owner + PascalCase component names (#92)#94
Open
halotukozak wants to merge 9 commits into
Open
feat(core): nest inline types in their owner + PascalCase component names (#92)#94halotukozak wants to merge 9 commits into
halotukozak wants to merge 9 commits into
Conversation
Inline (anonymous) request/response body schemas were generated as flat, structurally-deduplicated top-level model files with awkward names like `Domains_updateRequest`. They are now lifted per operation and generated as data classes nested inside the owning client class, e.g. `DomainsApi.DomainsUpdateRequest` / `DomainsApi.DomainsUpdateResponse`. - New `planOperationInlineTypes` pass (run by CodeGenerator) rewrites inline operation bodies into per-operation reference ids — no structural dedup, so each operation gets its own copy. - `Hierarchy` resolves those ids to the nested `ClassName`. - `ClientGenerator` nests the data classes in the client class and registers the ids before generating functions, so signatures resolve. - Naming: `PascalCase(operationId)` + `Request`/`Response` (no tag stripping — operationId is author-controlled and arbitrary); non-2xx and default responses get distinct suffixes. Inline objects nested in model properties (-> nested under the parent type) and PascalCasing of top-level component names are follow-ups. Refs #92 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Coverage Report
|
…line too Replaces the two separate inline mechanisms (ModelGenerator's collectAllInlineSchemas + the operation-only planner) with a single ownership-aware pass, planInlineTypes, that lifts every inline object schema — operation request/response bodies AND object-typed properties, recursively — into PlannedInlineType trees and rewrites the spec to references. - Parser: TypeRef.Inline no longer carries a stringly-typed contextHint; inline detection is purely structural. Naming/placement is now a pure generation concern. - Operation bodies nest in the client class (as before); object properties now nest in their parent data class (e.g. Pet.Address), recursively for nested inline objects. - No structural dedup: each occurrence is named/placed relative to its owner. Removes InlineSchemaKey, InlineTypeResolver (resolveInlineTypes), collectInlineTypeRefs. - Shared recursive emitter ModelGenerator.emitNestedInline registers reference ids -> nested ClassNames so resolution stays consistent. Refs #92 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Component schema, enum, and typealias type names are now emitted as PascalCase Kotlin identifiers (e.g. dataSetList -> DataSetList, data_owner -> DataOwner), resolved consistently through a single Hierarchy.classNameFor so $ref usages, nested-variant lookups, and the get() fallback all agree. Wire identity is untouched: @SerialName / @JsonClassDiscriminator and discriminator mapping keep the original spec names; only the Kotlin identifier changes (a non-polymorphic type name never appears on the wire). Closes #92 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the two id-keyed inline maps (clientInline/modelInline) with a gen-layer TransformedApiSpec whose endpoints and schemas carry their own lifted inline types (TransformedEndpoint/TransformedSchema). This removes the soft foreign keys between the spec and the inline maps, drops the Hierarchy.modelInline field and the ClientGenerator operationInlineTypes parameter, and keeps inline placement local to its owner. The single-pass planner is now the ApiSpec.transform() extension, with its mutually recursive walk deduplicated into plan()/planProperties()/collect(). Fix a latent bug: request bodies were lifted for every content type, so form/multipart inline bodies became a Reference and their properties no longer expanded into individual function parameters. Only JSON bodies are nested now; form/multipart bodies stay inline. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ne-types # Conflicts: # core/src/main/kotlin/com/avsystem/justworks/core/gen/InlineSchemaKey.kt # core/src/main/kotlin/com/avsystem/justworks/core/gen/InlineTypeResolver.kt # core/src/main/kotlin/com/avsystem/justworks/core/gen/model/ModelGenerator.kt # core/src/main/kotlin/com/avsystem/justworks/core/model/TypeRef.kt # core/src/main/kotlin/com/avsystem/justworks/core/parser/SpecParser.kt # core/src/test/kotlin/com/avsystem/justworks/core/gen/InlineSchemaDedupTest.kt
…port master features Reconcile the merge from master: keep the nested-inline architecture and rename its types coherently — ApiSpec.resolveInlines() returns a ResolvedApiSpec whose ResolvedEndpoint/ResolvedSchema carry NestedType (sealed Obj/Enum) trees. Ported from master onto this architecture: - inline enums generated as enums nested in their owner (incl. oneOf/anyOf variants) - uniqueItems -> Set, honor property defaults, empty response -> Unit - stripDiscriminatorProperties to suppress orphan discriminator enums Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ne-types # Conflicts: # core/src/main/kotlin/com/avsystem/justworks/core/gen/CodeGenerator.kt # core/src/main/kotlin/com/avsystem/justworks/core/gen/client/ClientGenerator.kt # core/src/main/kotlin/com/avsystem/justworks/core/gen/model/ModelGenerator.kt # core/src/test/kotlin/com/avsystem/justworks/core/gen/ClientGeneratorTest.kt # core/src/test/kotlin/com/avsystem/justworks/core/gen/IntegrationTest.kt # core/src/test/kotlin/com/avsystem/justworks/core/gen/ModelGeneratorInlineEnumTest.kt # core/src/test/kotlin/com/avsystem/justworks/core/gen/ModelGeneratorPolymorphicTest.kt # core/src/test/kotlin/com/avsystem/justworks/core/gen/ModelGeneratorRegressionTest.kt # core/src/test/kotlin/com/avsystem/justworks/core/gen/ModelGeneratorTest.kt
# Conflicts: # core/src/test/kotlin/com/avsystem/justworks/core/gen/ClientGeneratorTest.kt
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.
Closes #92.
Reworks how inline (anonymous) schemas are generated and normalizes type names — three parts, one coherent change:
1. Nest inline operation bodies in the client class
Inline request/response bodies were flat top-level files with names like
Domains_updateRequest. They now nest in the owning client class:DomainsApi.DomainsUpdateRequest/DomainsApi.DomainsUpdateResponse. Naming =PascalCase(operationId)+Request/Response(no tag-strip heuristic — operationId is author-controlled); non-2xx /defaultget distinct suffixes.2. Unified, ownership-aware inline pass
A single
planInlineTypesreplaces the two old mechanisms (collectAllInlineSchemas+ the operation-only planner). It lifts every inline object (operation bodies and object properties, recursively) intoPlannedInlineTypetrees and rewrites the spec to references. Object properties now nest under their parent type too (Pet.Address). No structural dedup — each occurrence is named/placed relative to its owner.TypeRef.Inlinelost its stringly-typedcontextHint; placement/naming is now purely a generation concern. RemovedInlineSchemaKey,InlineTypeResolver,collectInlineTypeRefs.3. PascalCase component type names
Component schema / enum / typealias names are emitted as PascalCase identifiers (
dataSetList→DataSetList), resolved consistently viaHierarchy.classNameForso$refs agree. Wire identity untouched (@SerialName/ discriminator keep spec names).Tests
End-to-end (
CodeGeneratorTest): operation-body nesting, property nesting, lowercase→PascalCase with$refresolution. Full core suite + plugin functional green; obsolete inline/dedup tests removed.🤖 Generated with Claude Code