Add closure signature to dependencies
Adds these missing dependencies to the deferred loading partition:
1. Signature of a local function / closure.
2. Bounds of type variables.
TBR=johnniwinther@google.com
Change-Id: I201d08cf874381e58e161d2f910b60d83932968c
Reviewed-on: https://dart-review.googlesource.com/71120
Reviewed-by: Stephen Adams <sra@google.com>
Commit-Queue: Stephen Adams <sra@google.com>
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index 5f32672..c176d1d 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -20,6 +20,7 @@
InstantiationConstantValue;
import 'elements/types.dart';
import 'elements/entities.dart';
+import 'kernel/kelements.dart' show KLocalFunction;
import 'library_loader.dart';
import 'universe/use.dart';
import 'universe/world_impact.dart'
@@ -278,16 +279,7 @@
// TODO(het): we would like to separate out types that are only needed for
// rti from types that are needed for their members.
if (type is FunctionType) {
- for (DartType argumentType in type.parameterTypes) {
- _collectTypeDependencies(argumentType, dependencies);
- }
- for (DartType argumentType in type.optionalParameterTypes) {
- _collectTypeDependencies(argumentType, dependencies);
- }
- for (DartType argumentType in type.namedParameterTypes) {
- _collectTypeDependencies(argumentType, dependencies);
- }
- _collectTypeDependencies(type.returnType, dependencies);
+ _collectFunctionTypeDependencies(type, dependencies);
} else if (type is TypedefType) {
type.typeArguments
.forEach((t) => _collectTypeDependencies(t, dependencies));
@@ -299,6 +291,23 @@
}
}
+ void _collectFunctionTypeDependencies(
+ FunctionType type, Dependencies dependencies) {
+ for (FunctionTypeVariable typeVariable in type.typeVariables) {
+ _collectTypeDependencies(typeVariable.bound, dependencies);
+ }
+ for (DartType argumentType in type.parameterTypes) {
+ _collectTypeDependencies(argumentType, dependencies);
+ }
+ for (DartType argumentType in type.optionalParameterTypes) {
+ _collectTypeDependencies(argumentType, dependencies);
+ }
+ for (DartType argumentType in type.namedParameterTypes) {
+ _collectTypeDependencies(argumentType, dependencies);
+ }
+ _collectTypeDependencies(type.returnType, dependencies);
+ }
+
/// Extract any dependencies that are known from the impact of [element].
void _collectDependenciesFromImpact(
MemberEntity element, Dependencies dependencies) {
@@ -307,14 +316,17 @@
element,
worldImpact,
new WorldImpactVisitorImpl(visitStaticUse: (StaticUse staticUse) {
- if (staticUse.element is MemberEntity) {
- dependencies.members.add(staticUse.element);
+ Entity usedEntity = staticUse.element;
+ if (usedEntity is MemberEntity) {
+ dependencies.members.add(usedEntity);
} else {
- assert(
- staticUse.element is Local,
- failedAt(
- staticUse.element, "Unexpected static use $staticUse."));
- dependencies.localFunctions.add(staticUse.element);
+ assert(usedEntity is KLocalFunction,
+ failedAt(usedEntity, "Unexpected static use $staticUse."));
+ KLocalFunction localFunction = usedEntity;
+ // TODO(sra): Consult KClosedWorld to see if signature is needed.
+ _collectFunctionTypeDependencies(
+ localFunction.functionType, dependencies);
+ dependencies.localFunctions.add(localFunction);
}
switch (staticUse.kind) {
case StaticUseKind.CONSTRUCTOR_INVOKE:
diff --git a/tests/compiler/dart2js_extra/deferred/34219_bounds_lib1.dart b/tests/compiler/dart2js_extra/deferred/34219_bounds_lib1.dart
new file mode 100644
index 0000000..81bf0ae
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/34219_bounds_lib1.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2018, 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.
+
+// Part of 34219_bounds_test.dart
+
+import '34219_bounds_lib2.dart';
+
+class SystemMessage extends GeneratedMessage {}
+
+var g;
+
+test1() {
+ new GeneratedMessage();
+ g = (<T extends SystemMessage>(T a, T b) => a == b);
+}
diff --git a/tests/compiler/dart2js_extra/deferred/34219_bounds_lib2.dart b/tests/compiler/dart2js_extra/deferred/34219_bounds_lib2.dart
new file mode 100644
index 0000000..7726460
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/34219_bounds_lib2.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2018, 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.
+
+// Part of 34219_bounds_test.dart
+
+class GeneratedMessage {}
diff --git a/tests/compiler/dart2js_extra/deferred/34219_bounds_lib3.dart b/tests/compiler/dart2js_extra/deferred/34219_bounds_lib3.dart
new file mode 100644
index 0000000..a567162
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/34219_bounds_lib3.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2018, 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.
+
+// Part of 34219_bounds_test.dart
+//
+// This library places GeneratedMessage into a different partition to
+// SystemMessage.
+
+import '34219_bounds_lib2.dart';
+
+test3() {
+ new GeneratedMessage();
+}
diff --git a/tests/compiler/dart2js_extra/deferred/34219_bounds_test.dart b/tests/compiler/dart2js_extra/deferred/34219_bounds_test.dart
new file mode 100644
index 0000000..67b77d9
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/34219_bounds_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2018, 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.
+// dart2jsOptions=--omit-implicit-checks
+
+// Tests that generic function type bounds are walked as dependencies of a
+// closure. If the generic function bounds are not visited, SystemMessage is
+// placed in the main unit while it's superclass GeneratedMessage is placed in a
+// deferred part.
+
+import '34219_bounds_lib1.dart' deferred as lib1;
+import '34219_bounds_lib3.dart' deferred as lib3;
+
+main() async {
+ await lib1.loadLibrary();
+ lib1.test1();
+ await lib3.loadLibrary();
+ lib3.test3();
+ if (lib1.g is bool Function(Object, Object)) print('!');
+}
diff --git a/tests/compiler/dart2js_extra/deferred/34219_signature_lib1.dart b/tests/compiler/dart2js_extra/deferred/34219_signature_lib1.dart
new file mode 100644
index 0000000..b3493bd
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/34219_signature_lib1.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2018, 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.
+
+// Part of 34219_signature_test.dart
+
+import '34219_signature_lib2.dart';
+
+class SystemMessage extends GeneratedMessage {}
+
+var g;
+
+test1() {
+ new GeneratedMessage();
+ g = (SystemMessage a, SystemMessage b) => a == b;
+}
diff --git a/tests/compiler/dart2js_extra/deferred/34219_signature_lib2.dart b/tests/compiler/dart2js_extra/deferred/34219_signature_lib2.dart
new file mode 100644
index 0000000..e702fe6
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/34219_signature_lib2.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2018, 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.
+
+// Part of 34219_signature_test.dart
+
+class GeneratedMessage {}
diff --git a/tests/compiler/dart2js_extra/deferred/34219_signature_lib3.dart b/tests/compiler/dart2js_extra/deferred/34219_signature_lib3.dart
new file mode 100644
index 0000000..35915d5
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/34219_signature_lib3.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2018, 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.
+
+// Part of 34219_signature_test.dart
+//
+// This library places GeneratedMessage into a different partition to
+// SystemMessage.
+
+import '34219_signature_lib2.dart';
+
+test3() {
+ new GeneratedMessage();
+}
diff --git a/tests/compiler/dart2js_extra/deferred/34219_signature_test.dart b/tests/compiler/dart2js_extra/deferred/34219_signature_test.dart
new file mode 100644
index 0000000..d6c2c05
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/34219_signature_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2018, 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.
+// dart2jsOptions=--omit-implicit-checks
+
+// Tests that closure signatures are walked as dependencies of a closure. If the
+// signature of the closure is not visited, SystemMessage is placed in the main
+// unit while it's superclass GeneratedMessage is placed in a deferred part.
+
+import '34219_signature_lib1.dart' deferred as lib1;
+import '34219_signature_lib3.dart' deferred as lib3;
+
+main() async {
+ await lib1.loadLibrary();
+ lib1.test1();
+ await lib3.loadLibrary();
+ lib3.test3();
+ if (lib1.g is bool Function(Object, Object)) print('!');
+}