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// TODO(ES6): properly activate extended mode 31"use strict"; 32 33function props(x) { 34 var array = []; 35 for (let p in x) array.push(p); 36 return array.sort(); 37} 38 39assertEquals(0, props({}).length); 40assertEquals(1, props({x:1}).length); 41assertEquals(2, props({x:1, y:2}).length); 42 43assertArrayEquals(["x"], props({x:1})); 44assertArrayEquals(["x", "y"], props({x:1, y:2})); 45assertArrayEquals(["x", "y", "zoom"], props({x:1, y:2, zoom:3})); 46 47assertEquals(0, props([]).length); 48assertEquals(1, props([1]).length); 49assertEquals(2, props([1,2]).length); 50 51assertArrayEquals(["0"], props([1])); 52assertArrayEquals(["0", "1"], props([1,2])); 53assertArrayEquals(["0", "1", "2"], props([1,2,3])); 54 55var o = {}; 56var a = []; 57let i = "outer_i"; 58let s = "outer_s"; 59for (let i = 0x0020; i < 0x01ff; i+=2) { 60 let s = 'char:' + String.fromCharCode(i); 61 a.push(s); 62 o[s] = i; 63} 64assertArrayEquals(a, props(o)); 65assertEquals(i, "outer_i"); 66assertEquals(s, "outer_s"); 67 68var a = []; 69assertEquals(0, props(a).length); 70a[Math.pow(2,30)-1] = 0; 71assertEquals(1, props(a).length); 72a[Math.pow(2,31)-1] = 0; 73assertEquals(2, props(a).length); 74a[1] = 0; 75assertEquals(3, props(a).length); 76 77var result = ''; 78for (let p in {a : [0], b : 1}) { result += p; } 79assertEquals('ab', result); 80 81var result = ''; 82for (let p in {a : {v:1}, b : 1}) { result += p; } 83assertEquals('ab', result); 84 85var result = ''; 86for (let p in { get a() {}, b : 1}) { result += p; } 87assertEquals('ab', result); 88 89var result = ''; 90for (let p in { get a() {}, set a(x) {}, b : 1}) { result += p; } 91assertEquals('ab', result); 92 93 94// Check that there is exactly one variable without initializer 95// in a for-in statement with let variables. 96// TODO(ES6): properly activate extended mode 97assertThrows("function foo() { 'use strict'; for (let in {}) { } }", SyntaxError); 98assertThrows("function foo() { 'use strict'; for (let x = 3 in {}) { } }", SyntaxError); 99assertThrows("function foo() { 'use strict'; for (let x, y in {}) { } }", SyntaxError); 100assertThrows("function foo() { 'use strict'; for (let x = 3, y in {}) { } }", SyntaxError); 101assertThrows("function foo() { 'use strict'; for (let x, y = 4 in {}) { } }", SyntaxError); 102assertThrows("function foo() { 'use strict'; for (let x = 3, y = 4 in {}) { } }", SyntaxError); 103 104 105// In a normal for statement the iteration variable is not 106// freshly allocated for each iteration. 107function closures1() { 108 let a = []; 109 for (let i = 0; i < 5; ++i) { 110 a.push(function () { return i; }); 111 } 112 for (let j = 0; j < 5; ++j) { 113 assertEquals(5, a[j]()); 114 } 115} 116closures1(); 117 118 119function closures2() { 120 let a = [], b = []; 121 for (let i = 0, j = 10; i < 5; ++i, ++j) { 122 a.push(function () { return i; }); 123 b.push(function () { return j; }); 124 } 125 for (let k = 0; k < 5; ++k) { 126 assertEquals(5, a[k]()); 127 assertEquals(15, b[k]()); 128 } 129} 130closures2(); 131 132 133// In a for-in statement the iteration variable is fresh 134// for earch iteration. 135function closures3(x) { 136 let a = []; 137 for (let p in x) { 138 a.push(function () { return p; }); 139 } 140 let k = 0; 141 for (let q in x) { 142 assertEquals(q, a[k]()); 143 ++k; 144 } 145} 146closures3({a : [0], b : 1, c : {v : 1}, get d() {}, set e(x) {}}); 147