blob: c7a23e8d32f18ec6b39693482bfe5935ec3af36a [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2011 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28// Flags: --harmony-completion
29
30"use strict";
31
32function props(x) {
33 var array = [];
34 for (let p in x) array.push(p);
35 return array.sort();
36}
37
38assertEquals(0, props({}).length);
39assertEquals(1, props({x:1}).length);
40assertEquals(2, props({x:1, y:2}).length);
41
42assertArrayEquals(["x"], props({x:1}));
43assertArrayEquals(["x", "y"], props({x:1, y:2}));
44assertArrayEquals(["x", "y", "zoom"], props({x:1, y:2, zoom:3}));
45
46assertEquals(0, props([]).length);
47assertEquals(1, props([1]).length);
48assertEquals(2, props([1,2]).length);
49
50assertArrayEquals(["0"], props([1]));
51assertArrayEquals(["0", "1"], props([1,2]));
52assertArrayEquals(["0", "1", "2"], props([1,2,3]));
53
54var o = {};
55var a = [];
56let i = "outer_i";
57let s = "outer_s";
58for (let i = 0x0020; i < 0x01ff; i+=2) {
59 let s = 'char:' + String.fromCharCode(i);
60 a.push(s);
61 o[s] = i;
62}
63assertArrayEquals(a, props(o));
64assertEquals(i, "outer_i");
65assertEquals(s, "outer_s");
66
67var a = [];
68assertEquals(0, props(a).length);
69a[Math.pow(2,30)-1] = 0;
70assertEquals(1, props(a).length);
71a[Math.pow(2,31)-1] = 0;
72assertEquals(2, props(a).length);
73a[1] = 0;
74assertEquals(3, props(a).length);
75
76var result = '';
77for (let p in {a : [0], b : 1}) { result += p; }
78assertEquals('ab', result);
79
80var result = '';
81for (let p in {a : {v:1}, b : 1}) { result += p; }
82assertEquals('ab', result);
83
84var result = '';
85for (let p in { get a() {}, b : 1}) { result += p; }
86assertEquals('ab', result);
87
88var result = '';
89for (let p in { get a() {}, set a(x) {}, b : 1}) { result += p; }
90assertEquals('ab', result);
91
92
93// Check that there is exactly one variable without initializer
94// in a for-in statement with let variables.
95assertThrows("function foo() { 'use strict'; for (let in {}) { } }", SyntaxError);
96assertThrows("function foo() { 'use strict'; for (let x = 3 in {}) { } }", SyntaxError);
97assertThrows("function foo() { 'use strict'; for (let x, y in {}) { } }", SyntaxError);
98assertThrows("function foo() { 'use strict'; for (let x = 3, y in {}) { } }", SyntaxError);
99assertThrows("function foo() { 'use strict'; for (let x, y = 4 in {}) { } }", SyntaxError);
100assertThrows("function foo() { 'use strict'; for (let x = 3, y = 4 in {}) { } }", SyntaxError);
101
102
103// In a normal for statement the iteration variable is
104// freshly allocated for each iteration.
105function closures1() {
106 let a = [];
107 for (let i = 0; i < 5; ++i) {
108 a.push(function () { return i; });
109 }
110 for (let j = 0; j < 5; ++j) {
111 assertEquals(j, a[j]());
112 }
113}
114closures1();
115
116
117function closures2() {
118 let a = [], b = [];
119 for (let i = 0, j = 10; i < 5; ++i, ++j) {
120 a.push(function () { return i; });
121 b.push(function () { return j; });
122 }
123 for (let k = 0; k < 5; ++k) {
124 assertEquals(k, a[k]());
125 assertEquals(k + 10, b[k]());
126 }
127}
128closures2();
129
130
131function closure_in_for_init() {
132 let a = [];
133 for (let i = 0, f = function() { return i }; i < 5; ++i) {
134 a.push(f);
135 }
136 for (let k = 0; k < 5; ++k) {
137 assertEquals(0, a[k]());
138 }
139}
140closure_in_for_init();
141
142
143function closure_in_for_cond() {
144 let a = [];
145 for (let i = 0; a.push(function () { return i; }), i < 5; ++i) { }
146 for (let k = 0; k < 5; ++k) {
147 assertEquals(k, a[k]());
148 }
149}
150closure_in_for_cond();
151
152
153function closure_in_for_next() {
154 let a = [];
155 for (let i = 0; i < 5; a.push(function () { return i; }), ++i) { }
156 for (let k = 0; k < 5; ++k) {
157 assertEquals(k + 1, a[k]());
158 }
159}
160closure_in_for_next();
161
162
163// In a for-in statement the iteration variable is fresh
164// for each iteration.
165function closures3(x) {
166 let a = [];
167 for (let p in x) {
168 a.push(function () { return p; });
169 }
170 let k = 0;
171 for (let q in x) {
172 assertEquals(q, a[k]());
173 ++k;
174 }
175}
176closures3({a : [0], b : 1, c : {v : 1}, get d() {}, set e(x) {}});
177
178// Check normal for statement completion values.
179assertEquals(1, eval("for (let i = 0; i < 10; i++) { 1; }"));
180assertEquals(9, eval("for (let i = 0; i < 10; i++) { i; }"));
181assertEquals(undefined, eval("for (let i = 0; false;) { }"));
182assertEquals(undefined, eval("for (const i = 0; false;) { }"));
183assertEquals(undefined, eval("for (let i = 0; i < 10; i++) { }"));
184assertEquals(undefined, eval("for (let i = 0; false;) { i; }"));
185assertEquals(undefined, eval("for (const i = 0; false;) { i; }"));
186assertEquals(undefined, eval("for (let i = 0; true;) { break; }"));
187assertEquals(undefined, eval("for (const i = 0; true;) { break; }"));
188assertEquals(undefined, eval("for (let i = 0; i < 10; i++) { continue; }"));
189assertEquals(undefined, eval("for (let i = 0; true;) { break; i; }"));
190assertEquals(undefined, eval("for (const i = 0; true;) { break; i; }"));
191assertEquals(undefined, eval("for (let i = 0; i < 10; i++) { continue; i; }"));
192assertEquals(0, eval("for (let i = 0; true;) { i; break; }"));
193assertEquals(0, eval("for (const i = 0; true;) { i; break; }"));
194assertEquals(9, eval("for (let i = 0; i < 10; i++) { i; continue; }"));
195assertEquals(undefined,
196 eval("for (let i = 0; true; i++) { i; if (i >= 3) break; }"));
197assertEquals(3,
198 eval("for (let i = 0; true; i++) { i; if (i >= 3) { i; break; } }"));
199assertEquals(undefined,
200 eval("for (let i = 0; true; i++) { if (i >= 3) break; i; }"));
201assertEquals(3,
202 eval("for (let i = 0; true; i++) { if (i >= 3) { i; break; }; i; }"));
203assertEquals(undefined,
204 eval("for (let i = 0; i < 10; i++) { if (i >= 3) continue; i; }"));
205assertEquals(9,
206 eval("for (let i = 0; i < 10; i++) { if (i >= 3) {i; continue; }; i; }"));
207assertEquals(undefined, eval("foo: for (let i = 0; true;) { break foo; }"));
208assertEquals(undefined, eval("foo: for (const i = 0; true;) { break foo; }"));
209assertEquals(3, eval("foo: for (let i = 3; true;) { i; break foo; }"));