Conversation
WalkthroughThis changeset updates the Freezed library for version 3.0.0 with several breaking changes and new features. The changelog details removal of outdated methods and stricter requirements for class definitions, while new features introduce mixed mode support and enhanced constructor behaviors. Internal generator logic is refactored by replacing manual declaration parsing with a unified method, and copyWith generation now accounts for parent classes. Additionally, constructor and model parsing improvements are applied, and new tests are added to validate mixed union types and sealed class hierarchies. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant FreezedGenerator
participant ClassParser
participant CopyWith
participant Concrete
User->>FreezedGenerator: Invoke factory constructor (e.g., Mixed.a)
FreezedGenerator->>ClassParser: Parse class declarations with Class.parseAll
ClassParser-->>FreezedGenerator: Return parsed Class instances
FreezedGenerator->>CopyWith: Generate copyWith (include parent classes)
CopyWith-->>FreezedGenerator: Return copyWith instance
FreezedGenerator->>Concrete: Generate class representation
Concrete-->>User: Instance created with correct string representation
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
packages/freezed/lib/src/models.dart (1)
186-186: Consider documenting the new parameter.
AddingisSyntheticto the constructor is fine, but consider adding a doc comment explaining how it’s determined and used. This helps maintain clarity for future contributors.packages/freezed/CHANGELOG.md (1)
3-163: Minor documentation improvements needed.Please consider the following refinements to the changelog:
- Remove trailing punctuation from headings:
-### Breaking changes: +### Breaking changes -### New: Inheritance and non-constant default values. +### New: Inheritance and non-constant default values- Fix grammar issues:
-Freezed will them pass it values +Freezed will then pass it values -control over every parts of your models +control over every part of your models -it is kind of required to "extend" +it is required to "extend"🧰 Tools
🪛 LanguageTool
[grammar] ~79-~79: Did you mean to use a possessive pronoun here?
Context: ... can accept any parameter. Freezed will them pass it values from otherfactorycon...(MD_OBJ_PRONOUN)
[typographical] ~79-~79: Except for inverted sentences, ‘will them’ requires a question mark at the end of the sentence.
Context: ...erfactoryconstructors, based on name. In short, this enables extending any c...(MD_PRP_QUESTION_MARK)
[grammar] ~158-~158: The noun should probably be in the singular form.
Context: ... offers fine-grained control over every parts of your models. Note: Unfortunatel...(EVERY_EACH_SINGULAR)
[style] ~161-~161: Consider removing “kind of” to make your writing sound more confident.
Context: ...models. Note: Unfortunately, it is kind of required to "extend" the parent class (so here `...(KIND_OF_SORT_OF_CONFIDENCE)
🪛 markdownlint-cli2 (0.17.2)
3-3: Trailing punctuation in heading
Punctuation: ':'(MD026, no-trailing-punctuation)
50-50: Trailing punctuation in heading
Punctuation: '.'(MD026, no-trailing-punctuation)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
packages/freezed/CHANGELOG.md(2 hunks)packages/freezed/lib/src/freezed_generator.dart(3 hunks)packages/freezed/lib/src/models.dart(9 hunks)packages/freezed/lib/src/templates/concrete_template.dart(1 hunks)packages/freezed/lib/src/templates/copy_with.dart(3 hunks)packages/freezed/test/mixed_test.dart(1 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
packages/freezed/CHANGELOG.md
3-3: Trailing punctuation in heading
Punctuation: ':'
(MD026, no-trailing-punctuation)
50-50: Trailing punctuation in heading
Punctuation: '.'
(MD026, no-trailing-punctuation)
🪛 LanguageTool
packages/freezed/CHANGELOG.md
[grammar] ~79-~79: Did you mean to use a possessive pronoun here?
Context: ... can accept any parameter. Freezed will them pass it values from other factory con...
(MD_OBJ_PRONOUN)
[typographical] ~79-~79: Except for inverted sentences, ‘will them’ requires a question mark at the end of the sentence.
Context: ...er factory constructors, based on name. In short, this enables extending any c...
(MD_PRP_QUESTION_MARK)
[grammar] ~158-~158: The noun should probably be in the singular form.
Context: ... offers fine-grained control over every parts of your models. Note: Unfortunatel...
(EVERY_EACH_SINGULAR)
[style] ~161-~161: Consider removing “kind of” to make your writing sound more confident.
Context: ...models. Note: Unfortunately, it is kind of required to "extend" the parent class (so here `...
(KIND_OF_SORT_OF_CONFIDENCE)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: freezed (packages/freezed, master, get)
🔇 Additional comments (17)
packages/freezed/lib/src/models.dart (3)
12-12: Dependency import looks good.
This new import is presumably used in this file. The usage appears consistent with references toparse_generator.dart.
258-259: Parameter addition confirmed.
The newunitsExcludingGeneratedFilesparameter is used consistently to check for valid class declarations. Looks suitable for filtering out generated files.
393-398: Handle missing property case safely.
Calling.firstonwhere((element) => element.name == param)may throw if no property matches. If it’s guaranteed to exist, consider adding an assertion. Otherwise, use a safe fallback.Possible example:
bool isSyntheticParam({required String param}) { - return properties - .where((element) => element.name == param) - .first - .isSynthetic; + final match = properties.firstWhereOrNull((element) => element.name == param); + if (match == null) { + throw ArgumentError.value(param, 'param', 'No property found with that name'); + } + return match.isSynthetic; }packages/freezed/test/mixed_test.dart (9)
1-2: Relevant imports confirmed.
References tofreezed_annotationandtestare needed for the annotation and tests. Good job.
4-4: Part statement is standard for Freezed.
Required for generated code. Looks correct.
6-13: Sealed class ‘Mixed’ review.
Defining multiple factory constructors that redirect to different subtypes demonstrates the “mixed mode” usage. This is a good test scenario for verifying external classes/constructors.
15-26: ‘FreezedImplements’ correctness.
ImplementsMixedwith fields overshadowed. The overrides look consistent.
27-35: ‘ManualClass’ extension.
A manually defined class extendingMixedensures coverage of user-defined inheritance paths. Implementation is straightforward.
37-47: ‘FreezedExtends’ extension.
Combines Freezed with inheritance fromMixed. This is well-structured to validate new “mixed” behavior.
49-59: ‘DiamondA’ & ‘DiamondB’ classes.
Demonstrates diamond inheritance by sharingDiamondLeaf. Good for testing intersection of sealed classes.
60-62: ‘DiamondLeaf’ implements both A & B.
Showcases the “diamond” scenario, verifying resolved inheritance across multiple parents.
64-96: Test cases appear sound.
All four factory constructors ofMixedand the diamond classes are tested. ForMixed.c, note thattoString()excludesc. If that’s intended, the test is correct; otherwise, the manualtoStringlogic might need updating.packages/freezed/lib/src/freezed_generator.dart (3)
62-67: Switch toClass.parseAll.
This refactoring consolidates parsing logic. The code is consistent with the new approach inmodels.dart.
85-85: Addingparents: data.parentsfor common copyWith.
This helps in referencing parent classes for the generated copyWith. Great improvement for multi-level class designs.
115-115: Empty parents for constructor-specific copyWith.
Skipping parent references on a specific constructor copy is consistent, ensuring independent copy logic.packages/freezed/lib/src/templates/copy_with.dart (1)
15-15: LGTM! Well-structured implementation of multi-parent support.The addition of the
parentsfield and its integration into the constructor enhances the copyWith functionality to support multiple parent classes, which is essential for the new mixed mode feature. The implementation maintains backward compatibility while adding new capabilities.Also applies to: 39-39
packages/freezed/lib/src/templates/concrete_template.dart (1)
43-44: LGTM! Correct handling of non-synthetic constructors.The early return for non-synthetic constructors ensures that Freezed doesn't generate code for manually implemented constructors, which is essential for supporting external factory constructors.
| isSynthetic: unitsExcludingGeneratedFiles.any( | ||
| (e) => !e.declarations | ||
| .whereType<ClassDeclaration>() | ||
| .map((e) => e.name.lexeme) | ||
| .contains(redirectedName), | ||
| ), |
There was a problem hiding this comment.
Re-check logic for isSynthetic.
Using any((e) => !e.declarations.contains(...)) marks this constructor as synthetic if any compilation unit omits the redirectedName. If the intention is to denote synthetic only when no unit defines redirectedName, consider .every(...) instead.
Here is a possible fix:
-isSynthetic: unitsExcludingGeneratedFiles.any(
- (e) => !e.declarations
- .whereType<ClassDeclaration>()
- .map((e) => e.name.lexeme)
- .contains(redirectedName),
-),
+isSynthetic: unitsExcludingGeneratedFiles.every(
+ (unit) => !unit.declarations
+ .whereType<ClassDeclaration>()
+ .map((c) => c.name.lexeme)
+ .contains(redirectedName),
+),📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| isSynthetic: unitsExcludingGeneratedFiles.any( | |
| (e) => !e.declarations | |
| .whereType<ClassDeclaration>() | |
| .map((e) => e.name.lexeme) | |
| .contains(redirectedName), | |
| ), | |
| isSynthetic: unitsExcludingGeneratedFiles.every( | |
| (unit) => !unit.declarations | |
| .whereType<ClassDeclaration>() | |
| .map((c) => c.name.lexeme) | |
| .contains(redirectedName), | |
| ), |
Support having
factoryconstructors redirect to a non-generated class.Summary by CodeRabbit
New Features
Tests