Skip to content
Open
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
17 changes: 9 additions & 8 deletions lib/src/lints/prefer_early_return/prefer_early_return_rule.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,20 @@ import 'package:solid_lints/src/lints/prefer_early_return/visitors/prefer_early_
/// }
/// ```
class PreferEarlyReturnRule extends AnalysisRule {
/// The name of the lint
/// Lint name
static const String lintName = 'prefer_early_return';

/// The message shown when the lint is triggered
static const String lintMessage = 'Use reverse if to reduce nesting';

/// Lint code
static const LintCode _code = LintCode(
lintName,
lintMessage,
"Use reverse if to reduce nesting",
);

/// Creates a new instance of [PreferEarlyReturnRule]
/// Creates an instance of [PreferEarlyReturnRule]
PreferEarlyReturnRule()
: super(
name: lintName,
description: lintMessage,
description: 'Use reverse if to reduce nesting',
);

@override
Expand All @@ -59,7 +56,11 @@ class PreferEarlyReturnRule extends AnalysisRule {
RuleVisitorRegistry registry,
RuleContext context,
) {
final visitor = PreferEarlyReturnVisitor(this);
final visitor = PreferEarlyReturnVisitor(
rule: this,
context: context,
);

registry.addBlockFunctionBody(this, visitor);
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:analyzer/analysis_rule/rule_context.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:solid_lints/src/lints/prefer_early_return/prefer_early_return_rule.dart';
Expand All @@ -6,19 +7,27 @@ import 'package:solid_lints/src/lints/prefer_early_return/visitors/throw_express

/// Visitor for [PreferEarlyReturnRule].
class PreferEarlyReturnVisitor extends RecursiveAstVisitor<void> {
/// The rule associated with this visitor.
/// The rule associated with the visitor.
final PreferEarlyReturnRule rule;

/// Creates an instance of [PreferEarlyReturnVisitor].
PreferEarlyReturnVisitor(this.rule);
/// The context associated with the visitor.
final RuleContext context;

/// Constructor for [PreferEarlyReturnVisitor].
PreferEarlyReturnVisitor({
required this.rule,
required this.context,
});

@override
void visitBlockFunctionBody(BlockFunctionBody node) {
super.visitBlockFunctionBody(node);

if (node.block.statements.isEmpty) return;

final (ifStatements, nextStatement) = _getStartIfStatements(node);
final (ifStatements, nextStatement) = _getIfStatementsAndNextStatement(
node,
);
if (ifStatements.isEmpty) return;

// limit visitor to only work with functions
Expand All @@ -29,25 +38,24 @@ class PreferEarlyReturnVisitor extends RecursiveAstVisitor<void> {

if (!nextStatementIsEmptyReturn && !nextStatementIsNull) return;

_handleIfStatement(ifStatements.last);
}
final lastIf = ifStatements.last;

void _handleIfStatement(IfStatement node) {
if (_isElseIfStatement(node)) return;
if (_hasElseStatement(node)) return;
if (_hasReturnStatement(node)) return;
if (_hasThrowExpression(node)) return;
if (lastIf case IfStatement(elseStatement: Statement())) return;
if (_hasReturnStatement(lastIf) || _hasThrowExpression(lastIf)) return;

rule.reportAtNode(node);
context.currentUnit?.diagnosticReporter.atNode(
lastIf,
rule.diagnosticCode,
);
}

// returns a list of if statements at the start of the function
// and the next statement after it
// examples:
// [if, if, if, return] -> ([if, if, if], return)
// [if, if, if, _doSomething, return] -> ([if, if, if], _doSomething)
// [if, if, if] -> ([if, if, if], null)
(List<IfStatement>, Statement?) _getStartIfStatements(
// returns a list of if statements at the start of the function
// and the next statement after it
// examples:
// [if, if, if, return] -> ([if, if, if], return)
// [if, if, if, _doSomething, return] -> ([if, if, if], _doSomething)
// [if, if, if] -> ([if, if, if], null)
(List<IfStatement>, Statement?) _getIfStatementsAndNextStatement(
BlockFunctionBody body,
) {
final List<IfStatement> ifStatements = [];
Expand All @@ -58,15 +66,8 @@ class PreferEarlyReturnVisitor extends RecursiveAstVisitor<void> {
return (ifStatements, statement);
}
}
return (ifStatements, null);
}

bool _hasElseStatement(IfStatement node) {
return node.elseStatement != null;
}

bool _isElseIfStatement(IfStatement node) {
return node.elseStatement != null && node.elseStatement is IfStatement;
return (ifStatements, null);
}

bool _hasReturnStatement(Statement node) {
Expand Down
Loading
Loading