313 lines
5.9 KiB
Dart
313 lines
5.9 KiB
Dart
// Copyright (c) 2011, 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";
|
|
|
|
// Tests function statements and expressions.
|
|
|
|
class Bug4089219 {
|
|
int x;
|
|
var f;
|
|
|
|
Bug4089219(int i) : this.x = i {
|
|
f = () => x;
|
|
}
|
|
}
|
|
|
|
class Bug4342163 {
|
|
final m;
|
|
Bug4342163(int a) : this.m = (() => a) {}
|
|
}
|
|
|
|
class StaticFunctionDef {
|
|
static const int one = 1;
|
|
static var fn1;
|
|
static var fn2;
|
|
static var fn3;
|
|
|
|
static init() {
|
|
fn1 = () { return one; };
|
|
fn2 = () { return (() { return one; })(); };
|
|
fn3 = () {
|
|
final local = 1;
|
|
return (() { return local; })();
|
|
};
|
|
}
|
|
}
|
|
|
|
class A {
|
|
var ma;
|
|
A(a) {ma = a;}
|
|
}
|
|
|
|
class B1 extends A {
|
|
final mfn;
|
|
B1(int a) : super(a), this.mfn = (() {return a;}) {
|
|
}
|
|
}
|
|
|
|
class B2 extends A {
|
|
final mfn;
|
|
B2(int a) : super(2), this.mfn = (() {return a;}) {
|
|
}
|
|
}
|
|
|
|
class B3 extends A {
|
|
final mfn;
|
|
B3(int a) : super(() {return a;}), this.mfn = (() {return a;}) {
|
|
}
|
|
}
|
|
|
|
typedef void Fisk();
|
|
|
|
class FunctionTest {
|
|
|
|
FunctionTest() {}
|
|
|
|
static void testMain() {
|
|
var test = new FunctionTest();
|
|
test.testForEach();
|
|
test.testVarOrder1();
|
|
test.testVarOrder2();
|
|
test.testLexicalClosureRef1();
|
|
test.testLexicalClosureRef2();
|
|
test.testLexicalClosureRef3();
|
|
test.testLexicalClosureRef4();
|
|
test.testLexicalClosureRef5();
|
|
test.testDefaultParametersOrder();
|
|
test.testParametersOrder();
|
|
test.testFunctionDefaults1();
|
|
test.testFunctionDefaults2();
|
|
test.testEscapingFunctions();
|
|
test.testThisBinding();
|
|
test.testFnBindingInStatics();
|
|
test.testFnBindingInInitLists();
|
|
test.testSubclassConstructorScopeAlias();
|
|
}
|
|
|
|
void testSubclassConstructorScopeAlias() {
|
|
var b1 = new B1(10);
|
|
Expect.equals(10, (b1.mfn)());
|
|
Expect.equals(10, b1.ma);
|
|
|
|
var b2 = new B2(11);
|
|
Expect.equals(11, (b2.mfn)());
|
|
Expect.equals(2, b2.ma);
|
|
|
|
var b3 = new B3(12);
|
|
Expect.equals(12, (b3.mfn)());
|
|
Expect.equals(12, (b3.ma)());
|
|
}
|
|
|
|
void testFnBindingInInitLists() {
|
|
Expect.equals(1, (new Bug4342163(1).m)());
|
|
}
|
|
|
|
void testFnBindingInStatics() {
|
|
StaticFunctionDef.init();
|
|
Expect.equals(1, ((StaticFunctionDef.fn1)()));
|
|
Expect.equals(1, ((StaticFunctionDef.fn2)()));
|
|
Expect.equals(1, ((StaticFunctionDef.fn3)()));
|
|
}
|
|
|
|
Fisk testReturnVoidFunction() {
|
|
void f() {}
|
|
Fisk x = f;
|
|
return f;
|
|
}
|
|
|
|
void testVarOrder1() {
|
|
var a = 0, b = a++, c = a++;
|
|
|
|
Expect.equals(a, 2);
|
|
Expect.equals(b, 0);
|
|
Expect.equals(c, 1);
|
|
}
|
|
|
|
void testVarOrder2() {
|
|
var a = 0;
|
|
f() {return a++;};
|
|
var b = f(), c = f();
|
|
|
|
Expect.equals(a, 2);
|
|
Expect.equals(b, 0);
|
|
Expect.equals(c, 1);
|
|
}
|
|
|
|
void testLexicalClosureRef1() {
|
|
var a = 1;
|
|
var f, g;
|
|
{
|
|
var b = 2;
|
|
f = () {return b - a;};
|
|
}
|
|
|
|
{
|
|
var b = 3;
|
|
g = () {return b - a;};
|
|
}
|
|
Expect.equals(1, f());
|
|
Expect.equals(2, g());
|
|
}
|
|
|
|
void testLexicalClosureRef2() {
|
|
var a = 1;
|
|
var f, g;
|
|
{
|
|
var b = 2;
|
|
f = () {return ((){return b - a;})();};
|
|
}
|
|
|
|
{
|
|
var b = 3;
|
|
g = () {return ((){return b - a;})();};
|
|
}
|
|
Expect.equals(1, f());
|
|
Expect.equals(2, g());
|
|
}
|
|
|
|
void testLexicalClosureRef3() {
|
|
var a = new List();
|
|
for (int i = 0; i < 10; i++) {
|
|
var x = i;
|
|
a.add(() {return x;});
|
|
}
|
|
|
|
var sum = 0;
|
|
for (int i = 0; i < a.length; i++) {
|
|
sum += (a[i])();
|
|
}
|
|
|
|
Expect.equals(45, sum);
|
|
}
|
|
|
|
void testLexicalClosureRef5() {
|
|
{
|
|
var a;
|
|
Expect.equals(null, a);
|
|
a = 1;
|
|
Expect.equals(1, a);
|
|
}
|
|
|
|
{
|
|
var a;
|
|
Expect.equals(null, a);
|
|
a = 1;
|
|
Expect.equals(1, a);
|
|
}
|
|
}
|
|
|
|
// Make sure labels are preserved, and a second 'i' does influence the first.
|
|
void testLexicalClosureRef4() {
|
|
var a = new List();
|
|
x:for (int i = 0; i < 10; i++) {
|
|
a.add(() {return i;});
|
|
continue x;
|
|
}
|
|
|
|
var sum = 0;
|
|
for (int i = 0; i < a.length; i++) {
|
|
sum += (a[i])();
|
|
}
|
|
|
|
Expect.equals(45, sum);
|
|
}
|
|
|
|
int tempField;
|
|
|
|
void testForEach() {
|
|
List<int> vals = [1,2,3];
|
|
int total = 0;
|
|
vals.forEach((int v) {
|
|
total += v;
|
|
});
|
|
Expect.equals(6, total);
|
|
}
|
|
|
|
void testDefaultParametersOrder() {
|
|
f([a = 1, b = 3]) {
|
|
return a - b;
|
|
}
|
|
Expect.equals(-2, f());
|
|
}
|
|
|
|
void testParametersOrder() {
|
|
f(a, b) {
|
|
return a - b;
|
|
}
|
|
Expect.equals(-2, f(1,3));
|
|
}
|
|
|
|
void testFunctionDefaults1() {
|
|
// TODO(jimhug): This return null shouldn't be necessary.
|
|
f() { return null; };
|
|
(([a = 10]) { Expect.equals(10, a); })();
|
|
((a, [b = 10]) { Expect.equals(10, b); })(1);
|
|
(([a = 10]) { Expect.equals(null, a); })( f() );
|
|
// FAILS: (([a = 10]) { Expect.equals(null ,a); })( f() );
|
|
}
|
|
|
|
void testFunctionDefaults2() {
|
|
Expect.equals(10, helperFunctionDefaults2());
|
|
Expect.equals(1, helperFunctionDefaults2(1));
|
|
}
|
|
|
|
num helperFunctionDefaults2([a = 10]) {
|
|
return ((){return a;})();
|
|
}
|
|
|
|
void testEscapingFunctions() {
|
|
f() { return 42; };
|
|
(() { Expect.equals(42, f()); })();
|
|
var o = new Bug4089219(42);
|
|
Expect.equals(42, (o.f)());
|
|
}
|
|
|
|
void testThisBinding() {
|
|
Expect.equals(this, () { return this; }());
|
|
}
|
|
}
|
|
|
|
typedef void Foo<A, B>(A a, B b);
|
|
|
|
class Bar<A, B> {
|
|
Foo<A, B> field;
|
|
Bar(A a, B b) : this.field = ((A a1, B b2){}) {
|
|
field(a, b);
|
|
}
|
|
}
|
|
|
|
typedef UntypedFunction(arg);
|
|
typedef UntypedFunction2(arg);
|
|
|
|
class UseFunctionTypes {
|
|
void test() {
|
|
Function f = null;
|
|
UntypedFunction uf = null;
|
|
UntypedFunction2 uf2 = null;
|
|
Foo foo = null;
|
|
Foo<int, String> fooIntString = null;
|
|
|
|
f = uf;
|
|
f = uf2;
|
|
f = foo;
|
|
f = fooIntString;
|
|
|
|
uf = f;
|
|
uf2 = f;
|
|
foo = f;
|
|
fooIntString = f;
|
|
|
|
foo = fooIntString;
|
|
fooIntString = foo;
|
|
|
|
uf = uf2;
|
|
uf2 = uf;
|
|
}
|
|
}
|
|
|
|
main() {
|
|
FunctionTest.testMain();
|
|
}
|