diff --git a/CHANGELOG.md b/CHANGELOG.md index e1e4d7177f..26b4abdb02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +* fix: partially handle normal completion function body for [`avoid-redundant-async`](https://dcm.dev/docs/individuals/rules/common/avoid-redundant-async). * fix: ignore enum constant arguments for [`no-magic-number`](https://dcm.dev/docs/individuals/rules/common/no-magic-number). * fix: correctly handle prefixed enums and static instance fields for [`prefer-moving-to-variable`](https://dcm.dev/docs/individuals/rules/common/prefer-moving-to-variable). * feat: add static code diagnostic [`prefer-provide-intl-description`](https://dcm.dev/docs/individuals/rules/intl/prefer-provide-intl-description). diff --git a/lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_redundant_async/visitor.dart b/lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_redundant_async/visitor.dart index 767e9520c1..81aed34a76 100644 --- a/lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_redundant_async/visitor.dart +++ b/lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_redundant_async/visitor.dart @@ -37,22 +37,40 @@ class _Visitor extends RecursiveAstVisitor { } } - final asyncVisitor = _AsyncVisitor(); + final asyncVisitor = _AsyncVisitor(body); body.parent?.visitChildren(asyncVisitor); + if (asyncVisitor._allReturns.isNotEmpty) { + return !asyncVisitor.hasValidAsync && + asyncVisitor._allReturns.length != + asyncVisitor._returnsInsideIf.length; + } + return !asyncVisitor.hasValidAsync; } } class _AsyncVisitor extends RecursiveAstVisitor { + final FunctionBody body; + bool hasValidAsync = false; + final _allReturns = {}; + final _returnsInsideIf = {}; + + _AsyncVisitor(this.body); + @override void visitReturnStatement(ReturnStatement node) { super.visitReturnStatement(node); final type = node.expression?.staticType; + _allReturns.add(node); + if (_isInsideIfStatement(node, body)) { + _returnsInsideIf.add(node); + } + if (type == null || !type.isDartAsyncFuture || type.nullabilitySuffix == NullabilitySuffix.question) { @@ -80,4 +98,12 @@ class _AsyncVisitor extends RecursiveAstVisitor { hasValidAsync = true; } + + bool _isInsideIfStatement(ReturnStatement node, FunctionBody body) { + final parent = node.thisOrAncestorMatching( + (parent) => parent == body || parent is IfStatement, + ); + + return parent is IfStatement; + } } diff --git a/test/src/analyzers/lint_analyzer/rules/rules_list/avoid_redundant_async/examples/example.dart b/test/src/analyzers/lint_analyzer/rules/rules_list/avoid_redundant_async/examples/example.dart index dd2bfa0298..37ad0d176a 100644 --- a/test/src/analyzers/lint_analyzer/rules/rules_list/avoid_redundant_async/examples/example.dart +++ b/test/src/analyzers/lint_analyzer/rules/rules_list/avoid_redundant_async/examples/example.dart @@ -59,4 +59,12 @@ void main() { () async => instance.someAsyncMethod(), // LINT onSelectedNamed: () async => instance.someAsyncMethod(), // LINT ); + + WithFunctionField(onSelectedNamed: () async { + if (shouldRefresh) return apiCall(); + }); +} + +Future apiCall() { + return Future.value(); }