Version 2.12.0-277.0.dev
Merge commit '53f5179b45911fd1f937239f91e55ec8badd7975' into 'dev'
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart
index 32d0b8e..3c49589 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart
@@ -60,7 +60,7 @@
var arguments = argumentList.arguments;
var argumentCount = arguments.length;
var templateContext = TemplateContext(argumentList.parent, fix.utils);
- var newNamed = <AddParameter>[];
+
var indexToNewArgumentMap = <int, AddParameter>{};
var argumentsToInsert = <int>[];
var argumentsToDelete = <int>[];
@@ -69,16 +69,14 @@
if (modification is AddParameter) {
var index = modification.index;
indexToNewArgumentMap[index] = modification;
- if (modification.isPositional) {
+ if (modification.isPositional || modification.isRequired) {
argumentsToInsert.add(index);
- } else if (modification.isRequired) {
- newNamed.add(modification);
} else {
var requiredIfCondition =
modification.argumentValue?.requiredIfCondition;
if (requiredIfCondition != null &&
requiredIfCondition.evaluateIn(templateContext)) {
- newNamed.add(modification);
+ argumentsToInsert.add(index);
}
}
} else if (modification is RemoveParameter) {
@@ -94,7 +92,6 @@
}
}
argumentsToInsert.sort();
- newNamed.sort((first, second) => first.name.compareTo(second.name));
/// Write to the [builder] the argument associated with a single
/// [parameter].
@@ -185,39 +182,21 @@
var insertionRange = insertionRanges[nextInsertionRange];
var lower = insertionRange.lower;
var upper = insertionRange.upper;
- while (upper >= lower && !indexToNewArgumentMap[upper].isRequired) {
+ var parameter = indexToNewArgumentMap[upper];
+ while (upper >= lower &&
+ (parameter.isPositional && !parameter.isRequired)) {
upper--;
}
if (upper >= lower) {
builder.addInsertion(offset, (builder) {
- writeInsertionRange(builder, _IndexRange(lower, upper), true);
+ writeInsertionRange(builder, _IndexRange(lower, upper),
+ nextRemaining > 0 || insertionCount > 0);
});
}
nextInsertionRange++;
}
}
//
- // Insert arguments for required named parameters.
- //
- if (newNamed.isNotEmpty) {
- int offset;
- var needsInitialComma = false;
- if (remainingArguments.isEmpty && argumentsToInsert.isEmpty) {
- offset = argumentList.rightParenthesis.offset;
- } else {
- offset = arguments[arguments.length - 1].end;
- needsInitialComma = true;
- }
- builder.addInsertion(offset, (builder) {
- for (var i = 0; i < newNamed.length; i++) {
- if (i > 0 || needsInitialComma) {
- builder.write(', ');
- }
- writeArgument(builder, newNamed[i]);
- }
- });
- }
- //
// The remaining deletion ranges are now ready to be removed.
//
for (var subRange in deletionRanges) {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart
index f6359cd..ee6c688 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart
@@ -2526,6 +2526,152 @@
''');
}
+ Future<void> test_widgets_Stack_overflow_clip() async {
+ setPackageContent('''
+class Stack {
+ const Stack({
+ @deprecated Overflow overflow: Overflow.clip,
+ Clip clipBehavior: Clip.hardEdge,
+ List<Widget> children: const <Widget>[]});
+}
+class Overflow {
+ static const Overflow clip = Overflow();
+ static const Overflow visible = Overflow();
+ const Overflow();
+}
+class Clip {
+ static const Clip hardEdge = Clip();
+ static const Clip none = Clip();
+ const Clip();
+}
+class Widget {}
+''');
+ addPackageDataFile('''
+version: 1
+transforms:
+ - title: "Migrate to 'clipBehavior'"
+ date: 2020-09-22
+ element:
+ uris: ['$importUri']
+ constructor: ''
+ inClass: 'Stack'
+ oneOf:
+ - if: "overflow == 'Overflow.clip'"
+ changes:
+ - kind: 'addParameter'
+ index: 0
+ name: 'clipBehavior'
+ style: optional_named
+ argumentValue:
+ expression: 'Clip.hardEdge'
+ requiredIf: "overflow == 'Overflow.clip'"
+ - kind: 'removeParameter'
+ name: 'overflow'
+ - if: "overflow == 'Overflow.visible'"
+ changes:
+ - kind: 'addParameter'
+ index: 0
+ name: 'clipBehavior'
+ style: optional_named
+ argumentValue:
+ expression: 'Clip.none'
+ requiredIf: "overflow == 'Overflow.visible'"
+ - kind: 'removeParameter'
+ name: 'overflow'
+ variables:
+ overflow:
+ kind: 'fragment'
+ value: 'arguments[overflow]'
+''');
+ await resolveTestCode('''
+import '$importUri';
+
+void f() {
+ const Stack(overflow: Overflow.clip, children: []);
+}
+''');
+ await assertHasFix('''
+import '$importUri';
+
+void f() {
+ const Stack(clipBehavior: Clip.hardEdge, children: []);
+}
+''');
+ }
+
+ Future<void> test_widgets_Stack_overflow_visible() async {
+ setPackageContent('''
+class Stack {
+ const Stack({
+ @deprecated Overflow overflow: Overflow.clip,
+ Clip clipBehavior: Clip.hardEdge,
+ List<Widget> children: const <Widget>[]});
+}
+class Overflow {
+ static const Overflow clip = Overflow();
+ static const Overflow visible = Overflow();
+ const Overflow();
+}
+class Clip {
+ static const Clip hardEdge = Clip();
+ static const Clip none = Clip();
+ const Clip();
+}
+class Widget {}
+''');
+ addPackageDataFile('''
+version: 1
+transforms:
+ - title: "Migrate to 'clipBehavior'"
+ date: 2020-09-22
+ element:
+ uris: ['$importUri']
+ constructor: ''
+ inClass: 'Stack'
+ oneOf:
+ - if: "overflow == 'Overflow.clip'"
+ changes:
+ - kind: 'addParameter'
+ index: 0
+ name: 'clipBehavior'
+ style: optional_named
+ argumentValue:
+ expression: 'Clip.hardEdge'
+ requiredIf: "overflow == 'Overflow.clip'"
+ - kind: 'removeParameter'
+ name: 'overflow'
+ - if: "overflow == 'Overflow.visible'"
+ changes:
+ - kind: 'addParameter'
+ index: 0
+ name: 'clipBehavior'
+ style: optional_named
+ argumentValue:
+ expression: 'Clip.none'
+ requiredIf: "overflow == 'Overflow.visible'"
+ - kind: 'removeParameter'
+ name: 'overflow'
+ variables:
+ overflow:
+ kind: 'fragment'
+ value: 'arguments[overflow]'
+''');
+ await resolveTestCode('''
+import '$importUri';
+
+void f() {
+ const Stack(overflow: Overflow.visible, children: []);
+}
+''');
+ await assertHasFix('''
+import '$importUri';
+
+void f() {
+ const Stack(clipBehavior: Clip.none, children: []);
+}
+''');
+ }
+
Future<void>
test_widgets_StatefulElement_inheritFromElement_deprecated() async {
setPackageContent('''
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/modify_parameters_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/modify_parameters_test.dart
index d67d30e..77e7e1f 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/modify_parameters_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/modify_parameters_test.dart
@@ -101,7 +101,7 @@
import '$importUri';
void f(C c) {
- c.m2(b: 1, a: 0);
+ c.m2(a: 0, b: 1);
}
''');
}
diff --git a/pkg/smith/lib/configuration.dart b/pkg/smith/lib/configuration.dart
index 370e772..9544b3a 100644
--- a/pkg/smith/lib/configuration.dart
+++ b/pkg/smith/lib/configuration.dart
@@ -381,7 +381,12 @@
useHotReload = useHotReload ?? false,
useHotReloadRollback = useHotReloadRollback ?? false,
useSdk = useSdk ?? false,
- useQemu = useQemu ?? false;
+ useQemu = useQemu ?? false {
+ if (name.contains(" ")) {
+ throw ArgumentError(
+ "Name of test configuration cannot contain spaces: $name");
+ }
+ }
/// Returns `true` if this configuration's options all have the same values
/// as [other].
diff --git a/pkg/smith/test/configuration_test.dart b/pkg/smith/test/configuration_test.dart
index d558cc2..7a5b424 100644
--- a/pkg/smith/test/configuration_test.dart
+++ b/pkg/smith/test/configuration_test.dart
@@ -303,7 +303,7 @@
);
var debugWithAsserts2 = Configuration(
- "different name",
+ "different-name",
Architecture.x64,
Compiler.dart2js,
Mode.debug,
diff --git a/pkg/test_runner/lib/src/options.dart b/pkg/test_runner/lib/src/options.dart
index 7c51016..af07581a 100644
--- a/pkg/test_runner/lib/src/options.dart
+++ b/pkg/test_runner/lib/src/options.dart
@@ -854,7 +854,7 @@
for (var sanitizerName in sanitizers.split(",")) {
var sanitizer = Sanitizer.find(sanitizerName);
var configuration = Configuration(
- "custom configuration_${configurationNumber++}",
+ "custom-configuration-${configurationNumber++}",
architecture,
compiler,
mode,
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index dc2404f..347484e 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -124,7 +124,7 @@
/// If [growable] is `false`, which is the default,
/// the list is a fixed-length list of length zero.
/// If [growable] is `true`, the list is growable and equivalent to `<E>[]`.
- @Since("2.8")
+ @Since("2.9")
external factory List.empty({bool growable = false});
/// Creates a list containing all [elements].
diff --git a/tests/language/operator/operator_triple_shift_error_test.dart b/tests/language/operator/operator_triple_shift_error_test.dart
new file mode 100644
index 0000000..ffe2632
--- /dev/null
+++ b/tests/language/operator/operator_triple_shift_error_test.dart
@@ -0,0 +1,72 @@
+// 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.
+
+// SharedOptions=--enable-experiment=triple-shift
+
+// Can only be declared with exactly one required positional parameter.
+class C2 {
+ Object? operator >>>(arg1, arg2) => arg1;
+ // ^
+ // [cfe] Operator '>>>' should have exactly one parameter.
+ // ^^^
+ // [analyzer] COMPILE_TIME_ERROR.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR
+}
+
+class CO1 {
+ Object? operator >>>([arg1]) => arg1;
+ // ^^^^
+ // [cfe] An operator can't have optional parameters.
+ // [analyzer] COMPILE_TIME_ERROR.OPTIONAL_PARAMETER_IN_OPERATOR
+}
+
+class C1O1 {
+ Object? operator >>>(arg1, [arg2]) => arg1;
+ // ^
+ // [cfe] Operator '>>>' should have exactly one parameter.
+ // ^^^^
+ // [analyzer] COMPILE_TIME_ERROR.OPTIONAL_PARAMETER_IN_OPERATOR
+}
+
+class C1N1 {
+ Object? operator >>>(arg1, {arg2}) => arg1;
+ // ^
+ // [cfe] Operator '>>>' should have exactly one parameter.
+ // ^^^^
+ // [analyzer] COMPILE_TIME_ERROR.OPTIONAL_PARAMETER_IN_OPERATOR
+}
+
+class C0 {
+ Object? operator >>>() => 0;
+ // ^
+ // [cfe] Operator '>>>' should have exactly one parameter.
+ // ^^^
+ // [analyzer] COMPILE_TIME_ERROR.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR
+}
+
+// Operators cannot be generic.
+class Gen {
+ Object? operator >>> <T>(T arg1) => arg1;
+ // ^
+ // [cfe] Types parameters aren't allowed when defining an operator.
+ // ^^^
+ // [analyzer] SYNTACTIC_ERROR.TYPE_PARAMETERS_ON_OPERATOR
+}
+
+// Operators cannot be static.
+class Static {
+ /**/ static Object? operator >>>(arg) => arg;
+ // ^^^^^^
+ // [cfe] Operators can't be static.
+ // [analyzer] SYNTACTIC_ERROR.STATIC_OPERATOR
+}
+
+main() {
+ C0();
+ CO1();
+ C1O1();
+ C1N1();
+ C2();
+ Gen();
+ Static();
+}
diff --git a/tests/language/operator/operator_triple_shift_test.dart b/tests/language/operator/operator_triple_shift_test.dart
new file mode 100644
index 0000000..2bbb811
--- /dev/null
+++ b/tests/language/operator/operator_triple_shift_test.dart
@@ -0,0 +1,77 @@
+// 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.
+
+// SharedOptions=--enable-experiment=triple-shift
+
+import "package:expect/expect.dart";
+
+class C {
+ static int ctr = 0;
+ final Object? _text;
+ C([Object? text]) : _text = text ?? "${++ctr}";
+
+ // It's possible to declare a `>>>` operator.
+ C operator >>>(arg) => C("(${++ctr}:$_text>>>$arg)");
+
+ // + binds more strongly than `>>`, `>>>` and `<<`.
+ C operator +(arg) => C("(${++ctr}:$_text+$arg)");
+ // Both `>>` and `<<` binds exactly as strongly as `>>>`.
+ C operator >>(arg) => C("(${++ctr}:$_text>>$arg)");
+ C operator <<(arg) => C("(${++ctr}:$_text<<$arg)");
+ // & binds less strongly than `>>`, `>>>` and `<<`.
+ C operator &(arg) => C("(${++ctr}:$_text&$arg)");
+
+ String toString() => "${_text}";
+}
+
+class NSM {
+ noSuchMethod(i) => i.memberName;
+}
+
+// Valid in extensions too.
+extension ShiftIt<T> on T {
+ List<T> operator >>>(int count) => List<T>.filled(count, this);
+}
+
+main() {
+ // It's possible to use the `>>>` operator.
+ // Evaluation is left-to-right.
+ Expect.equals("(3:1>>>2)", "${C() >>> C()}");
+
+ var c = C();
+ Expect.equals("4", "$c");
+ c >>>= C();
+ Expect.equals("(6:4>>>5)", "$c");
+
+ // Precedence is as expected.
+ // Different precedence than + (which binds stronger) and & (which doesn't).
+ Expect.equals("(11:(9:7+8)>>>10)", "${C() + C() >>> C()}");
+ Expect.equals("(16:12>>>(15:13+14))", "${C() >>> C() + C()}");
+ Expect.equals("(23:(19:17+18)>>>(22:20+21))", "${C() + C() >>> C() + C()}");
+ Expect.equals("(28:(26:24>>>25)&27)", "${C() >>> C() & C()}");
+ Expect.equals("(33:29&(32:30>>>31))", "${C() & C() >>> C()}");
+ Expect.equals("(40:(38:34&(37:35>>>36))&39)", "${C() & C() >>> C() & C()}");
+
+ // Same precedence as `>>` and `<<`, left associative.
+ Expect.equals("(45:(43:41>>>42)>>44)", "${C() >>> C() >> C()}");
+ Expect.equals("(50:(48:46>>47)>>>49)", "${C() >> C() >>> C()}");
+ Expect.equals("(55:(53:51>>>52)<<54)", "${C() >>> C() << C()}");
+ Expect.equals("(60:(58:56<<57)>>>59)", "${C() << C() >>> C()}");
+ Expect.equals("(67:(65:(63:61<<62)>>>64)>>66)",
+ "${C() << C() >>> C() >> C()}");
+
+ /// The `>>>` Symbol works.
+ var literalSymbol = #>>>;
+ var constSymbol = const Symbol(">>>");
+ var newSymbol = new Symbol(">>>");
+ Expect.identical(literalSymbol, constSymbol);
+ Expect.equals(literalSymbol, newSymbol);
+
+ dynamic n = NSM();
+ var nsmSymbol = n >>> 42;
+ Expect.equals(nsmSymbol, literalSymbol);
+
+ var o = Object();
+ Expect.listEquals([o, o, o, o, o], o >>> 5);
+}
diff --git a/tools/VERSION b/tools/VERSION
index e6d915e..5527eb6 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 12
PATCH 0
-PRERELEASE 276
+PRERELEASE 277
PRERELEASE_PATCH 0
\ No newline at end of file