This repository was archived by the owner on Jul 16, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 271
feat: add static code diagnostic prefer-using-list-view
#1088
Merged
incendial
merged 2 commits into
dart-code-checker:master
from
lsaudon:prefer-using-list-view
Dec 5, 2022
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
49 changes: 49 additions & 0 deletions
49
...rs/lint_analyzer/rules/rules_list/prefer_using_list_view/prefer_using_list_view_rule.dart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// ignore_for_file: public_member_api_docs | ||
|
||
import 'package:analyzer/dart/ast/ast.dart'; | ||
import 'package:analyzer/dart/ast/visitor.dart'; | ||
import 'package:collection/collection.dart'; | ||
|
||
import '../../../../../utils/flutter_types_utils.dart'; | ||
import '../../../../../utils/node_utils.dart'; | ||
import '../../../lint_utils.dart'; | ||
import '../../../models/internal_resolved_unit_result.dart'; | ||
import '../../../models/issue.dart'; | ||
import '../../../models/severity.dart'; | ||
import '../../models/flutter_rule.dart'; | ||
import '../../rule_utils.dart'; | ||
|
||
part 'visitor.dart'; | ||
|
||
class PreferUsingListViewRule extends FlutterRule { | ||
static const String ruleId = 'prefer-using-list-view'; | ||
|
||
static const _warning = | ||
'Preferred to use ListView instead of the combo SingleChildScrollView and Column.'; | ||
|
||
PreferUsingListViewRule([Map<String, Object> config = const {}]) | ||
: super( | ||
id: ruleId, | ||
severity: readSeverity(config, Severity.performance), | ||
excludes: readExcludes(config), | ||
includes: readIncludes(config), | ||
); | ||
|
||
@override | ||
Iterable<Issue> check(InternalResolvedUnitResult source) { | ||
final visitor = _Visitor(); | ||
|
||
source.unit.visitChildren(visitor); | ||
|
||
return visitor.expressions | ||
.map((expression) => createIssue( | ||
rule: this, | ||
location: nodeLocation( | ||
node: expression, | ||
source: source, | ||
), | ||
message: _warning, | ||
)) | ||
.toList(growable: false); | ||
} | ||
} |
38 changes: 38 additions & 0 deletions
38
lib/src/analyzers/lint_analyzer/rules/rules_list/prefer_using_list_view/visitor.dart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
part of 'prefer_using_list_view_rule.dart'; | ||
|
||
class _Visitor extends RecursiveAstVisitor<void> { | ||
final _expressions = <Expression>[]; | ||
|
||
Iterable<Expression> get expressions => _expressions; | ||
|
||
@override | ||
void visitInstanceCreationExpression(InstanceCreationExpression node) { | ||
super.visitInstanceCreationExpression(node); | ||
|
||
if (isSingleChildScrollViewWidget(node.staticType) && | ||
_hasColumnChild(node)) { | ||
_expressions.add(node); | ||
} | ||
} | ||
|
||
bool _hasColumnChild(InstanceCreationExpression node) { | ||
final child = node.argumentList.arguments.firstWhereOrNull( | ||
(arg) => arg is NamedExpression && arg.name.label.name == 'child', | ||
); | ||
|
||
if (child != null && child is NamedExpression) { | ||
final expression = child.expression; | ||
|
||
if (expression is InstanceCreationExpression && | ||
isColumnWidget(expression.staticType)) { | ||
final notChildren = expression.argumentList.arguments.firstWhereOrNull( | ||
(arg) => arg is NamedExpression && arg.name.label.name != 'children', | ||
); | ||
|
||
return notChildren == null; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
...src/analyzers/lint_analyzer/rules/rules_list/prefer_using_list_view/examples/example.dart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import 'package:flutter/material.dart'; | ||
|
||
void main() { | ||
runApp(MyApp()); | ||
} | ||
|
||
class MyApp extends StatelessWidget { | ||
@override | ||
Widget build(BuildContext context) { | ||
// LINT | ||
return SingleChildScrollView( | ||
child: Column( | ||
children: [ | ||
Text('Wow lint rule'), | ||
Text('Wow another lint rule'), | ||
], | ||
), | ||
); | ||
} | ||
} | ||
|
||
class MyApp extends StatelessWidget { | ||
@override | ||
Widget build(BuildContext context) { | ||
return SingleChildScrollView( | ||
child: Column( | ||
crossAxisAlignment: CrossAxisAlignment.start, | ||
children: [ | ||
Text('Wow lint rule'), | ||
Text('Wow another lint rule'), | ||
], | ||
), | ||
); | ||
} | ||
} | ||
|
||
class MyApp extends StatelessWidget { | ||
@override | ||
Widget build(BuildContext context) { | ||
return SingleChildScrollView( | ||
child: Column( | ||
mainAxisAlignment: MainAxisAlignment.start, | ||
children: [ | ||
Text('Wow lint rule'), | ||
Text('Wow another lint rule'), | ||
], | ||
), | ||
); | ||
} | ||
} | ||
|
||
class MyApp extends StatelessWidget { | ||
@override | ||
Widget build(BuildContext context) { | ||
return MaterialApp( | ||
home: Scaffold( | ||
body: SingleChildScrollView( | ||
child: Text(), | ||
), | ||
), | ||
); | ||
} | ||
} | ||
|
||
class SingleChildScrollView {} | ||
|
||
class Column {} |
39 changes: 39 additions & 0 deletions
39
...nt_analyzer/rules/rules_list/prefer_using_list_view/prefer_using_list_view_rule_test.dart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import 'package:dart_code_metrics/src/analyzers/lint_analyzer/models/severity.dart'; | ||
import 'package:dart_code_metrics/src/analyzers/lint_analyzer/rules/rules_list/prefer_using_list_view/prefer_using_list_view_rule.dart'; | ||
import 'package:test/test.dart'; | ||
|
||
import '../../../../../helpers/rule_test_helper.dart'; | ||
|
||
const _examplePath = 'prefer_using_list_view/examples/example.dart'; | ||
|
||
void main() { | ||
group( | ||
'PreferUsingListViewRule', | ||
() { | ||
test('initialization', () async { | ||
final unit = await RuleTestHelper.resolveFromFile(_examplePath); | ||
final issues = PreferUsingListViewRule().check(unit); | ||
|
||
RuleTestHelper.verifyInitialization( | ||
issues: issues, | ||
ruleId: 'prefer-using-list-view', | ||
severity: Severity.performance, | ||
); | ||
}); | ||
|
||
test('reports about found issues', () async { | ||
final unit = await RuleTestHelper.resolveFromFile(_examplePath); | ||
final issues = PreferUsingListViewRule().check(unit); | ||
|
||
RuleTestHelper.verifyIssues( | ||
issues: issues, | ||
startLines: [11], | ||
startColumns: [12], | ||
messages: [ | ||
'Preferred to use ListView instead of the combo SingleChildScrollView and Column.', | ||
], | ||
); | ||
}); | ||
}, | ||
); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import RuleDetails from '@site/src/components/RuleDetails'; | ||
|
||
<RuleDetails version="5.2.0" severity="performance" /> | ||
|
||
Warns when a `Column` widget with only `children` parameter is wrapped in a `SingleChildScrollView` widget. | ||
|
||
Additional resources: | ||
|
||
- <https://stackoverflow.com/a/62147092> | ||
|
||
### Example {#example} | ||
|
||
**❌ Bad:** | ||
|
||
```dart | ||
SingleChildScrollView( | ||
child: Column( | ||
children: [ | ||
Text('Wow lint rule'), | ||
Text('Wow another lint rule'), | ||
], | ||
), | ||
), | ||
``` | ||
|
||
**✅ Good:** | ||
|
||
```dart | ||
ListView( | ||
children: [ | ||
Text('Wow lint rule'), | ||
Text('Wow another lint rule'), | ||
], | ||
), | ||
``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.