64d7bc5acf
Review URL: https://chromiumcodereview.appspot.com//10248007 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@7101 260f80e4-7a28-3924-810f-c04153c831b5
205 lines
5.1 KiB
Dart
205 lines
5.1 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.
|
|
// Dart test program testing closures.
|
|
|
|
class LocalFunctionTest {
|
|
LocalFunctionTest() : field1 = 100, field2_ = 200 { }
|
|
static int f(int n) {
|
|
int a = 0;
|
|
g(int m) {
|
|
a = 3*n + m + 1; // Capture parameter n and local a.
|
|
return a;
|
|
}
|
|
var b = g(n);
|
|
return a + b;
|
|
}
|
|
static int h(int n) {
|
|
k(int n) {
|
|
var a = new List(n);
|
|
var b = new List(n);
|
|
int i;
|
|
for (i = 0; i < n; i++) {
|
|
var j = i;
|
|
a[i] = () => i; // Captured i is always n.
|
|
b[i] = () => j; // Captured j varies from 0 to n-1.
|
|
}
|
|
var a_sum = 0;
|
|
var b_sum = 0;
|
|
for (int i = 0; i < n; i++) {
|
|
a_sum += a[i]();
|
|
b_sum += b[i]();
|
|
}
|
|
return a_sum + b_sum;
|
|
}
|
|
return k(n);
|
|
}
|
|
static int h2(int n) {
|
|
k(int n) {
|
|
var a = new List(n);
|
|
var b = new List(n);
|
|
for (int i = 0; i < n; i++) {
|
|
var j = i;
|
|
a[i] = () => i; // Captured i varies from 0 to n-1.
|
|
b[i] = () => j; // Captured j varies from 0 to n-1.
|
|
}
|
|
var a_sum = 0;
|
|
var b_sum = 0;
|
|
for (int i = 0; i < n; i++) {
|
|
a_sum += a[i]();
|
|
b_sum += b[i]();
|
|
}
|
|
return a_sum + b_sum;
|
|
}
|
|
return k(n);
|
|
}
|
|
int field1;
|
|
int field2_;
|
|
int get field2() { return field2_; }
|
|
void set field2(int value) { field2_ = value; }
|
|
|
|
int method(int n) {
|
|
incField1() { field1++; }
|
|
incField2() { field2++; }
|
|
for (int i = 0; i < n; i++) {
|
|
incField1();
|
|
incField2();
|
|
}
|
|
return field1 + field2;
|
|
}
|
|
int execute(int times, apply(int x)) {
|
|
for (int i = 0; i < times; i++) {
|
|
apply(i);
|
|
}
|
|
return field1;
|
|
}
|
|
int testExecute(int n) {
|
|
execute(n, (int x) { field1 += x; });
|
|
return field1;
|
|
}
|
|
static int foo(int n) {
|
|
return -100; // Wrong foo.
|
|
}
|
|
static testSelfReference1(int n) {
|
|
int foo(int n) {
|
|
if (n == 0) {
|
|
return 0;
|
|
} else {
|
|
return 1 + foo(n - 1); // Local foo, not static foo.
|
|
}
|
|
};
|
|
return foo(n); // Local foo, not static foo.
|
|
}
|
|
static void hep(Function f) {
|
|
f();
|
|
}
|
|
static testSelfReference3(int n) {
|
|
int i = 0;
|
|
var yup; // Not in same scope as yup below.
|
|
hep(yup() {
|
|
if (++i < n) hep(yup);
|
|
});
|
|
return i;
|
|
}
|
|
static testNesting(int n) {
|
|
var a = new List(n*n);
|
|
f0() {
|
|
for (int i = 0; i < n; i++) {
|
|
int vi = i;
|
|
f1() {
|
|
for (int j = 0; j < n; j++) {
|
|
int vj = j;
|
|
a[i*n + j] = () => vi*n + vj;
|
|
}
|
|
}
|
|
f1();
|
|
}
|
|
}
|
|
f0();
|
|
int result = 0;
|
|
for (int k = 0; k < n*n; k++) {
|
|
Expect.equals(k, a[k]());
|
|
result += a[k]();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
static var field5;
|
|
static var set_field5_func;
|
|
static testClosureCallStatement(int x) {
|
|
LocalFunctionTest.set_field5_func = (int n) { field5 = n * n; };
|
|
(LocalFunctionTest.set_field5_func)(x);
|
|
Expect.equals(x * x, LocalFunctionTest.field5);
|
|
return true;
|
|
}
|
|
|
|
static testExceptions() {
|
|
var f = (int n) => n + 1;
|
|
Expect.equals(2, f(1));
|
|
Expect.equals(true, f is Function);
|
|
Expect.equals(true, f is Object);
|
|
Expect.equals(true, f.toString().startsWith("Closure"));
|
|
bool exception_caught = false;
|
|
try {
|
|
f(1, 2);
|
|
} catch (ClosureArgumentMismatchException e) {
|
|
exception_caught = true;
|
|
}
|
|
Expect.equals(true, exception_caught);
|
|
exception_caught = false;
|
|
try {
|
|
f();
|
|
} catch (ClosureArgumentMismatchException e) {
|
|
exception_caught = true;
|
|
}
|
|
Expect.equals(true, exception_caught);
|
|
exception_caught = false;
|
|
try {
|
|
f.xyz(0);
|
|
} catch (NoSuchMethodException e) {
|
|
exception_caught = true;
|
|
}
|
|
Expect.equals(true, exception_caught);
|
|
|
|
// Overwrite closure value.
|
|
f = 3;
|
|
exception_caught = false;
|
|
try {
|
|
f(1);
|
|
} catch (ObjectNotClosureException e) {
|
|
exception_caught = true;
|
|
}
|
|
Expect.equals(true, exception_caught);
|
|
|
|
// Do not expect any exceptions to be thrown.
|
|
var g = ([int n = 1]) => n + 1;
|
|
Expect.equals(2, g());
|
|
Expect.equals(3, g(2));
|
|
}
|
|
|
|
static int doThis(int n, int f(int n)) {
|
|
return f(n);
|
|
}
|
|
|
|
static testMain() {
|
|
Expect.equals(2*(3*2 + 2 + 1), f(2));
|
|
Expect.equals(10*10 + 10*9/2, h(10));
|
|
Expect.equals(90, h2(10));
|
|
Expect.equals(320, new LocalFunctionTest().method(10));
|
|
Expect.equals(145, new LocalFunctionTest().testExecute(10));
|
|
Expect.equals(5, testSelfReference1(5));
|
|
Expect.equals(5, testSelfReference3(5));
|
|
Expect.equals(24*25/2, testNesting(5));
|
|
Expect.equals(true, testClosureCallStatement(7));
|
|
Expect.equals(99, doThis(10, int _(n) => n * n - 1));
|
|
Expect.equals(99, doThis(10, int f(n) => n * n - 1));
|
|
Expect.equals(99, doThis(10, (n) => n * n - 1));
|
|
Expect.equals(99, doThis(10, f(n) => n * n - 1));
|
|
testExceptions();
|
|
}
|
|
}
|
|
|
|
main() {
|
|
LocalFunctionTest.testMain();
|
|
}
|