1// 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-scoping 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_next(); 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 earch 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