blob: 05cf5da965814e476ac2371b84ea6e91dac22740 [file] [log] [blame]
// 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<T>() {}
@pragma('dart2js:noInline')
method2<T>() => T;
@pragma('dart2js:noInline')
method3<T>() => T;
@pragma('dart2js:noInline')
method4<T>() => T;
@pragma('dart2js:noInline')
method5<T>() => T;
@pragma('dart2js:noInline')
method6<T>() {}
}
class Class2 {}
class Class3 implements Class1 {
@pragma('dart2js:noInline')
method1<T>() {}
@pragma('dart2js:noInline')
method2<T>() {}
@pragma('dart2js:noInline')
method3<T>() {}
@pragma('dart2js:noInline')
method4<T>() {}
@pragma('dart2js:noInline')
method5<T>() {}
@pragma('dart2js:noInline')
method6<T>() {}
}
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<int>();
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<int>();
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<int>(); // 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<CallStructure> getCallStructures(String name) {
return codegenWorld
.invocationsByName(name)
?.keys
?.map((s) => s.callStructure) ??
[];
}
void checkInvocationsFor(
String methodName, List<CallStructure> expectedCallStructures) {
Iterable<CallStructure> 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]);
});
}