From 3cddacd02f5ddf8768854ba862889834dcd6a41d Mon Sep 17 00:00:00 2001 From: Dmitry Zhifarsky Date: Mon, 5 Dec 2022 11:06:32 +0400 Subject: [PATCH] fix: remove recursive traversal for ban-name --- CHANGELOG.md | 4 ++ .../rules_list/ban_name/ban_name_rule.dart | 37 +++++++--- .../rules/rules_list/ban_name/visitor.dart | 72 +++++++++---------- .../ban_name/ban_name_rule_test.dart | 10 +-- 4 files changed, 69 insertions(+), 54 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6c680e5d3..9e9494bc8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased + +* fix: remove recursive traversal for [`ban-name`](https://dartcodemetrics.dev/docs/rules/common/ban-name) rule. + ## 5.1.0 * feat: add static code diagnostic [`arguments-ordering`](https://dartcodemetrics.dev/docs/rules/common/arguments-ordering). diff --git a/lib/src/analyzers/lint_analyzer/rules/rules_list/ban_name/ban_name_rule.dart b/lib/src/analyzers/lint_analyzer/rules/rules_list/ban_name/ban_name_rule.dart index 79a630382e..e36305b433 100644 --- a/lib/src/analyzers/lint_analyzer/rules/rules_list/ban_name/ban_name_rule.dart +++ b/lib/src/analyzers/lint_analyzer/rules/rules_list/ban_name/ban_name_rule.dart @@ -42,14 +42,33 @@ class BanNameRule extends CommonRule { source.unit.visitChildren(visitor); - return visitor.nodes - .map( - (node) => createIssue( - rule: this, - location: nodeLocation(node: node.node, source: source), - message: node.message, - ), - ) - .toList(growable: false); + final filteredNodeList = visitor.nodes.where((node) { + if (node.endNode != null) { + final inlineNode = source.content + .substring( + node.node.offset, + node.endNode!.end, + ) + .replaceAll('\n', ''); + + if (!inlineNode.contains(node.fullName)) { + return false; + } + } + + return true; + }); + + return filteredNodeList.map( + (node) => createIssue( + rule: this, + location: nodeLocation( + node: node.node, + source: source, + endNode: node.endNode, + ), + message: node.message, + ), + ); } } diff --git a/lib/src/analyzers/lint_analyzer/rules/rules_list/ban_name/visitor.dart b/lib/src/analyzers/lint_analyzer/rules/rules_list/ban_name/visitor.dart index 34dd9c887b..7040aed061 100644 --- a/lib/src/analyzers/lint_analyzer/rules/rules_list/ban_name/visitor.dart +++ b/lib/src/analyzers/lint_analyzer/rules/rules_list/ban_name/visitor.dart @@ -3,30 +3,29 @@ part of 'ban_name_rule.dart'; class _Visitor extends GeneralizingAstVisitor { final Map _entryMap; + final _nodeBreadcrumb = {}; final _nodes = <_NodeInfo>[]; Iterable<_NodeInfo> get nodes => _nodes; - final _visitedNodes = {}; - _Visitor(List<_BanNameConfigEntry> entries) : _entryMap = Map.fromEntries(entries.map((e) => MapEntry(e.ident, e))); @override void visitSimpleIdentifier(SimpleIdentifier node) { - _visitIdent(node, node); + _visitIdent(node, node.name); } @override void visitPrefixedIdentifier(PrefixedIdentifier node) { - _visitIdent(node, node.identifier); - _visitIdent(node, node.prefix); + _visitIdent(node, node.identifier.name); + _visitIdent(node, node.prefix.name); } @override void visitLibraryIdentifier(LibraryIdentifier node) { for (final component in node.components) { - _visitIdent(node, component); + _visitIdent(node, component.name); } } @@ -34,54 +33,43 @@ class _Visitor extends GeneralizingAstVisitor { void visitDeclaration(Declaration node) { final name = node.declaredElement?.displayName; if (name != null) { - _checkBannedName(node, name); + _visitIdent(node, name); } super.visitDeclaration(node); } - void _visitIdent(AstNode node, SimpleIdentifier name) { - _checkBannedName(name, name.name); - - if (node is PrefixedIdentifier) { - _checkBannedName(node, node.name); + void _visitIdent(AstNode node, String name) { + final prevNode = + _nodeBreadcrumb.isNotEmpty ? _nodeBreadcrumb.values.last : null; + if (node.offset - 1 == prevNode?.end) { + _nodeBreadcrumb.addAll({name: node}); + } else { + _nodeBreadcrumb.clear(); } - _traverseParents(name.parent); - } - - void _traverseParents(AstNode? node) { - if (node is MethodInvocation) { - _checkBannedName( - node, - '${node.realTarget}.${node.methodName}', - ); - _traverseParents(node.parent); + if (_nodeBreadcrumb.isEmpty) { + _nodeBreadcrumb.addAll({name: node}); } - if (node is PropertyAccess) { - _checkBannedName( + if (_entryMap.containsKey(name)) { + _nodes.add(_NodeInfo( node, - '${node.realTarget}.${node.propertyName}', - ); - _traverseParents(node.realTarget); - } + fullName: name, + message: '${_entryMap[name]!.description} ($name is banned)', + )); - if (node is ConstructorName) { - _traverseParents(node.parent); + return; } - if (node is InstanceCreationExpression) { - _checkBannedName(node, node.constructorName.toString()); - } - } - - void _checkBannedName(AstNode node, String name) { - if (_entryMap.containsKey(name) && !_visitedNodes.contains(node)) { - _visitedNodes.add(node); + final breadcrumbString = _nodeBreadcrumb.keys.join('.'); + if (_entryMap.containsKey(breadcrumbString)) { _nodes.add(_NodeInfo( - node, - message: '${_entryMap[name]!.description} ($name is banned)', + _nodeBreadcrumb.values.first, + fullName: breadcrumbString, + message: + '${_entryMap[breadcrumbString]!.description} ($breadcrumbString is banned)', + endNode: _nodeBreadcrumb.values.last, )); } } @@ -89,10 +77,14 @@ class _Visitor extends GeneralizingAstVisitor { class _NodeInfo { final AstNode node; + final String fullName; final String message; + final AstNode? endNode; _NodeInfo( this.node, { + required this.fullName, required this.message, + this.endNode, }); } diff --git a/test/src/analyzers/lint_analyzer/rules/rules_list/ban_name/ban_name_rule_test.dart b/test/src/analyzers/lint_analyzer/rules/rules_list/ban_name/ban_name_rule_test.dart index 9b279397c2..6f55e9fd94 100644 --- a/test/src/analyzers/lint_analyzer/rules/rules_list/ban_name/ban_name_rule_test.dart +++ b/test/src/analyzers/lint_analyzer/rules/rules_list/ban_name/ban_name_rule_test.dart @@ -51,11 +51,11 @@ void main() { ' late var strangeName; // LINT\n' '}', 'strangeName', - 'StrangeClass.someMethod()', - 'DateTime.now()', - 'DateTime.now()', - 'DateTime.now()', - 'DateTime.now()', + 'StrangeClass.someMethod', + 'DateTime.now', + 'DateTime.now', + 'DateTime.now', + 'DateTime.now', ], messages: [ 'Please use myShowDialog (showDialog is banned)',