Skip to content

Commit dde8e6f

Browse files
authored
add quick fix to avoid_final_with_getter (#164)
* add avoid_final_with_getter rule * Update analysis_options.yaml to exclude final fields with getters * Refactor avoid_final_with_getter_rule.dart and avoid_final_with_getter_visitor.dart * Fix incorrect test comments in avoid_final_with_getter_test.dart * change avoid_final_with_getter, now it lints getter, no getter name equality * Refactor avoid_final_with_getter_visitor.dart to remove isStatic property from declaredElement * add more tests to avoid_final_with_getter_test.dart * Add avoid_final_with_getter rule to CHANGELOG.md * add quick fix to avoid_final_with_getter * Refactor avoid_final_with_getter_visitor.dart to use local variable instead of accessing visitor.variable directly
1 parent 9be59e9 commit dde8e6f

4 files changed

Lines changed: 70 additions & 7 deletions

File tree

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
part of 'avoid_final_with_getter_rule.dart';
2+
3+
class _FinalWithGetterFix extends DartFix {
4+
@override
5+
void run(
6+
CustomLintResolver resolver,
7+
ChangeReporter reporter,
8+
CustomLintContext context,
9+
AnalysisError analysisError,
10+
List<AnalysisError> others,
11+
) {
12+
context.registry.addMethodDeclaration((node) {
13+
if (analysisError.sourceRange.intersects(node.sourceRange)) {
14+
final info = analysisError.data as FinalWithGetterInfo?;
15+
if (info == null) return;
16+
17+
_addReplacement(reporter, info);
18+
}
19+
});
20+
}
21+
22+
void _addReplacement(
23+
ChangeReporter reporter,
24+
FinalWithGetterInfo info,
25+
) {
26+
final changeBuilder = reporter.createChangeBuilder(
27+
message: "Remove getter and make variable public.",
28+
priority: 1,
29+
);
30+
31+
changeBuilder.addDartFileEdit((builder) {
32+
builder.addDeletion(info.getter.sourceRange);
33+
builder.addDeletion(SourceRange(info.variable.name.offset, 1));
34+
});
35+
}
36+
}

lib/src/lints/avoid_final_with_getter/avoid_final_with_getter_rule.dart

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
import 'package:analyzer/error/error.dart';
12
import 'package:analyzer/error/listener.dart';
3+
import 'package:analyzer/source/source_range.dart';
24
import 'package:custom_lint_builder/custom_lint_builder.dart';
35
import 'package:solid_lints/src/lints/avoid_final_with_getter/visitors/avoid_final_with_getter_visitor.dart';
46
import 'package:solid_lints/src/models/rule_config.dart';
57
import 'package:solid_lints/src/models/solid_lint_rule.dart';
68

9+
part 'avoid_final_with_getter_fix.dart';
10+
711
/// Avoid using final private fields with getters.
812
///
913
/// Final private variables used in a pair with a getter
@@ -59,9 +63,18 @@ class AvoidFinalWithGetterRule extends SolidLintRule {
5963
final visitor = AvoidFinalWithGetterVisitor();
6064
node.accept(visitor);
6165

62-
for (final getter in visitor.getters) {
63-
reporter.reportErrorForNode(code, getter);
66+
for (final element in visitor.getters) {
67+
reporter.reportErrorForNode(
68+
code,
69+
element.getter,
70+
null,
71+
null,
72+
element,
73+
);
6474
}
6575
});
6676
}
77+
78+
@override
79+
List<Fix> getFixes() => [_FinalWithGetterFix()];
6780
}

lib/src/lints/avoid_final_with_getter/visitors/avoid_final_with_getter_visitor.dart

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ import 'package:solid_lints/src/lints/avoid_final_with_getter/visitors/getter_va
66
/// A visitor that checks for final private fields with getters.
77
/// If a final private field has a getter, it is considered as a public field.
88
class AvoidFinalWithGetterVisitor extends RecursiveAstVisitor<void> {
9-
final _getters = <MethodDeclaration>[];
9+
final _getters = <FinalWithGetterInfo>{};
1010

1111
/// List of getters
12-
Iterable<MethodDeclaration> get getters => _getters;
12+
Set<FinalWithGetterInfo> get getters => _getters;
1313

1414
@override
1515
void visitMethodDeclaration(MethodDeclaration node) {
@@ -24,10 +24,24 @@ class AvoidFinalWithGetterVisitor extends RecursiveAstVisitor<void> {
2424
final visitor = GetterVariableVisitor(node);
2525
node.parent?.accept(visitor);
2626

27-
if (visitor.hasVariable) {
28-
_getters.add(node);
27+
final variable = visitor.variable;
28+
29+
if (variable != null) {
30+
_getters.add(FinalWithGetterInfo(node, variable));
2931
}
3032
}
3133
super.visitMethodDeclaration(node);
3234
}
3335
}
36+
37+
/// Information about the final private field with a getter.
38+
class FinalWithGetterInfo {
39+
/// The getter method declaration.
40+
final MethodDeclaration getter;
41+
42+
/// The variable declaration.
43+
final VariableDeclaration variable;
44+
45+
/// Creates a new instance of [FinalWithGetterInfo]
46+
const FinalWithGetterInfo(this.getter, this.variable);
47+
}

lib/src/lints/avoid_final_with_getter/visitors/getter_variable_visitor.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class GetterVariableVisitor extends RecursiveAstVisitor<void> {
1313
: _getterId = getter.getterReferenceId;
1414

1515
/// Is there a variable associated with the getter
16-
bool get hasVariable => _variable != null;
16+
VariableDeclaration? get variable => _variable;
1717

1818
@override
1919
void visitVariableDeclaration(VariableDeclaration node) {

0 commit comments

Comments
 (0)