OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 // Dart test program testing closures. | |
5 | |
6 class LocalFunctionTest { | |
7 LocalFunctionTest() : field1 = 100, field2_ = 200 { } | |
8 static int f(int n) { | |
9 int a = 0; | |
10 g(int m) { | |
11 a = 3*n + m + 1; // Capture parameter n and local a. | |
12 return a; | |
13 } | |
14 var b = g(n); | |
15 return a + b; | |
16 } | |
17 static int h(int n) { | |
18 k(int n) { | |
19 var a = new List(n); | |
20 var b = new List(n); | |
21 int i; | |
22 for (i = 0; i < n; i++) { | |
23 var j = i; | |
24 a[i] = () => i; // Captured i is always n. | |
25 b[i] = () => j; // Captured j varies from 0 to n-1. | |
26 } | |
27 var a_sum = 0; | |
28 var b_sum = 0; | |
29 for (int i = 0; i < n; i++) { | |
30 a_sum += a[i](); | |
31 b_sum += b[i](); | |
32 } | |
33 return a_sum + b_sum; | |
34 } | |
35 return k(n); | |
36 } | |
37 static int h2(int n) { | |
38 k(int n) { | |
39 var a = new List(n); | |
40 var b = new List(n); | |
41 for (int i = 0; i < n; i++) { | |
42 var j = i; | |
43 a[i] = () => i; // Captured i varies from 0 to n-1. | |
44 b[i] = () => j; // Captured j varies from 0 to n-1. | |
45 } | |
46 var a_sum = 0; | |
47 var b_sum = 0; | |
48 for (int i = 0; i < n; i++) { | |
49 a_sum += a[i](); | |
50 b_sum += b[i](); | |
51 } | |
52 return a_sum + b_sum; | |
53 } | |
54 return k(n); | |
55 } | |
56 int field1; | |
57 int field2_; | |
58 int get field2() { return field2_; } | |
59 void set field2(int value) { field2_ = value; } | |
60 | |
61 int method(int n) { | |
62 incField1() { field1++; } | |
63 incField2() { field2++; } | |
64 for (int i = 0; i < n; i++) { | |
65 incField1(); | |
66 incField2(); | |
67 } | |
68 return field1 + field2; | |
69 } | |
70 int execute(int times, apply(int x)) { | |
71 for (int i = 0; i < times; i++) { | |
72 apply(i); | |
73 } | |
74 return field1; | |
75 } | |
76 int testExecute(int n) { | |
77 execute(n, (int x) { field1 += x; }); | |
78 return field1; | |
79 } | |
80 static int foo(int n) { | |
81 return -100; // Wrong foo. | |
82 } | |
83 static testSelfReference1(int n) { | |
84 int foo(int n) { | |
85 if (n == 0) { | |
86 return 0; | |
87 } else { | |
88 return 1 + foo(n - 1); // Local foo, not static foo. | |
89 } | |
90 }; | |
91 return foo(n); // Local foo, not static foo. | |
92 } | |
93 static void hep(Function f) { | |
94 f(); | |
95 } | |
96 static testSelfReference3(int n) { | |
97 int i = 0; | |
98 var yup; // Not in same scope as yup below. | |
99 hep(yup() { | |
100 if (++i < n) hep(yup); | |
101 }); | |
102 return i; | |
103 } | |
104 static testNesting(int n) { | |
105 var a = new List(n*n); | |
106 f0() { | |
107 for (int i = 0; i < n; i++) { | |
108 int vi = i; | |
109 f1() { | |
110 for (int j = 0; j < n; j++) { | |
111 int vj = j; | |
112 a[i*n + j] = () => vi*n + vj; | |
113 } | |
114 } | |
115 f1(); | |
116 } | |
117 } | |
118 f0(); | |
119 int result = 0; | |
120 for (int k = 0; k < n*n; k++) { | |
121 Expect.equals(k, a[k]()); | |
122 result += a[k](); | |
123 } | |
124 return result; | |
125 } | |
126 | |
127 static var field5; | |
128 static var set_field5_func; | |
129 static testClosureCallStatement(int x) { | |
130 LocalFunctionTest.set_field5_func = (int n) { field5 = n * n; }; | |
131 (LocalFunctionTest.set_field5_func)(x); | |
132 Expect.equals(x * x, LocalFunctionTest.field5); | |
133 return true; | |
134 } | |
135 | |
136 static testExceptions() { | |
137 var f = (int n) => n + 1; | |
138 Expect.equals(2, f(1)); | |
139 Expect.equals(true, f is Function); | |
140 Expect.equals(true, f is Object); | |
141 Expect.equals(true, f.toString().startsWith("Closure")); | |
142 bool exception_caught = false; | |
143 try { | |
144 f(1, 2); | |
145 } catch (ClosureArgumentMismatchException e) { | |
146 exception_caught = true; | |
147 } | |
148 Expect.equals(true, exception_caught); | |
149 exception_caught = false; | |
150 try { | |
151 f(); | |
152 } catch (ClosureArgumentMismatchException e) { | |
153 exception_caught = true; | |
154 } | |
155 Expect.equals(true, exception_caught); | |
156 exception_caught = false; | |
157 try { | |
158 f.xyz(0); | |
159 } catch (NoSuchMethodException e) { | |
160 exception_caught = true; | |
161 } | |
162 Expect.equals(true, exception_caught); | |
163 | |
164 // Overwrite closure value. | |
165 f = 3; | |
166 exception_caught = false; | |
167 try { | |
168 f(1); | |
169 } catch (ObjectNotClosureException e) { | |
170 exception_caught = true; | |
171 } | |
172 Expect.equals(true, exception_caught); | |
173 | |
174 // Do not expect any exceptions to be thrown. | |
175 var g = ([int n = 1]) => n + 1; | |
176 Expect.equals(2, g()); | |
177 Expect.equals(3, g(2)); | |
178 } | |
179 | |
180 static int doThis(int n, int f(int n)) { | |
181 return f(n); | |
182 } | |
183 | |
184 static testMain() { | |
185 Expect.equals(2*(3*2 + 2 + 1), f(2)); | |
186 Expect.equals(10*10 + 10*9/2, h(10)); | |
187 Expect.equals(90, h2(10)); | |
188 Expect.equals(320, new LocalFunctionTest().method(10)); | |
189 Expect.equals(145, new LocalFunctionTest().testExecute(10)); | |
190 Expect.equals(5, testSelfReference1(5)); | |
191 Expect.equals(5, testSelfReference3(5)); | |
192 Expect.equals(24*25/2, testNesting(5)); | |
193 Expect.equals(true, testClosureCallStatement(7)); | |
194 Expect.equals(99, doThis(10, int _(n) => n * n - 1)); | |
195 Expect.equals(99, doThis(10, int f(n) => n * n - 1)); | |
196 Expect.equals(99, doThis(10, (n) => n * n - 1)); | |
197 Expect.equals(99, doThis(10, f(n) => n * n - 1)); | |
198 testExceptions(); | |
199 } | |
200 } | |
201 | |
202 main() { | |
203 LocalFunctionTest.testMain(); | |
204 } | |
OLD | NEW |