Version 2.15.0-105.0.dev
Merge commit '283ce865c835ee1058b3c8cb5679a30ba33b19cc' into 'dev'
diff --git a/DEPS b/DEPS
index 0f21607..239e999 100644
--- a/DEPS
+++ b/DEPS
@@ -44,7 +44,7 @@
# co19 is a cipd package. Use update.sh in tests/co19[_2] to update these
# hashes. It requires access to the dart-build-access group, which EngProd
# has.
- "co19_rev": "4aae571b0358e2f063ab68f2eb92857e31deb0b9",
+ "co19_rev": "21e89324642656dcd903e97352d9d16da6a361ee",
"co19_2_rev": "3e1ea1af9ef293d7f6a8f3332b5c71c7072a30e0",
# The internal benchmarks to use. See go/dart-benchmarks-internal
diff --git a/pkg/analyzer/lib/src/workspace/bazel.dart b/pkg/analyzer/lib/src/workspace/bazel.dart
index afe00a5..cd57df0 100644
--- a/pkg/analyzer/lib/src/workspace/bazel.dart
+++ b/pkg/analyzer/lib/src/workspace/bazel.dart
@@ -461,7 +461,7 @@
var binPaths = _findBinFolderPaths(folder);
String symlinkPrefix =
_findSymlinkPrefix(provider, root, binPaths: binPaths);
- binPaths ??= [context.join(root, '$symlinkPrefix-bin')];
+ binPaths = binPaths..add(context.join(root, '$symlinkPrefix-bin'));
return BazelWorkspace._(provider, root, symlinkPrefix, readonlyRoot,
binPaths, context.join(root, '$symlinkPrefix-genfiles'),
lookForBuildFileSubstitutes: lookForBuildFileSubstitutes);
@@ -474,7 +474,7 @@
var binPaths = _findBinFolderPaths(parent);
String symlinkPrefix =
_findSymlinkPrefix(provider, root, binPaths: binPaths);
- binPaths ??= [context.join(root, '$symlinkPrefix-bin')];
+ binPaths = binPaths..add(context.join(root, '$symlinkPrefix-bin'));
return BazelWorkspace._(
provider,
root,
@@ -491,7 +491,7 @@
var binPaths = _findBinFolderPaths(folder);
String symlinkPrefix =
_findSymlinkPrefix(provider, root, binPaths: binPaths);
- binPaths ??= [context.join(root, '$symlinkPrefix-bin')];
+ binPaths = binPaths..add(context.join(root, '$symlinkPrefix-bin'));
return BazelWorkspace._(
provider,
root,
@@ -516,11 +516,12 @@
/// the immediate folders found in `$root/blaze-out/` and `$root/bazel-out/`
/// for folders named "bin".
///
- /// If no "bin" folder is found in any of those locations, `null` is returned.
- static List<String>? _findBinFolderPaths(Folder root) {
+ /// If no "bin" folder is found in any of those locations, empty list is
+ /// returned.
+ static List<String> _findBinFolderPaths(Folder root) {
var out = _firstExistingFolder(root, ['blaze-out', 'bazel-out']);
if (out == null) {
- return null;
+ return [];
}
List<String> binPaths = [];
@@ -532,7 +533,7 @@
binPaths.add(possibleBin.path);
}
}
- return binPaths.isEmpty ? null : binPaths;
+ return binPaths;
}
/// Return the symlink prefix, _X_, for folders `X-bin` or `X-genfiles`.
diff --git a/pkg/analyzer/test/src/workspace/bazel_test.dart b/pkg/analyzer/test/src/workspace/bazel_test.dart
index 3e22df8..88e983e 100644
--- a/pkg/analyzer/test/src/workspace/bazel_test.dart
+++ b/pkg/analyzer/test/src/workspace/bazel_test.dart
@@ -658,6 +658,26 @@
expect(package?.workspace, equals(workspace));
}
+ void test_findPackageFor_generatedFileInBlazeOutAndBin() {
+ _addResources([
+ '/ws/blaze-out/host/bin/some/code/code.packages',
+ '/ws/blaze-out/host/bin/some/code/code.dart',
+ '/ws/blaze-bin/some/code/code.dart',
+ ]);
+ workspace = BazelWorkspace.find(
+ resourceProvider,
+ convertPath('/ws/some/code/testing'),
+ )!;
+
+ // Make sure that we can find the package of the generated file.
+ var file = workspace.findFile(convertPath('/ws/some/code/code.dart'));
+ package = workspace.findPackageFor(file!.path);
+
+ expect(package, isNotNull);
+ expect(package?.root, convertPath('/ws/some/code'));
+ expect(package?.workspace, equals(workspace));
+ }
+
void test_findPackageFor_inBlazeOut_notPackage() {
var path =
convertPath('/ws/blaze-out/k8-opt/bin/news/lib/news_base.pb.dart');
@@ -858,8 +878,8 @@
resourceProvider, convertPath('/workspace/my/module'))!;
expect(workspace.root, convertPath('/workspace'));
expect(workspace.readonly, isNull);
- expect(workspace.binPaths.single,
- convertPath('/workspace/blaze-out/host/bin'));
+ expect(
+ workspace.binPaths.first, convertPath('/workspace/blaze-out/host/bin'));
expect(workspace.genfiles, convertPath('/workspace/blaze-genfiles'));
expect(
workspace
@@ -893,11 +913,12 @@
resourceProvider, convertPath('/workspace/my/module'))!;
expect(workspace.root, convertPath('/workspace'));
expect(workspace.readonly, isNull);
- expect(workspace.binPaths, hasLength(2));
+ expect(workspace.binPaths, hasLength(3));
expect(workspace.binPaths,
contains(convertPath('/workspace/blaze-out/host/bin')));
expect(workspace.binPaths,
contains(convertPath('/workspace/blaze-out/k8-fastbuild/bin')));
+ expect(workspace.binPaths, contains(convertPath('/workspace/blaze-bin')));
expect(workspace.genfiles, convertPath('/workspace/blaze-genfiles'));
}
diff --git a/pkg/analyzer/tool/messages/generate.dart b/pkg/analyzer/tool/messages/generate.dart
index 17946b6..4ca88ae 100644
--- a/pkg/analyzer/tool/messages/generate.dart
+++ b/pkg/analyzer/tool/messages/generate.dart
@@ -1,4 +1,3 @@
-// @dart = 2.9
/// This file contains code to generate scanner and parser message
/// based on the information in pkg/front_end/messages.yaml.
///
@@ -168,7 +167,7 @@
}
sortedErrorCodes.sort();
for (var errorCode in sortedErrorCodes) {
- final entry = entryMap[errorCode];
+ final entry = entryMap[errorCode]!;
final className = nameForEntry(entry)[0];
out.writeln();
out.writeln('const $className _$errorCode =');
@@ -188,7 +187,7 @@
}
void generateFastaAnalyzerErrorCodeList() {
- final sorted = List<Map>.filled(translatedEntries.length, null);
+ final sorted = List<Map?>.filled(translatedEntries.length, null);
for (var entry in translatedEntries) {
var index = entry['index'];
if (index is int && index >= 1 && index <= sorted.length) {
@@ -201,7 +200,7 @@
}
out.writeln('final fastaAnalyzerErrorCodes = <ErrorCode?>[null,');
for (var entry in sorted) {
- List<String> name = nameForEntry(entry);
+ List<String> name = nameForEntry(entry!);
out.writeln('_${name[1]},');
}
out.writeln('];');
@@ -266,7 +265,7 @@
print('');
print('The following ParserErrorCodes could be auto generated:');
for (String analyzerName in analyzerToFasta.keys.toList()..sort()) {
- List<String> fastaNames = analyzerToFasta[analyzerName];
+ List<String> fastaNames = analyzerToFasta[analyzerName]!;
if (fastaNames.length == 1) {
print(' $analyzerName = ${fastaNames.first}');
} else {
@@ -283,7 +282,7 @@
Token token = scanString(parserSource).tokens;
while (!token.isEof) {
if (token.isIdentifier) {
- String fastaErrorCode;
+ String? fastaErrorCode;
String lexeme = token.lexeme;
if (lexeme.length > 7) {
if (lexeme.startsWith('message')) {
@@ -299,7 +298,7 @@
untranslatedFastaErrorCodes.add(fastaErrorCode);
}
}
- token = token.next;
+ token = token.next!;
}
if (untranslatedFastaErrorCodes.isNotEmpty) {
print('');
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index c0e53d5..82b4c61 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -989,57 +989,70 @@
void Precompiler::AddCalleesOfHelper(const Object& entry,
String* temp_selector,
Class* temp_cls) {
- const intptr_t cid = entry.GetClassId();
- if ((cid == kOneByteStringCid) || (cid == kNullCid)) {
- // Skip common leaf constants early in order to
- // process object pools faster.
- return;
- }
- if (entry.IsUnlinkedCall()) {
- const auto& call_site = UnlinkedCall::Cast(entry);
- // A dynamic call.
- *temp_selector = call_site.target_name();
- AddSelector(*temp_selector);
- if (IsPotentialClosureCall(*temp_selector)) {
- const Array& arguments_descriptor =
- Array::Handle(Z, call_site.arguments_descriptor());
- AddClosureCall(*temp_selector, arguments_descriptor);
- }
- } else if (entry.IsMegamorphicCache()) {
- // A dynamic call.
- const auto& cache = MegamorphicCache::Cast(entry);
- *temp_selector = cache.target_name();
- AddSelector(*temp_selector);
- if (IsPotentialClosureCall(*temp_selector)) {
- const Array& arguments_descriptor =
- Array::Handle(Z, cache.arguments_descriptor());
- AddClosureCall(*temp_selector, arguments_descriptor);
- }
- } else if (entry.IsField()) {
- // Potential need for field initializer.
- const auto& field = Field::Cast(entry);
- AddField(field);
- } else if (entry.IsInstance()) {
- // Const object, literal or args descriptor.
- const auto& instance = Instance::Cast(entry);
- AddConstObject(instance);
- } else if (entry.IsFunction()) {
- // Local closure function.
- const auto& target = Function::Cast(entry);
- AddFunction(target, RetainReasons::kLocalClosure);
- if (target.IsFfiTrampoline()) {
- const auto& callback_target =
- Function::Handle(Z, target.FfiCallbackTarget());
- if (!callback_target.IsNull()) {
- AddFunction(callback_target, RetainReasons::kFfiCallbackTarget);
+ switch (entry.GetClassId()) {
+ case kOneByteStringCid:
+ case kNullCid:
+ // Skip common leaf constants early in order to
+ // process object pools faster.
+ return;
+ case kUnlinkedCallCid: {
+ const auto& call_site = UnlinkedCall::Cast(entry);
+ // A dynamic call.
+ *temp_selector = call_site.target_name();
+ AddSelector(*temp_selector);
+ if (IsPotentialClosureCall(*temp_selector)) {
+ const Array& arguments_descriptor =
+ Array::Handle(Z, call_site.arguments_descriptor());
+ AddClosureCall(*temp_selector, arguments_descriptor);
}
+ break;
}
- } else if (entry.IsCode()) {
- const auto& target_code = Code::Cast(entry);
- if (target_code.IsAllocationStubCode()) {
- *temp_cls ^= target_code.owner();
- AddInstantiatedClass(*temp_cls);
+ case kMegamorphicCacheCid: {
+ // A dynamic call.
+ const auto& cache = MegamorphicCache::Cast(entry);
+ *temp_selector = cache.target_name();
+ AddSelector(*temp_selector);
+ if (IsPotentialClosureCall(*temp_selector)) {
+ const Array& arguments_descriptor =
+ Array::Handle(Z, cache.arguments_descriptor());
+ AddClosureCall(*temp_selector, arguments_descriptor);
+ }
+ break;
}
+ case kFieldCid: {
+ // Potential need for field initializer.
+ const auto& field = Field::Cast(entry);
+ AddField(field);
+ break;
+ }
+ case kFunctionCid: {
+ // Local closure function.
+ const auto& target = Function::Cast(entry);
+ AddFunction(target, RetainReasons::kLocalClosure);
+ if (target.IsFfiTrampoline()) {
+ const auto& callback_target =
+ Function::Handle(Z, target.FfiCallbackTarget());
+ if (!callback_target.IsNull()) {
+ AddFunction(callback_target, RetainReasons::kFfiCallbackTarget);
+ }
+ }
+ break;
+ }
+ case kCodeCid: {
+ const auto& target_code = Code::Cast(entry);
+ if (target_code.IsAllocationStubCode()) {
+ *temp_cls ^= target_code.owner();
+ AddInstantiatedClass(*temp_cls);
+ }
+ break;
+ }
+ default:
+ if (entry.IsInstance()) {
+ // Const object, literal or args descriptor.
+ const auto& instance = Instance::Cast(entry);
+ AddConstObject(instance);
+ }
+ break;
}
}
diff --git a/tests/language/const/instantiated_function_constant_error_test.dart b/tests/language/const/instantiated_function_constant_error_test.dart
new file mode 100644
index 0000000..91b5ec4
--- /dev/null
+++ b/tests/language/const/instantiated_function_constant_error_test.dart
@@ -0,0 +1,180 @@
+// 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=constructor-tearoffs
+
+// Test the support for error detection with generic function instantiation
+// expressions that are constant or potentially constant. Include both some
+// explicit generic function instantiations, and some implicit ones (for the
+// latter, the type arguments are derived by type inference based on the
+// context type). The main goal is to test the new feature where the underlying
+// function is given as an existing function object, which also implies that
+// there are several new possible syntactic forms, e.g., `(b ? f1 : f2)<int>`.
+// The errors generally arise because one or more subexpressions are not
+// constant.
+
+import 'instantiated_function_constant_test.dart' as prefix;
+
+void f1<X extends num>(X x, [num n = 0, List<X> xList = const []]) {}
+void f2<Y extends num>(Y y, [int i = 1, Map<Y, Y> yMap = const {}]) {}
+
+const b = true;
+
+const c01 = f1;
+const c02 = f2;
+
+void test<Z extends num>() {
+ void g1<X extends num>(X x, [num n = 0, List<X> xList = const []]) {}
+ void g2<Y extends num>(Y y, [int i = 1, Map<Y, Y> yMap = const {}]) {}
+
+ // Explicitly instantiate function declaration.
+
+ const c03 = f1<Z>;
+ //^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ const c04 = prefix.f2<Z>;
+ //^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ const c05 = prefix.f1<Z>;
+ //^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ const c06 = f2<Z>;
+ //^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ const c07 = g1<int>;
+ //^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ const c08 = prefix.g2<int>;
+ //^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ const c09 = prefix.g1<int>;
+ //^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ const c10 = g2<int>;
+ //^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ const c11 = g1<Z>;
+ //^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ const c12 = prefix.g2<Z>;
+ //^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ const c13 = prefix.g1<Z>;
+ //^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ const c14 = g2<Z>;
+ //^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ // Explicitly instantiate constant variable.
+
+ const c07 = prefix.c01<Z>;
+ //^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ const c08 = c02<Z>;
+ //^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ const c09 = c01<Z>;
+ //^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ const c10 = prefix.c02<Z>;
+ //^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ // Implicitly instantiate function declaration.
+
+ const void Function(Z) c11 = f1;
+ //^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ const void Function(Z, [int, Map<int, int>]) c12 = prefix.f2;
+ //^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ // Implicitly instantiate constant variable.
+
+ const void Function(Z) c13 = prefix.c01;
+ //^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ const void Function(Z, [int, Map<int, int>]) c14 = c02;
+ //^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+}
+
+// Test new potentially constant expressions. A type variable is a potentially
+// constant type expression, so there are no errors in the initializer list.
+class A<U extends num> {
+ final x1, x2, x3, x4, x5, x6;
+ final void Function(U) x7;
+ final void Function(U) x8;
+ final void Function(U, [int, Map<num, Never>]) x9;
+ final void Function(U) x10;
+
+ const A(bool b)
+ : x1 = (b ? f1 : prefix.f2)<U>,
+ x2 = (b ? prefix.c01 : c02)<U>,
+ x3 = ((b ? prefix.f1 : f2))<U>,
+ x4 = ((b ? c01 : prefix.c02))<U>,
+ x5 = (null ?? f1)<U>,
+ x6 = ((c01 as dynamic) as void Function<X extends num>(X,
+ [num, List<X>]))<U>,
+ x7 = b ? f1 : f2,
+ x8 = b ? c01 : c02,
+ x9 = null ?? c02,
+ x10 =
+ (c01 as dynamic) as void Function<X extends num>(X, [int, List<X>]);
+}
+
+void main() {
+ const ff = false;
+ const A<double>(true);
+ const A<num>(ff);
+
+ void h<V>() {
+ const A<V>(true);
+ //^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ const A<V>(ff);
+ //^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ }
+}
diff --git a/tests/language/const/instantiated_function_constant_test.dart b/tests/language/const/instantiated_function_constant_test.dart
new file mode 100644
index 0000000..b86f99d
--- /dev/null
+++ b/tests/language/const/instantiated_function_constant_test.dart
@@ -0,0 +1,85 @@
+// 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=constructor-tearoffs
+
+// Test the support for generic function instantiation with constant and
+// potentially constant expressions. Include both some explicit generic
+// function instantiations, and some implicit ones (for the latter, the type
+// arguments are derived by type inference based on the context type). The
+// main goal is to test the new feature where the underlying function is
+// given as an existing function object, which also implies that there are
+// several new possible syntactic forms, e.g., `(b ? f1 : f2)<int>`.
+
+import 'instantiated_function_constant_test.dart' as prefix;
+
+void f1<X extends num>(X x, [num n = 0, List<X> xList = const []]) {}
+void f2<Y extends num>(Y y, [int i = 1, Map<Y, Y> yMap = const {}]) {}
+
+const b = true;
+
+const c01 = f1;
+const c02 = f2;
+
+// Explicitly instantiate function declaration.
+const c03 = f1<int>;
+const c04 = prefix.f2<int>;
+const c05 = prefix.f1<int>;
+const c06 = f2<int>;
+
+// Explicitly instantiate constant variable.
+const c07 = prefix.c01<int>;
+const c08 = c02<int>;
+const c09 = c01<int>;
+const c10 = prefix.c02<int>;
+
+// Implicitly instantiate function declaration.
+const void Function(double) c11 = f1;
+const void Function(Never, [int, Map<int, int>]) c12 = prefix.f2;
+
+// Implicitly instantiate constant variable.
+const void Function(double) c13 = prefix.c01;
+const void Function(Never, [int, Map<int, int>]) c14 = c02;
+
+// Test new potentially constant expressions. A type variable is a potentially
+// constant type expression, so there are no errors in the initializer list.
+class A<U extends num> {
+ final x1, x2, x3, x4, x5, x6;
+ final void Function(U) x7;
+ final void Function(U) x8;
+ final void Function(U, [int, Map<num, Never>]) x9;
+ final void Function(U) x10;
+ final void Function(num) x11;
+ final void Function(double) x12;
+ final void Function(num, [int, Map<num, Never>]) x13;
+ final void Function(int) x14;
+
+ const A(bool b)
+ : x1 = b ? (b ? f1 : prefix.f2)<U> : (b ? f1 : prefix.f2)<int>,
+ x2 = b ? (b ? prefix.c01 : c02)<U> : (b ? prefix.c01 : c02)<int>,
+ x3 = b ? ((b ? prefix.f1 : f2))<U> : ((b ? prefix.f1 : f2))<int>,
+ x4 = b ? ((b ? c01 : prefix.c02))<U> : ((b ? c01 : prefix.c02))<int>,
+ x5 = b ? (null ?? f1)<U> : (null ?? f1)<int>,
+ x6 = b
+ ? ((c01 as dynamic) as void Function<X extends num>(X,
+ [num, List<X>]))<U>
+ : ((c01 as dynamic) as void Function<X extends num>(X,
+ [num, List<X>]))<int>,
+ x7 = b ? f1 : f2,
+ x8 = b ? c01 : c02,
+ x9 = null ?? c02,
+ x10 =
+ (c01 as dynamic) as void Function<X extends num>(X, [int, List<X>]),
+ x11 = b ? f1 : f2,
+ x12 = b ? c01 : c02,
+ x13 = null ?? c02,
+ x14 =
+ (c01 as dynamic) as void Function<X extends num>(X, [int, List<X>]);
+}
+
+void main() {
+ const ff = false;
+ const A<double>(true);
+ const A<num>(ff);
+}
diff --git a/tools/VERSION b/tools/VERSION
index 5845878..89f18db 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 15
PATCH 0
-PRERELEASE 104
+PRERELEASE 105
PRERELEASE_PATCH 0
\ No newline at end of file