From 8ca522236b06e2e548b9746e9f1ee71e51d3af3d Mon Sep 17 00:00:00 2001 From: "alexiuk.genius" Date: Thu, 18 Apr 2024 11:14:44 +0200 Subject: [PATCH] Refactor avoid_final_with_getter_rule.dart and avoid_final_with_getter_visitor.dart --- .../avoid_final_with_getter_rule.dart | 2 +- .../avoid_final_with_getter_visitor.dart | 77 ------------------- .../avoid_final_with_getter_visitor.dart | 28 +++++++ .../visitors/variable_getter_visitor.dart | 56 ++++++++++++++ lint_test/avoid_final_with_getter_test.dart | 6 +- 5 files changed, 90 insertions(+), 79 deletions(-) delete mode 100644 lib/src/lints/avoid_final_with_getter/avoid_final_with_getter_visitor.dart create mode 100644 lib/src/lints/avoid_final_with_getter/visitors/avoid_final_with_getter_visitor.dart create mode 100644 lib/src/lints/avoid_final_with_getter/visitors/variable_getter_visitor.dart diff --git a/lib/src/lints/avoid_final_with_getter/avoid_final_with_getter_rule.dart b/lib/src/lints/avoid_final_with_getter/avoid_final_with_getter_rule.dart index a9d6c81..a4d5139 100644 --- a/lib/src/lints/avoid_final_with_getter/avoid_final_with_getter_rule.dart +++ b/lib/src/lints/avoid_final_with_getter/avoid_final_with_getter_rule.dart @@ -1,6 +1,6 @@ import 'package:analyzer/error/listener.dart'; import 'package:custom_lint_builder/custom_lint_builder.dart'; -import 'package:solid_lints/src/lints/avoid_final_with_getter/avoid_final_with_getter_visitor.dart'; +import 'package:solid_lints/src/lints/avoid_final_with_getter/visitors/avoid_final_with_getter_visitor.dart'; import 'package:solid_lints/src/models/rule_config.dart'; import 'package:solid_lints/src/models/solid_lint_rule.dart'; diff --git a/lib/src/lints/avoid_final_with_getter/avoid_final_with_getter_visitor.dart b/lib/src/lints/avoid_final_with_getter/avoid_final_with_getter_visitor.dart deleted file mode 100644 index c5b9a72..0000000 --- a/lib/src/lints/avoid_final_with_getter/avoid_final_with_getter_visitor.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'package:analyzer/dart/ast/ast.dart'; -import 'package:analyzer/dart/ast/visitor.dart'; -import 'package:analyzer/dart/element/element.dart'; - -/// A visitor that checks for final private fields with getters. -/// If a final private field has a getter, it is considered as a public field. -class AvoidFinalWithGetterVisitor extends RecursiveAstVisitor { - final _variables = []; - - /// List of final private fields with getters - Iterable get variables => _variables; - - @override - void visitVariableDeclaration(VariableDeclaration node) { - final isPrivate = node.declaredElement?.isPrivate ?? false; - final isFinalPrivate = node.isFinal && isPrivate; - - if (!isFinalPrivate) return; - - final visitor = _GettersVisitor(node); - node.parent?.parent?.parent?.accept(visitor); - - if (visitor.getter != null) { - _variables.add(node); - } - super.visitVariableDeclaration(node); - } -} - -class _GettersVisitor extends RecursiveAstVisitor { - final VariableDeclaration variable; - final String fieldName; - - MethodDeclaration? getter; - - _GettersVisitor(this.variable) - : fieldName = variable.name.toString().replaceFirst('_', ''); - - @override - void visitMethodDeclaration(MethodDeclaration node) { - final name = node.name.toString(); - - if (name == fieldName && node.isGetter) { - final nodeId = node.getterReferenceId; - - final variableId = variable.variableId; - - if (nodeId == variableId) { - getter = node; - } - } - super.visitMethodDeclaration(node); - } -} - -extension on MethodDeclaration { - int? get getterReferenceId => switch (body) { - ExpressionFunctionBody( - expression: SimpleIdentifier( - staticElement: Element( - declaration: PropertyAccessorElement( - variable: PropertyInducingElement(id: final int id) - ) - ) - ) - ) => - id, - _ => null, - }; -} - -extension on VariableDeclaration { - int? get variableId => switch (declaredElement) { - VariableElement(id: final int id) => id, - _ => null, - }; -} diff --git a/lib/src/lints/avoid_final_with_getter/visitors/avoid_final_with_getter_visitor.dart b/lib/src/lints/avoid_final_with_getter/visitors/avoid_final_with_getter_visitor.dart new file mode 100644 index 0000000..b4bfc07 --- /dev/null +++ b/lib/src/lints/avoid_final_with_getter/visitors/avoid_final_with_getter_visitor.dart @@ -0,0 +1,28 @@ +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:analyzer/dart/ast/visitor.dart'; +import 'package:solid_lints/src/lints/avoid_final_with_getter/visitors/variable_getter_visitor.dart'; + +/// A visitor that checks for final private fields with getters. +/// If a final private field has a getter, it is considered as a public field. +class AvoidFinalWithGetterVisitor extends RecursiveAstVisitor { + final _variables = []; + + /// List of final private fields with getters + Iterable get variables => _variables; + + @override + void visitVariableDeclaration(VariableDeclaration node) { + final isPrivate = node.declaredElement?.isPrivate ?? false; + final isFinalPrivate = node.isFinal && isPrivate; + + if (!isFinalPrivate) return; + + final visitor = VariableGetterVisitor(node); + node.parent?.parent?.parent?.accept(visitor); + + if (visitor.getter != null) { + _variables.add(node); + } + super.visitVariableDeclaration(node); + } +} diff --git a/lib/src/lints/avoid_final_with_getter/visitors/variable_getter_visitor.dart b/lib/src/lints/avoid_final_with_getter/visitors/variable_getter_visitor.dart new file mode 100644 index 0000000..6347155 --- /dev/null +++ b/lib/src/lints/avoid_final_with_getter/visitors/variable_getter_visitor.dart @@ -0,0 +1,56 @@ +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:analyzer/dart/ast/visitor.dart'; +import 'package:analyzer/dart/element/element.dart'; + +/// A visitor that checks for final private fields with getters. +class VariableGetterVisitor extends RecursiveAstVisitor { + final VariableDeclaration _variable; + final String _fieldName; + MethodDeclaration? _getter; + + /// Creates a new instance of [VariableGetterVisitor] + VariableGetterVisitor(this._variable) + : _fieldName = _variable.name.toString().replaceFirst('_', ''); + + /// The getter of the variable + MethodDeclaration? get getter => _getter; + + @override + void visitMethodDeclaration(MethodDeclaration node) { + final name = node.name.toString(); + + if (name == _fieldName && node.isGetter) { + final nodeId = node.getterReferenceId; + + final variableId = _variable.variableId; + + if (nodeId == variableId) { + _getter = node; + } + } + super.visitMethodDeclaration(node); + } +} + +extension on MethodDeclaration { + int? get getterReferenceId => switch (body) { + ExpressionFunctionBody( + expression: SimpleIdentifier( + staticElement: Element( + declaration: PropertyAccessorElement( + variable: PropertyInducingElement(id: final int id) + ) + ) + ) + ) => + id, + _ => null, + }; +} + +extension on VariableDeclaration { + int? get variableId => switch (declaredElement) { + VariableElement(id: final int id) => id, + _ => null, + }; +} diff --git a/lint_test/avoid_final_with_getter_test.dart b/lint_test/avoid_final_with_getter_test.dart index 59862d6..4dad1d5 100644 --- a/lint_test/avoid_final_with_getter_test.dart +++ b/lint_test/avoid_final_with_getter_test.dart @@ -8,8 +8,12 @@ class Fail { final int _myField = 0; int get myField => _myField; +} + +class Skipped { + final int _myField = 0; - int get myField2 => _myField + 1; + int get myField => _myField + 1; } class Good {