blob: 8051fe2cf0d5caa02bf4e588c30def0d0702b0af [file] [log] [blame]
// 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.
import "package:expect/expect.dart";
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 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);
} on NoSuchMethodError catch (e) {
exception_caught = true;
}
Expect.equals(true, exception_caught);
exception_caught = false;
try {
f();
} on NoSuchMethodError catch (e) {
exception_caught = true;
}
Expect.equals(true, exception_caught);
exception_caught = false;
try {
f.xyz(0);
} on NoSuchMethodError catch (e) {
exception_caught = true;
}
Expect.equals(true, exception_caught);
// Overwrite closure value.
f = 3;
exception_caught = false;
try {
f(1);
} on NoSuchMethodError catch (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(24*25/2, testNesting(5));
Expect.equals(true, testClosureCallStatement(7));
Expect.equals(99, doThis(10, (n) => n * n - 1));
testExceptions();
}
}
main() {
LocalFunctionTest.testMain();
}