From 041eeae7c5489fe50d3fb36f9b91a64a818ed3e7 Mon Sep 17 00:00:00 2001 From: Alexandre Ardhuin Date: Tue, 17 May 2022 18:19:31 +0200 Subject: [PATCH] add unnecessary_to_list_in_spreads --- example/all.yaml | 1 + lib/src/rules.dart | 2 + .../rules/unnecessary_to_list_in_spreads.dart | 65 +++++++++++++++++++ .../rules/unnecessary_to_list_in_spreads.dart | 21 ++++++ 4 files changed, 89 insertions(+) create mode 100644 lib/src/rules/unnecessary_to_list_in_spreads.dart create mode 100644 test_data/rules/unnecessary_to_list_in_spreads.dart diff --git a/example/all.yaml b/example/all.yaml index 4d81d29c9..3791152e1 100644 --- a/example/all.yaml +++ b/example/all.yaml @@ -184,6 +184,7 @@ linter: - unnecessary_string_escapes - unnecessary_string_interpolations - unnecessary_this + - unnecessary_to_list_in_spreads - unrelated_type_equality_checks - unsafe_html - use_build_context_synchronously diff --git a/lib/src/rules.dart b/lib/src/rules.dart index 2d3102b50..0b1fadc73 100644 --- a/lib/src/rules.dart +++ b/lib/src/rules.dart @@ -188,6 +188,7 @@ import 'rules/unnecessary_statements.dart'; import 'rules/unnecessary_string_escapes.dart'; import 'rules/unnecessary_string_interpolations.dart'; import 'rules/unnecessary_this.dart'; +import 'rules/unnecessary_to_list_in_spreads.dart'; import 'rules/unrelated_type_equality_checks.dart'; import 'rules/unsafe_html.dart'; import 'rules/use_build_context_synchronously.dart'; @@ -401,6 +402,7 @@ void registerLintRules({bool inTestMode = false}) { ..register(UnnecessaryStringEscapes()) ..register(UnnecessaryStringInterpolations()) ..register(UnnecessaryThis()) + ..register(UnnecessaryToListInSpreads()) ..register(UnrelatedTypeEqualityChecks()) ..register(UnsafeHtml()) ..register(UseBuildContextSynchronously(inTestMode: inTestMode)) diff --git a/lib/src/rules/unnecessary_to_list_in_spreads.dart b/lib/src/rules/unnecessary_to_list_in_spreads.dart new file mode 100644 index 000000000..4ffa5620b --- /dev/null +++ b/lib/src/rules/unnecessary_to_list_in_spreads.dart @@ -0,0 +1,65 @@ +// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:analyzer/dart/ast/visitor.dart'; + +import '../analyzer.dart'; +import '../util/dart_type_utilities.dart'; + +const _desc = r'Unnecessary toList() in spreads.'; + +const _details = r''' + +Unnecessary `toList()` in spreads. + +**BAD:** +```dart +children: [ + ...['foo', 'bar', 'baz'].map((String s) => Text(s)).toList(), +] +``` + +**GOOD:** +```dart +children: [ + ...['foo', 'bar', 'baz'].map((String s) => Text(s)), +] +``` + +'''; + +class UnnecessaryToListInSpreads extends LintRule { + UnnecessaryToListInSpreads() + : super( + name: 'unnecessary_to_list_in_spreads', + description: _desc, + details: _details, + group: Group.style, + ); + + @override + void registerNodeProcessors( + NodeLintRegistry registry, LinterContext context) { + var visitor = _Visitor(this); + registry.addSpreadElement(this, visitor); + } +} + +class _Visitor extends SimpleAstVisitor { + final LintRule rule; + + _Visitor(this.rule); + + @override + void visitSpreadElement(SpreadElement node) { + var expression = node.expression; + if (expression is MethodInvocation && + expression.methodName.name == 'toList' && + DartTypeUtilities.implementsInterface( + expression.target?.staticType, 'Iterable', 'dart.core')) { + rule.reportLint(expression.methodName); + } + } +} diff --git a/test_data/rules/unnecessary_to_list_in_spreads.dart b/test_data/rules/unnecessary_to_list_in_spreads.dart new file mode 100644 index 000000000..8d7c0e994 --- /dev/null +++ b/test_data/rules/unnecessary_to_list_in_spreads.dart @@ -0,0 +1,21 @@ +// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// test w/ `dart test -N unnecessary_to_list_in_spreads` + +var t1 = [ + ...[1, 2].toList(), // LINT +]; +var t2 = [ + ...{1, 2}.toList(), // LINT +]; +var t3 = [ + ...?[1, 2].toList(), // LINT +]; +var t4 = [ + ...?{1, 2}.toList(), // LINT +]; +var t5 = [ + ...[1, 2].whereType().toList(), // LINT +];