Skip to content

[dart-dio] Fix inheritance with json_serializable using super parameters#23329

Open
AshitaNema wants to merge 4 commits intoOpenAPITools:masterfrom
AshitaNema:fix/dart-dio-json-serializable-inheritance
Open

[dart-dio] Fix inheritance with json_serializable using super parameters#23329
AshitaNema wants to merge 4 commits intoOpenAPITools:masterfrom
AshitaNema:fix/dart-dio-json-serializable-inheritance

Conversation

@AshitaNema
Copy link
Copy Markdown

@AshitaNema AshitaNema commented Mar 24, 2026

Fix for Dart-Dio Generator: Super Constructor Parameters for Inheritance

Summary

Fixed issue #22547 where the dart-dio generator with json_serializable was not properly handling inheritance. Child classes were not calling the parent constructor with required parameters, causing compilation errors in generated Dart code.

Problem

When using allOf with the dart-dio generator and json_serializable library, child models that inherited from parent models would fail to compile because:

  1. Child classes didn't extend parent classes
  2. Child constructors did not call super() with parent properties
  3. Parent properties were redeclared in child classes
  4. The parentVars field was not being populated

Example Issue

For this schema:

Animal:
  type: object
  required: [className]
  properties:
    className:
      type: string
    color:
      type: string
      default: red

Dog:
  allOf:
    - $ref: "#/components/schemas/Animal"
    - type: object
      properties:
        breed:
          type: string

Before (broken):

class Dog {  // ❌ Missing: extends Animal
  Dog({
    required this.className,  // ❌ Wrong: redeclares parent property
    this.color = 'red',        // ❌ Wrong: redeclares parent property
    this.breed,
  });  // ❌ Missing: : super(className: className, color: color)

  final String className;  // ❌ Wrong: redeclares parent field
  final String? color;     // ❌ Wrong: redeclares parent field
  final String? breed;
}

After (fixed):

class Dog extends Animal {  // ✓ Extends parent
  Dog({
    this.breed,                // ✓ Child property with 'this.'
    required super.className,  // ✓ Super parameter (Dart 2.17+)
    super.color = 'red',      // ✓ Super parameter with default
  });

  final String? breed;  // ✓ Only declares child property
}

Solution

1. Java Code Changes

DartDioClientCodegen.java

  1. Constructor: Added this.supportsInheritance = true to prevent DefaultCodegen from copying parent properties into child's 'vars'

  2. postProcessAllModels: Added inheritance processing for json_serializable only:

    • Build a map of all models for quick lookup
    • For each child model with a parent:
      • Set parentVars from the parent model's vars
      • Remove parent properties from child's vars to avoid duplication
    • Only applies when serializationLibrary == json_serializable (built_value has its own adaptToDartInheritance logic)

2. Template Changes

class.mustache

  • Added extends {{{parent}}} to class declaration when parent exists
  • Changed field declarations from {{#allVars}} to {{#vars}} so only child properties are declared
  • Kept {{#allVars}} for equals/hashCode to include both parent and child properties in equality checks

dart_constructor.mustache

  • Separated child properties (using {{#vars}}) from parent properties (using {{#parentVars}})
  • Child properties use this.{name} syntax (they're class fields)
  • Parent properties use super.{name} syntax (Dart 2.17+ super parameters)
  • This eliminates the need for the : super(...) initializer list and parameter redeclaration

Key Variables Used

After the fix, for Dog model:

  • vars: [breed] - only child's own properties
  • parentVars: [className, color] - parent's properties
  • allVars: [className, color, breed] - all properties combined (for equals/hashCode)

Files Modified

Core Changes:

  1. modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartDioClientCodegen.java
  2. modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/json_serializable/dart_constructor.mustache
  3. modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/json_serializable/class.mustache

Sample Files (regenerated):

  • All models in samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake-json_serializable/
  • Examples: Dog, Cat, ChildWithNullable

Testing

Verified the fix works correctly with the Animal/Dog/Cat inheritance example from the test suite.

To regenerate samples:

./mvnw clean install -DskipTests -Dmaven.javadoc.skip=true
./bin/generate-samples.sh bin/configs/dart-dio-petstore-client-lib-fake-json_serializable.yaml

Notes

  • This fix only applies to serializationLibrary: json_serializable
  • built_value serialization already has proper inheritance handling via adaptToDartInheritance()
  • Uses Dart 2.17+ super parameters feature for cleaner, more idiomatic code
  • The fix ensures proper Dart inheritance semantics where child classes extend parents

References


Summary by cubic

Fixes broken inheritance in dart-dio with json_serializable by making child models extend parents and pass required fields via Dart super parameters. Removes duplicated fields, tightens equality, and stops compile errors.

  • Bug Fixes
    • Enabled inheritance handling (supportsInheritance = true) to stop copying parent props into child vars.
    • For json_serializable only, set parentVars from the parent and remove duplicates from child vars in postProcessAllModels.
    • Updated templates: add extends {{parent}}; use super.{name} for parent constructor params; declare only child fields; use allVars plus a runtimeType check in equality/hash.
    • Regenerated petstore_client_lib_fake-json_serializable code and docs; child model docs list only child properties; no change to built_value.

Written for commit e2539dc. Summary will update on new commits.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 55 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake-json_serializable/lib/src/model/dog.dart">

<violation number="1" location="samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake-json_serializable/lib/src/model/dog.dart:22">
P2: Inheritance introduced asymmetric `==` semantics between `Animal` and `Dog`, violating equality contract.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/json_serializable/dart_constructor.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/json_serializable/dart_constructor.mustache:11">
P1: Inherited constructor params (`parentVars`) omit `useOptional` handling, causing inconsistent and potentially incorrect generation for optional-wrapper inherited fields.</violation>
</file>

Since this is your first cubic review, here's how it works:

  • cubic automatically reviews your code and comments on bugs and improvements
  • Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
  • Add one-off context when rerunning by tagging @cubic-dev-ai with guidance or docs links (including llms.txt)
  • Ask questions if you need clarification on any suggestion

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

…ers - Add 'extends' clause to child classes when parent exists - Use Dart 2.17+ super parameters (super.property) in constructors - Separate child properties (this.name) from parent properties (super.name) - Set parentVars in postProcessAllModels for json_serializable - Only declare child properties in class body (not parent properties) - Use allVars for equals/hashCode to include all properties Fixes OpenAPITools#22547
@wing328
Copy link
Copy Markdown
Member

wing328 commented Mar 25, 2026

cc @jaumard (2018/09) @josh-burton (2019/12) @amondnet (2019/12) @sbu-WBT (2020/12) @kuhnroyal (2020/12) @agilob (2020/12) @ahmednfwela (2021/08)

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 49 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake-json_serializable/lib/src/model/animal.dart">

<violation number="1">
P2: Removing the runtimeType check in Animal allows Animal == Dog when base fields match, while Dog == Animal remains false (Dog uses `other is Dog` and includes `breed`). This breaks equality/hashCode symmetry across the inheritance hierarchy and can cause incorrect Set/Map behavior.</violation>
</file>

<file name="samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake-json_serializable/lib/src/model/parent_with_nullable.dart">

<violation number="1">
P2: Removing the runtimeType guard allows ParentWithNullable to consider subclass instances equal, which is asymmetric with ChildWithNullable’s overridden == and can break hash/equality behavior.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants