// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Flags: --allow-natives-syntax --opt
// Test functionality of block scopes.

"use strict";

// Hoisting of var declarations.
function f1() {
  {
    var x = 1;
    var y;
  }
  assertEquals(1, x)
  assertEquals(undefined, y)
}
for (var j = 0; j < 5; ++j) f1();
%OptimizeFunctionOnNextCall(f1);
f1();
assertOptimized(f1);

// Dynamic lookup in and through block contexts.
function f2(one) {
  var x = one + 1;
  let y = one + 2;
  const u = one + 4;
  class a { static foo() { return one + 6; } }
  {
    let z = one + 3;
    const v = one + 5;
    class b { static foo() { return one + 7; } }
    assertEquals(1, eval('one'));
    assertEquals(2, eval('x'));
    assertEquals(3, eval('y'));
    assertEquals(4, eval('z'));
    assertEquals(5, eval('u'));
    assertEquals(6, eval('v'));
    assertEquals(7, eval('a.foo()'));
    assertEquals(8, eval('b.foo()'));
  }
}

f2(1);

// Lookup in and through block contexts.
function f3(one) {
  var x = one + 1;
  let y = one + 2;
  const u = one + 4;
  class a { static foo() { return one + 6; } }
  {
    let z = one + 3;
    const v = one + 5;
    class b { static foo() { return one + 7; } }
    assertEquals(1, one);
    assertEquals(2, x);
    assertEquals(3, y);
    assertEquals(4, z);
    assertEquals(5, u);
    assertEquals(6, v);
    assertEquals(7, a.foo());
    assertEquals(8, b.foo());
  }
}
for (var j = 0; j < 5; ++j) f3(1);
%OptimizeFunctionOnNextCall(f3);
f3(1);



// Dynamic lookup from closure.
function f4(one) {
  var x = one + 1;
  let y = one + 2;
  const u = one + 4;
  class a { static foo() { return one + 6; } }
  {
    let z = one + 3;
    const v = one + 5;
    class b { static foo() { return one + 7; } }
    function f() {
      assertEquals(1, eval('one'));
      assertEquals(2, eval('x'));
      assertEquals(3, eval('y'));
      assertEquals(4, eval('z'));
      assertEquals(5, eval('u'));
      assertEquals(6, eval('v'));
      assertEquals(7, eval('a.foo()'));
      assertEquals(8, eval('b.foo()'));
    }
    f();
  }
}
f4(1);


// Lookup from closure.
function f5(one) {
  var x = one + 1;
  let y = one + 2;
  const u = one + 4;
  class a { static foo() { return one + 6; } }
  {
    let z = one + 3;
    const v = one + 5;
    class b { static foo() { return one + 7; } }
    function f() {
      assertEquals(1, one);
      assertEquals(2, x);
      assertEquals(3, y);
      assertEquals(4, z);
      assertEquals(5, u);
      assertEquals(6, v);
      assertEquals(7, a.foo());
      assertEquals(8, b.foo());
    }
    f();
  }
}
f5(1);


// Return from block.
function f6() {
  let x = 1;
  const u = 3;
  {
    let y = 2;
    const v = 4;
    return x + y;
  }
}
assertEquals(3, f6(6));


// Variable shadowing and lookup.
function f7(a) {
  let b = 1;
  var c = 1;
  var d = 1;
  const e = 1;
  class f { static foo() { return 1; } }
  { // let variables shadowing argument, let, const, class and var variables
    let a = 2;
    let b = 2;
    let c = 2;
    let e = 2;
    let f = 2;
    assertEquals(2,a);
    assertEquals(2,b);
    assertEquals(2,c);
    assertEquals(2,e);
    assertEquals(2,f);
  }
  { // const variables shadowing argument, let, const and var variables
    const a = 2;
    const b = 2;
    const c = 2;
    const e = 2;
    const f = 2;
    assertEquals(2,a);
    assertEquals(2,b);
    assertEquals(2,c);
    assertEquals(2,e);
    assertEquals(2,f);
  }
  { // class variables shadowing argument, let, const and var variables
    class a { static foo() { return 2; } }
    class b { static foo() { return 2; } }
    class c { static foo() { return 2; } }
    class d { static foo() { return 2; } }
    class e { static foo() { return 2; } }
    class f { static foo() { return 2; } }
    assertEquals(2,a.foo());
    assertEquals(2,b.foo());
    assertEquals(2,c.foo());
    assertEquals(2,e.foo());
    assertEquals(2,f.foo());
  }
  try {
    throw 'stuff1';
  } catch (a) {
    assertEquals('stuff1',a);
    // catch variable shadowing argument
    a = 2;
    assertEquals(2,a);
    {
      // let variable shadowing catch variable
      let a = 3;
      assertEquals(3,a);
      try {
        throw 'stuff2';
      } catch (a) {
        assertEquals('stuff2',a);
        // catch variable shadowing let variable
        a = 4;
        assertEquals(4,a);
      }
      assertEquals(3,a);
    }
    assertEquals(2,a);
  }
  try {
    throw 'stuff3';
  } catch (c) {
    // catch variable shadowing var variable
    assertEquals('stuff3',c);
    {
      // const variable shadowing catch variable
      const c = 3;
      assertEquals(3,c);
    }
    assertEquals('stuff3',c);
    try {
      throw 'stuff4';
    } catch(c) {
      assertEquals('stuff4',c);
      // catch variable shadowing catch variable
      c = 3;
      assertEquals(3,c);
    }
    (function(c) {
      // argument shadowing catch variable
      c = 3;
      assertEquals(3,c);
    })();
    assertEquals('stuff3', c);
    (function() {
      // var variable shadowing catch variable
      var c = 3;
    })();
    assertEquals('stuff3', c);
    c = 2;
  }
  assertEquals(1,c);
  (function(a,b,c,e,f) {
    // arguments shadowing argument, let, const, class and var variable
    a = 2;
    b = 2;
    c = 2;
    e = 2;
    f = 2;
    assertEquals(2,a);
    assertEquals(2,b);
    assertEquals(2,c);
    assertEquals(2,e);
    assertEquals(2,f);
    // var variable shadowing var variable
    var d = 2;
  })(1,1);
  assertEquals(1,a);
  assertEquals(1,b);
  assertEquals(1,c);
  assertEquals(1,d);
  assertEquals(1,e);
  assertEquals(1,f.foo());
}
f7(1);


// Ensure let and const variables are block local
// and var variables function local.
function f8() {
  var let_accessors = [];
  var var_accessors = [];
  var const_accessors = [];
  var class_accessors = [];
  for (var i = 0; i < 10; i++) {
    let x = i;
    var y = i;
    const z = i;
    class a { static foo() { return x; } }
    let_accessors[i] = function() { return x; }
    var_accessors[i] = function() { return y; }
    const_accessors[i] = function() { return z; }
    class_accessors[i] = function() { return a; }
  }
  for (var j = 0; j < 10; j++) {
    y = j + 10;
    assertEquals(j, let_accessors[j]());
    assertEquals(y, var_accessors[j]());
    assertEquals(j, const_accessors[j]());
    assertEquals(j, class_accessors[j]().foo());
  }
}
f8();
