Version 2.12.0-185.0.dev
Merge commit 'd407e16cff550aab55004bdd0fd53a76ce290c49' into 'dev'
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_parentheses.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_parentheses.dart
new file mode 100644
index 0000000..b3d860c
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_unnecessary_parentheses.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2021, 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/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
+
+class RemoveUnnecessaryParentheses extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_UNNECESSARY_PARENTHESES;
+
+ @override
+ Future<void> compute(ChangeBuilder builder) async {
+ var outer = coveredNode;
+ if (outer is ParenthesizedExpression &&
+ outer.parent is! ParenthesizedExpression) {
+ await builder.addDartFileEdit(file, (builder) {
+ builder.addDeletion(range.token(outer.leftParenthesis));
+ builder.addDeletion(range.token(outer.rightParenthesis));
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static RemoveUnnecessaryParentheses newInstance() =>
+ RemoveUnnecessaryParentheses();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 67f5bed..ec4fa0c 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -400,6 +400,11 @@
'Remove unnecessary const keyword');
static const REMOVE_UNNECESSARY_NEW = FixKind(
'dart.fix.remove.unnecessaryNew', 50, 'Remove unnecessary new keyword');
+ static const REMOVE_UNNECESSARY_PARENTHESES = FixKind(
+ 'dart.fix.remove.unnecessaryParentheses',
+ 50,
+ 'Remove unnecessary parentheses',
+ appliedTogetherMessage: 'Remove all unnecessary parentheses in file');
static const REMOVE_UNUSED_CATCH_CLAUSE = FixKind(
'dart.fix.remove.unusedCatchClause', 50, "Remove unused 'catch' clause");
static const REMOVE_UNUSED_CATCH_STACK = FixKind(
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index e240962..832147a 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -111,6 +111,7 @@
import 'package:analysis_server/src/services/correction/dart/remove_type_arguments.dart';
import 'package:analysis_server/src/services/correction/dart/remove_unnecessary_cast.dart';
import 'package:analysis_server/src/services/correction/dart/remove_unnecessary_new.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_unnecessary_parentheses.dart';
import 'package:analysis_server/src/services/correction/dart/remove_unused.dart';
import 'package:analysis_server/src/services/correction/dart/remove_unused_catch_clause.dart';
import 'package:analysis_server/src/services/correction/dart/remove_unused_catch_stack.dart';
@@ -478,6 +479,9 @@
LintNames.unnecessary_overrides: [
RemoveMethodDeclaration.newInstance,
],
+ LintNames.unnecessary_parenthesis: [
+ RemoveUnnecessaryParentheses.newInstance,
+ ],
LintNames.unnecessary_this: [
RemoveThisExpression.newInstance,
],
diff --git a/pkg/analysis_server/lib/src/services/linter/lint_names.dart b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
index c291cc2..48910dc 100644
--- a/pkg/analysis_server/lib/src/services/linter/lint_names.dart
+++ b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
@@ -95,6 +95,7 @@
static const String unnecessary_null_in_if_null_operators =
'unnecessary_null_in_if_null_operators';
static const String unnecessary_overrides = 'unnecessary_overrides';
+ static const String unnecessary_parenthesis = 'unnecessary_parenthesis';
static const String unnecessary_this = 'unnecessary_this';
static const String use_full_hex_values_for_flutter_colors =
'use_full_hex_values_for_flutter_colors';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
index 46ff4d4..70b6a66 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
@@ -31,6 +31,19 @@
/// Return the lint code being tested.
String get lintCode;
+ /// Return the [LintCode] for the [lintCode] (which is actually a name).
+ Future<LintCode> lintCodeByName(String name) async {
+ var errors = await _computeErrors();
+ var lintCodeSet = errors
+ .map((error) => error.errorCode)
+ .where((errorCode) => errorCode.name == name)
+ .toSet();
+ if (lintCodeSet.length != 1) {
+ fail('Expected exactly one LintCode, actually: $lintCodeSet');
+ }
+ return lintCodeSet.single;
+ }
+
bool Function(AnalysisError) lintNameFilter(String name) {
return (e) {
return e.errorCode is LintCode && e.errorCode.name == name;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_parentheses_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_parentheses_test.dart
new file mode 100644
index 0000000..206e56f
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_parentheses_test.dart
@@ -0,0 +1,78 @@
+// Copyright (c) 2021, 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/correction/fix.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveUnnecessaryParenthesesTest);
+ });
+}
+
+@reflectiveTest
+class RemoveUnnecessaryParenthesesTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_UNNECESSARY_PARENTHESES;
+
+ @override
+ String get lintCode => LintNames.unnecessary_parenthesis;
+
+ Future<void> test_all() async {
+ await resolveTestCode('''
+void f() {
+ (1);
+ (22);
+ (333);
+}
+''');
+ var lintCode = await lintCodeByName(this.lintCode);
+ await assertHasFixAllFix(lintCode, '''
+void f() {
+ 1;
+ 22;
+ 333;
+}
+''');
+ }
+
+ Future<void> test_double_atInner() async {
+ await resolveTestCode('''
+void f() {
+ ((42));
+}
+''');
+ await assertNoFix(errorFilter: (e) => e.offset == 14);
+ }
+
+ Future<void> test_double_atOuter() async {
+ await resolveTestCode('''
+void f() {
+ ((42));
+}
+''');
+ await assertHasFix('''
+void f() {
+ (42);
+}
+''', errorFilter: (e) => e.offset == 13);
+ }
+
+ Future<void> test_single() async {
+ await resolveTestCode('''
+void f() {
+ (42);
+}
+''');
+ await assertHasFix('''
+void f() {
+ 42;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
index 6b82811..fc73623 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -128,6 +128,8 @@
import 'remove_unnecessary_cast_test.dart' as remove_unnecessary_cast;
import 'remove_unnecessary_const_test.dart' as remove_unnecessary_const;
import 'remove_unnecessary_new_test.dart' as remove_unnecessary_new;
+import 'remove_unnecessary_parentheses_test.dart'
+ as remove_unnecessary_parentheses;
import 'remove_unused_catch_clause_test.dart' as remove_unused_catch_clause;
import 'remove_unused_catch_stack_test.dart' as remove_unused_catch_stack;
import 'remove_unused_element_test.dart' as remove_unused_element;
@@ -283,6 +285,7 @@
remove_unnecessary_cast.main();
remove_unnecessary_const.main();
remove_unnecessary_new.main();
+ remove_unnecessary_parentheses.main();
remove_unused_catch_clause.main();
remove_unused_catch_stack.main();
remove_unused_element.main();
diff --git a/tools/VERSION b/tools/VERSION
index f4ded95..e708aa8 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 12
PATCH 0
-PRERELEASE 184
+PRERELEASE 185
PRERELEASE_PATCH 0
\ No newline at end of file