bulk fix for `prefer_collection_literals`
Change-Id: Idc83fdc00296388f9e7b0eb35ae4d195577906ef
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/164401
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Phil Quitslund <pquitslund@google.com>
diff --git a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
index ac0d56c..78b882b 100644
--- a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
@@ -20,8 +20,11 @@
import 'package:analysis_server/src/services/correction/dart/convert_to_generic_function_syntax.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_if_null.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_int_literal.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_list_literal.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_map_literal.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_null_aware.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_relative_import.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_set_literal.dart';
import 'package:analysis_server/src/services/correction/dart/convert_to_where_type.dart';
import 'package:analysis_server/src/services/correction/dart/create_method.dart';
import 'package:analysis_server/src/services/correction/dart/make_final.dart';
@@ -63,70 +66,167 @@
/// A fix producer that produces changes to fix multiple diagnostics.
class BulkFixProcessor {
- /// A map from the name of a lint rule to a generator used to create the
- /// correction producer used to build a fix for that diagnostic. The
- /// generators used for non-lint diagnostics are in the [nonLintProducerMap].
- static const Map<String, ProducerGenerator> lintProducerMap = {
- LintNames.annotate_overrides: AddOverride.newInstance,
- LintNames.avoid_annotating_with_dynamic: RemoveTypeAnnotation.newInstance,
- LintNames.avoid_empty_else: RemoveEmptyElse.newInstance,
- LintNames.avoid_init_to_null: RemoveInitializer.newInstance,
- LintNames.avoid_redundant_argument_values: RemoveArgument.newInstance,
- LintNames.avoid_return_types_on_setters: RemoveTypeAnnotation.newInstance,
- LintNames.avoid_single_cascade_in_expression_statements:
- ReplaceCascadeWithDot.newInstance,
- LintNames.avoid_types_on_closure_parameters:
- RemoveTypeAnnotation.newInstance,
- LintNames.await_only_futures: RemoveAwait.newInstance,
- LintNames.curly_braces_in_flow_control_structures:
- UseCurlyBraces.newInstance,
- LintNames.diagnostic_describe_all_properties:
- AddDiagnosticPropertyReference.newInstance,
- LintNames.empty_catches: RemoveEmptyCatch.newInstance,
- LintNames.empty_constructor_bodies: RemoveEmptyConstructorBody.newInstance,
- LintNames.empty_statements: RemoveEmptyStatement.newInstance,
- LintNames.hash_and_equals: CreateMethod.equalsOrHashCode,
- LintNames.no_duplicate_case_values: RemoveDuplicateCase.newInstance,
- LintNames.non_constant_identifier_names: RenameToCamelCase.newInstance,
- LintNames.null_closures: ReplaceNullWithClosure.newInstance,
- LintNames.omit_local_variable_types: ReplaceWithVar.newInstance,
- LintNames.prefer_adjacent_string_concatenation: RemoveOperator.newInstance,
- LintNames.prefer_conditional_assignment:
- ReplaceWithConditionalAssignment.newInstance,
- LintNames.prefer_const_constructors_in_immutables: AddConst.newInstance,
- LintNames.prefer_const_declarations: ReplaceFinalWithConst.newInstance,
- LintNames.prefer_contains: ConvertToContains.newInstance,
- LintNames.prefer_equal_for_default_values:
- ReplaceColonWithEquals.newInstance,
- LintNames.prefer_final_fields: MakeFinal.newInstance,
- LintNames.prefer_final_locals: MakeFinal.newInstance,
- LintNames.prefer_for_elements_to_map_fromIterable:
- ConvertMapFromIterableToForLiteral.newInstance,
- LintNames.prefer_generic_function_type_aliases:
- ConvertToGenericFunctionSyntax.newInstance,
- LintNames.prefer_if_elements_to_conditional_expressions:
- ConvertConditionalExpressionToIfElement.newInstance,
- LintNames.prefer_if_null_operators: ConvertToIfNull.newInstance,
- LintNames.prefer_int_literals: ConvertToIntLiteral.newInstance,
- LintNames.prefer_is_empty: ReplaceWithIsEmpty.newInstance,
- LintNames.prefer_is_not_empty: UesIsNotEmpty.newInstance,
- LintNames.prefer_iterable_whereType: ConvertToWhereType.newInstance,
- LintNames.prefer_null_aware_operators: ConvertToNullAware.newInstance,
- LintNames.prefer_relative_imports: ConvertToRelativeImport.newInstance,
- LintNames.prefer_single_quotes: ConvertToSingleQuotes.newInstance,
- LintNames.prefer_spread_collections: ConvertAddAllToSpread.newInstance,
- LintNames.slash_for_doc_comments: ConvertDocumentationIntoLine.newInstance,
- LintNames.sort_child_properties_last: SortChildPropertyLast.newInstance,
- LintNames.type_init_formals: RemoveTypeAnnotation.newInstance,
- LintNames.unawaited_futures: AddAwait.newInstance,
- LintNames.unnecessary_brace_in_string_interps:
- RemoveInterpolationBraces.newInstance,
- LintNames.unnecessary_const: RemoveUnnecessaryConst.newInstance,
- LintNames.unnecessary_lambdas: ReplaceWithTearOff.newInstance,
- LintNames.unnecessary_new: RemoveUnnecessaryNew.newInstance,
- LintNames.unnecessary_overrides: RemoveMethodDeclaration.newInstance,
- LintNames.unnecessary_this: RemoveThisExpression.newInstance,
- LintNames.use_rethrow_when_possible: UseRethrow.newInstance,
+ /// A map from the name of a lint rule to a list of generators used to create
+ /// the correction producer used to build a fix for that diagnostic. Most
+ /// entries will have only one generator. In cases where there is more than
+ /// one, they will be applied in series and the expectation is that only one
+ /// will produce a change for a given fix. If more than one change is produced
+ /// the result will almost certainly be invalid code. The generators used for
+ /// non-lint diagnostics are in the [nonLintProducerMap].
+ static const Map<String, List<ProducerGenerator>> lintProducerMap = {
+ LintNames.annotate_overrides: [
+ AddOverride.newInstance,
+ ],
+ LintNames.avoid_annotating_with_dynamic: [
+ RemoveTypeAnnotation.newInstance,
+ ],
+ LintNames.avoid_empty_else: [
+ RemoveEmptyElse.newInstance,
+ ],
+ LintNames.avoid_init_to_null: [
+ RemoveInitializer.newInstance,
+ ],
+ LintNames.avoid_redundant_argument_values: [
+ RemoveArgument.newInstance,
+ ],
+ LintNames.avoid_return_types_on_setters: [
+ RemoveTypeAnnotation.newInstance,
+ ],
+ LintNames.avoid_single_cascade_in_expression_statements: [
+ ReplaceCascadeWithDot.newInstance,
+ ],
+ LintNames.avoid_types_on_closure_parameters: [
+ RemoveTypeAnnotation.newInstance,
+ ],
+ LintNames.await_only_futures: [
+ RemoveAwait.newInstance,
+ ],
+ LintNames.curly_braces_in_flow_control_structures: [
+ UseCurlyBraces.newInstance,
+ ],
+ LintNames.diagnostic_describe_all_properties: [
+ AddDiagnosticPropertyReference.newInstance,
+ ],
+ LintNames.empty_catches: [
+ RemoveEmptyCatch.newInstance,
+ ],
+ LintNames.empty_constructor_bodies: [
+ RemoveEmptyConstructorBody.newInstance,
+ ],
+ LintNames.empty_statements: [
+ RemoveEmptyStatement.newInstance,
+ ],
+ LintNames.hash_and_equals: [CreateMethod.equalsOrHashCode],
+ LintNames.no_duplicate_case_values: [
+ RemoveDuplicateCase.newInstance,
+ ],
+ LintNames.non_constant_identifier_names: [
+ RenameToCamelCase.newInstance,
+ ],
+ LintNames.null_closures: [
+ ReplaceNullWithClosure.newInstance,
+ ],
+ LintNames.omit_local_variable_types: [
+ ReplaceWithVar.newInstance,
+ ],
+ LintNames.prefer_adjacent_string_concatenation: [
+ RemoveOperator.newInstance,
+ ],
+ LintNames.prefer_collection_literals: [
+ ConvertToListLiteral.newInstance,
+ ConvertToMapLiteral.newInstance,
+ ConvertToSetLiteral.newInstance,
+ ],
+ LintNames.prefer_conditional_assignment: [
+ ReplaceWithConditionalAssignment.newInstance,
+ ],
+ LintNames.prefer_const_constructors_in_immutables: [
+ AddConst.newInstance,
+ ],
+ LintNames.prefer_const_declarations: [
+ ReplaceFinalWithConst.newInstance,
+ ],
+ LintNames.prefer_contains: [
+ ConvertToContains.newInstance,
+ ],
+ LintNames.prefer_equal_for_default_values: [
+ ReplaceColonWithEquals.newInstance,
+ ],
+ LintNames.prefer_final_fields: [
+ MakeFinal.newInstance,
+ ],
+ LintNames.prefer_final_locals: [
+ MakeFinal.newInstance,
+ ],
+ LintNames.prefer_for_elements_to_map_fromIterable: [
+ ConvertMapFromIterableToForLiteral.newInstance,
+ ],
+ LintNames.prefer_generic_function_type_aliases: [
+ ConvertToGenericFunctionSyntax.newInstance,
+ ],
+ LintNames.prefer_if_elements_to_conditional_expressions: [
+ ConvertConditionalExpressionToIfElement.newInstance,
+ ],
+ LintNames.prefer_if_null_operators: [
+ ConvertToIfNull.newInstance,
+ ],
+ LintNames.prefer_int_literals: [
+ ConvertToIntLiteral.newInstance,
+ ],
+ LintNames.prefer_is_empty: [
+ ReplaceWithIsEmpty.newInstance,
+ ],
+ LintNames.prefer_is_not_empty: [
+ UesIsNotEmpty.newInstance,
+ ],
+ LintNames.prefer_iterable_whereType: [
+ ConvertToWhereType.newInstance,
+ ],
+ LintNames.prefer_null_aware_operators: [
+ ConvertToNullAware.newInstance,
+ ],
+ LintNames.prefer_relative_imports: [
+ ConvertToRelativeImport.newInstance,
+ ],
+ LintNames.prefer_single_quotes: [
+ ConvertToSingleQuotes.newInstance,
+ ],
+ LintNames.prefer_spread_collections: [
+ ConvertAddAllToSpread.newInstance,
+ ],
+ LintNames.slash_for_doc_comments: [
+ ConvertDocumentationIntoLine.newInstance,
+ ],
+ LintNames.sort_child_properties_last: [
+ SortChildPropertyLast.newInstance,
+ ],
+ LintNames.type_init_formals: [
+ RemoveTypeAnnotation.newInstance,
+ ],
+ LintNames.unawaited_futures: [
+ AddAwait.newInstance,
+ ],
+ LintNames.unnecessary_brace_in_string_interps: [
+ RemoveInterpolationBraces.newInstance,
+ ],
+ LintNames.unnecessary_const: [
+ RemoveUnnecessaryConst.newInstance,
+ ],
+ LintNames.unnecessary_lambdas: [
+ ReplaceWithTearOff.newInstance,
+ ],
+ LintNames.unnecessary_new: [
+ RemoveUnnecessaryNew.newInstance,
+ ],
+ LintNames.unnecessary_overrides: [
+ RemoveMethodDeclaration.newInstance,
+ ],
+ LintNames.unnecessary_this: [
+ RemoveThisExpression.newInstance,
+ ],
+ LintNames.use_rethrow_when_possible: [
+ UseRethrow.newInstance,
+ ],
};
/// A map from an error code to a generator used to create the correction
@@ -190,9 +290,11 @@
var errorCode = error.errorCode;
if (errorCode is LintCode) {
- var generator = lintProducerMap[errorCode.name];
- if (generator != null) {
- await compute(generator());
+ var generators = lintProducerMap[errorCode.name];
+ if (generators != null) {
+ for (var generator in generators) {
+ await compute(generator());
+ }
}
} else {
var generator = nonLintProducerMap[errorCode];
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_list_literal_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_list_literal_test.dart
new file mode 100644
index 0000000..8810f14
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_list_literal_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2020, 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:analysis_server/src/services/linter/lint_names.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'bulk_fix_processor.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertToListLiteralTest);
+ });
+}
+
+@reflectiveTest
+class ConvertToListLiteralTest extends BulkFixProcessorTest {
+ @override
+ String get lintCode => LintNames.prefer_collection_literals;
+
+ Future<void> test_singleFile() async {
+ await resolveTestUnit('''
+List l = List();
+var l2 = List<int>();
+''');
+ await assertHasFix('''
+List l = [];
+var l2 = <int>[];
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_map_literal_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_map_literal_test.dart
new file mode 100644
index 0000000..066755e
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_map_literal_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2020, 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:analysis_server/src/services/linter/lint_names.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'bulk_fix_processor.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertToMapLiteralTest);
+ });
+}
+
+@reflectiveTest
+class ConvertToMapLiteralTest extends BulkFixProcessorTest {
+ @override
+ String get lintCode => LintNames.prefer_collection_literals;
+
+ Future<void> test_singleFile() async {
+ await resolveTestUnit('''
+Map m = Map();
+var m2 = Map<String, int>();
+''');
+ await assertHasFix('''
+Map m = {};
+var m2 = <String, int>{};
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_set_literal_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_set_literal_test.dart
new file mode 100644
index 0000000..526e697
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/convert_to_set_literal_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2020, 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:analysis_server/src/services/linter/lint_names.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'bulk_fix_processor.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertToSetLiteralTest);
+ });
+}
+
+@reflectiveTest
+class ConvertToSetLiteralTest extends BulkFixProcessorTest {
+ @override
+ String get lintCode => LintNames.prefer_collection_literals;
+
+ Future<void> test_singleFile() async {
+ await resolveTestUnit('''
+Set s = Set();
+var s1 = Set<int>();
+''');
+ await assertHasFix('''
+Set s = {};
+var s1 = <int>{};
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
index 4d7e35b..fd34894 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
@@ -19,8 +19,11 @@
import 'convert_to_if_element_test.dart' as convert_to_if_element;
import 'convert_to_if_null_test.dart' as convert_to_if_null;
import 'convert_to_int_literal_test.dart' as convert_to_int_literal;
+import 'convert_to_list_literal_test.dart' as convert_to_list_literal;
+import 'convert_to_map_literal_test.dart' as convert_to_map_literal;
import 'convert_to_null_aware_test.dart' as convert_to_null_aware;
import 'convert_to_relative_import_test.dart' as convert_to_relative_import;
+import 'convert_to_set_literal_test.dart' as convert_to_set_literal;
import 'convert_to_single_quoted_strings_test.dart'
as convert_to_single_quoted_strings;
import 'convert_to_spread_test.dart' as convert_to_spread;
@@ -70,8 +73,11 @@
convert_to_if_element.main();
convert_to_if_null.main();
convert_to_int_literal.main();
+ convert_to_list_literal.main();
+ convert_to_map_literal.main();
convert_to_null_aware.main();
convert_to_relative_import.main();
+ convert_to_set_literal.main();
convert_to_single_quoted_strings.main();
convert_to_spread.main();
convert_to_where_type.main();