blob: b72b604a0772939321a38f6fe8eb989161c5c834 [file] [log] [blame] [edit]
// 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.
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/js_emitter/model.dart';
import 'package:compiler/src/js_model/js_world.dart' show JClosedWorld;
import 'package:expect/async_helper.dart';
import 'package:expect/expect.dart';
import '../helpers/program_lookup.dart';
import 'package:compiler/src/util/memory_compiler.dart';
const String code = '''
// This needs one-arg instantiation.
@pragma('dart2js:noInline')
T f1a<T>(T t) => t;
// This needs no instantiation because it is not closurized.
@pragma('dart2js:noInline')
T f1b<T>(T t1, T t2) => t1;
class Class {
// This needs two-arg instantiation.
@pragma('dart2js:noInline')
bool f2a<T, S>(T t, S s) => t == s;
// This needs no instantiation because it is not closurized.
@pragma('dart2js:noInline')
bool f2b<T, S>(T t, S s1, S s2) => t == s1;
}
@pragma('dart2js:noInline')
int method1(int i, int Function(int) f) => f(i);
@pragma('dart2js:noInline')
bool method2(int a, int b, bool Function(int, int) f) => f(a, b);
@pragma('dart2js:noInline')
int method3(int a, int b, int c, int Function(int, int, int) f) => f(a, b, c);
main() {
// This needs three-arg instantiation.
T local1<T, S, U>(T t, S s, U u) => t;
// This needs no instantiation because but a local function is always
// closurized so we assume it does.
T local2<T, S, U>(T t, S s, U u1, U u2) => t;
print(method1(42, f1a));
print(f1b(42, 87));
Class c = Class();
print(method2(0, 1, c.f2a));
print(c.f2b(42, 87, 123));
print(method3(0, 1, 2, local1));
print(local2(42, 87, 123, 256));
}
''';
main() {
asyncTest(() async {
CompilationResult result = await runCompiler(
memorySourceFiles: {'main.dart': code},
options: [Flags.omitImplicitChecks],
);
Expect.isTrue(result.isSuccess);
Compiler compiler = result.compiler!;
JClosedWorld closedWorld = compiler.backendClosedWorldForTesting!;
ProgramLookup programLookup = ProgramLookup(compiler.backendStrategy);
void checkStubs(ClassEntity element, List<String> expectedStubs) {
Class? cls = programLookup.getClass(element);
List<String> actualStubs = <String>[];
if (cls != null) {
for (StubMethod stub in cls.callStubs) {
actualStubs.add(stub.name!.key);
}
}
Expect.setEquals(
expectedStubs,
actualStubs,
"Unexpected stubs for $element:\n "
"Expected: $expectedStubs\n Actual: $actualStubs",
);
}
checkStubs(closedWorld.commonElements.getInstantiationClass(1), [
r'call$1',
r'$signature',
]);
checkStubs(closedWorld.commonElements.getInstantiationClass(2), [
r'call$2',
r'$signature',
]);
checkStubs(closedWorld.commonElements.getInstantiationClass(3), [
r'call$3',
r'call$4',
r'$signature',
]);
});
}