105 lines
3.2 KiB
Plaintext
105 lines
3.2 KiB
Plaintext
Chaining list(s) to a list literal via https://api.dart.dev/stable/dart-core/List/addAll.html[`List<E>.addAll`] should be replaced by a literal with the https://dart.dev/language/operators#spread-operators[spread operator] (``++...++``).
|
|
|
|
== Why is this an issue?
|
|
|
|
Chaining list(s) to a list literal via `addAll`, e.g. ``++[42]..addAll(l1)..addAll(l1);++``, is both less efficient and less verbose than using a list literal with the spread operator: ``++[42, ...l1, ...l1]++``.
|
|
|
|
* `addAll` chains can be less efficient because each `addAll` call is treated as a separate method call, resulting in unnecessary invocations and allocations, when the goal is to build a single list with all the items provided as arguments
|
|
* `addAll` chains are generally more verbose and less clear because spreading a list can be done via dedicate syntax (``++...++``) which is closer to natural language
|
|
|
|
The rule also applies when the chained list is a https://dart.dev/language/operators#conditional-expressions[conditional expression], because the spread operator can be applied conditionally:
|
|
|
|
[source,dart]
|
|
----
|
|
[42]..addAll(i1 == i2 ? [43, 44] : []); // Noncompliant
|
|
[42, if (i1 == i2) ...[43, 44]]; // Compliant
|
|
----
|
|
|
|
=== Exceptions
|
|
|
|
The rule doesn't apply when the list chained is a literal, because S7089 already covers this case.
|
|
|
|
[source,dart]
|
|
----
|
|
[]..addAll([42]); // Not applicable
|
|
----
|
|
|
|
The rule doesn't cover https://dart.dev/language/collections#control-flow-operators[if and for collections] either, for the same reason (S7089 covers it).
|
|
|
|
[source,dart]
|
|
----
|
|
[42]..addAll([if (i1 == 42) 43, 44]); // Not applicable
|
|
[42]..addAll([for (final i in [1, 2, 3]) i * i]); // Not applicable
|
|
----
|
|
|
|
The rule doesn't apply when the `addAll` is not called via cascade operator, but via standard dereference (`.`):
|
|
|
|
[source,dart]
|
|
----
|
|
[].addAll(l1); // Not applicable
|
|
[]..addAll(l1); // Noncompliant
|
|
----
|
|
|
|
== How to fix it
|
|
|
|
Take advantage of the spread operator and, if needed, of its capacity to be applied conditionally.
|
|
|
|
=== Code examples
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,dart,diff-id=1,diff-type=noncompliant]
|
|
----
|
|
[42]..addAll(aList)..addAll(anotherList);
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,dart,diff-id=1,diff-type=compliant]
|
|
----
|
|
[42, ...aList, ...anotherList];
|
|
----
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,dart,diff-id=2,diff-type=noncompliant]
|
|
----
|
|
[42]..addAll(i1 == i2 ? [43, 44] : []);
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,dart,diff-id=2,diff-type=compliant]
|
|
----
|
|
[42, if (i1 == i2) ...[43, 44]];
|
|
----
|
|
|
|
== Resources
|
|
|
|
=== Documentation
|
|
|
|
* Dart Docs - https://dart.dev/tools/linter-rules/prefer_spread_collections[Dart Linter rule - prefer_spread_collections]
|
|
* Dart Docs - https://dart.dev/language/operators#spread-operators[Language - Spread operators]
|
|
* Dart API Reference - https://api.dart.dev/stable/dart-core/List/addAll.html[`List<E>.addAll`]
|
|
|
|
=== Related rules
|
|
|
|
* S3257 - Collection literals should be preferred
|
|
* S7089 - Inline list literals should be preferred to chains of insertions
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
|
|
'''
|
|
== Implementation Specification
|
|
(visible only on this page)
|
|
|
|
=== Message
|
|
|
|
The addition of multiple elements could be inlined.
|
|
|
|
=== Highlighting
|
|
|
|
The first method invocation in the chain of `addAll` invocations.
|
|
|
|
endif::env-github,rspecator-view[]
|