blob: f12fe382cd309b4e4da7cd62d9cb493115b64bd4 [file] [log] [blame]
// Copyright (c) 2013, 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:expect/expect.dart';
import "package:async_helper/async_helper.dart";
import 'compiler_helper.dart';
import 'type_mask_test_helper.dart';
void compileAndFind(String code, String className, String memberName,
bool disableInlining, check(compiler, element)) {
Uri uri = new Uri(scheme: 'source');
var compiler = compilerFor(code, uri, disableInlining: disableInlining);
asyncTest(() => compiler.run(uri).then((_) {
var cls = findElement(compiler, className);
var member = cls.lookupLocalMember(memberName);
return check(compiler, member);
}));
}
const String TEST_1 = r"""
class A {
x(p) => p;
}
main() { new A().x("s"); }
""";
const String TEST_2 = r"""
class A {
x(p) => p;
}
main() { new A().x(1); }
""";
const String TEST_3 = r"""
class A {
x(p) => x(p - 1);
}
main() { new A().x(1); }
""";
const String TEST_4 = r"""
class A {
x(p) => x(p - 1);
}
main() { new A().x(1.5); }
""";
const String TEST_5 = r"""
class A {
x(p) => p;
}
main() {
new A().x(1);
new A().x(1.5);
}
""";
const String TEST_6 = r"""
class A {
x(p) => p;
}
main() {
new A().x(1.5);
new A().x(1);
}
""";
const String TEST_7a = r"""
class A {
x(p) => x("x");
}
main() {
new A().x(1);
}
""";
const String TEST_7b = r"""
class A {
x(p) => x("x");
}
main() {
new A().x({});
}
""";
const String TEST_8 = r"""
class A {
x(p1, p2, p3) => x(p1, "x", {});
}
main() {
new A().x(1, 2, 3);
}
""";
const String TEST_9 = r"""
class A {
x(p1, p2) => x(p1, p2);
}
main() {
new A().x(1, 2);
}
""";
const String TEST_10 = r"""
class A {
x(p1, p2) => x(p1, p2);
}
void f(p) {
p.x("x", "y");
}
main() {
f(null);
new A().x(1, 2);
}
""";
const String TEST_11 = r"""
class A {
x(p1, p2) => x(1, 2);
}
main() {
new A().x("x", "y");
}
""";
const String TEST_12 = r"""
class A {
x(p1, [p2 = 1]) => 1;
}
main() {
new A().x("x", 1);
new A().x("x");
}
""";
const String TEST_13 = r"""
class A {
x(p) => 1;
}
f(p) => p.x(2.2);
main() {
new A().x(1);
f(new A());
}
""";
const String TEST_14 = r"""
class A {
x(p1, [p2 = "s"]) => 1;
}
main() {
new A().x(1);
}
""";
const String TEST_15 = r"""
class A {
x(p1, [p2 = true]) => 1;
}
f(p) => p.a("x");
main() {
new A().x("x");
new A().x("x", false);
f(null);
}
""";
const String TEST_16 = r"""
class A {
x(p1, [p2 = 1, p3 = "s"]) => 1;
}
main() {
new A().x(1);
new A().x(1, 2);
new A().x(1, 2, "x");
new A().x(1, p2: 2);
new A().x(1, p3: "x");
new A().x(1, p3: "x", p2: 2);
new A().x(1, p2: 2, p3: "x");
}
""";
const String TEST_17 = r"""
class A {
x(p1, [p2 = 1, p3 = "s"]) => 1;
}
main() {
new A().x(1, true, 1.1);
new A().x(1, false, 2.2);
new A().x(1, p3: 3.3, p2: true);
new A().x(1, p2: false, p3: 4.4);
}
""";
const String TEST_18 = r"""
class A {
x(p1, p2) => x(p1, p2);
}
class B extends A {
}
main() {
new B().x("a", "b");
new A().x(1, 2);
}
""";
void doTest(String test, bool enableInlining, Function f) {
compileAndFind(test, 'A', 'x', enableInlining, (compiler, element) {
var expectedTypes = f(compiler);
var signature = element.functionSignature;
int index = 0;
var inferrer = compiler.globalInference.typesInferrerInternal;
signature.forEachParameter((Element element) {
Expect.equals(expectedTypes[index++],
simplify(inferrer.getTypeOfElement(element), compiler), test);
});
Expect.equals(index, expectedTypes.length);
});
}
void runTest(String test, Function f) {
doTest(test, false, f);
doTest(test, true, f);
}
subclassOfInterceptor(compiler) {
return findTypeMask(compiler, 'Interceptor', 'nonNullSubclass');
}
void test() {
runTest(TEST_1, (compiler) => [compiler.closedWorld.commonMasks.stringType]);
runTest(TEST_2, (compiler) => [compiler.closedWorld.commonMasks.uint31Type]);
runTest(TEST_3, (compiler) => [compiler.closedWorld.commonMasks.intType]);
runTest(TEST_4, (compiler) => [compiler.closedWorld.commonMasks.numType]);
runTest(TEST_5, (compiler) => [compiler.closedWorld.commonMasks.numType]);
runTest(TEST_6, (compiler) => [compiler.closedWorld.commonMasks.numType]);
runTest(TEST_7a, (compiler) => [subclassOfInterceptor(compiler)]);
runTest(
TEST_7b,
(compiler) =>
[compiler.closedWorld.commonMasks.dynamicType.nonNullable()]);
runTest(
TEST_8,
(compiler) => [
compiler.closedWorld.commonMasks.uint31Type,
subclassOfInterceptor(compiler),
compiler.closedWorld.commonMasks.dynamicType.nonNullable()
]);
runTest(
TEST_9,
(compiler) => [
compiler.closedWorld.commonMasks.uint31Type,
compiler.closedWorld.commonMasks.uint31Type
]);
runTest(
TEST_10,
(compiler) => [
compiler.closedWorld.commonMasks.uint31Type,
compiler.closedWorld.commonMasks.uint31Type
]);
runTest(
TEST_11,
(compiler) =>
[subclassOfInterceptor(compiler), subclassOfInterceptor(compiler)]);
runTest(
TEST_12,
(compiler) => [
compiler.closedWorld.commonMasks.stringType,
compiler.closedWorld.commonMasks.uint31Type
]);
runTest(TEST_13, (compiler) => [compiler.closedWorld.commonMasks.numType]);
runTest(
TEST_14,
(compiler) => [
compiler.closedWorld.commonMasks.uint31Type,
compiler.closedWorld.commonMasks.stringType
]);
runTest(
TEST_15,
(compiler) => [
compiler.closedWorld.commonMasks.stringType,
compiler.closedWorld.commonMasks.boolType
]);
runTest(
TEST_16,
(compiler) => [
compiler.closedWorld.commonMasks.uint31Type,
compiler.closedWorld.commonMasks.uint31Type,
compiler.closedWorld.commonMasks.stringType
]);
runTest(
TEST_17,
(compiler) => [
compiler.closedWorld.commonMasks.uint31Type,
compiler.closedWorld.commonMasks.boolType,
compiler.closedWorld.commonMasks.doubleType
]);
runTest(
TEST_18,
(compiler) =>
[subclassOfInterceptor(compiler), subclassOfInterceptor(compiler)]);
}
void main() {
test();
}