Version 2.14.0-299.0.dev
Merge commit '72d8a215e715b5373bcdddf5f6e384a031f602c6' into 'dev'
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/flutter_remove_widget.dart b/pkg/analysis_server/lib/src/services/correction/dart/flutter_remove_widget.dart
index 9818245..596a3f5 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/flutter_remove_widget.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/flutter_remove_widget.dart
@@ -4,15 +4,30 @@
import 'package:analysis_server/src/services/correction/assist.dart';
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/assist/assist.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 FlutterRemoveWidget extends CorrectionProducer {
@override
AssistKind get assistKind => DartAssistKind.FLUTTER_REMOVE_WIDGET;
+ /// todo(pq): find out why overlapping edits are not being applied (and enable)
+ @override
+ bool get canBeAppliedInBulk => false;
+
+ @override
+ bool get canBeAppliedToFile => false;
+
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_UNNECESSARY_CONTAINER;
+
+ @override
+ FixKind? get multiFixKind => DartFixKind.REMOVE_UNNECESSARY_CONTAINER_MULTI;
+
@override
Future<void> compute(ChangeBuilder builder) async {
var widgetCreation = flutter.identifyNewExpression(node);
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_container_with_sized_box.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_container_with_sized_box.dart
new file mode 100644
index 0000000..08c9126
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_container_with_sized_box.dart
@@ -0,0 +1,39 @@
+// 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/error/error.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 ReplaceContainerWithSizedBox extends CorrectionProducer {
+ @override
+ bool get canBeAppliedInBulk => true;
+
+ @override
+ bool get canBeAppliedToFile => true;
+
+ @override
+ FixKind get fixKind => DartFixKind.REPLACE_CONTAINER_WITH_SIZED_BOX;
+
+ @override
+ FixKind? get multiFixKind =>
+ DartFixKind.REPLACE_CONTAINER_WITH_SIZED_BOX_MULTI;
+
+ @override
+ Future<void> compute(ChangeBuilder builder) async {
+ final diagnostic = this.diagnostic;
+ if (diagnostic is AnalysisError) {
+ await builder.addDartFileEdit(file, (builder) {
+ builder.addSimpleReplacement(range.error(diagnostic), 'SizedBox');
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static ReplaceContainerWithSizedBox newInstance() =>
+ ReplaceContainerWithSizedBox();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index c8c725d..1ab5812 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -606,6 +606,14 @@
'dart.fix.remove.unnecessaryNew.multi',
DartFixKindPriority.IN_FILE,
'Remove unnecessary new keywords everywhere in file');
+ static const REMOVE_UNNECESSARY_CONTAINER = FixKind(
+ 'dart.fix.remove.unnecessaryContainer',
+ DartFixKindPriority.DEFAULT,
+ "Remove unnecessary 'Container'");
+ static const REMOVE_UNNECESSARY_CONTAINER_MULTI = FixKind(
+ 'dart.fix.remove.unnecessaryContainer.multi',
+ DartFixKindPriority.IN_FILE,
+ "Remove unnecessary 'Container's in file");
static const REMOVE_UNNECESSARY_PARENTHESES = FixKind(
'dart.fix.remove.unnecessaryParentheses',
DartFixKindPriority.DEFAULT,
@@ -734,6 +742,14 @@
'dart.fix.replace.returnTypeFuture',
DartFixKindPriority.DEFAULT,
"Return 'Future' from 'async' function");
+ static const REPLACE_CONTAINER_WITH_SIZED_BOX = FixKind(
+ 'dart.fix.replace.containerWithSizedBox',
+ DartFixKindPriority.DEFAULT,
+ "Replace with 'SizedBox'");
+ static const REPLACE_CONTAINER_WITH_SIZED_BOX_MULTI = FixKind(
+ 'dart.fix.replace.containerWithSizedBox.multi',
+ DartFixKindPriority.DEFAULT,
+ "Replace with 'SizedBox' everywhere in file");
static const REPLACE_VAR_WITH_DYNAMIC = FixKind(
'dart.fix.replace.varWithDynamic',
DartFixKindPriority.DEFAULT,
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 f35e02b..c04be05 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -77,6 +77,7 @@
import 'package:analysis_server/src/services/correction/dart/create_setter.dart';
import 'package:analysis_server/src/services/correction/dart/data_driven.dart';
import 'package:analysis_server/src/services/correction/dart/extend_class_for_mixin.dart';
+import 'package:analysis_server/src/services/correction/dart/flutter_remove_widget.dart';
import 'package:analysis_server/src/services/correction/dart/ignore_diagnostic.dart';
import 'package:analysis_server/src/services/correction/dart/import_library.dart';
import 'package:analysis_server/src/services/correction/dart/inline_invocation.dart';
@@ -134,6 +135,7 @@
import 'package:analysis_server/src/services/correction/dart/replace_boolean_with_bool.dart';
import 'package:analysis_server/src/services/correction/dart/replace_cascade_with_dot.dart';
import 'package:analysis_server/src/services/correction/dart/replace_colon_with_equals.dart';
+import 'package:analysis_server/src/services/correction/dart/replace_container_with_sized_box.dart';
import 'package:analysis_server/src/services/correction/dart/replace_final_with_const.dart';
import 'package:analysis_server/src/services/correction/dart/replace_final_with_var.dart';
import 'package:analysis_server/src/services/correction/dart/replace_new_with_const.dart';
@@ -378,6 +380,9 @@
// TODO(brianwilkerson) Consider applying in bulk.
RemoveUnusedParameter.newInstance,
],
+ LintNames.avoid_unnecessary_containers: [
+ FlutterRemoveWidget.newInstance,
+ ],
LintNames.await_only_futures: [
RemoveAwait.newInstance,
],
@@ -520,6 +525,9 @@
LintNames.prefer_void_to_null: [
ReplaceNullWithVoid.newInstance,
],
+ LintNames.sized_box_for_whitespace: [
+ ReplaceContainerWithSizedBox.newInstance,
+ ],
LintNames.slash_for_doc_comments: [
ConvertDocumentationIntoLine.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 87d349c..2d61eacc 100644
--- a/pkg/analysis_server/lib/src/services/linter/lint_names.dart
+++ b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
@@ -36,6 +36,8 @@
static const String avoid_unused_constructor_parameters =
'avoid_unused_constructor_parameters';
static const String await_only_futures = 'await_only_futures';
+ static const String avoid_unnecessary_containers =
+ 'avoid_unnecessary_containers';
static const String curly_braces_in_flow_control_structures =
'curly_braces_in_flow_control_structures';
static const String diagnostic_describe_all_properties =
@@ -96,6 +98,7 @@
static const String prefer_typing_uninitialized_variables =
'prefer_typing_uninitialized_variables';
static const String prefer_void_to_null = 'prefer_void_to_null';
+ static const String sized_box_for_whitespace = 'sized_box_for_whitespace';
static const String slash_for_doc_comments = 'slash_for_doc_comments';
static const String sort_child_properties_last = 'sort_child_properties_last';
static const String sort_constructors_first = 'sort_constructors_first';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_remove_widget_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_remove_widget_test.dart
index f6ed88f..b4571e7 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_remove_widget_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_remove_widget_test.dart
@@ -3,14 +3,20 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import '../fix/fix_processor.dart';
import 'assist_processor.dart';
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(FlutterRemoveWidgetTest);
+ defineReflectiveTests(RemoveContainerTest);
+ defineReflectiveTests(RemoveContainerBulkTest);
});
}
@@ -235,3 +241,101 @@
''');
}
}
+
+@reflectiveTest
+class RemoveContainerBulkTest extends BulkFixProcessorTest {
+ @override
+ String get lintCode => LintNames.avoid_unnecessary_containers;
+
+ @override
+ void setUp() {
+ super.setUp();
+ writeTestPackageConfig(
+ flutter: true,
+ );
+ }
+
+ @FailingTest(reason: 'nested row container not being removed')
+ Future<void> test_singleFile() async {
+ await resolveTestCode('''
+import 'package:flutter/material.dart';
+
+Widget buildRow() {
+ return Container(
+ child: Row(
+ children: [
+ Text('...'),
+ Container(
+ child: Row(
+ children: [
+ Text('...'),
+ ],
+ ),
+ )
+ ],
+ )
+ );
+}
+''');
+ await assertHasFix('''
+import 'package:flutter/material.dart';
+
+Widget buildRow() {
+ return Row(
+ children: [
+ Text('...'),
+ Row(
+ children: [
+ Text('...'),
+ ],
+ )
+ ],
+ );
+}
+''');
+ }
+}
+
+@reflectiveTest
+class RemoveContainerTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_UNNECESSARY_CONTAINER;
+
+ @override
+ String get lintCode => LintNames.avoid_unnecessary_containers;
+
+ @override
+ void setUp() {
+ super.setUp();
+ writeTestPackageConfig(
+ flutter: true,
+ );
+ }
+
+ Future<void> test_simple() async {
+ await resolveTestCode('''
+import 'package:flutter/material.dart';
+
+Widget buildRow() {
+ return Container(
+ child: Row(
+ children: [
+ Text('...'),
+ ],
+ )
+ );
+}
+''');
+ await assertHasFix('''
+import 'package:flutter/material.dart';
+
+Widget buildRow() {
+ return Row(
+ children: [
+ Text('...'),
+ ],
+ );
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_container_with_sized_box_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_container_with_sized_box_test.dart
new file mode 100644
index 0000000..009c386
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_container_with_sized_box_test.dart
@@ -0,0 +1,102 @@
+// 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(ReplaceContainedWithSizedBoxTest);
+ defineReflectiveTests(ReplaceContainedWithSizedBoxMultiTest);
+ });
+}
+
+@reflectiveTest
+class ReplaceContainedWithSizedBoxMultiTest extends BulkFixProcessorTest {
+ @override
+ String get lintCode => LintNames.sized_box_for_whitespace;
+
+ @override
+ void setUp() {
+ super.setUp();
+ writeTestPackageConfig(
+ flutter: true,
+ );
+ }
+
+ Future<void> test_singleFile() async {
+ await resolveTestCode('''
+import 'package:flutter/material.dart';
+
+Widget buildRow() {
+ return Container(
+ width: 10,
+ child:
+ Container(
+ width: 10,
+ child: Row(),
+ ),
+ );
+}
+''');
+ await assertHasFix('''
+import 'package:flutter/material.dart';
+
+Widget buildRow() {
+ return SizedBox(
+ width: 10,
+ child:
+ SizedBox(
+ width: 10,
+ child: Row(),
+ ),
+ );
+}
+''');
+ }
+}
+
+@reflectiveTest
+class ReplaceContainedWithSizedBoxTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.REPLACE_CONTAINER_WITH_SIZED_BOX;
+
+ @override
+ String get lintCode => LintNames.sized_box_for_whitespace;
+
+ @override
+ void setUp() {
+ super.setUp();
+ writeTestPackageConfig(
+ flutter: true,
+ );
+ }
+
+ Future<void> test_simple() async {
+ await resolveTestCode('''
+import 'package:flutter/material.dart';
+
+Widget buildRow() {
+ return Container(
+ width: 10,
+ child: Row(),
+ );
+}
+''');
+ await assertHasFix('''
+import 'package:flutter/material.dart';
+
+Widget buildRow() {
+ return SizedBox(
+ width: 10,
+ child: Row(),
+ );
+}
+''');
+ }
+}
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 fec18cc..6178199 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
@@ -160,6 +160,8 @@
import 'replace_boolean_with_bool_test.dart' as replace_boolean_with_bool;
import 'replace_cascade_with_dot_test.dart' as replace_cascade_with_dot;
import 'replace_colon_with_equals_test.dart' as replace_colon_with_equals;
+import 'replace_container_with_sized_box_test.dart'
+ as replace_container_with_sized_box;
import 'replace_final_with_const_test.dart' as replace_final_with_const;
import 'replace_final_with_var_test.dart' as replace_final_with_var;
import 'replace_new_with_const_test.dart' as replace_new_with_const;
@@ -331,6 +333,7 @@
replace_boolean_with_bool.main();
replace_cascade_with_dot.main();
replace_colon_with_equals.main();
+ replace_container_with_sized_box.main();
replace_final_with_const.main();
replace_final_with_var.main();
replace_new_with_const.main();
diff --git a/tests/language/generic/super_bounded_types_error_test.dart b/tests/language/generic/super_bounded_types_error_test.dart
index 63434cd..5f523bc 100644
--- a/tests/language/generic/super_bounded_types_error_test.dart
+++ b/tests/language/generic/super_bounded_types_error_test.dart
@@ -3135,20 +3135,10 @@
// [analyzer] unspecified
// ^
// [cfe] Type argument 'dynamic Function(Never)' doesn't conform to the bound 'dynamic Function(X)' of the type variable 'X' on 'FinvCyclicCoBound'.
- var fsource = toF(source);
-// ^
-// [analyzer] unspecified
-// ^
-// [cfe] Inferred type argument 'dynamic Function(Never)' doesn't conform to the bound 'dynamic Function(X)' of the type variable 'X' on 'FinvCyclicCoBound'.
-// ^
-// [analyzer] unspecified
-// [cfe] Inferred type argument 'dynamic Function(Never)' doesn't conform to the bound 'dynamic Function(X)' of the type variable 'X' on 'FinvCyclicCoBound'.
- F<AinvCyclicCoBound<FinvCyclicCoBound<Function(Never)>, Function(Never)>>
-// ^
-// [analyzer] unspecified
- target = fsource;
-// ^
-// [cfe] Type argument 'dynamic Function(Never)' doesn't conform to the bound 'dynamic Function(X)' of the type variable 'X' on 'FinvCyclicCoBound'.
+// [cfe] Inferred type argument 'dynamic Function(Never)' doesn't conform to the bound 'dynamic Function(Y)' of the type variable 'Y' on 'AinvCyclicCoBound'.
+
+ // We do not use `source` in further tests, because the type of `source`
+ // is an error, and we do not generally test error-on-error situations.
}
}
@@ -3156,32 +3146,13 @@
void f(B<AinvCyclicCoBound> source) {
// ^
// [analyzer] unspecified
-// ^
-// [analyzer] unspecified
// ^
// [cfe] Type argument 'AinvCyclicCoBound<dynamic Function(Never) Function(dynamic Function(Never)), dynamic Function(Never)>' doesn't conform to the bound 'B<X>' of the type variable 'X' on 'B'.
-// ^
// [cfe] Type argument 'dynamic Function(Never)' doesn't conform to the bound 'dynamic Function(X)' of the type variable 'X' on 'FinvCyclicCoBound'.
- var fsource = toF(source);
-// ^
-// [analyzer] unspecified
-// ^
-// [cfe] Inferred type argument 'AinvCyclicCoBound<dynamic Function(Never) Function(dynamic Function(Never)), dynamic Function(Never)>' doesn't conform to the bound 'B<X>' of the type variable 'X' on 'B'.
-// ^
-// [cfe] Inferred type argument 'dynamic Function(Never)' doesn't conform to the bound 'dynamic Function(X)' of the type variable 'X' on 'FinvCyclicCoBound'.
-// ^
-// [analyzer] unspecified
-// [cfe] Inferred type argument 'AinvCyclicCoBound<dynamic Function(Never) Function(dynamic Function(Never)), dynamic Function(Never)>' doesn't conform to the bound 'B<X>' of the type variable 'X' on 'B'.
-// ^
-// [cfe] Inferred type argument 'dynamic Function(Never)' doesn't conform to the bound 'dynamic Function(X)' of the type variable 'X' on 'FinvCyclicCoBound'.
- F<B<AinvCyclicCoBound<FinvCyclicCoBound<Function(Never)>, Function(Never)>>>
-// ^
-// [analyzer] unspecified
- target = fsource;
-// ^
-// [cfe] Type argument 'AinvCyclicCoBound<dynamic Function(Never) Function(dynamic Function(Never)), dynamic Function(Never)>' doesn't conform to the bound 'B<X>' of the type variable 'X' on 'B'.
-// ^
-// [cfe] Type argument 'dynamic Function(Never)' doesn't conform to the bound 'dynamic Function(X)' of the type variable 'X' on 'FinvCyclicCoBound'.
+// [cfe] Inferred type argument 'dynamic Function(Never)' doesn't conform to the bound 'dynamic Function(Y)' of the type variable 'Y' on 'AinvCyclicCoBound'.
+
+ // We do not use `source` in further tests, because the type of `source`
+ // is an error, and we do not generally test error-on-error situations.
}
}
diff --git a/tools/VERSION b/tools/VERSION
index ca8974c..3dfa234 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 14
PATCH 0
-PRERELEASE 298
+PRERELEASE 299
PRERELEASE_PATCH 0
\ No newline at end of file