/*
 * Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/licenses/publicdomain/
 */

var gTestfile = "for-loop.js";
//-----------------------------------------------------------------------------
var BUGNUMBER = 985733;
var summary =
  "ES6 for-loop semantics for for(;;) loops whose heads contain lexical "
  "declarations";

print(BUGNUMBER + ": " + summary);

/**************
 * BEGIN TEST *
 **************/

function isError(code, type)
{
  try
  {
    Function(code);
    throw new Error("didn't throw");
  }
  catch (e)
  {
    assertEq(e instanceof type, true,
             "unexpected error for `" + code + "`: got " + e);
  }
}

function isOK(code)
{
  Function(code);
}

isError("for (const x; ; ) ;", SyntaxError);
isError("for (const x = 5, y; ; ) ;", SyntaxError);
isError("for (const [z]; ; ) ;", SyntaxError);
//isError("for (const [z, z]; ; ) ;", SyntaxError);
//isError("for (const [z, z] = [0, 1]; ; ) ;", SyntaxError);

isOK("for (let x; ; ) ;");
isOK("for (let x = 5, y; ; ) ;");

// I'm fairly sure this is supposed to work: the negative-lookahead rules in
// IterationStatement ensure that |for (let| *always* is a loop header starting
// with a lexical declaration.  But I'm not 100% certain, so these tests might
// need to be fixed when we implement the negative-lookahead restrictions.
isOK("for (let [z] = [3]; ; ) ;");
isError("for (let [z, z]; ; ) ;", SyntaxError); // because missing initializer

// This is wrong!  Per 13.2.1.1, "It is a Syntax Error if the BoundNames of
// BindingList contains any duplicate entries."  But we don't implement this
// yet, so it becomes a TypeError at runtime.
isError("for (let [z, z] = [0, 1]; ; ) ;", TypeError);

// A for-loop with lexical declarations, with a mixture of bindings that are and
// aren't aliased.  (The mixture stress-tests any code that incorrectly assumes
// all bindings are aliased.)
var funcs = [];
for (let [i, j, k] = [0, 1, 2]; i < 10; i++)
  funcs.push(() => i);

assertEq(funcs[0](), 0);
assertEq(funcs[1](), 1);
assertEq(funcs[2](), 2);
assertEq(funcs[3](), 3);
assertEq(funcs[4](), 4);
assertEq(funcs[5](), 5);
assertEq(funcs[6](), 6);
assertEq(funcs[7](), 7);
assertEq(funcs[8](), 8);
assertEq(funcs[9](), 9);

var outer = "OUTER V IGNORE";
var save;
for (let outer = (save = function() { return outer; }); ; )
  break;
assertEq(save(), save);

var funcs = [];
function t(i, name, expect)
{
  assertEq(funcs[i].name, name);
  assertEq(funcs[i](), expect);
}

if (save() !== "OUTER V IGNORE")
{
  var v = "OUTER V IGNORE";
  var i = 0;
  for (let v = (funcs.push(function init() { return v; }),
               0);
      v = (funcs.push(function test() { return v; }),
           v + 1);
      v = (funcs.push(function incr() { return v; }),
           v + 1))
  {
    v = (funcs.push(function body() { return v; }),
         v + 1);
    i++;
    if (i >= 3)
      break;
  }
  t(0, "init", 2);
  t(1, "test", 2);
  t(2, "body", 2);
  t(3, "incr", 5);
  t(4, "test", 5);
  t(5, "body", 5);
  t(6, "incr", 8);
  t(7, "test", 8);
  t(8, "body", 8);
  assertEq(funcs.length, 9);
}

/******************************************************************************/

if (typeof reportCompare === "function")
  reportCompare(true, true);

print("Tests complete");
