// 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 {} class C implements B {} class D implements B {} class E extends B {} class F extends B>{} class G { call() {} } class H implements G { call() {} } class I { call(T t) {} } main() { new A(); new C(); new D(); new E(); new F(); new H(); new I(); method(); } method() { local1() {} local2(T t) {} local3(S s) {} local1(); local2(null); local3(null); } '''; const Map> expectedIsChecksMap = const >{ 'A': const [], 'B': const [], 'C': const [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 [r'$isB'], 'E': const [], 'F': const [], 'G': const [], 'H': const [r'$isG'], 'I': const [], 'method_local1': const [r'$signature'], 'method_local2': const [r'$signature'], 'method_local3': const [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 closures = []; 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 expectedIsChecks = expectedIsChecksMap[element.name]; if (!expectedIsChecks.isEmpty) { Class cls = programLookup.getClass(element); List 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(); }); }