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 33 function props(x) { 34 var array = []; 35 for (let p in x) array.push(p); 36 return array.sort(); 37 } 38 39 assertEquals(0, props({}).length); 40 assertEquals(1, props({x:1}).length); 41 assertEquals(2, props({x:1, y:2}).length); 42 43 assertArrayEquals(["x"], props({x:1})); 44 assertArrayEquals(["x", "y"], props({x:1, y:2})); 45 assertArrayEquals(["x", "y", "zoom"], props({x:1, y:2, zoom:3})); 46 47 assertEquals(0, props([]).length); 48 assertEquals(1, props([1]).length); 49 assertEquals(2, props([1,2]).length); 50 51 assertArrayEquals(["0"], props([1])); 52 assertArrayEquals(["0", "1"], props([1,2])); 53 assertArrayEquals(["0", "1", "2"], props([1,2,3])); 54 55 var o = {}; 56 var a = []; 57 let i = "outer_i"; 58 let s = "outer_s"; 59 for (let i = 0x0020; i < 0x01ff; i+=2) { 60 let s = 'char:' + String.fromCharCode(i); 61 a.push(s); 62 o[s] = i; 63 } 64 assertArrayEquals(a, props(o)); 65 assertEquals(i, "outer_i"); 66 assertEquals(s, "outer_s"); 67 68 var a = []; 69 assertEquals(0, props(a).length); 70 a[Math.pow(2,30)-1] = 0; 71 assertEquals(1, props(a).length); 72 a[Math.pow(2,31)-1] = 0; 73 assertEquals(2, props(a).length); 74 a[1] = 0; 75 assertEquals(3, props(a).length); 76 77 var result = ''; 78 for (let p in {a : [0], b : 1}) { result += p; } 79 assertEquals('ab', result); 80 81 var result = ''; 82 for (let p in {a : {v:1}, b : 1}) { result += p; } 83 assertEquals('ab', result); 84 85 var result = ''; 86 for (let p in { get a() {}, b : 1}) { result += p; } 87 assertEquals('ab', result); 88 89 var result = ''; 90 for (let p in { get a() {}, set a(x) {}, b : 1}) { result += p; } 91 assertEquals('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 97 assertThrows("function foo() { 'use strict'; for (let in {}) { } }", SyntaxError); 98 assertThrows("function foo() { 'use strict'; for (let x = 3 in {}) { } }", SyntaxError); 99 assertThrows("function foo() { 'use strict'; for (let x, y in {}) { } }", SyntaxError); 100 assertThrows("function foo() { 'use strict'; for (let x = 3, y in {}) { } }", SyntaxError); 101 assertThrows("function foo() { 'use strict'; for (let x, y = 4 in {}) { } }", SyntaxError); 102 assertThrows("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. 107 function 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 } 116 closures1(); 117 118 119 function 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 } 130 closures2(); 131 132 133 // In a for-in statement the iteration variable is fresh 134 // for earch iteration. 135 function 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 } 146 closures3({a : [0], b : 1, c : {v : 1}, get d() {}, set e(x) {}}); 147