Skip to content
This repository was archived by the owner on Jul 16, 2023. It is now read-only.

Commit 2e0c6da

Browse files
authored
fix: ignore Providers for avoid-returning-widgets (#1121)
1 parent ea9eaad commit 2e0c6da

File tree

4 files changed

+85
-5
lines changed

4 files changed

+85
-5
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
## Unreleased
44

5-
* feat: add [`use-setstate-synchronously`](https://dartcodemetrics.dev/docs/rules/flutter/use-setstate-synchronously)
5+
* fix: ignore Providers for ['avoid-returning-widgets'](https://dartcodemetrics.dev/docs/rules/common/avoid-returning-widgets).
6+
* feat: add [`use-setstate-synchronously`](https://dartcodemetrics.dev/docs/rules/flutter/use-setstate-synchronously).
67

78
## 5.3.0
89

lib/src/utils/flutter_types_utils.dart

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,15 @@ import 'package:analyzer/dart/element/type.dart';
44
import 'package:collection/collection.dart';
55

66
bool hasWidgetType(DartType type) =>
7-
isWidgetOrSubclass(type) ||
8-
_isIterable(type) ||
9-
_isList(type) ||
10-
_isFuture(type);
7+
(isWidgetOrSubclass(type) ||
8+
_isIterable(type) ||
9+
_isList(type) ||
10+
_isFuture(type)) &&
11+
!(_isMultiProvider(type) ||
12+
_isSubclassOfInheritedProvider(type) ||
13+
_isIterableInheritedProvider(type) ||
14+
_isListInheritedProvider(type) ||
15+
_isFutureInheritedProvider(type));
1116

1217
bool isWidgetOrSubclass(DartType? type) =>
1318
_isWidget(type) || _isSubclassOfWidget(type);
@@ -92,3 +97,30 @@ bool _isRenderObjectElement(DartType? type) =>
9297

9398
bool _isSubclassOfRenderObjectElement(DartType? type) =>
9499
type is InterfaceType && type.allSupertypes.any(_isRenderObjectElement);
100+
101+
bool _isMultiProvider(DartType? type) =>
102+
type?.getDisplayString(withNullability: false) == 'MultiProvider';
103+
104+
bool _isSubclassOfInheritedProvider(DartType? type) =>
105+
type is InterfaceType && type.allSupertypes.any(_isInheritedProvider);
106+
107+
bool _isInheritedProvider(DartType? type) =>
108+
type != null &&
109+
type
110+
.getDisplayString(withNullability: false)
111+
.startsWith('InheritedProvider<');
112+
113+
bool _isIterableInheritedProvider(DartType type) =>
114+
type.isDartCoreIterable &&
115+
type is InterfaceType &&
116+
_isSubclassOfInheritedProvider(type.typeArguments.firstOrNull);
117+
118+
bool _isListInheritedProvider(DartType type) =>
119+
type.isDartCoreList &&
120+
type is InterfaceType &&
121+
_isSubclassOfInheritedProvider(type.typeArguments.firstOrNull);
122+
123+
bool _isFutureInheritedProvider(DartType type) =>
124+
type.isDartAsyncFuture &&
125+
type is InterfaceType &&
126+
_isSubclassOfInheritedProvider(type.typeArguments.firstOrNull);

test/src/analyzers/lint_analyzer/rules/rules_list/avoid_returning_widgets/avoid_returning_widgets_rule_test.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import '../../../../../helpers/rule_test_helper.dart';
77
const _examplePath = 'avoid_returning_widgets/examples/example.dart';
88
const _notNamedParameterExamplePath =
99
'avoid_returning_widgets/examples/not_named_parameter_example.dart';
10+
const _providerExamplePath =
11+
'avoid_returning_widgets/examples/provider_example.dart';
1012

1113
void main() {
1214
group('AvoidReturningWidgetsRule', () {
@@ -113,5 +115,12 @@ void main() {
113115

114116
RuleTestHelper.verifyNoIssues(issues);
115117
});
118+
119+
test('reports no issues for providers', () async {
120+
final unit = await RuleTestHelper.resolveFromFile(_providerExamplePath);
121+
final issues = AvoidReturningWidgetsRule().check(unit);
122+
123+
RuleTestHelper.verifyNoIssues(issues);
124+
});
116125
});
117126
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
class MyWidget extends StatelessWidget {
2+
List<Provider> _getProvidersList() => [Provider()];
3+
4+
MultiProvider _getMultiProvider() => MultiProvider(providers: []);
5+
6+
@override
7+
Widget build(BuildContext context) {
8+
_getProvidersList();
9+
10+
_getMultiProvider();
11+
12+
return Container();
13+
}
14+
}
15+
16+
class StatelessWidget extends Widget {}
17+
18+
class Widget {}
19+
20+
class Container extends Widget {
21+
final Widget? child;
22+
23+
const Container({this.child});
24+
}
25+
26+
class MultiProvider {
27+
final List<Widget> providers;
28+
29+
const MultiProvider({required this.providers});
30+
}
31+
32+
class Provider<T> extends InheritedProvider<T> {
33+
final Widget? child;
34+
35+
const Provider(this.child);
36+
}
37+
38+
class InheritedProvider<T> extends Widget {}

0 commit comments

Comments
 (0)