// 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/compiler.dart'; import 'package:compiler/src/universe/call_structure.dart'; import 'package:compiler/src/universe/codegen_world_builder.dart'; import 'package:expect/expect.dart'; import '../helpers/memory_compiler.dart'; const String code = r''' class Class1 { @pragma('dart2js:noInline') method1() {} @pragma('dart2js:noInline') method2() => T; @pragma('dart2js:noInline') method3() => T; @pragma('dart2js:noInline') method4() => T; @pragma('dart2js:noInline') method5() => T; @pragma('dart2js:noInline') method6() {} } class Class2 {} class Class3 implements Class1 { @pragma('dart2js:noInline') method1() {} @pragma('dart2js:noInline') method2() {} @pragma('dart2js:noInline') method3() {} @pragma('dart2js:noInline') method4() {} @pragma('dart2js:noInline') method5() {} @pragma('dart2js:noInline') method6() {} } main(args) { dynamic c1 = args != null ? new Class1() : new Class2(); c1.method1(); // No type arguments are inferred here. dynamic c2 = args != null ? new Class1() : new Class2(); c2.method2(); var c3 = args != null ? new Class1() : new Class3(); c3.method3(); // Type arguments are inferred here. var c4 = args != null ? new Class1() : new Class3(); c4.method4(); dynamic c5 = args != null ? new Class1() : new Class2(); c5.method5(); // No type arguments are inferred here. var c6 = args != null ? new Class1() : new Class3(); c6.method5(); // Type arguments are inferred here. dynamic c7 = args != null ? new Class1() : new Class2(); c7.method6(); // Type arguments are not needed. var c8 = args != null ? new Class1() : new Class3(); c8.method6(); // Type arguments are inferred here but not needed. } '''; main() { asyncTest(() async { CompilationResult result = await runCompiler(memorySourceFiles: {'main.dart': code}); Expect.isTrue(result.isSuccess); Compiler compiler = result.compiler; CodegenWorld codegenWorld = compiler.codegenWorldForTesting; CallStructure noTypeArguments = new CallStructure(0, [], 0); CallStructure oneTypeArgument = new CallStructure(0, [], 1); Iterable getCallStructures(String name) { return codegenWorld .invocationsByName(name) ?.keys ?.map((s) => s.callStructure) ?? []; } void checkInvocationsFor( String methodName, List expectedCallStructures) { Iterable actualCallStructures = getCallStructures(methodName); Expect.setEquals( expectedCallStructures, actualCallStructures, "Unexpected call structures for '$methodName'. " "Expected ${expectedCallStructures}, " "actual ${actualCallStructures}."); } checkInvocationsFor('method1', [noTypeArguments]); checkInvocationsFor('method2', [oneTypeArgument]); checkInvocationsFor('method3', [oneTypeArgument]); checkInvocationsFor('method4', [oneTypeArgument]); checkInvocationsFor('method5', [noTypeArguments, oneTypeArgument]); checkInvocationsFor('method6', [noTypeArguments]); }); }