Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Collection literals fixes #1430

Merged
merged 3 commits into from
Feb 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 37 additions & 10 deletions lib/src/rules/prefer_collection_literals.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,25 +66,52 @@ class _Visitor extends SimpleAstVisitor<void> {
final constructorName = node.constructorName.name?.name;

// Lists, Maps.
if (DartTypeUtilities.isClass(node.staticType, 'List', 'dart.core') ||
DartTypeUtilities.isClass(node.staticType, 'Map', 'dart.core') ||
DartTypeUtilities.isClass(
node.staticType, 'LinkedHashMap', 'dart.collection')) {
if (isList(node) || isMap(node) || isHashMap(node)) {
if (constructorName == null && node.argumentList.arguments.isEmpty) {
rule.reportLint(node);
}
return;
}

// Sets.
if (DartTypeUtilities.isClass(node.staticType, 'Set', 'dart.core') ||
DartTypeUtilities.isClass(
node.staticType, 'LinkedHashSet', 'dart.collection')) {
if (constructorName == null ||
constructorName == 'from' ||
constructorName == 'of') {
if (isSet(node) || isHashSet(node)) {
// Skip: LinkedHashSet<int> s = ...;
var parent = node.parent;
if (parent is VariableDeclaration) {
var parent2 = parent.parent;
if (parent2 is VariableDeclarationList) {
var assignmentType = parent2.type?.type;
if (assignmentType != null &&
!DartTypeUtilities.isClass(assignmentType, 'Set', 'dart.core')) {
return;
}
}
}

if (constructorName == null) {
rule.reportLint(node);
} else if (constructorName == 'from' || constructorName == 'of') {
var args = node.argumentList.arguments;
if (args.length != 1) {
return;
}
var arg = args.first;
if (arg is ListLiteral || arg is ListLiteral2) {
rule.reportLint(node);
}
}
}
}

// todo (pq): migrate to using typeProvider
bool isSet(Expression expression) =>
DartTypeUtilities.isClass(expression.staticType, 'Set', 'dart.core');
bool isHashSet(Expression expression) => DartTypeUtilities.isClass(
expression.staticType, 'LinkedHashSet', 'dart.collection');
bool isList(Expression expression) =>
DartTypeUtilities.isClass(expression.staticType, 'List', 'dart.core');
bool isMap(Expression expression) =>
DartTypeUtilities.isClass(expression.staticType, 'Map', 'dart.core');
bool isHashMap(Expression expression) => DartTypeUtilities.isClass(
expression.staticType, 'LinkedHashMap', 'dart.collection');
}
11 changes: 11 additions & 0 deletions test/mock_sdk.dart
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ class Iterator<E> {
}

abstract class Iterable<E> {
const Iterable();
const factory Iterable.empty() = Iterable;
Iterator<E> get iterator;
bool contains(Object element);
E firstWhere(bool test(E element), { E orElse()});
Expand All @@ -135,13 +137,19 @@ abstract class List<E> implements Iterable<E> {
int indexOf(Object element);
bool get isEmpty;
bool get isNotEmpty;
Set<E> toSet() => new Set<E>.from(this);
}

abstract class Map<K, V> extends Object {
/* external */ factory Map();
factory Map.from(Map other) = LinkedHashMap<K, V>.from;
factory Map.fromIterable(Iterable iterable,
{K key(element), V value(element)}) = LinkedHashMap<K, V>.fromIterable;
factory Map.fromIterables(Iterable<K> keys, Iterable<V> values) =
LinkedHashMap<K, V>.fromIterables;
factory Map.of(Map<K, V> other) = LinkedHashMap<K, V>.of;
factory Map.identity() = LinkedHashMap<K, V>.identity;
/* external */ factory Map.unmodifiable(Map other);
Iterable<K> get keys;
bool get isEmpty;
bool get isNotEmpty;
Expand Down Expand Up @@ -207,6 +215,9 @@ abstract class LinkedHashMap<K, V> implements Map<K, V> {
bool isValidKey(potentialKey)});
/* external */ factory LinkedHashMap.identity();
factory LinkedHashMap.from(Map other);
factory LinkedHashMap.fromIterable(Iterable iterable,
{K key(element), V value(element)});
factory LinkedHashMap.fromIterables(Iterable<K> keys, Iterable<V> values);
factory LinkedHashMap.of(Map<K, V> other) =>
new LinkedHashMap<K, V>()..addAll(other);
}
Expand Down
9 changes: 9 additions & 0 deletions test/rules/prefer_collection_literals.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,13 @@ void main() {
var ss2 = new LinkedHashSet(); // LINT
var ss3 = LinkedHashSet.from([]); // LINT
var ss4 = LinkedHashSet.of([]); // LINT

Set<int> ss5 = LinkedHashSet<int>(); // LINT
LinkedHashSet<int> ss6 = LinkedHashSet<int>(); // OK

Set<int> ss7 = LinkedHashSet.from([1, 2, 3]); // LINT
LinkedHashSet<int> ss8 = LinkedHashSet.from([1, 2, 3]); // OK

Iterable iter = Iterable.empty(); // OK
var sss = Set.from(iter); // OK
}