eab26cd2bd
Change-Id: Ia1f913a01f2be006158967b145db3ee34b297cfe Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/155660 Commit-Queue: Joshua Litt <joshualitt@google.com> Reviewed-by: Sigmund Cherem <sigmund@google.com>
136 lines
4.1 KiB
Dart
136 lines
4.1 KiB
Dart
// 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.
|
|
|
|
// @dart = 2.7
|
|
|
|
import 'package:async_helper/async_helper.dart';
|
|
import 'package:compiler/src/commandline_options.dart';
|
|
import 'package:compiler/src/common_elements.dart';
|
|
import 'package:compiler/src/compiler.dart';
|
|
import 'package:compiler/src/elements/entities.dart';
|
|
import 'package:compiler/src/js_backend/runtime_types_resolution.dart';
|
|
import 'package:compiler/src/js_emitter/model.dart';
|
|
import 'package:compiler/src/world.dart';
|
|
import 'package:expect/expect.dart';
|
|
import '../helpers/program_lookup.dart';
|
|
import '../helpers/memory_compiler.dart';
|
|
|
|
const String code = '''
|
|
class A {}
|
|
class B<T> {}
|
|
class C<T> implements B<T> {}
|
|
class D<T> implements B<int> {}
|
|
class E<T> extends B<T> {}
|
|
class F<T> extends B<List<T>>{}
|
|
class G {
|
|
call() {}
|
|
}
|
|
class H implements G {
|
|
call() {}
|
|
}
|
|
class I<T> {
|
|
call(T t) {}
|
|
}
|
|
|
|
main() {
|
|
new A();
|
|
new C();
|
|
new D();
|
|
new E();
|
|
new F();
|
|
new H();
|
|
new I();
|
|
method<int>();
|
|
}
|
|
|
|
method<T>() {
|
|
local1() {}
|
|
local2(T t) {}
|
|
local3<S>(S s) {}
|
|
|
|
local1();
|
|
local2(null);
|
|
local3(null);
|
|
}
|
|
''';
|
|
|
|
const Map<String, List<String>> expectedIsChecksMap =
|
|
const <String, List<String>>{
|
|
'A': const <String>[],
|
|
'B': const <String>[],
|
|
'C': const <String>[r'$isB'],
|
|
// TODO(sigmund): change these tests to check that the new rti medatada
|
|
// includes the information we need to check the equivalent of D.$asB and
|
|
// F.$asB
|
|
'D': const <String>[r'$isB'],
|
|
'E': const <String>[],
|
|
'F': const <String>[],
|
|
'G': const <String>[],
|
|
'H': const <String>[r'$isG'],
|
|
'I': const <String>[],
|
|
'method_local1': const <String>[r'$signature'],
|
|
'method_local2': const <String>[r'$signature'],
|
|
'method_local3': const <String>[r'$signature'],
|
|
};
|
|
|
|
main() {
|
|
runTest() async {
|
|
CompilationResult result = await runCompiler(
|
|
memorySourceFiles: {'main.dart': code},
|
|
options: [Flags.disableRtiOptimization, Flags.disableInlining]);
|
|
Expect.isTrue(result.isSuccess);
|
|
Compiler compiler = result.compiler;
|
|
JClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
|
|
JElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
|
|
RuntimeTypesNeed rtiNeed = closedWorld.rtiNeed;
|
|
ProgramLookup programLookup = new ProgramLookup(compiler.backendStrategy);
|
|
|
|
List<ClassEntity> closures = <ClassEntity>[];
|
|
|
|
void processMember(MemberEntity element) {
|
|
if (element is FunctionEntity) {
|
|
Expect.isTrue(rtiNeed.methodNeedsTypeArguments(element),
|
|
"Expected $element to need type arguments.");
|
|
Expect.isTrue(rtiNeed.methodNeedsSignature(element),
|
|
"Expected $element to need signature.");
|
|
elementEnvironment.forEachNestedClosure(element,
|
|
(FunctionEntity local) {
|
|
closures.add(local.enclosingClass);
|
|
});
|
|
}
|
|
}
|
|
|
|
void processClass(ClassEntity element) {
|
|
Expect.equals(elementEnvironment.isGenericClass(element),
|
|
closedWorld.rtiNeed.classNeedsTypeArguments(element));
|
|
elementEnvironment.forEachConstructor(element, processMember);
|
|
elementEnvironment.forEachLocalClassMember(element, processMember);
|
|
|
|
List<String> expectedIsChecks = expectedIsChecksMap[element.name];
|
|
if (!expectedIsChecks.isEmpty) {
|
|
Class cls = programLookup.getClass(element);
|
|
List<String> isChecks = cls.isChecks.map((m) => m.name.key).toList();
|
|
if (cls.functionTypeIndex != null) {
|
|
isChecks.add(r'$signature');
|
|
}
|
|
Expect.setEquals(
|
|
expectedIsChecks,
|
|
isChecks,
|
|
"Unexpected is checks for $element: "
|
|
"Expected $expectedIsChecks, actual $isChecks.");
|
|
}
|
|
}
|
|
|
|
LibraryEntity library = elementEnvironment.mainLibrary;
|
|
elementEnvironment.forEachClass(library, processClass);
|
|
elementEnvironment.forEachLibraryMember(library, processMember);
|
|
closures.forEach(processClass);
|
|
}
|
|
|
|
asyncTest(() async {
|
|
print('--test from kernel------------------------------------------------');
|
|
await runTest();
|
|
});
|
|
}
|