Skip to content
This repository was archived by the owner on Feb 16, 2026. It is now read-only.

feat: Support json serializable (closes #377)#410

Open
Gustl22 wants to merge 13 commits into
peiffer-innovations:mainfrom
Gustl22:377-json-serializable
Open

feat: Support json serializable (closes #377)#410
Gustl22 wants to merge 13 commits into
peiffer-innovations:mainfrom
Gustl22:377-json-serializable

Conversation

@Gustl22

@Gustl22 Gustl22 commented Sep 25, 2025

Copy link
Copy Markdown
Contributor

Description

Closes #377

Checklist

Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]). This will ensure a smooth and quick review process.

  • I read the Code Style Guide and followed the process outlined there for submitting PRs.
  • All existing and new tests are passing. Note: test failing due to incompatibility with 3.35.x
  • I updated/added relevant documentation (doc comments with ///).
  • The analyzer (flutter analyze or dart analyze) does not report any problems on my PR. Note: analyze fails to incompatibility with 3.35.x
  • I updated pubspec.yaml with an appropriate new version according to the pub versioning philosophy.
  • I updated CHANGELOG.md to add a description of the change.
  • I am authorized to release this code under the MIT License and agree to do so

UI Change

Does your PR affect any UI screens?

  • Yes, the relevant screens are included below.
  • No, there are no UI impacts with this PR.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for parsing entities that implement the @JsonSerializable() annotation and custom fromJson methods, enabling seamless integration with json_serializable patterns.
  • Documentation

    • Added guide for enabling and using JSON-serializable entity parsing via build configuration.
  • Examples

    • Included example demonstrating JSON-serializable entity parsing with a sample team management widget.

✏️ Tip: You can customize this high-level summary in your review settings.

@Gustl22 Gustl22 force-pushed the 377-json-serializable branch from 2395fa4 to 0dd7d1c Compare September 25, 2025 21:58
final calculateListenVariables = jsonWidgetListenVariables == null;
final resultListenVariables = jsonWidgetListenVariables ?? <String>{};
final processedMapArg = {};
final processedMapArg = <String, dynamic>{};

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Does the processMapArg need support other types than String as key? If so we could make this parser generic.
String is required by serialization parsing (as json only supports String as key).

@Gustl22 Gustl22 marked this pull request as ready for review September 29, 2025 09:35
@coderabbitai

coderabbitai Bot commented Nov 9, 2025

Copy link
Copy Markdown

Walkthrough

This PR adds support for parsing entities annotated with @JsonSerializable() during code generation. A new parseJsonSerializable configuration flag enables automatic decoding of classes and enums via their fromJson factories. Changes include builder configuration updates, decoder logic extensions, type tracking enhancements, and documentation with examples.

Changes

Cohort / File(s) Summary
Version and Documentation
packages/codegen/CHANGELOG.md, packages/codegen/pubspec.yaml
Version bumped to 4.1.0; changelog entry added documenting JsonSerializable parsing support.
Builder Configuration
packages/codegen/lib/builder.dart, packages/codegen/lib/src/builder/json_widget_library_builder.dart
New parseJsonSerializable parameter added to JsonWidgetLibraryBuilder; constructor and field added to pass the configuration flag through to decode operations.
Decoder Logic Extension
packages/codegen/lib/src/decoder/decoders.dart
Decode function signature extended with parseJsonSerializable parameter; added conditional branches to generate fromJson() calls for ClassElement, EnumElement, and Iterable types with fromJson factories when enabled.
Type Tracking
packages/codegen/lib/src/model/param.dart
New type field of type DartType added to Param class; constructor and factory updated to propagate type information from analyzer.
Type Refinement
packages/json_dynamic_widget/lib/src/components/processors/map_arg_processor.dart
Type narrowing from Map to Map<String, dynamic> throughout MapArgProcessor for improved type precision.
Documentation
packages/json_dynamic_widget/README.md
New section "Parse JsonSerializable Entities" added with example build.yaml configuration.
Example Configuration
examples/json_dynamic_widget_example/build.yaml, examples/json_dynamic_widget_example/pubspec.yaml
Build.yaml configured with parse_json_serializable: true; dependencies added for json_annotation and json_serializable.
Example Implementation
examples/json_dynamic_widget_example/lib/src/json_serializable/*
New model classes added: Person (with fromJson/toJson), PersonType enum (with fromJson/toJson), TeamWidget widget, and _TeamBuilder widget builder demonstrating JsonSerializable integration.

Sequence Diagram

sequenceDiagram
    participant CodeGen as Code Generator
    participant Decoder as Decoder
    participant Analyzer as Type Analyzer
    participant Generated as Generated Code

    CodeGen->>Analyzer: Analyze class/enum type
    Analyzer->>Analyzer: Check for fromJson factory
    Analyzer-->>Decoder: Return type with fromJson
    
    alt parseJsonSerializable enabled
        Decoder->>Decoder: Detect ClassElement/EnumElement<br/>with fromJson
        Decoder->>Generated: Generate Class.fromJson(map['field'])
        Generated-->>Decoder: Decoded value
    else parseJsonSerializable disabled
        Decoder->>Decoder: Use existing decoder<br/>or default value
        Decoder-->>Generated: Fallback behavior
    end
    
    Generated-->>CodeGen: Return decoded object
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • PR #417: Modifies the same codegen decoder and Param infrastructure (packages/codegen/lib/src/decoder/decoders.dart and packages/codegen/lib/src/model/param.dart), providing foundational type tracking that this PR extends with JsonSerializable handling.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: Support json serializable' clearly and accurately summarizes the main change in the pull request, which adds support for JSON serializable entities parsing.
Linked Issues check ✅ Passed The PR successfully implements the objectives from issue #377: adds json_serializable support with @JsonValue annotation handling for enums, ClassElements with fromJson factories, and InterfaceTypes with Iterable support, eliminating the need for custom boilerplate ArgEncoder/ArgDecoder implementations.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing json_serializable support per issue #377. Type narrowing in MapArgProcessor and the new Param.type field are supporting changes necessary for the main feature, not out-of-scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


🧹 Recent nitpick comments
examples/json_dynamic_widget_example/pubspec.yaml (1)

31-33: Redundant json_dynamic_widget_codegen declaration.

json_dynamic_widget_codegen is declared here in dev_dependencies and also in dependency_overrides (lines 39-40) with the same path. The override already forces the local path, so this entry could be simplified to just the package name without the path, or removed entirely if only the override is needed.

Suggested simplification
 dev_dependencies:
   build_runner: "^2.10.4"
   flutter_lints: "^6.0.0"
   flutter_test:
     sdk: "flutter"
   icons_launcher: "^3.0.3"
-  json_dynamic_widget_codegen:
-    path: "../../packages/codegen"
+  json_dynamic_widget_codegen: any
   json_serializable: "^6.11.2"

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 804e6b1 and 63847c4.

📒 Files selected for processing (11)
  • examples/json_dynamic_widget_example/build.yaml
  • examples/json_dynamic_widget_example/lib/src/json_serializable/person.dart
  • examples/json_dynamic_widget_example/lib/src/json_serializable/team_builder.dart
  • examples/json_dynamic_widget_example/lib/src/json_serializable/team_widget.dart
  • examples/json_dynamic_widget_example/pubspec.yaml
  • packages/codegen/CHANGELOG.md
  • packages/codegen/lib/src/builder/json_widget_library_builder.dart
  • packages/codegen/lib/src/decoder/decoders.dart
  • packages/codegen/lib/src/model/param.dart
  • packages/codegen/pubspec.yaml
  • packages/json_dynamic_widget/README.md
✅ Files skipped from review due to trivial changes (1)
  • examples/json_dynamic_widget_example/build.yaml
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/codegen/pubspec.yaml
  • packages/codegen/CHANGELOG.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (12)
examples/json_dynamic_widget_example/pubspec.yaml (1)

17-17: LGTM!

json_annotation is correctly placed in dependencies since the annotations are needed at runtime for the serialization code to function.

examples/json_dynamic_widget_example/lib/src/json_serializable/person.dart (1)

1-33: LGTM!

This is a well-structured example demonstrating json_serializable integration:

  • Person class follows standard patterns with fromJson factory and toJson method
  • PersonType enum correctly uses @JsonEnum(alwaysCreate: true) to ensure the enum map is generated, and @JsonValue for custom string mappings
  • The unknownValue fallback in fromJson provides safe deserialization for unrecognized values
examples/json_dynamic_widget_example/lib/src/json_serializable/team_widget.dart (1)

5-32: LGTM!

This widget effectively demonstrates the range of parameter types the parseJsonSerializable codegen feature needs to handle:

  • Required and nullable Person instances
  • Collections (List<Person>, Set<Person>)
  • Primitives (int, String)
  • Enums (PersonType) with nullable variant

The unused fields in build() are appropriate for a codegen test fixture.

examples/json_dynamic_widget_example/lib/src/json_serializable/team_builder.dart (1)

1-19: LGTM!

The builder follows the standard json_dynamic_widget pattern:

  • @jsonWidget annotation triggers code generation
  • Abstract buildCustom method declares the return type for the generated implementation
  • The person.dart import is necessary for the generated code to resolve Person and PersonType types used by TeamWidget
packages/codegen/lib/src/model/param.dart (2)

39-39: Good addition of DartType for richer type introspection.

Exposing the full DartType enables the codegen to inspect type metadata (e.g., checking for fromJson factories on classes/enums) which is essential for the parseJsonSerializable feature.


6-16: Breaking change properly handled: all Param constructor calls have been updated with the new type parameter.

The addition of required this.type is a breaking change to the constructor signature. Verification confirms that the only Param instantiation in the codebase—within the Param.fromFormalParameter factory method—has been correctly updated to include type: param.type.

packages/codegen/lib/src/decoder/decoders.dart (2)

2-2: LGTM!

The new import for type.dart is necessary for the InterfaceType check, and the optional parseJsonSerializable parameter with a default of false maintains backward compatibility.

Also applies to: 156-163


177-194: LGTM!

The early return pattern when a decoder is found in kDecoders is cleaner than the previous approach and avoids unnecessary computation in the JsonSerializable path.

packages/codegen/lib/src/builder/json_widget_library_builder.dart (2)

16-22: LGTM!

The constructor with the optional parseJsonSerializable parameter and the accompanying documentation clearly explain the feature's purpose and its relationship to the json_serializable package.


879-879: LGTM!

The parseJsonSerializable flag is correctly passed through to the decode function, enabling the JsonSerializable parsing feature when configured.

packages/json_dynamic_widget/README.md (2)

31-31: LGTM!

The table of contents entry follows the existing format and correctly links to the new documentation section.


753-769: LGTM!

The documentation clearly explains the feature, its purpose, and how to enable it via build.yaml. The configuration example is correct and will help users adopt the feature.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@jpeiffer

jpeiffer commented Nov 9, 2025

Copy link
Copy Markdown
Contributor

Sorry for the late review. I'd been heads down in a new code generator for json_theme and only now found time to notice this. Just updated the PR to resolve the conflicts. I'll test it later and if it still works, merge it.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4876811 and 804e6b1.

📒 Files selected for processing (13)
  • packages/codegen/CHANGELOG.md (1 hunks)
  • packages/codegen/lib/builder.dart (1 hunks)
  • packages/codegen/lib/src/builder/json_widget_library_builder.dart (2 hunks)
  • packages/codegen/lib/src/decoder/decoders.dart (4 hunks)
  • packages/codegen/pubspec.yaml (1 hunks)
  • packages/json_dynamic_widget/README.md (2 hunks)
  • packages/json_dynamic_widget/example/build.yaml (1 hunks)
  • packages/json_dynamic_widget/example/lib/src/components/example_registrar.dart (1 hunks)
  • packages/json_dynamic_widget/example/lib/src/json_serializable/person.dart (1 hunks)
  • packages/json_dynamic_widget/example/lib/src/json_serializable/team_builder.dart (1 hunks)
  • packages/json_dynamic_widget/example/lib/src/json_serializable/team_widget.dart (1 hunks)
  • packages/json_dynamic_widget/example/pubspec.yaml (2 hunks)
  • packages/json_dynamic_widget/lib/src/components/processors/map_arg_processor.dart (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (12)
packages/codegen/pubspec.yaml (1)

4-4: LGTM! Version bump aligns with feature addition.

The minor version bump from 4.0.0+1 to 4.1.0 correctly reflects the addition of the new parseJsonSerializable feature.

packages/json_dynamic_widget/example/build.yaml (1)

1-6: LGTM! Configuration enables the new feature.

The build configuration correctly enables parse_json_serializable for the example project to demonstrate the new JsonSerializable parsing capability.

packages/json_dynamic_widget/example/pubspec.yaml (2)

17-17: LGTM! Adds required dependency for JsonSerializable support.

The json_annotation dependency is necessary for using @JsonSerializable annotations in example code.


31-31: LGTM! Codegen version update matches the new feature.

The update to ^4.1.0 aligns with the codegen package version bump that introduces parseJsonSerializable support.

packages/json_dynamic_widget/README.md (2)

31-31: LGTM! TOC updated with new feature section.

The table of contents correctly includes the new "Parse JsonSerializable Entities" section.


754-768: LGTM! Clear documentation for the new feature.

The documentation provides clear instructions on:

  • When to use the feature (entities with @JsonSerializable or custom fromJson)
  • How to enable it (build.yaml configuration)
  • Links to the relevant package
packages/json_dynamic_widget/lib/src/components/processors/map_arg_processor.dart (3)

27-27: LGTM! Improved type safety.

The narrowed type constraint to Map<String, dynamic> is appropriate for JSON parsing, where keys are always strings.


35-38: LGTM! Consistent type constraints throughout.

The explicit Map<String, dynamic> types ensure type safety and align with JSON parsing semantics where keys are always strings.


90-90: LGTM! Parameter type aligns with usage.

The Map<String, dynamic> parameter type is consistent with the narrowed type constraints and reflects JSON structure.

packages/codegen/lib/src/builder/json_widget_library_builder.dart (2)

17-23: LGTM! Well-documented public API addition.

The new parseJsonSerializable parameter:

  • Has a sensible default (false) maintaining backward compatibility
  • Is clearly documented with a reference to json_serializable
  • Enables the new feature as intended

880-887: LGTM! Feature flag properly threaded through decoder.

The parseJsonSerializable flag is correctly passed to the decode() function, enabling the new JsonSerializable parsing behavior when requested.

packages/json_dynamic_widget/example/lib/src/components/example_registrar.dart (1)

7-7: Generated file is not in repository; import usage cannot be verified automatically.

The generated file example_registrar.g.dart is not present in the repository (it's built into .dart_tool/ at build time and typically not committed). The import on line 7 has no direct references in the source code, but the @jsonWidgetRegistrar code generator likely needs the team_builder.dart import to register _TeamBuilder as a JSON widget builder.

Verify one of the following:

  • Run dart run build_runner build in the example directory and inspect build/ or .dart_tool/ output to confirm _TeamBuilder is referenced in the generated code
  • Check the json_dynamic_widget generator documentation to understand how @jsonWidgetRegistrar processes builder imports
  • If the import is confirmed as unused after generation, remove both the import and the unused_import ignore directive

Comment thread packages/codegen/CHANGELOG.md Outdated
Comment thread packages/codegen/lib/src/decoder/decoders.dart
# Conflicts:
#	examples/json_dynamic_widget_example/build.yaml
#	examples/json_dynamic_widget_example/lib/src/json_serializable/person.dart
#	examples/json_dynamic_widget_example/lib/src/json_serializable/team_builder.dart
#	examples/json_dynamic_widget_example/lib/src/json_serializable/team_widget.dart
#	packages/codegen/CHANGELOG.md
#	packages/codegen/pubspec.yaml
#	packages/json_dynamic_widget/README.md
#	packages/json_dynamic_widget/example/pubspec.yaml
@Gustl22

Gustl22 commented Jan 15, 2026

Copy link
Copy Markdown
Contributor Author

@jpeiffer I updated the PR to the recent changes of main. I noticed that the json'_dynamic_widget_example is broken, even in main: dotted_border_builder. Maybe this should be tested in the PR pipeline.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support JsonSerializable annotations (like JsonValue)

2 participants