Conversation
WalkthroughMigrates freezed_lint to Analyzer v8 and diagnostic-based reporting. Updates lint rule implementations to use DiagnosticReporter and newer element APIs, adjusts symbol/name accessors, and aligns fix handling with Diagnostic types. Bumps dependencies and tweaks CHANGELOG header. No new exported entities beyond updated method signatures and extension receiver types. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Dev as Developer
participant CL as custom_lint
participant Rule as MissingMixin/MissingPrivateEmptyCtor
participant Analyzer as Analyzer (v8)
participant DR as DiagnosticReporter
Dev->>CL: Run analysis
CL->>Analyzer: Resolve library/unit
Analyzer-->>CL: Resolved elements/AST
CL->>Rule: run(resolver, reporter, context)
Rule->>Analyzer: Inspect elements (methods/fields/constructors)
Rule-->>DR: report(Diagnostic with code/severity, location)
DR-->>CL: Emit diagnostics
CL-->>Dev: Show lint results
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 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: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/freezed_lint/lib/src/missing_mixin.dart (1)
63-69: Fix insertion point: breaks whenimplementsis present.Inserting just before
{appends afterimplements, yielding invalid syntax (e.g.,implements X, _$Foo {). Insert:
- after the last mixin type if a
withclause exists, or- before
implementsif present, or- before
{otherwise.- final offset = node.leftBracket.offset - 1; - if (node.withClause != null) { - builder.addSimpleInsertion(offset, ', _\$$name'); - } else { - builder.addSimpleInsertion(offset, ' with _\$$name'); - } + final withClause = node.withClause; + final implClause = node.implementsClause; + if (withClause != null) { + builder.addSimpleInsertion(withClause.end, ', _\$$name'); + } else if (implClause != null) { + builder.addSimpleInsertion(implClause.offset, ' with _\$$name '); + } else { + builder.addSimpleInsertion(node.leftBracket.offset, ' with _\$$name'); + }packages/freezed_lint/lib/src/missing_private_empty_ctor.dart (1)
46-49: Guard against “null” prefix in suggested constructor.This relies on
constToken()returning a non-null string. With the fix inelement_extensions.dart(return''), this is safe. If you keep it nullable, coalesce to''here:- final constToken = element.constToken(); + final constToken = element.constToken(); // returns '' or 'const 'and similarly for the message at Line 72.
🧹 Nitpick comments (6)
packages/freezed_lint/CHANGELOG.md (1)
1-1: Clarify “Unreleased patch” scope.Consider using “## Unreleased” with a bullet noting “Migrate to analyzer v8 and diagnostic API” and linking this PR, to match prior sections’ style.
packages/freezed_lint/lib/src/tools/element_extensions.dart (1)
4-6: Be explicit about nullability ingetDisplayString.Future analyzer changes sometimes tweak defaults. Using the named arg is safer and clearer:
- bool hasName(String name) => getDisplayString() == name; + bool hasName(String name) => + getDisplayString(withNullability: false) == name;packages/freezed_lint/lib/src/missing_mixin.dart (2)
27-27: Minor: preferdisplayNamefor consistency.- final name = '_\$${element.name}'; + final name = '_\$${element.displayName}';
35-36: Optional: handle prefixed imports to avoid false negatives.If the mixin were ever referenced with a prefix (unlikely with parts),
m.name.lexemewouldn’t match. A more robust check:- if (mixins.any((m) => name == m.name.lexeme)) return; + if (mixins.any((m) => (m.element?.name ?? m.name.lexeme) == name)) return;Please confirm
NamedType.elementis available under analyzer v8 in your min SDK.packages/freezed_lint/lib/src/missing_private_empty_ctor.dart (2)
42-44: Optionally exclude factory constructors.A private empty factory (e.g.,
factory Foo._();) would satisfy this check but doesn’t provide the intended generative private ctor pattern.- final ctors = element.constructors.where((ctor) => - ctor.isPrivate && ctor.formalParameters.isEmpty && ctor.name == '_'); + final ctors = element.constructors.where((ctor) => + !ctor.isFactory && + ctor.isPrivate && + ctor.formalParameters.isEmpty && + ctor.name == '_');
1-4: Remove unused analyzer error import.
analyzer/error/error.dartappears unused after migrating to diagnostics. Safe to drop to avoid confusion with hiddenLintCode.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
packages/freezed_lint/CHANGELOG.md(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 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/pubspec.yamlpackages/freezed_lint/CHANGELOG.mdpackages/freezed_lint/lib/src/missing_mixin.dartpackages/freezed_lint/lib/src/missing_private_empty_ctor.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 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/pubspec.yamlpackages/freezed_lint/CHANGELOG.mdpackages/freezed_lint/lib/src/missing_mixin.dartpackages/freezed_lint/lib/src/missing_private_empty_ctor.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)
| import 'package:analyzer/diagnostic/diagnostic.dart'; | ||
| import 'package:analyzer/error/listener.dart' show DiagnosticReporter; |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Confirm DiagnosticReporter.atElement2 availability.
Ensure the atElement2 helper exists for DiagnosticReporter in custom_lint_builder:^0.8.1. If not, switch to the supported reporter API/util in that version.
🌐 Web query:
custom_lint atElement2 DiagnosticReporter site:pub.dev
💡 Result:
I searched pub.dev and couldn't find any package or API named "atElement2 DiagnosticReporter". I did find the custom_lint package/docs (related to custom lint plugins) if that helps. Would you like me to search the wider web (GitHub, analyzer API, or Dart SDK) for "atElement2" or "DiagnosticReporter"? [1]
Sources:
[1] custom_lint package docs — pub.dev. (pub.dev)
Citations:
Replace non-existent atElement2 with supported reportError* API.
The DiagnosticReporter.atElement2 helper isn’t provided by custom_lint_builder:^0.8.1; update any calls to use the ErrorReporter.reportErrorForNode (or another available reportError*) method instead.
🤖 Prompt for AI Agents
In packages/freezed_lint/lib/src/missing_mixin.dart around lines 1 to 2, the
code imports analyzer diagnostics and uses the non-existent
DiagnosticReporter.atElement2 API from custom_lint_builder; replace any usage of
atElement2 with the supported ErrorReporter.reportErrorForNode (or another
appropriate reportError* variant). Update the code to obtain an ErrorReporter
(or DiagnosticReporter) instance and call reportErrorForNode with the
corresponding error code and the AST node where the issue occurs (or use
reportErrorForElement/reportErrorForSpan as appropriate), and remove or adjust
any atElement2-specific arguments so the call matches the chosen reportError*
signature.
| Diagnostic analysisError, | ||
| List<Diagnostic> others, | ||
| ) { |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Verify Diagnostic.sourceRange extension availability.
analysisError.sourceRange isn’t on analyzer’s Diagnostic type. It’s likely provided by custom_lint_builder extensions. Please confirm it resolves under ^0.8.1. If not, compute the node range from the diagnostic’s location.
🌐 Web query:
custom_lint Diagnostic sourceRange extension
💡 Result:
Do you want an example extension (code) that converts a custom_lint/analysis Diagnostic into a source range (offset+length or a SourceRange/TextRange), or do you need links/docs about existing utilities (RangeFactory / custom_lint) that do this?
🏁 Script executed:
#!/bin/bash
# Search for any usage of `sourceRange` in Dart files
rg -n "sourceRange" -C3 --glob "*.dart"
# Check locked version of custom_lint_builder in pubspec.lock
grep -R "custom_lint_builder" -n pubspec.lockLength of output: 1419
🏁 Script executed:
#!/bin/bash
# Check pubspec.yaml files for custom_lint_builder version
fd "pubspec.yaml" --exec grep -Hn "custom_lint_builder" {}
# Look for imports of custom_lint_builder in the file that uses sourceRange
head -20 packages/freezed_lint/lib/src/missing_private_empty_ctor.dart
# Check if sourceRange is defined on Diagnostic type by looking at imports and usage
rg -n "import.*custom_lint" packages/freezed_lint/lib/src/missing_private_empty_ctor.dartLength of output: 948
🌐 Web query:
Does custom_lint_builder provide a sourceRange extension on analyzer Diagnostic?
💡 Result:
No. custom_lint_builder adds a sourceRange extension on AnalysisError (and on SyntacticEntity), not on analyzer Diagnostic. [1][2]
Sources:
- custom_lint_builder API: AnalysisErrorSourceRange extension. [1]
- custom_lint_builder API index (shows SyntacticEntitySourceRange, etc.). [2]
Use AnalysisError for .sourceRange extension
.sourceRange is provided by custom_lint_builder’s AnalysisErrorSourceRange on AnalysisError, not on analyzer’s Diagnostic. Update the rule methods in
packages/freezed_lint/lib/src/missing_private_empty_ctor.dart(lines 62–64)packages/freezed_lint/lib/src/missing_mixin.dart(lines 51–53)
to acceptAnalysisError(andList<AnalysisError>) instead ofDiagnostic(andList<Diagnostic>).
🤖 Prompt for AI Agents
In packages/freezed_lint/lib/src/missing_private_empty_ctor.dart (lines 62–64)
and packages/freezed_lint/lib/src/missing_mixin.dart (lines 51–53), the rule
methods accept Diagnostic / List<Diagnostic> but .sourceRange is provided by
custom_lint_builder's AnalysisError; change the parameter types to AnalysisError
and List<AnalysisError>, update any related variable names/usages to the new
type, and add the necessary import for AnalysisError from custom_lint_builder
(or the correct package) so .sourceRange calls compile.
| extension ClassElementExt on ClassElement { | ||
| String? constToken() { | ||
| if (constructors2.any((c) => c.isConst)) return 'const '; | ||
| if (constructors.any((c) => c.isConst)) return 'const '; | ||
| return null; | ||
| } | ||
| } |
There was a problem hiding this comment.
Bug: constToken() returns null and will render “nullFoo._();”.
constToken() currently returns String? and null when no const ctor exists. Call sites interpolate it directly, producing “null...” in messages/edits.
Fix by returning an empty string instead of null and adjusting the signature:
-extension ClassElementExt on ClassElement {
- String? constToken() {
- if (constructors.any((c) => c.isConst)) return 'const ';
- return null;
- }
+extension ClassElementExt on ClassElement {
+ String constToken() {
+ return constructors.any((c) => c.isConst) ? 'const ' : '';
+ }
}📝 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.
| extension ClassElementExt on ClassElement { | |
| String? constToken() { | |
| if (constructors2.any((c) => c.isConst)) return 'const '; | |
| if (constructors.any((c) => c.isConst)) return 'const '; | |
| return null; | |
| } | |
| } | |
| extension ClassElementExt on ClassElement { | |
| String constToken() { | |
| return constructors.any((c) => c.isConst) ? 'const ' : ''; | |
| } | |
| } |
🤖 Prompt for AI Agents
In packages/freezed_lint/lib/src/tools/element_extensions.dart around lines
8-13, the constToken() helper returns a nullable String and returns null when no
const constructor exists which causes string interpolation to produce
"nullFoo._();" in messages; change the signature to return non-nullable String
(remove ?), return an empty string ('') instead of null when no const exists,
and update any call sites if they relied on null to treat the value as empty (no
other behavior changes needed).
| analyzer: ^8.0.0 | ||
| analyzer_plugin: ^0.13.0 | ||
| custom_lint_builder: ^0.8.0 | ||
| custom_lint_builder: ^0.8.1 | ||
| freezed_annotation: 3.1.0 | ||
|
|
||
| dev_dependencies: | ||
| custom_lint: ^0.8.0 | ||
| custom_lint: ^0.8.1 | ||
| build_verify: ^3.1.0 |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Confirm analyzer/custom_lint compatibility and consider widening freezed_annotation.
- Please verify
custom_lint_builder:^0.8.1andcustom_lint:^0.8.1are officially compatible withanalyzer:^8.0.0andanalyzer_plugin:^0.13.0. - Consider
freezed_annotation: ^3.1.0to allow non-breaking patches unless you intentionally pin.
Would you like me to check the latest compatibility notes for these versions?
🌐 Web query:
custom_lint 0.8.1 analyzer 8 compatibility
custom_lint_builder 0.8.1 DiagnosticReporter atElement2
dart analyzer_plugin 0.13 compatibility analyzer 8
💡 Result:
Short summary and recommended fixes:
-
analyzer_plugin 0.13.x requires pkg:analyzer 8.x (changelog shows 0.13.5/0.13.6/0.13.7 bumped to analyzer ^8.0.0 / ^8.1.0 / 8.1.1 respectively). [1]
-
custom_lint / custom_lint_builder recent releases (custom_lint 0.8.x, custom_lint_builder 0.8.0) depend on analyzer and analyzer_plugin; that combination can hit breaking API changes between analyzer 7.x and 8.x. (custom_lint page; custom_lint_builder metadata). [2][3]
-
Symptom you mentioned (analyzer_plugin calling methods removed/renamed in analyzer 7.4.5 — e.g. publiclyExporting2 / DiagnosticReporter/atElement2–style incompatibilities) is a known compatibility issue reported by users: analyzer_plugin 0.13.0 fails to compile against analyzer 7.4.5 (GitHub issue / reports). Workarounds people used: pin analyzer to an older compatible version (e.g. 7.3.0) or ensure analyzer_plugin/analyzer versions align (upgrade analyzer to an 8.x line compatible with analyzer_plugin). [4]
What to do:
- If you must stay on analyzer 7.x: pin analyzer_plugin/custom_lint/*builder to versions that declare support for that analyzer (or use dependency_overrides to force analyzer 7.3.0 as a temporary workaround). [3][4]
- If you can upgrade: update analyzer to 8.x and use analyzer_plugin 0.13.6+ (or whatever analyzer_plugin release requires the analyzer 8.x range) and the matching custom_lint packages. Verify pub deps (pub deps --style=compact) and run pub get/build_runner after changes. [1][2]
Sources:
[1] analyzer_plugin changelog (shows analyzer 8.x requirements). (pub.dev)
[2] custom_lint package page (latest 0.8.x). (pub.dev)
[3] custom_lint_builder package page / changelog. (pub.dev)
[4] GitHub issue / reports about analyzer_plugin 0.13.0 incompatible with analyzer 7.4.5. (github.com)
If you want, tell me your pubspec.yaml and I’ll suggest exact version pins to make your build_runner/custom_lint setup work.
Citations:
- 1: https://pub.dev/packages/analyzer_plugin/versions/0.13.6/changelog?utm_source=openai
- 2: https://pub.dev/packages/custom_lint?utm_source=openai
- 3: https://pub.dev/packages/custom_lint_builder?utm_source=openai
- 4: custom_lint fails in workspace on Flutter 3.32.0 invertase/dart_custom_lint#332
Update analyzer_plugin to ^0.13.6 and widen freezed_annotation
- In packages/freezed_lint/pubspec.yaml, bump analyzer_plugin from ^0.13.0 to ^0.13.6 so it’s compatible with analyzer: ^8.0.0 alongside custom_lint_builder ^0.8.1 and custom_lint ^0.8.1.
- Change
freezed_annotation: 3.1.0tofreezed_annotation: ^3.1.0to allow non-breaking patch updates.
🤖 Prompt for AI Agents
In packages/freezed_lint/pubspec.yaml around lines 12 to 19, update
analyzer_plugin from ^0.13.0 to ^0.13.6 and change freezed_annotation from 3.1.0
to ^3.1.0; edit those dependency entries accordingly so analyzer_plugin matches
analyzer ^8.0.0 and custom_lint versions, and widen freezed_annotation to allow
non-breaking patch updates.
Summary by CodeRabbit
No user-facing behavior changes expected; existing projects should continue to work after dependency updates.