block-scoping.js revision 592a9fc1d8ea420377a2e7efd0600e20b058be2b
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: --allow-natives-syntax --harmony-scoping
29// Test functionality of block scopes.
30
31// TODO(ES6): properly activate extended mode
32"use strict";
33
34// Hoisting of var declarations.
35function f1() {
36  {
37    var x = 1;
38    var y;
39  }
40  assertEquals(1, x)
41  assertEquals(undefined, y)
42}
43f1();
44
45
46// Dynamic lookup in and through block contexts.
47function f2(one) {
48  var x = one + 1;
49  let y = one + 2;
50  const u = one + 4;
51  {
52    let z = one + 3;
53    const v = one + 5;
54    assertEquals(1, eval('one'));
55    assertEquals(2, eval('x'));
56    assertEquals(3, eval('y'));
57    assertEquals(4, eval('z'));
58    assertEquals(5, eval('u'));
59    assertEquals(6, eval('v'));
60  }
61}
62f2(1);
63
64
65// Lookup in and through block contexts.
66function f3(one) {
67  var x = one + 1;
68  let y = one + 2;
69  const u = one + 4;
70  {
71    let z = one + 3;
72    const v = one + 5;
73    assertEquals(1, one);
74    assertEquals(2, x);
75    assertEquals(3, y);
76    assertEquals(4, z);
77    assertEquals(5, u);
78    assertEquals(6, v);
79
80  }
81}
82f3(1);
83
84
85// Dynamic lookup from closure.
86function f4(one) {
87  var x = one + 1;
88  let y = one + 2;
89  const u = one + 4;
90  {
91    let z = one + 3;
92    const v = one + 5;
93    function f() {
94      assertEquals(1, eval('one'));
95      assertEquals(2, eval('x'));
96      assertEquals(3, eval('y'));
97      assertEquals(4, eval('z'));
98      assertEquals(5, eval('u'));
99      assertEquals(6, eval('v'));
100    };
101  }
102}
103f4(1);
104
105
106// Lookup from closure.
107function f5(one) {
108  var x = one + 1;
109  let y = one + 2;
110  const u = one + 4;
111  {
112    let z = one + 3;
113    const v = one + 5;
114    function f() {
115      assertEquals(1, one);
116      assertEquals(2, x);
117      assertEquals(3, y);
118      assertEquals(4, z);
119      assertEquals(5, u);
120      assertEquals(6, v);
121    };
122  }
123}
124f5(1);
125
126
127// Return from block.
128function f6() {
129  let x = 1;
130  const u = 3;
131  {
132    let y = 2;
133    const v = 4;
134    return x + y;
135  }
136}
137assertEquals(3, f6(6));
138
139
140// Variable shadowing and lookup.
141function f7(a) {
142  let b = 1;
143  var c = 1;
144  var d = 1;
145  const e = 1;
146  { // let variables shadowing argument, let, const and var variables
147    let a = 2;
148    let b = 2;
149    let c = 2;
150    let e = 2;
151    assertEquals(2,a);
152    assertEquals(2,b);
153    assertEquals(2,c);
154    assertEquals(2,e);
155  }
156  { // const variables shadowing argument, let, const and var variables
157    const a = 2;
158    const b = 2;
159    const c = 2;
160    const e = 2;
161    assertEquals(2,a);
162    assertEquals(2,b);
163    assertEquals(2,c);
164    assertEquals(2,e);
165  }
166  try {
167    throw 'stuff1';
168  } catch (a) {
169    assertEquals('stuff1',a);
170    // catch variable shadowing argument
171    a = 2;
172    assertEquals(2,a);
173    {
174      // let variable shadowing catch variable
175      let a = 3;
176      assertEquals(3,a);
177      try {
178        throw 'stuff2';
179      } catch (a) {
180        assertEquals('stuff2',a);
181        // catch variable shadowing let variable
182        a = 4;
183        assertEquals(4,a);
184      }
185      assertEquals(3,a);
186    }
187    assertEquals(2,a);
188  }
189  try {
190    throw 'stuff3';
191  } catch (c) {
192    // catch variable shadowing var variable
193    assertEquals('stuff3',c);
194    {
195      // const variable shadowing catch variable
196      const c = 3;
197      assertEquals(3,c);
198    }
199    assertEquals('stuff3',c);
200    try {
201      throw 'stuff4';
202    } catch(c) {
203      assertEquals('stuff4',c);
204      // catch variable shadowing catch variable
205      c = 3;
206      assertEquals(3,c);
207    }
208    (function(c) {
209      // argument shadowing catch variable
210      c = 3;
211      assertEquals(3,c);
212    })();
213    assertEquals('stuff3', c);
214    (function() {
215      // var variable shadowing catch variable
216      var c = 3;
217    })();
218    assertEquals('stuff3', c);
219    c = 2;
220  }
221  assertEquals(1,c);
222  (function(a,b,c,e) {
223    // arguments shadowing argument, let, const and var variable
224    a = 2;
225    b = 2;
226    c = 2;
227    e = 2;
228    assertEquals(2,a);
229    assertEquals(2,b);
230    assertEquals(2,c);
231    assertEquals(2,e);
232    // var variable shadowing var variable
233    var d = 2;
234  })(1,1);
235  assertEquals(1,a);
236  assertEquals(1,b);
237  assertEquals(1,c);
238  assertEquals(1,d);
239  assertEquals(1,e);
240}
241f7(1);
242
243
244// Ensure let and const variables are block local
245// and var variables function local.
246function f8() {
247  var let_accessors = [];
248  var var_accessors = [];
249  var const_accessors = [];
250  for (var i = 0; i < 10; i++) {
251    let x = i;
252    var y = i;
253    const z = i;
254    let_accessors[i] = function() { return x; }
255    var_accessors[i] = function() { return y; }
256    const_accessors[i] = function() { return z; }
257  }
258  for (var j = 0; j < 10; j++) {
259    y = j + 10;
260    assertEquals(j, let_accessors[j]());
261    assertEquals(y, var_accessors[j]());
262    assertEquals(j, const_accessors[j]());
263  }
264}
265f8();
266