Version 2.15.0-148.0.dev
Merge commit '8a9a2e40661e0c6fde9d2f632dd2fde0b66470ba' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c2f101f..b76d62e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,201 @@
### Language
+- **[Constructor tearoffs][]**: **BETA PREVIEW**
+
+ Previous Dart versions allowed a method on an instance to be passed as a
+ closure, and similarly for static methods. This is commonly referred to as
+ "closurizing" or "tearing off" a method. Constructors were not previously
+ eligible for closurization, forcing users to explicitly write wrapper
+ functions when using constructors as first class functions, as in the calls to
+ `List.map` in the following example:
+
+ ```dart
+ class A {
+ int x;
+ A(this.x);
+ A.fromString(String s) : x = int.parse(s);
+ }
+
+ void main() {
+ var listOfInts = [1, 2, 3];
+ var listOfStrings = ["1", "2", "3"];
+ for(var a in listOfInts.map((x) => A(x))) {
+ print(a.x);
+ }
+ for(var a in listOfStrings.map((x) => A.fromString(x))) {
+ print(a.x);
+ }
+ }
+ ```
+
+ New in Dart 2.15, constructors are now allowed to be torn off. Named
+ constructors are closurized using their declared name (here `A.fromString`),
+ and unnamed closures are referred to for closurization using the keyword `new`
+ (here `A.new`). The example above may now be written as:
+
+ ```dart
+ class A {
+ int x;
+ A(this.x);
+ A.fromString(String s) : x = int.parse(s);
+ }
+
+ void main() {
+ var listOfInts = [1, 2, 3];
+ var listOfStrings = ["1", "2", "3"];
+ for(A a in listOfInts.map(A.new)) {
+ print(a.x);
+ }
+ for(A a in listOfStrings.map(A.fromString)) {
+ print(a.x);
+ }
+ }
+ ```
+
+ Constructors for generic classes may be torn off as generic functions, or
+ instantiated at the tear off site. So in the following code, the tear off
+ `G.new` used to initialize the variable `f` produces a generic function which
+ may be used to produce an instance of `G<T>` for any type `T` provided when
+ `f` is called. The tear off `G<String>.new` used to initialize the variable
+ `g` on the other hand produces a non-generic function which may only be used
+ to produce instances of type `G<String>`.
+
+ ```dart
+ class G<T> {
+ T x;
+ G(this.x);
+ }
+
+ void main() {
+ G<T> Function<T>(T x) f = G.new;
+ var x = f<int>(3);
+ G<String> Function(String y) g = G<String>.new;
+ var y = g("hello");
+ }
+ ```
+
+ The new constructor tearoff feature is currently in **BETA PREVIEW**. The
+ feature is enabled in beta releases only, and is still subject to breaking
+ changes. It is not fully supported by all tools and there may be known issues
+ with the tool support. Feedback on the feature is welcome, but it is not
+ recommended that production code use the feature until it has been released in
+ a stable version.
+
+ The new constructor tearoff feature is only available as part of the 2.15
+ [language version](https://dart.dev/guides/language/evolution). To use this
+ feature, you must set the lower bound on the sdk constraint for your package
+ to 2.15 or greater (if using a beta preview release, an sdk constraint of
+ `>=2.15.0-0` must be used).
+
+- **[Generic type literals][Explicit instantiation]**: **BETA PREVIEW**
+
+ Previous Dart versions allowed class names to be used as type literals. So
+ for example,`int` may be used as an expression, producing a value of type
+ `Type`. Generic classes (e.g. `List`) could be referred to by name as an
+ expression, but no type arguments could be provided and so only the `dynamic`
+ instantiation could be produced directly as an expression without using
+ indirect methods:
+
+ ```dart
+ // Workaround to capture generic type literals.
+ Type typeOf<T>() => T;
+
+ void main() {
+ var x = int; // The Type literal corresponding to `int`.
+ var y = List; // The Type literal corresponding to `List<dynamic>`.
+ // Use workaround to capture generic type literal.
+ var z = typeOf<List<int>>(); // The Type literal for `List<int>`.
+ }
+ ```
+
+ New in Dart 2.15, instantiations of generic classes may now be used as Type
+ literals:
+
+ ```dart
+ void main() {
+ var x = int; // The Type literal corresponding to `int`.
+ var y = List; // The Type literal corresponding to `List<dynamic>`.
+ var z = List<int>; // The Type literal corresponding to `List<int>`.
+ }
+ ```
+
+ The new generic type literal feature is currently in **BETA PREVIEW**. The
+ feature is enabled in beta releases only, and is still subject to breaking
+ changes. It is not fully supported by all tools and there may be known issues
+ with the tool support. Feedback on the feature is welcome, but it is not
+ recommended that production code use the feature until it has been released in
+ a stable version.
+
+ Generic type literals are only available as part of the 2.15 [language
+ version](https://dart.dev/guides/language/evolution). To use this feature, you
+ must set the lower bound on the sdk constraint for your package to 2.15 or
+ greater (if using a beta preview release, an sdk constraint of
+ `>=2.15.0-0` must be used).
+
+- **[Explicit generic method instantiations][Explicit instantiation]**: **BETA
+ PREVIEW**
+
+ Previous Dart versions allowed generic methods to be implicitly specialized
+ (or "instantiated") to non-generic versions when assigned to a location with a
+ compatible monomorphic type. Example:
+
+ ```dart
+ // The generic identity function.
+ T id<T>(T x) => x;
+
+ void main() {
+ // Initialize `intId` with a version of `id` implicitly specialized to
+ // `int`.
+ int Function(int) intId = id;
+ print(intId(3));
+ // Initialize `stringId` with a version of `id` implicitly specialized to
+ // `String`.
+ String Function(String) stringId = id;
+ print(stringId("hello"));
+ }
+ ```
+
+ New in Dart 2.15, generic methods may be explicitly instantiated using the
+ syntax `f<T>` where `f` is the generic method to specialize and `T` is the
+ type argument (in general, type arguments) to be used to specialize the
+ method. Example:
+
+ ```dart
+ // The generic identity function.
+ T id<T>(T x) => x;
+
+ void main() {
+ // Initialize `intId` with a version of `id` explicitly specialized to
+ // `int`.
+ var intId = id<int>;
+ print(intId(3));
+ // Initialize `stringId` with a version of `id` explicitly specialized to
+ // `String`.
+ var stringId = id<String>;
+ print(stringId("hello"));
+ }
+ ```
+
+ The new generic method instantation feature is currently in **BETA PREVIEW**.
+ The feature is enabled in beta releases only, and is still subject to breaking
+ changes. It is not fully supported by all tools and there may be known issues
+ with the tool support. Feedback on the feature is welcome, but it is not
+ recommended that production code use the feature until it has been released in
+ a stable version.
+
+ Explicit generic method instantiations are only available as part of the 2.15
+ [language version](https://dart.dev/guides/language/evolution). To use this
+ feature, you must set the lower bound on the sdk constraint for your package
+ to 2.15 or greater (if using a beta preview release, an sdk constraint of
+ `>=2.15.0-0` must be used).
+
+ [Constructor tearoffs]:
+ https://github.com/dart-lang/language/blob/master/accepted/future-releases/constructor-tearoffs/feature-specification.md
+
+ [Explicit instantiation]:
+ https://github.com/dart-lang/language/blob/master/accepted/future-releases/constructor-tearoffs/feature-specification.md#explicitly-instantiated-classes-and-functions
+
- Annotations on type parameters of classes can no longer refer to class members
without a prefix. For example, this used to be permitted:
diff --git a/pkg/.gitignore b/pkg/.gitignore
index 6c1be22..b95fe80 100644
--- a/pkg/.gitignore
+++ b/pkg/.gitignore
@@ -7,5 +7,7 @@
/*.vcxproj.user
/*.vcxproj.filters
/*.xcodeproj
+.dart_tool
.idea/
+.packages
analysis_server/language_model/
diff --git a/pkg/analysis_server/lib/src/services/correction/organize_imports.dart b/pkg/analysis_server/lib/src/services/correction/organize_imports.dart
index aacc03d..3708b48 100644
--- a/pkg/analysis_server/lib/src/services/correction/organize_imports.dart
+++ b/pkg/analysis_server/lib/src/services/correction/organize_imports.dart
@@ -350,23 +350,16 @@
@override
String toString() => '(priority=$priority; text=$text)';
+ /// Should keep these in sync! Copied from
+ /// https://github.com/dart-lang/linter/blob/658f497eef/lib/src/rules/directives_ordering.dart#L380-L387
+ /// Consider finding a way to share this code!
static int _compareUri(String a, String b) {
- var aList = _splitUri(a);
- var bList = _splitUri(b);
- int result;
- if ((result = aList[0].compareTo(bList[0])) != 0) return result;
- if ((result = aList[1].compareTo(bList[1])) != 0) return result;
- return 0;
- }
-
- /// Split the given [uri] like `package:some.name/and/path.dart` into a list
- /// like `[package:some.name, and/path.dart]`.
- static List<String> _splitUri(String uri) {
- var index = uri.indexOf('/');
- if (index == -1) {
- return <String>[uri, ''];
- }
- return <String>[uri.substring(0, index), uri.substring(index + 1)];
+ var indexA = a.indexOf('/');
+ var indexB = b.indexOf('/');
+ if (indexA == -1 || indexB == -1) return a.compareTo(b);
+ var result = a.substring(0, indexA).compareTo(b.substring(0, indexB));
+ if (result != 0) return result;
+ return a.substring(indexA + 1).compareTo(b.substring(indexB + 1));
}
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/organize_imports_test.dart b/pkg/analysis_server/test/src/services/correction/fix/organize_imports_test.dart
index 093dddd..4a54aa0 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/organize_imports_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/organize_imports_test.dart
@@ -40,4 +40,39 @@
void f(Stream<String> args) { }
''');
}
+
+ Future<void> test_organizePathImports() async {
+ newFile('/home/test/lib/a.dart', content: '''
+class A {
+ static void m() {}
+}
+''');
+ newFile('/home/test/lib/a/b.dart', content: '''
+class B {
+ static void m() {}
+}
+''');
+
+ await resolveTestCode('''
+import 'dart:async';
+import 'a/b.dart';
+import 'a.dart';
+
+void f(Stream<String> args) {
+ A.m();
+ B.m();
+}
+''');
+ await assertHasFix('''
+import 'dart:async';
+
+import 'a.dart';
+import 'a/b.dart';
+
+void f(Stream<String> args) {
+ A.m();
+ B.m();
+}
+''');
+ }
}
diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart
index 989ad83..625616f 100644
--- a/pkg/vm/lib/transformations/type_flow/analysis.dart
+++ b/pkg/vm/lib/transformations/type_flow/analysis.dart
@@ -1008,11 +1008,12 @@
target = typeFlowAnalysis.hierarchyCache.hierarchy.getDispatchTarget(
classNode, selector.name,
setter: selector.isSetter);
- if (target != null) {
- _dispatchTargets[selector] = target;
- }
+ target ??= _DispatchableInvocation.kNoSuchMethodMarker;
+ _dispatchTargets[selector] = target;
}
- return target;
+ return identical(target, _DispatchableInvocation.kNoSuchMethodMarker)
+ ? null
+ : target;
}
String dump() => "$this {supers: $supertypes}";
diff --git a/tools/VERSION b/tools/VERSION
index 7776bae..99dda00 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 15
PATCH 0
-PRERELEASE 147
+PRERELEASE 148
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index cc0f243..20a574e 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -2886,13 +2886,6 @@
],
"shards": 6,
"fileset": "web_platform_hostasserts_nnbd"
- },
- {
- "name": "dart2js nnbd unit tests",
- "arguments": [
- "-nunittest-weak-asserts-no-sdk-linux",
- "pkg//compiler/"
- ]
}
]
},