blob: ba3721c92f5fce4ba8a876ad61e595c0e37139ee [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
'../../../sdk/lib/_internal/compiler/implementation/types/types.dart'
show TypeMask;
import 'compiler_helper.dart';
import 'parser_helper.dart';
const String TEST = """
returnNum1(a) {
if (a) return 1;
else return 2.0;
}
returnNum2(a) {
if (a) return 1.0;
else return 2;
}
returnInt1(a) {
if (a) return 1;
else return 2;
}
returnDouble(a) {
if (a) return 1.0;
else return 2.0;
}
returnGiveUp(a) {
if (a) return 1;
else return 'foo';
}
returnInt2() {
var a = 42;
return a++;
}
returnNum3() {
var a = 42;
return ++a;
}
returnNum4() {
var a = 42;
a++;
return a;
}
returnIntOrNull(a) {
if (a) return 42;
}
returnInt3(a) {
if (a) return 42;
throw 42;
}
returnInt4() {
return (42);
}
get topLevelGetter => 42;
returnDynamic() => topLevelGetter(42);
class A {
factory A() = A.generative;
A.generative();
operator==(other) => 42;
get myField => 42;
set myField(a) {}
returnNum1() => ++myField;
returnNum2() => ++this.myField;
returnNum3() => this.myField += 42;
returnNum4() => myField += 42;
operator[](index) => 42;
operator[]= (index, value) {}
returnNum5() => ++this[0];
returnNum6() => this[0] += 1;
}
class B extends A {
B() : super.generative();
returnNum1() => ++new A().myField;
returnNum2() => new A().myField += 4;
returnNum3() => ++new A()[0];
returnNum4() => new A()[0] += 42;
returnNum5() => ++super.myField;
returnNum6() => super.myField += 4;
returnNum7() => ++super[0];
returnNum8() => super[0] += 54;
}
main() {
returnNum1(true);
returnNum2(true);
returnInt1(true);
returnInt2(true);
returnInt3(true);
returnInt4();
returnDouble(true);
returnGiveUp(true);
returnNum3();
returnNum4();
returnIntOrNull(true);
returnDynamic();
new A() == null;
new A()..returnNum1()
..returnNum2()
..returnNum3()
..returnNum4()
..returnNum5()
..returnNum6();
new B()..returnNum1()
..returnNum2()
..returnNum3()
..returnNum4()
..returnNum5()
..returnNum6()
..returnNum7()
..returnNum8();
}
""";
void main() {
Uri uri = new Uri.fromComponents(scheme: 'source');
var compiler = compilerFor(TEST, uri);
compiler.runCompiler(uri);
var typesInferrer = compiler.typesTask.typesInferrer;
checkReturn(String name, type) {
var element = findElement(compiler, name);
Expect.equals(type, typesInferrer.returnTypeOf[element]);
}
checkReturn('returnNum1', typesInferrer.numType);
checkReturn('returnNum2', typesInferrer.numType);
checkReturn('returnInt1', typesInferrer.intType);
checkReturn('returnInt2', typesInferrer.intType);
checkReturn('returnDouble', typesInferrer.doubleType);
checkReturn('returnGiveUp', typesInferrer.dynamicType);
checkReturn('returnNum3', typesInferrer.numType);
checkReturn('returnNum4', typesInferrer.numType);
checkReturn('returnIntOrNull', typesInferrer.intType.nullable());
checkReturn('returnInt3', typesInferrer.intType);
checkReturn('returnDynamic', typesInferrer.dynamicType);
checkReturn('returnInt4', typesInferrer.intType);
checkReturnInClass(String className, String methodName, type) {
var cls = findElement(compiler, className);
var element = cls.lookupLocalMember(buildSourceString(methodName));
Expect.equals(type, typesInferrer.returnTypeOf[element]);
}
checkReturnInClass('A', 'returnNum1', typesInferrer.numType);
checkReturnInClass('A', 'returnNum2', typesInferrer.numType);
checkReturnInClass('A', 'returnNum3', typesInferrer.numType);
checkReturnInClass('A', 'returnNum4', typesInferrer.numType);
checkReturnInClass('A', 'returnNum5', typesInferrer.numType);
checkReturnInClass('A', 'returnNum6', typesInferrer.numType);
checkReturnInClass('A', '==', typesInferrer.dynamicType);
checkReturnInClass('B', 'returnNum1', typesInferrer.numType);
checkReturnInClass('B', 'returnNum2', typesInferrer.numType);
checkReturnInClass('B', 'returnNum3', typesInferrer.numType);
checkReturnInClass('B', 'returnNum4', typesInferrer.numType);
checkReturnInClass('B', 'returnNum5', typesInferrer.numType);
checkReturnInClass('B', 'returnNum6', typesInferrer.numType);
checkReturnInClass('B', 'returnNum7', typesInferrer.numType);
checkReturnInClass('B', 'returnNum8', typesInferrer.numType);
checkFactoryConstructor(String className) {
var cls = findElement(compiler, className);
var element = cls.localLookup(buildSourceString(className));
Expect.equals(new TypeMask.nonNullExact(cls.rawType),
typesInferrer.returnTypeOf[element]);
}
checkFactoryConstructor('A');
}