diff --git a/lib/src/lints/avoid_unnecessary_return_variable/visitors/avoid_unnecessary_return_variable_visitor.dart b/lib/src/lints/avoid_unnecessary_return_variable/visitors/avoid_unnecessary_return_variable_visitor.dart index ebfad8e4..95233f43 100644 --- a/lib/src/lints/avoid_unnecessary_return_variable/visitors/avoid_unnecessary_return_variable_visitor.dart +++ b/lib/src/lints/avoid_unnecessary_return_variable/visitors/avoid_unnecessary_return_variable_visitor.dart @@ -15,7 +15,7 @@ class AvoidUnnecessaryReturnVariableVisitor extends SimpleAstVisitor { @override void visitReturnStatement(ReturnStatement node) { - final expr = node.expression; + final expr = node.expression?.unParenthesized; if (expr is! SimpleIdentifier) return; final element = expr.element; @@ -23,7 +23,8 @@ class AvoidUnnecessaryReturnVariableVisitor extends SimpleAstVisitor { if (!element.isFinal && !element.isConst) return; - final block = node.parent; + //get enclosing block function body + final block = node.thisOrAncestorOfType()?.block; if (block == null) return; final returnVariableUsageVisitor = ReturnVariableUsageVisitor( @@ -34,16 +35,18 @@ class AvoidUnnecessaryReturnVariableVisitor extends SimpleAstVisitor { block.visitChildren(returnVariableUsageVisitor); if (!returnVariableUsageVisitor.hasBadStatementCount) return; + //check if declaration statement is found + final declaration = returnVariableUsageVisitor.variableDeclaration; + if (declaration == null) return; + //it is 100% bad if return statement follows declaration if (!returnVariableUsageVisitor.foundTokensBetweenDeclarationAndReturn) { _rule.reportAtNode(node); return; } - final declaration = returnVariableUsageVisitor.variableDeclaration; - //check if immutable - final initializer = declaration?.initializer; + final initializer = declaration.initializer; if (initializer == null) return; if (!_isExpressionImmutable(initializer)) return; diff --git a/test/lints/avoid_unnecessary_return_variable/avoid_unnecessary_return_variable_rule_test.dart b/test/lints/avoid_unnecessary_return_variable/avoid_unnecessary_return_variable_rule_test.dart index d2e42b16..704cc16d 100644 --- a/test/lints/avoid_unnecessary_return_variable/avoid_unnecessary_return_variable_rule_test.dart +++ b/test/lints/avoid_unnecessary_return_variable/avoid_unnecessary_return_variable_rule_test.dart @@ -172,4 +172,57 @@ void _doNothing() {} [lint(304, 14)], ); } + + void test_does_not_report_if_return_is_cached_nested_block() async { + await assertNoDiagnostics(r''' +Future testAvoidUnnecessaryReturnVariableNestedBlock() async { + final cached = 'cached'; + if (cached.isNotEmpty) { + // Should NOT trigger the avoid_unnecessary_return_variable lint + return cached; + } + return null; +} +'''); + } + + void test_reports_if_return_is_cached_and_only_returned_nested_block() async { + await assertDiagnostics( + r''' +int test(bool b) { + final a = 3; + if (b) { + return a; + } + return 0; +} +''', + [lint(49, 9)], + ); + } + + void test_reports_if_return_in_parentheses() async { + await assertDiagnostics( + r''' +int test() { + final a = 3; + return (a); +} +''', + [lint(30, 11)], + ); + } + + void test_does_not_report_if_return_is_cached_and_used_after_return_nested_block() async { + await assertNoDiagnostics(r''' +int test(bool b) { + final a = 3; + if (b) { + return a; + } + return a + 1; } +'''); + } +} +