-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue 167 #184
Issue 167 #184
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
import 'package:analyzer/dart/ast/ast.dart'; | ||
import 'package:analyzer/dart/ast/visitor.dart'; | ||
import 'package:solid_lints/src/lints/prefer_early_return/visitors/return_statement_visitor.dart'; | ||
import 'package:solid_lints/src/lints/prefer_early_return/visitors/throw_expression_visitor.dart'; | ||
|
||
/// The AST visitor that will collect all unnecessary if statements | ||
class PreferEarlyReturnVisitor extends RecursiveAstVisitor<void> { | ||
|
@@ -33,6 +34,7 @@ class PreferEarlyReturnVisitor extends RecursiveAstVisitor<void> { | |
if (_isElseIfStatement(node)) return; | ||
if (_hasElseStatement(node)) return; | ||
if (_hasReturnStatement(node)) return; | ||
if (_hasThrowExpression(node)) return; | ||
|
||
_nodes.add(node); | ||
} | ||
|
@@ -70,4 +72,10 @@ class PreferEarlyReturnVisitor extends RecursiveAstVisitor<void> { | |
node.accept(visitor); | ||
return visitor.nodes.isNotEmpty; | ||
} | ||
|
||
bool _hasThrowExpression(Statement node) { | ||
final visitor = ThrowExpressionVisitor(); | ||
node.accept(visitor); | ||
return visitor.nodes.isNotEmpty; | ||
} | ||
Comment on lines
+75
to
+80
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please sync with |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import 'package:analyzer/dart/ast/ast.dart'; | ||
import 'package:analyzer/dart/ast/visitor.dart'; | ||
|
||
/// The AST visitor that will collect every Return statement | ||
class ThrowExpressionVisitor extends RecursiveAstVisitor<void> { | ||
final _nodes = <ThrowExpression>[]; | ||
|
||
/// All unnecessary return statements | ||
Iterable<ThrowExpression> get nodes => _nodes; | ||
|
||
@override | ||
void visitThrowExpression(ThrowExpression node) { | ||
super.visitThrowExpression(node); | ||
_nodes.add(node); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,22 +1,23 @@ | ||||||
/// Model class for AvoidReturningWidgetsExclude parameters | ||||||
class AvoidReturningWidgetsExclude { | ||||||
|
||||||
/// Model class for ExcludeRule parameters | ||||||
class ExcludeRule { | ||||||
/// The name of the method that should be excluded from the lint. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's think about better naming here, this isn't a rule.
Suggested change
|
||||||
final String methodName; | ||||||
|
||||||
/// The name of the class that should be excluded from the lint. | ||||||
final String? className; | ||||||
|
||||||
/// Constructor for [AvoidReturningWidgetsExclude] model | ||||||
const AvoidReturningWidgetsExclude({ | ||||||
/// Constructor for [ExcludeRule] model | ||||||
const ExcludeRule({ | ||||||
required this.methodName, | ||||||
required this.className, | ||||||
}); | ||||||
|
||||||
/// | ||||||
factory AvoidReturningWidgetsExclude.fromJson( | ||||||
factory ExcludeRule.fromJson( | ||||||
Map<dynamic, dynamic> json, | ||||||
) { | ||||||
return AvoidReturningWidgetsExclude( | ||||||
return ExcludeRule( | ||||||
methodName: json['method_name'] as String, | ||||||
className: json['class_name'] as String?, | ||||||
); | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import 'package:analyzer/dart/ast/ast.dart'; | ||
import 'package:collection/collection.dart'; | ||
import 'package:solid_lints/src/models/exclude_rule.dart'; | ||
|
||
/// A data model class that represents the "avoid returning widgets" input | ||
/// parameters. | ||
class ExcludeParameters { | ||
/// A list of methods that should be excluded from the lint. | ||
final List<ExcludeRule> exclude; | ||
|
||
/// Constructor for [ExcludeParameters] model | ||
ExcludeParameters({ | ||
required this.exclude, | ||
}); | ||
|
||
/// Method for creating from json data | ||
factory ExcludeParameters.fromJson({ | ||
required Iterable<dynamic> excludeList, | ||
}) { | ||
final exclude = <ExcludeRule>[]; | ||
|
||
for (final item in excludeList) { | ||
if (item is Map) { | ||
exclude.add(ExcludeRule.fromJson(item)); | ||
} | ||
} | ||
return ExcludeParameters( | ||
exclude: exclude, | ||
); | ||
} | ||
|
||
/// Method to define ignoring | ||
bool shouldIgnore(Declaration node) { | ||
final methodName = node.declaredElement?.name; | ||
|
||
final excludedItem = | ||
exclude.firstWhereOrNull((e) => e.methodName == methodName); | ||
|
||
if (excludedItem == null) return false; | ||
|
||
final className = excludedItem.className; | ||
|
||
if (className == null || node is! MethodDeclaration) { | ||
return true; | ||
} else { | ||
final classDeclaration = node.thisOrAncestorOfType<ClassDeclaration>(); | ||
|
||
if (classDeclaration == null) return false; | ||
|
||
return classDeclaration.name.toString() == className; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can make this key reusable, so that all other rules use it consistently.