Version 2.18.0-136.0.dev
Merge commit '95360796c29d04575ccced5fe6105083c181fdb6' into 'dev'
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 3b66316..4cda143 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,6 @@
+## 4.2.0-dev
+* Update SDK constraints to `>=2.17.0 <3.0.0`.
+
## 4.1.0
* Deprecated `ParameterElement.isNotOptional`, use `isRequired` instead.
* Deprecated `ResourceProviderMixin.newFile2`, use `newFile` instead.
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 7c4342a..25c8cda 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,10 +1,10 @@
name: analyzer
-version: 4.1.0
+version: 4.2.0-dev
description: This package provides a library that performs static analysis of Dart code.
repository: https://github.com/dart-lang/sdk/tree/main/pkg/analyzer
environment:
- sdk: '>=2.15.0 <3.0.0'
+ sdk: '>=2.17.0 <3.0.0'
dependencies:
_fe_analyzer_shared: ^40.0.0
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index 184e44e..e84fc46 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -499,6 +499,9 @@
info.coverageId = '${field.hashCode}';
}
+ _addClosureInfo(info, field,
+ libraryEntity: fieldEntity.library, memberEntity: fieldEntity);
+
state.info.fields.add(info);
return info;
}
@@ -549,9 +552,10 @@
}
FunctionInfo visitFunction(ir.FunctionNode function,
- {FunctionEntity functionEntity}) {
- var parent = function.parent;
- String name = parent.toStringInternal();
+ {FunctionEntity functionEntity, LocalFunctionInfo localFunctionInfo}) {
+ final parent = function.parent;
+ String name =
+ parent is ir.LocalFunction ? 'call' : parent.toStringInternal();
bool isConstructor = parent is ir.Constructor;
bool isFactory = parent is ir.Procedure && parent.isFactory;
// Kernel `isStatic` refers to static members, constructors, and top-level
@@ -632,6 +636,15 @@
outputUnit: null);
state.entityToInfo[functionEntity] = info;
+ if (function.parent is ir.Member)
+ _addClosureInfo(info, function.parent,
+ libraryEntity: functionEntity.library, memberEntity: functionEntity);
+ else {
+ // This branch is only reached when function is a 'call' method.
+ // TODO(markzipan): Ensure call methods never have children.
+ info.closures = [];
+ }
+
if (compiler.options.experimentCallInstrumentation) {
// We use function.hashCode because it is globally unique and it is
// available while we are doing codegen.
@@ -641,6 +654,41 @@
state.info.functions.add(info);
return info;
}
+
+ /// Adds closure information to [info], using all nested closures in [member].
+ void _addClosureInfo(Info info, ir.Member member,
+ {LibraryEntity libraryEntity, MemberEntity memberEntity}) {
+ final localFunctionInfoCollector = LocalFunctionInfoCollector();
+ member.accept(localFunctionInfoCollector);
+ List<ClosureInfo> nestedClosures = <ClosureInfo>[];
+ localFunctionInfoCollector.localFunctions.forEach((key, value) {
+ FunctionEntity closureEntity;
+ environment.forEachNestedClosure(memberEntity, (closure) {
+ if (closure.enclosingClass.name == value.name) {
+ closureEntity = closure;
+ }
+ });
+ final closureClassEntity = closureEntity.enclosingClass;
+ final closureInfo =
+ ClosureInfo(name: value.name, outputUnit: null, size: null);
+ state.entityToInfo[closureClassEntity] = closureInfo;
+
+ FunctionEntity callMethod = closedWorld.elementEnvironment
+ .lookupClassMember(closureClassEntity, Identifiers.call);
+ final functionInfo = visitFunction(key.function,
+ functionEntity: callMethod, localFunctionInfo: value);
+ state.entityToInfo[closureEntity] = functionInfo;
+
+ closureInfo.function = functionInfo;
+ functionInfo.parent = closureInfo;
+ state.info.closures.add(closureInfo);
+
+ closureInfo.parent = info;
+ nestedClosures.add(closureInfo);
+ });
+ if (info is FunctionInfo) info.closures = nestedClosures;
+ if (info is FieldInfo) info.closures = nestedClosures;
+ }
}
/// Annotates [KernelInfoCollector] with info extracted from closed-world
@@ -853,24 +901,25 @@
}
ClosureInfo visitClosureClass(ClassEntity element) {
- ClosureInfo closureInfo = ClosureInfo(
- name: element.name,
- outputUnit: _unitInfoForClass(element),
- size: dumpInfoTask.sizeOf(element));
- kernelInfo.state.entityToInfo[element] = closureInfo;
+ final kClosureInfos = kernelInfo.state.info.closures
+ .where((info) => info.name == element.name)
+ .toList();
+ assert(
+ kClosureInfos.length == 1,
+ 'Ambiguous closure resolution. '
+ 'Expected singleton, found $kClosureInfos');
+ final kClosureInfo = kClosureInfos.first;
+
+ kClosureInfo.outputUnit = _unitInfoForClass(element);
+ kClosureInfo.size = dumpInfoTask.sizeOf(element);
FunctionEntity callMethod = closedWorld.elementEnvironment
.lookupClassMember(element, Identifiers.call);
- FunctionInfo functionInfo = visitFunction(callMethod, element.name);
- if (functionInfo == null) return null;
+ visitFunction(callMethod, element.name);
- closureInfo.function = functionInfo;
- functionInfo.parent = closureInfo;
- closureInfo.treeShakenStatus = TreeShakenStatus.Live;
-
- kernelInfo.state.info.closures.add(closureInfo);
- return closureInfo;
+ kClosureInfo.treeShakenStatus = TreeShakenStatus.Live;
+ return kClosureInfo;
}
// TODO(markzipan): [parentName] is used for disambiguation, but this might
@@ -879,8 +928,6 @@
int size = dumpInfoTask.sizeOf(function);
// TODO(sigmund): consider adding a small info to represent unreachable
// code here.
- if (size == 0 && !shouldKeep(function)) return null;
-
var compareName = function.name;
if (function.isConstructor) {
compareName = compareName == ""
@@ -898,9 +945,10 @@
!(function.isSetter ^ i.modifiers.isSetter))
.toList();
assert(
- kFunctionInfos.length == 1,
+ kFunctionInfos.length <= 1,
'Ambiguous function resolution. '
- 'Expected singleton, found $kFunctionInfos');
+ 'Expected single or none, found $kFunctionInfos');
+ if (kFunctionInfos.length == 0) return null;
final kFunctionInfo = kFunctionInfos.first;
List<CodeSpan> code = dumpInfoTask.codeOf(function);
@@ -943,19 +991,13 @@
int _addClosureInfo(BasicInfo info, MemberEntity member) {
assert(info is FunctionInfo || info is FieldInfo);
int size = 0;
- List<ClosureInfo> nestedClosures = <ClosureInfo>[];
environment.forEachNestedClosure(member, (closure) {
ClosureInfo closureInfo = visitClosureClass(closure.enclosingClass);
if (closureInfo != null) {
- closureInfo.parent = info;
- closureInfo.treeShakenStatus = info.treeShakenStatus;
- nestedClosures.add(closureInfo);
+ closureInfo.treeShakenStatus = TreeShakenStatus.Live;
size += closureInfo.size;
}
});
- if (info is FunctionInfo) info.closures = nestedClosures;
- if (info is FieldInfo) info.closures = nestedClosures;
-
return size;
}
@@ -1432,3 +1474,73 @@
DumpInfoStateData();
}
+
+class LocalFunctionInfo {
+ final ir.LocalFunction localFunction;
+ final List<ir.TreeNode> hierarchy;
+ final String name;
+ bool isInvoked = false;
+
+ LocalFunctionInfo._(this.localFunction, this.hierarchy, this.name);
+
+ factory LocalFunctionInfo(ir.LocalFunction localFunction) {
+ String name = '';
+ ir.TreeNode node = localFunction;
+ final hierarchy = <ir.TreeNode>[];
+ bool inClosure = false;
+ while (node != null) {
+ // Only consider nodes used for resolving a closure's full name.
+ if (node is ir.FunctionDeclaration) {
+ hierarchy.add(node);
+ name = '_${node.variable.name}' + name;
+ inClosure = false;
+ } else if (node is ir.FunctionExpression) {
+ hierarchy.add(node);
+ name = (inClosure ? '_' : '_closure') + name;
+ inClosure = true;
+ } else if (node is ir.Member) {
+ hierarchy.add(node);
+ var cleanName = node.toStringInternal();
+ if (cleanName.endsWith('.'))
+ cleanName = cleanName.substring(0, cleanName.length - 1);
+ final isFactory = node is ir.Procedure && node.isFactory;
+ if (isFactory) {
+ cleanName = cleanName.replaceAll('.', '\$');
+ cleanName = '${node.enclosingClass.toStringInternal()}_' + cleanName;
+ } else {
+ cleanName = cleanName.replaceAll('.', '_');
+ }
+ name = cleanName + name;
+ inClosure = false;
+ }
+ node = node.parent;
+ }
+
+ return LocalFunctionInfo._(localFunction, hierarchy, name);
+ }
+}
+
+class LocalFunctionInfoCollector extends ir.RecursiveVisitor<void> {
+ final localFunctions = <ir.LocalFunction, LocalFunctionInfo>{};
+
+ @override
+ void visitFunctionExpression(ir.FunctionExpression node) {
+ assert(localFunctions[node] == null);
+ localFunctions[node] = LocalFunctionInfo(node);
+ defaultExpression(node);
+ }
+
+ @override
+ void visitFunctionDeclaration(ir.FunctionDeclaration node) {
+ assert(localFunctions[node] == null);
+ localFunctions[node] = LocalFunctionInfo(node);
+ defaultStatement(node);
+ }
+
+ @override
+ void visitLocalFunctionInvocation(ir.LocalFunctionInvocation node) {
+ if (localFunctions[node.localFunction] == null)
+ visitFunctionDeclaration(node.localFunction);
+ localFunctions[node.localFunction].isInvoked = true;
+ }
+}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 7db7cad..2496daf 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -260,14 +260,14 @@
dart/appjit*: SkipSlow # DFE too slow
dart/b162922506_test: SkipSlow # Generates large input file
dart/data_uri_spawn_test: Skip # Please triage.
-dart/isolates/fast_object_copy_test*: Slow # issue 46740
+dart/isolates/fast_object_copy_test*: SkipSlow
dart/minimal_kernel_test: SkipSlow # gen_kernel is too slow on simulated architectures
dart/null_safety_autodetection_in_kernel_compiler_test: SkipSlow # gen_kernel is too slow on simulated architectures
dart/snapshot_version_test: RuntimeError # Please triage.
dart_2/appjit*: SkipSlow # DFE too slow
dart_2/b162922506_test: SkipSlow # Generates large input file
dart_2/data_uri_spawn_test: Skip # Please triage.
-dart_2/isolates/fast_object_copy_test*: Slow # issue 46740
+dart_2/isolates/fast_object_copy_test*: SkipSlow
dart_2/minimal_kernel_test: SkipSlow # gen_kernel is too slow on simulated architectures
dart_2/null_safety_autodetection_in_kernel_compiler_test: SkipSlow # gen_kernel is too slow on simulated architectures
dart_2/snapshot_version_test: RuntimeError # Please triage.
diff --git a/tools/VERSION b/tools/VERSION
index 6d4108b..16a594e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 18
PATCH 0
-PRERELEASE 135
+PRERELEASE 136
PRERELEASE_PATCH 0
\ No newline at end of file