mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 03:47:13 +00:00
6b3576f673
Also fixes a variety of miscellaneous accidental strong mode compile time or runtime check violations. Change-Id: Ia8a41ac291aff3689efae0b11a9c51a2db30ef33 Reviewed-on: https://dart-review.googlesource.com/34924 Reviewed-by: Bob Nystrom <rnystrom@google.com>
379 lines
6.4 KiB
Dart
379 lines
6.4 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)
|
|
: this.mfn = (() {
|
|
return a;
|
|
}),
|
|
super(a);
|
|
}
|
|
|
|
class B2 extends A {
|
|
final mfn;
|
|
B2(int a)
|
|
: this.mfn = (() {
|
|
return a;
|
|
}),
|
|
super(2);
|
|
}
|
|
|
|
class B3 extends A {
|
|
final mfn;
|
|
B3(int a)
|
|
: this.mfn = (() {
|
|
return a;
|
|
}),
|
|
super(() {
|
|
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;
|
|
Foo<Object, Object> fooObjectObject = null;
|
|
|
|
f = uf;
|
|
f = uf2;
|
|
f = foo;
|
|
f = fooIntString;
|
|
|
|
uf = f;
|
|
uf2 = f;
|
|
foo = f;
|
|
fooIntString = f;
|
|
|
|
fooIntString = foo;
|
|
|
|
foo = fooObjectObject;
|
|
fooObjectObject = foo;
|
|
|
|
uf = uf2;
|
|
uf2 = uf;
|
|
}
|
|
}
|
|
|
|
main() {
|
|
FunctionTest.testMain();
|
|
}
|