Conversation
WalkthroughMigrates the codebase to Dart analyzer v2 APIs: switches to element2/element3, name3, methods2/getters2, updates error reporting from diagnostics to errors, and adjusts tests and lints accordingly. Pubspecs broaden analyzer ranges (>=7.5.9 <9.0.0) and add pub_semver. analysis_options adds an ignore for deprecated_member_use. Changes
Sequence Diagram(s)Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Pre-merge checks (2 passed, 1 warning)❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Poem
✨ Finishing Touches🧪 Generate unit tests
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/freezed/lib/src/parse_generator.dart (1)
72-79: Fix no-op cast; strongly type the resolved unit.
unit as ResolvedUnitResult;is a no-op and doesn’t change the type ofunit. Use a typed variable to avoid dynamic.- final unit = await element.session!.getResolvedUnit( - element.firstFragment.libraryFragment!.source.fullName, - ); - unit as ResolvedUnitResult; - final Object? ast = unit.unit.declarations.firstWhereOrNull( + final resolvedUnit = await element.session!.getResolvedUnit( + element.firstFragment.libraryFragment!.source.fullName, + ) as ResolvedUnitResult; + final Object? ast = resolvedUnit.unit.declarations.firstWhereOrNull( (declaration) => - declaration.declaredFragment?.element.name3 == element.name3!, + declaration.declaredFragment?.element.name3 == element.name3!, );packages/freezed_lint/lib/src/missing_private_empty_ctor.dart (1)
10-17: User-facing message spacing typo.
There’s a missing space: “accessors,requires”. Add a trailing space to the previous string.- 'Freezed classes containing methods, fields or accessors,' + 'Freezed classes containing methods, fields or accessors, '
🧹 Nitpick comments (18)
packages/freezed_lint/lib/src/missing_mixin.dart (3)
50-51: Unusedothersparameter—prefix with underscore to silence lints.Minor polish to avoid an unused parameter warning.
- AnalysisError analysisError, - List<AnalysisError> others, + AnalysisError analysisError, + List<AnalysisError> _,
63-68: Insertion offset is brittle when there’s no space before{.Using
node.leftBracket.offset - 1assumes a space before the brace. If code isclass A{, the insertion occurs before the last identifier, producing invalid code. Insert atleftBracket.offsetinstead and include a leading space when needed.- final offset = node.leftBracket.offset - 1; + final offset = node.leftBracket.offset; if (node.withClause != null) { - builder.addSimpleInsertion(offset, ', _\$$name'); + builder.addSimpleInsertion(offset, ', _\$$name'); } else { - builder.addSimpleInsertion(offset, ' with _\$$name'); + builder.addSimpleInsertion(offset, ' with _\$$name'); }
56-56: Use a stable name in the fix message.
node.nameis aSimpleIdentifier; relying on itstoString()is fine but usingelement.displayName(already computed below) avoids surprises.- message: 'Add mixin _\$${node.name}', + message: 'Add mixin _\$$name',packages/freezed/lib/src/templates/concrete_template.dart (1)
525-542: metadata2 is deprecated in analyzer ≥8; keep plan to migrate tometadatawhen bumping.Using
metadata2.annotationsis valid across 7.5.9–8.x, but it’s deprecated in newer analyzer versions. Your analysis_options ignore makes this workable for now; when you raise the lower bound to ≥8, flip back tometadata.annotationsand drop the ignore. (pub.dev)Optionally centralize this behind a helper to ease the eventual switch:
// e.g. lib/src/tools/analyzer_compat.dart import 'package:analyzer/dart/element/element2.dart'; extension AnnotationsCompat on Annotatable { // TODO: when requiring analyzer >=8, switch to `metadata.annotations`. Iterable<ElementAnnotation> get annotationsCompat => metadata2.annotations; }Then iterate
for (final meta in parameter.annotationsCompat) { ... }.analysis_options.yaml (1)
10-11: Scope the deprecation ignore if possible.Rather than a global
deprecated_member_use: ignore, consider targeted// ignore: deprecated_member_useat the few call-sites (e.g.,metadata2) so unrelated deprecations remain visible.packages/freezed/test/common.dart (1)
2-4: Drop now-unused diagnostic import.
package:analyzer/diagnostic/diagnostic.dartseems unused after migrating toAnalysisError/Severity.-import 'package:analyzer/diagnostic/diagnostic.dart'; import 'package:analyzer/error/error.dart';packages/freezed_lint/pubspec.yaml (1)
12-12: Analyzer range broadened — sanity-check API availability at the floor.Your code uses v2 APIs (
element2,name3,ErrorsResult.errors). Please confirm these are present in analyzer 7.5.9 specifically; otherwise raise the floor.Suggested CI hardening:
- Job A: resolve to minimum versions (e.g.,
dart pub downgrade analyzer:7.5.9) and run tests.- Job B: resolve to latest allowed (
dart pub upgrade) and run tests.I can draft the workflow snippet on request.
packages/freezed/lib/src/parse_generator.dart (1)
66-71: Avoid shadowing theannotationparameter.The local
annotationhides the method parameter and hurts readability.- final annotation = typeChecker.firstAnnotationOf( + final ann = typeChecker.firstAnnotationOf( element, throwOnUnresolved: false, ); - if (annotation == null) return; + if (ann == null) return; ... - final datas = <AnnotationMeta>[(declaration: ast, annotation: annotation)]; + final datas = <AnnotationMeta>[(declaration: ast, annotation: ann)];packages/freezed/test/typedef_parameter_test.dart (1)
42-44: Use semantic default-constructor check withisDefaultConstructor
Replacevar constructor = freezedClass.constructors2.firstWhere( (e) => e.name3 == 'new', );with
import 'package:freezed/src/templates/prototypes.dart'; var constructor = freezedClass.constructors2.firstWhere(isDefaultConstructor);This uses the existing helper function instead of brittle string-matching.
packages/freezed/lib/src/tools/type.dart (1)
65-69: Prefer display strings for typedef type arguments.
UsingjoinonDartTyperelies ontoString(). UsegetDisplayString()for consistency.- displayType = type.alias!.element2.name3!; - if (type.alias!.typeArguments.isNotEmpty) { - displayType += '<${type.alias!.typeArguments.join(', ')}>'; - } + displayType = type.alias!.element2.name3!; + if (type.alias!.typeArguments.isNotEmpty) { + final args = type.alias!.typeArguments + .map((t) => t.getDisplayString()) + .join(', '); + displayType += '<$args>'; + }packages/freezed_lint/lib/src/missing_private_empty_ctor.dart (1)
1-3: Keep analyzer range alignment in freezed_lint.
Given past blockers withcustom_lintupgrades, double-checkfreezed_lint’s pubspec analyzer range matches the repo-wide<9.0.0constraint and that transitiveanalyzer_plugin/source_genversions remain compatible.packages/freezed/lib/src/tools/recursive_import_locator.dart (1)
93-95: Nit: rename misleading parameter.fromImport() takes a LibraryImport but the param is named export.
Apply this diff:
- static _LibraryDirectives? fromImport(LibraryImport export) { - final library = export.importedLibrary2; + static _LibraryDirectives? fromImport(LibraryImport import) { + final library = import.importedLibrary2;packages/freezed/lib/src/tools/imports.dart (3)
9-12: Tiny clarity/robustness nits: seed visited withthis+ rename loop var.
- Seeding avoids re-visiting
thison cyclic exports (you already handle cycles; this just reduces redundant visitor calls).- Rename
importtoexportedfor accuracy.final visitedLibraries = <LibraryElement2>{}; + // Avoid re-visiting `this` via cycles. + visitedLibraries.add(this); LibraryElement2? visitLibrary(LibraryElement2 library) { @@ - for (final import in exportedLibraries2) { - final result = visitLibrary(import); + for (final exported in exportedLibraries2) { + final result = visitLibrary(exported); if (result != null) return result; }Also applies to: 23-23
15-18: Optional: consider BFS to prevent deep recursion.A queue-based traversal avoids stack overflows on very deep export graphs. Current DFS is fine for typical SDK/plugin sizes.
3-3: Rename extension LibraryHasImport to LibraryExportTraversal
No other occurrences ofLibraryHasImportwere found outside its own declaration; it’s safe to apply the diff.packages/freezed/test/decorator_test.dart (2)
36-37: Preferelement.name3directly;library2is redundant here.
elementis already a library; accessinglibrary2adds noise.- (element) => element.library2.name3 == 'decorator', + (element) => element.name3 == 'decorator',
99-118: Stabilize expectations: ignore ordering of errors.Analyzer error ordering can fluctuate. Use
unorderedEqualswhile preserving the two accepted variants.- expect( - errorResult.errors.map((e) => e.errorCode.name), - anyOf([ - [ + final names = errorResult.errors.map((e) => e.errorCode.name).toList(); + expect( + names, + anyOf([ + unorderedEquals([ 'UNUSED_RESULT', 'UNUSED_RESULT', 'DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE', 'DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE', 'DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE', 'DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE', - ], - [ + ]), + unorderedEquals([ 'UNUSED_RESULT', 'UNUSED_RESULT', 'DEPRECATED_MEMBER_USE', 'DEPRECATED_MEMBER_USE', 'DEPRECATED_MEMBER_USE', 'DEPRECATED_MEMBER_USE', - ], + ]), ]), );packages/freezed/test/multiple_constructors_test.dart (1)
47-49: Reduce repetition forgetField2(...).type.getDisplayString().Minor: a local helper/extension would DRY these assertions and ease future API shifts.
Example:
extension on ClassElement2 { String fieldTypeDisplay(String name) => getField2(name)!.type.getDisplayString(); }Also applies to: 577-579, 586-588, 593-595, 603-605, 612-614, 619-621, 630-632, 634-636, 638-640, 642-644
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (30)
analysis_options.yaml(1 hunks)packages/freezed/lib/src/ast.dart(3 hunks)packages/freezed/lib/src/models.dart(26 hunks)packages/freezed/lib/src/parse_generator.dart(3 hunks)packages/freezed/lib/src/templates/concrete_template.dart(2 hunks)packages/freezed/lib/src/templates/parameter_template.dart(4 hunks)packages/freezed/lib/src/templates/properties.dart(3 hunks)packages/freezed/lib/src/templates/prototypes.dart(2 hunks)packages/freezed/lib/src/tools/imports.dart(1 hunks)packages/freezed/lib/src/tools/recursive_import_locator.dart(7 hunks)packages/freezed/lib/src/tools/type.dart(4 hunks)packages/freezed/pubspec.yaml(1 hunks)packages/freezed/test/bidirectional_test.dart(1 hunks)packages/freezed/test/common.dart(3 hunks)packages/freezed/test/common_types_test.dart(1 hunks)packages/freezed/test/decorator_test.dart(3 hunks)packages/freezed/test/deep_copy_test.dart(3 hunks)packages/freezed/test/generic_test.dart(1 hunks)packages/freezed/test/generics_refs_test.dart(1 hunks)packages/freezed/test/json_test.dart(1 hunks)packages/freezed/test/map_test.dart(2 hunks)packages/freezed/test/multiple_constructors_test.dart(10 hunks)packages/freezed/test/optional_maybe_test.dart(1 hunks)packages/freezed/test/single_class_constructor_test.dart(5 hunks)packages/freezed/test/typedef_parameter_test.dart(2 hunks)packages/freezed/test/when_test.dart(1 hunks)packages/freezed_lint/lib/src/missing_mixin.dart(4 hunks)packages/freezed_lint/lib/src/missing_private_empty_ctor.dart(4 hunks)packages/freezed_lint/lib/src/tools/element_extensions.dart(1 hunks)packages/freezed_lint/pubspec.yaml(1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: lishaduck
PR: rrousselGit/freezed#1147
File: packages/freezed_lint/pubspec.yaml:12-12
Timestamp: 2025-01-07T20:51:22.701Z
Learning: The analyzer version update to >=7.0.0 in freezed_lint package is blocked by invertase/dart_custom_lint#300, preventing alignment with freezed package's analyzer requirements.
Learnt from: lishaduck
PR: rrousselGit/freezed#1147
File: packages/freezed_lint/pubspec.yaml:12-12
Timestamp: 2025-01-07T20:51:22.701Z
Learning: The analyzer version upgrade in freezed_lint is blocked by invertase/dart_custom_lint#300 which handles the broader upgrade of analyzer, analyzer_plugin, and source_gen dependencies in custom_lint.
📚 Learning: 2025-01-07T20:51:22.701Z
Learnt from: lishaduck
PR: rrousselGit/freezed#1147
File: packages/freezed_lint/pubspec.yaml:12-12
Timestamp: 2025-01-07T20:51:22.701Z
Learning: The analyzer version upgrade in freezed_lint is blocked by invertase/dart_custom_lint#300 which handles the broader upgrade of analyzer, analyzer_plugin, and source_gen dependencies in custom_lint.
Applied to files:
packages/freezed_lint/lib/src/tools/element_extensions.dartpackages/freezed_lint/pubspec.yamlpackages/freezed/lib/src/templates/concrete_template.dartpackages/freezed/pubspec.yamlpackages/freezed/lib/src/templates/properties.dartpackages/freezed/lib/src/templates/prototypes.dartpackages/freezed_lint/lib/src/missing_private_empty_ctor.dartpackages/freezed_lint/lib/src/missing_mixin.dartpackages/freezed/lib/src/models.dartpackages/freezed/lib/src/ast.dart
📚 Learning: 2025-01-07T20:51:22.701Z
Learnt from: lishaduck
PR: rrousselGit/freezed#1147
File: packages/freezed_lint/pubspec.yaml:12-12
Timestamp: 2025-01-07T20:51:22.701Z
Learning: The analyzer version update to >=7.0.0 in freezed_lint package is blocked by invertase/dart_custom_lint#300, preventing alignment with freezed package's analyzer requirements.
Applied to files:
packages/freezed_lint/lib/src/tools/element_extensions.dartpackages/freezed_lint/pubspec.yamlpackages/freezed/lib/src/templates/concrete_template.dartpackages/freezed/pubspec.yamlpackages/freezed/lib/src/templates/properties.dartpackages/freezed_lint/lib/src/missing_private_empty_ctor.dartpackages/freezed_lint/lib/src/missing_mixin.dartpackages/freezed/lib/src/templates/parameter_template.dartpackages/freezed/lib/src/models.dartpackages/freezed/lib/src/ast.dart
⏰ 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: freezed (packages/freezed, stable, get)
🔇 Additional comments (72)
packages/freezed_lint/lib/src/missing_mixin.dart (3)
1-2: Good import split; avoids LintCode clash.Importing
AnalysisErrorwhile hiding analyzer’sLintCodeis correct soLintCoderesolves to custom_lint’s type.
27-27: Usingelement.name3is consistent with analyzer v2 elements.This avoids deprecated accessors and aligns with
declaredFragment?.element. Looks good.
17-17: pubspec.yaml’sanalyzer: ">=7.5.9 <9.0.0"andcustom_lint_builder: ^0.8.0cover therun(CustomLintResolver, ErrorReporter, CustomLintContext)signature introduced in v0.8.0. (pub.dev)packages/freezed/lib/src/templates/concrete_template.dart (1)
2-2: Element v2 import: LGTM.Switching to element2.dart aligns with the v2 element API used across the repo. (pub.dev)
packages/freezed/test/generics_refs_test.dart (1)
24-24: Assert on ErrorsResult.errors: LGTM.Matches the current analyzer API;
errorsis the right property. (pub.dev)packages/freezed/test/optional_maybe_test.dart (1)
24-24: Assert on ErrorsResult.errors: LGTM.Consistent with the updated analyzer API. (pub.dev)
packages/freezed/test/map_test.dart (1)
306-306: UseerrorResult.errorsin expectations: LGTM.Both assertions correctly target the new property. (pub.dev)
Also applies to: 427-427
packages/freezed/test/bidirectional_test.dart (1)
23-23: Assert on ErrorsResult.errors: LGTM.Aligned with the analyzer API. (pub.dev)
packages/freezed/pubspec.yaml (1)
13-14: Version ranges align acrossfreezedandfreezed_lint; no conflicting constraints found.packages/freezed/test/generic_test.dart (1)
55-55: Assert on ErrorsResult.errors: LGTM.Correctly updated to the new property. (pub.dev)
packages/freezed/lib/src/templates/prototypes.dart (1)
1-1: Import to element2 looks fine.No further action.
packages/freezed/test/common.dart (2)
26-28: Correct migration to ErrorsResult.errors + Severity filter.Looks good.
37-37: Public field type update is consistent.
List<AnalysisError>aligns with the new API.packages/freezed/test/json_test.dart (1)
755-755: Updated assertion to errors — OK.packages/freezed/test/when_test.dart (1)
305-305: Updated to errors — OK.packages/freezed/test/common_types_test.dart (1)
28-28: Updated to errors — OK.packages/freezed_lint/lib/src/tools/element_extensions.dart (2)
1-1: element2 import is consistent with the migration.
8-11: Ensure min analyzer in range exposes constructors2.Given the widened constraint (>=7.5.9 <9.0.0), verify
ClassElement2.constructors2exists across the range. Consider adding CI that resolves deps at both the minimum and latest to guard this.I can propose a CI matrix step to test min/max dependency resolutions if helpful.
packages/freezed/test/deep_copy_test.dart (3)
34-34: errors isEmpty assertion — OK.
52-52: errors isEmpty assertion — OK.
737-741: Mapping to errorCode.name — OK; confirm code stability across range.
UNUSED_RESULTname should remain consistent across analyzer versions in your range.If needed, I can add a test guard that accepts both historic and new spellings.
packages/freezed_lint/pubspec.yaml (2)
14-14: custom_lint_builder ^0.8.0 compatibility.Double-check
custom_lint_builderandanalyzer_plugincompatibility with analyzer up to <9.0.0 to avoid resolution conflicts.
18-18: custom_lint ^0.8.0 downgrade — verify still supports analyzer >=7.5.9.If not, consider pinning with an upper bound or bumping to a compatible minor.
packages/freezed/lib/src/parse_generator.dart (1)
6-6: Import migration looks correct.Switch to element2.dart aligns with the analyzer v2 API.
packages/freezed/test/typedef_parameter_test.dart (2)
24-24: LGTM: updated toErrorsResult.errors.Matches the analyzer API change from diagnostics to errors.
48-66: LGTM: element2/name3 alias assertions.The updated alias accessors and
name3expectations look consistent with the v2 API.packages/freezed/lib/src/templates/parameter_template.dart (3)
14-18: LGTM: migrate generics definition toTypeParameterElement2+displayString2().
39-42: LGTM: migrate generics parameter list toTypeParameterElement2+name3.
72-80: parseDecorators usage is correct: it expects a List and metadata2.annotations already provides that.packages/freezed/lib/src/templates/properties.dart (4)
2-2: Import migration to element2 looks correct.
54-64: Guard against potential null name3 during recovery.
In rare parser-recovery/synthetic cases,element.name3could be null. Consider a safe fallback to avoid a crash.Would you prefer a defensive fallback like
parameter.nameif available, or keep the hard fail?
61-61: metadata2 migration LGTM.
Usage ofmetadata2.annotationsaligns with v2 API.
117-118: Ignore internal template change (no public API impact)
This update toTypeParameterElement2? parameterElementlives in the code‐generator’s internal template and isn’t exposed to users—no external or exported call-sites are affected.Likely an incorrect or invalid review comment.
packages/freezed/lib/src/tools/type.dart (4)
27-37: Element lookup migration is correct.
InterfaceType.element3andFunctionType.alias?.element2are the right replacements.
87-91: Dynamic type retrieval via element3.library2 is fine.
Assumingtype.element3is available for interface types, this keeps behavior parity.
94-95: Prefix owner rendering migration LGTM.
owner.name3is the correct accessor.
42-42: The diff in callers all use the updatedLibraryElement2‐based API (e.g. passing.library2), andtools/type.dartisn’t publicly re-exported fromlib/—it lives underlib/src. No public API broke.packages/freezed_lint/lib/src/missing_private_empty_ctor.dart (5)
16-17: Severity migration LGTM.
ErrorSeverity.ERRORmatches analyzer v2.
32-38: members2/accessors2 migration LGTM.
Correct non-static filtering retained.
41-43: Constructor check is precise.
constructors2withisPrivate, empty params, andname3 == '_'matchesClass._();.
61-63: Fix API migration for fixes LGTM.
UsingAnalysisErrorandList<AnalysisError>aligns with v2.
22-24: ConfirmedErrorReportersupport—importatElement2.
Yourpubspec.yamlalready pinscustom_lint_builder: ^0.8.0, which provides theErrorReporter reporterAPI; ensure theatElement2extension is imported soreporter.atElement2(...)resolves.packages/freezed/test/single_class_constructor_test.dart (2)
3-3: Analyzer v2 migration in tests looks good.Importing element2 and updating analyze() to return LibraryElement2 aligns with the new API.
Also applies to: 28-40
382-383: Correct switch to ErrorsResult.errors.Using errors instead of diagnostics matches analyzer >=7.x changes.
packages/freezed/lib/src/tools/imports.dart (1)
31-34: LGTM: helper reads clearly.Simple wrapper around the finder; no behavior change.
packages/freezed/test/decorator_test.dart (3)
20-20: LGTM: migrated toErrorsResult.errors.
46-61: LGTM: v2 API updates (fields2,name3,metadata2,getter2).Assertions read cleanly and match the new analyzer surface.
57-61: LGTM: metadata assertions reflect new annotation API.packages/freezed/test/multiple_constructors_test.dart (7)
5-5: LGTM: switch toelement2.dart.
26-28: LGTM: helper usesClassElement2+name3.Reads well and centralizes lookups.
40-41: LGTM:getField2(...).typeinterface-type assertion is correct.
66-71: LGTM: migrated accessors (getters,PropertyAccessorElement2,name3).Also applies to: 74-81
85-99: LGTM:fields2/name3doc assertions look consistent with v2.Also applies to: 102-117
184-185: LGTM:ErrorsResult.errorscheck.
1-1: Cross-package analyzer range sanity check complete.
- Both
packages/freezedandpackages/freezed_lintnow requireanalyzer: ">=7.5.9 <9.0.0".packages/freezed_lintpinscustom_lint: ^0.8.0; confirm that this version supports the analyzer range and that CI resolves a consistent pub-get across all packages.packages/freezed/lib/src/models.dart (17)
7-7: LGTM!The import change from
element.darttoelement2.dartcorrectly aligns with the Dart analyzer v2 migration.
30-30: LGTM!The extension targets are correctly updated to use
Element2andConstructorElement2types from the analyzer v2 API.Also applies to: 39-39
41-41: LGTM!The migration from
nametoname3is correct. Thename3property is the v2 API equivalent for accessing element names.Also applies to: 54-54
100-101: LGTM!The updates correctly migrate to v2 API:
element3for accessing interface type elementsClassElement2for class element typesname3for accessing element namesAlso applies to: 119-119, 122-122
272-272: LGTM!The change from
nametoname2for theNamedTypeis correct, aligning with the analyzer v2 API for AST node names.
286-286: LGTM!The use of
name3for accessing element names is correctly applied to parameter elements.
321-321: LGTM!The migration to
element2for accessing annotation elements andlibrary2for library references follows the v2 API convention.
427-427: LGTM!The changes correctly update method signatures and implementations:
ConstructorElement2parameter types in static helperslibrary2for library element accessmetadata2.annotationsfor accessing metadata in v2 APIAlso applies to: 439-439, 454-454, 456-456, 466-466
525-525: LGTM!The change from
nametoname2forNamedTypeis consistent with the analyzer v2 API for AST nodes.
555-555: LGTM!The library getter signature correctly returns
LibraryElement2as part of the v2 API migration.
573-573: LGTM!The migrations correctly use v2 API equivalents:
fields2for accessing class fieldsname3for field namestypeParameters2for type parametersAlso applies to: 679-680, 683-683, 686-686
748-748: LGTM!The change from
nametoname2for accessing AST node names is correct.
836-836: LGTM!The use of
metadata2.annotationsfor accessing metadata correctly follows the v2 API pattern.
865-865: LGTM!All library and type system references are correctly updated to use
library2from the v2 API.Also applies to: 867-867, 921-921, 967-967
1064-1064: LGTM!The field access methods are correctly migrated:
FieldElement2typesetter2andgetter2properties for accessors- Consistent use of v2 API naming conventions
Also applies to: 1069-1080
1132-1132: LGTM!The library imports checking correctly uses
library2for accessing library elements.Also applies to: 1135-1135
1360-1364: LGTM!The extension on
LibraryElement2correctly uses:
name3for element nameslibrary2for library references- Proper null-safe navigation with the v2 API
Also applies to: 1370-1371
| final mixins = withClause.mixinTypes; | ||
| if (mixins.any((m) => name == m.name.lexeme)) return; | ||
| if (mixins.any((m) => name == m.name2.lexeme)) return; | ||
| reporter.atElement2(element, _code, arguments: [name]); |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Potential API mismatch: m.name2.lexeme may not exist depending on analyzer; prefer name2.name.
On recent analyzer versions, NamedType.name2 is an Identifier whose stable string is name, not lexeme. Using lexeme can fail or be less future-proof. Consider switching to name2.name.
Apply:
- if (mixins.any((m) => name == m.name2.lexeme)) return;
+ if (mixins.any((m) => name == m.name2.name)) return;To confirm usage across the repo:
🏁 Script executed:
#!/bin/bash
rg -nP --type=dart -C1 '\.name2\.(lexeme|name)\b'Length of output: 753
Replace .name2.lexeme with .name2.name across all occurrences
- packages/freezed_lint/lib/src/missing_mixin.dart:35
- packages/freezed/lib/src/models.dart:272, 748
Apply these diffs:
--- a/packages/freezed_lint/lib/src/missing_mixin.dart
+++ b/packages/freezed_lint/lib/src/missing_mixin.dart
@@ -34,7 +34,7 @@
final mixins = withClause.mixinTypes;
- if (mixins.any((m) => name == m.name2.lexeme)) return;
+ if (mixins.any((m) => name == m.name2.name)) return;
reporter.atElement2(element, _code, arguments: [name]);--- a/packages/freezed/lib/src/models.dart
+++ b/packages/freezed/lib/src/models.dart
@@ -270,7 +270,7 @@
final redirectedName =
- constructor.redirectedConstructor?.type.name2.lexeme;
+ constructor.redirectedConstructor?.type.name2.name;--- a/packages/freezed/lib/src/models.dart
+++ b/packages/freezed/lib/src/models.dart
@@ -745,7 +745,7 @@
...?clazz._node.withClause?.mixinTypes,
- ].map((e) => e.name2.lexeme);
+ ].map((e) => e.name2.name);Verify no remaining instances:
rg -nP --type=dart '\.name2\.lexeme'🤖 Prompt for AI Agents
In packages/freezed_lint/lib/src/missing_mixin.dart around lines 34–36 (and
similarly in packages/freezed/lib/src/models.dart at lines ~272 and ~748),
change usages of `.name2.lexeme` to `.name2.name` so the code accesses the
token's name property instead of lexeme; update each occurrence to use
`.name2.name`, run the provided search command (rg -nP --type=dart
'\.name2\.lexeme') to ensure no remaining instances, and run tests/linting to
confirm nothing else breaks.
| final className = classElement.enclosingElement2.name3; | ||
|
|
||
| return name == null ? '$className$generics' : '$className$generics.$name'; | ||
| } |
There was a problem hiding this comment.
Bug: Using library name instead of class name in fullName.
className should come from the class element, not its enclosing library.
Apply this diff:
- final className = classElement.enclosingElement2.name3;
+ final className = classElement.name3!;📝 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.
| final className = classElement.enclosingElement2.name3; | |
| return name == null ? '$className$generics' : '$className$generics.$name'; | |
| } | |
| final className = classElement.name3!; | |
| return name == null ? '$className$generics' : '$className$generics.$name'; |
🤖 Prompt for AI Agents
In packages/freezed/lib/src/ast.dart around lines 73 to 76, fullName is
incorrectly using the enclosing element's name (library) as className; replace
the use of classElement.enclosingElement2.name3 with the class element's own
name (classElement.name) so fullName uses the actual class name when composing
'$className$generics' or '$className$generics.$name'.
| final Object? ast = unit.unit.declarations.firstWhereOrNull( | ||
| (declaration) => | ||
| declaration.declaredFragment?.element.name == element.name!, | ||
| declaration.declaredFragment?.element.name3 == element.name3!, | ||
| ); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Match elements by identity, not by (possibly-null) name.
Comparing name3 risks a null bang on unnamed elements. Use element identity for robustness.
- final Object? ast = resolvedUnit.unit.declarations.firstWhereOrNull(
- (declaration) =>
- declaration.declaredFragment?.element.name3 == element.name3!,
- );
+ final Object? ast = resolvedUnit.unit.declarations.firstWhereOrNull(
+ (declaration) => declaration.declaredFragment?.element == element,
+ );Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In packages/freezed/lib/src/parse_generator.dart around lines 76-79, the code
matches declarations by comparing declaration.declaredFragment?.element.name3 to
element.name3!, which can NPE on unnamed elements; change the predicate to
compare element identity instead (e.g., compare element ==
declaration.declaredFragment?.element or element ==
declaration.declaredElement), remove the null-bang, and keep the
firstWhereOrNull call so unnamed elements are handled safely.
| bool isDefaultConstructor(ConstructorElement2 constructor) { | ||
| return constructor.name3 == 'new'; | ||
| } |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Default-ctor detection via string 'new' is brittle; handle both unnamed forms.
Some analyzer versions expose the unnamed constructor as '' (empty), others as 'new'. Comparing to 'new' only risks misclassification.
Apply this for robustness:
-bool isDefaultConstructor(ConstructorElement2 constructor) {
- return constructor.name3 == 'new';
-}
+bool isDefaultConstructor(ConstructorElement2 constructor) {
+ final n = constructor.name3;
+ return n.isEmpty || n == 'new';
+}If ConstructorElement2 offers a boolean for unnamed/default, prefer that instead (e.g., isDefaultConstructor / isNamedConstructor). Would you like me to adjust if confirmed?
🏁 Script executed:
#!/bin/bash
set -eux
echo "Snippet around isDefaultConstructor:"
rg -n "isDefaultConstructor" -C3 packages/freezed/lib/src/templates/prototypes.dart || true
echo "Imports in file:"
sed -n '1,20p' packages/freezed/lib/src/templates/prototypes.dart || true
echo "Search for name3 usage:"
rg -n "name3" -C3 packages/freezed/lib/src/templates/prototypes.dart || trueLength of output: 1329
Use the built‐in isDefaultConstructor instead of manual string checks.
Replace the name3 comparison with the API’s boolean:
-bool isDefaultConstructor(ConstructorElement2 constructor) {
- return constructor.name3 == 'new';
-}
+bool isDefaultConstructor(ConstructorElement2 constructor) {
+ return constructor.isDefaultConstructor;
+}
```([pub.dev](https://pub.dev/documentation/analyzer/latest/dart_element_element2/ConstructorElement2-class.html))
<details>
<summary>🤖 Prompt for AI Agents</summary>
In packages/freezed/lib/src/templates/prototypes.dart around lines 44–46, the
code checks for a default constructor by comparing constructor.name3 == 'new';
replace this manual string check with the built-in boolean property by using
constructor.isDefaultConstructor instead (update the conditional accordingly).
Ensure any related logic expecting the old check still works with the boolean
API and run tests/linting to confirm no further adjustments are needed.
</details>
<!-- fingerprinting:phantom:poseidon:chinchilla -->
<!-- This is an auto-generated comment by CodeRabbit -->
| yield* children2; | ||
|
|
There was a problem hiding this comment.
Yielding library.children2 likely returns units, not top-level elements.
Return top-level declarations from each compilation unit instead.
Apply this diff:
- yield* children2;
+ for (final unit in fragments) {
+ // CompilationUnitElement2.children2 are the unit's top-level elements.
+ yield* unit.children2;
+ }📝 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.
| yield* children2; | |
| // Instead of yielding the units themselves... | |
| // ...iterate each compilation unit fragment and yield its top‐level elements. | |
| for (final unit in fragments) { | |
| // CompilationUnitElement2.children2 are the unit's top‐level declarations. | |
| yield* unit.children2; | |
| } |
🤖 Prompt for AI Agents
In packages/freezed/lib/src/tools/recursive_import_locator.dart around lines
31-32, the code currently does "yield* children2;" which yields compilation
units rather than top-level declarations; replace that with iterating over each
compilation unit in children2 and yield its top-level declarations (e.g., for
each unit in children2 do "yield* unit.declarations") so the stream returns
top-level members instead of units.
| return (directive.showStatements.isEmpty && | ||
| directive.hideStatements.isEmpty) || | ||
| (directive.hideStatements.isNotEmpty && | ||
| !directive.hideStatements.contains(element.name)) || | ||
| directive.showStatements.contains(element.name); | ||
| !directive.hideStatements.contains(element.name3)) || | ||
| directive.showStatements.contains(element.name3); | ||
| }); |
There was a problem hiding this comment.
Show/hide combinator logic is incorrect (OR vs AND).
When both are present, result must be (in show OR show is empty) AND not in hide.
Apply this diff:
- .where((element) {
- return (directive.showStatements.isEmpty &&
- directive.hideStatements.isEmpty) ||
- (directive.hideStatements.isNotEmpty &&
- !directive.hideStatements.contains(element.name3)) ||
- directive.showStatements.contains(element.name3);
- });
+ .where((element) {
+ final name = element.name3;
+ if (name == null) return false;
+ final show = directive.showStatements;
+ final hide = directive.hideStatements;
+ final shown = show.isEmpty || show.contains(name);
+ final notHidden = !hide.contains(name);
+ return shown && notHidden;
+ });📝 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.
| return (directive.showStatements.isEmpty && | |
| directive.hideStatements.isEmpty) || | |
| (directive.hideStatements.isNotEmpty && | |
| !directive.hideStatements.contains(element.name)) || | |
| directive.showStatements.contains(element.name); | |
| !directive.hideStatements.contains(element.name3)) || | |
| directive.showStatements.contains(element.name3); | |
| }); | |
| .where((element) { | |
| final name = element.name3; | |
| if (name == null) return false; | |
| final show = directive.showStatements; | |
| final hide = directive.hideStatements; | |
| final shown = show.isEmpty || show.contains(name); | |
| final notHidden = !hide.contains(name); | |
| return shown && notHidden; | |
| }); |
🤖 Prompt for AI Agents
In packages/freezed/lib/src/tools/recursive_import_locator.dart around lines 55
to 60, the combinator logic uses ORs causing incorrect results when both show
and hide are present; replace the current condition with one that requires (show
is empty OR show contains the symbol) AND the symbol is not in hide. Concretely,
change the predicate to ensure directive.showStatements.isEmpty ||
directive.showStatements.contains(element.name3) is combined with &&
!directive.hideStatements.contains(element.name3), preserving the existing
checks for empty hide/show lists.
| return l.importedLibrary2!.anyTransitiveExport((library) { | ||
| return library.id == _getElementForType(type)?.library2?.id; | ||
| }); |
There was a problem hiding this comment.
Fix potential NPE on importedLibrary2.
l.importedLibrary2! can be null for unresolved/conditional imports, causing crashes.
Apply:
- return l.importedLibrary2!.anyTransitiveExport((library) {
- return library.id == _getElementForType(type)?.library2?.id;
- });
+ final imported = l.importedLibrary2;
+ if (imported == null) return false;
+ return imported.anyTransitiveExport(
+ (library) => library.id == _getElementForType(type)?.library2?.id,
+ );📝 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.
| return l.importedLibrary2!.anyTransitiveExport((library) { | |
| return library.id == _getElementForType(type)?.library2?.id; | |
| }); | |
| final imported = l.importedLibrary2; | |
| if (imported == null) return false; | |
| return imported.anyTransitiveExport( | |
| (library) => library.id == _getElementForType(type)?.library2?.id, | |
| ); |
🤖 Prompt for AI Agents
In packages/freezed/lib/src/tools/type.dart around lines 45 to 47, the code
force-unwraps l.importedLibrary2 which can be null for unresolved or conditional
imports; guard against that by checking for null before calling
anyTransitiveExport — either use a null-aware call with a fallback (e.g.
l.importedLibrary2?.anyTransitiveExport(...) ?? false) or assign
l.importedLibrary2 to a local variable and return false if it is null, then call
anyTransitiveExport when non-null.
Summary by CodeRabbit
Chores
Refactor
Tests