Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/freezed_lint/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Unreleased 0.1.0
## Unreleased patch

Support new Analyzer API and custom_lint

Expand Down
14 changes: 7 additions & 7 deletions packages/freezed_lint/lib/src/missing_mixin.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:analyzer/error/error.dart' hide LintCode;
import 'package:analyzer/error/listener.dart' show ErrorReporter;
import 'package:analyzer/diagnostic/diagnostic.dart';
import 'package:analyzer/error/listener.dart' show DiagnosticReporter;
Comment on lines +1 to +2
Copy link

Choose a reason for hiding this comment

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

💡 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.

import 'package:custom_lint_builder/custom_lint_builder.dart';
import 'package:freezed_lint/src/tools/freezed_annotation_checker.dart';

Expand All @@ -14,7 +14,7 @@ class MissingMixin extends DartLintRule {
@override
void run(
CustomLintResolver resolver,
ErrorReporter reporter,
DiagnosticReporter reporter,
CustomLintContext context,
) {
context.registry.addClassDeclaration((node) {
Expand All @@ -24,15 +24,15 @@ class MissingMixin extends DartLintRule {
final annotation = freezedAnnotationChecker.hasAnnotationOfExact(element);
if (!annotation) return;

final name = '_\$${element.name3}';
final name = '_\$${element.name}';
final withClause = node.withClause;
if (withClause == null) {
reporter.atElement2(element, _code, arguments: [name]);
return;
}

final mixins = withClause.mixinTypes;
if (mixins.any((m) => name == m.name2.lexeme)) return;
if (mixins.any((m) => name == m.name.lexeme)) return;
reporter.atElement2(element, _code, arguments: [name]);
});
}
Expand All @@ -47,8 +47,8 @@ class _AddMixinFreezedClassFix extends DartFix {
CustomLintResolver resolver,
ChangeReporter reporter,
CustomLintContext context,
AnalysisError analysisError,
List<AnalysisError> others,
Diagnostic analysisError,
List<Diagnostic> others,
) {
context.registry.addClassDeclaration((node) {
if (!analysisError.sourceRange.intersects(node.sourceRange)) return;
Expand Down
23 changes: 12 additions & 11 deletions packages/freezed_lint/lib/src/missing_private_empty_ctor.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:analyzer/diagnostic/diagnostic.dart';
import 'package:analyzer/error/error.dart' hide LintCode;
import 'package:analyzer/error/listener.dart' show ErrorReporter;
import 'package:analyzer/error/listener.dart' show DiagnosticReporter;
import 'package:custom_lint_builder/custom_lint_builder.dart';
import 'package:freezed_lint/src/tools/element_extensions.dart';
import 'package:freezed_lint/src/tools/freezed_annotation_checker.dart';
Expand All @@ -13,13 +14,13 @@ class MissingPrivateEmptyCtor extends DartLintRule {
correctionMessage:
'Freezed classes containing methods, fields or accessors,'
'requires a {0}',
errorSeverity: ErrorSeverity.ERROR,
errorSeverity: DiagnosticSeverity.ERROR,
);

@override
void run(
CustomLintResolver resolver,
ErrorReporter reporter,
DiagnosticReporter reporter,
CustomLintContext context,
) {
context.registry.addClassDeclaration((node) {
Expand All @@ -29,17 +30,17 @@ class MissingPrivateEmptyCtor extends DartLintRule {
final annotation = freezedAnnotationChecker.hasAnnotationOfExact(element);
if (!annotation) return;

final methods = element.methods2.where((method) => !method.isStatic);
final fields = element.fields2.where((field) => !field.isStatic);
final methods = element.methods.where((method) => !method.isStatic);
final fields = element.fields.where((field) => !field.isStatic);

final accessors = [
...element.getters2,
...element.setters2,
...element.getters,
...element.setters,
].where((accessor) => !accessor.isStatic);
if (methods.isEmpty && fields.isEmpty && accessors.isEmpty) return;

final ctors = element.constructors2.where((ctor) =>
ctor.isPrivate && ctor.formalParameters.isEmpty && ctor.name3 == '_');
final ctors = element.constructors.where((ctor) =>
ctor.isPrivate && ctor.formalParameters.isEmpty && ctor.name == '_');
if (ctors.isNotEmpty) return;

final constToken = element.constToken();
Expand All @@ -58,8 +59,8 @@ class _AddPrivateEmptyCtorFix extends DartFix {
CustomLintResolver resolver,
ChangeReporter reporter,
CustomLintContext context,
AnalysisError analysisError,
List<AnalysisError> others,
Diagnostic analysisError,
List<Diagnostic> others,
) {
Comment on lines +62 to 64
Copy link

Choose a reason for hiding this comment

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

💡 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.lock

Length 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.dart

Length 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 accept AnalysisError (and List<AnalysisError>) instead of Diagnostic (and List<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.

context.registry.addClassDeclaration((node) {
if (!analysisError.sourceRange.intersects(node.sourceRange)) return;
Expand Down
6 changes: 3 additions & 3 deletions packages/freezed_lint/lib/src/tools/element_extensions.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';

extension DartTypeExt on DartType {
bool hasName(String name) => getDisplayString() == name;
}

extension ClassElementExt on ClassElement2 {
extension ClassElementExt on ClassElement {
String? constToken() {
if (constructors2.any((c) => c.isConst)) return 'const ';
if (constructors.any((c) => c.isConst)) return 'const ';
return null;
}
}
Comment on lines +8 to 13
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

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.

Suggested change
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).

6 changes: 3 additions & 3 deletions packages/freezed_lint/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ environment:
sdk: ">=3.0.0 <4.0.0"

dependencies:
analyzer: ^7.0.0
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
Comment on lines +12 to 19
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Confirm analyzer/custom_lint compatibility and consider widening freezed_annotation.

  • Please verify custom_lint_builder:^0.8.1 and custom_lint:^0.8.1 are officially compatible with analyzer:^8.0.0 and analyzer_plugin:^0.13.0.
  • Consider freezed_annotation: ^3.1.0 to 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:


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.0 to freezed_annotation: ^3.1.0 to 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.

test: ^1.22.2