blob: 982dcf924bb7f920a2e270853a87f65ab59e3506 [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.
// @dart = 2.9
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() {
dynamic 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();
}