// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Flags: --harmony-class-fields

// Utility function for testing that the expected strings occur
// in the stack trace produced when running the given function.
function testTrace(name, fun, expected, unexpected) {
  var threw = false;
  try {
    fun();
  } catch (e) {
    for (var i = 0; i < expected.length; i++) {
      assertTrue(
        e.stack.indexOf(expected[i]) != -1,
        name + " doesn't contain expected[" + i + "] stack = " + e.stack
      );
    }
    if (unexpected) {
      for (var i = 0; i < unexpected.length; i++) {
        assertEquals(
          e.stack.indexOf(unexpected[i]),
          -1,
          name + " contains unexpected[" + i + "]"
        );
      }
    }
    threw = true;
  }
  assertTrue(threw, name + " didn't throw");
}

function thrower() {
  FAIL;
}

function testClassConstruction() {
  class X {
    static x = thrower();
  }
}

// ReferenceError: FAIL is not defined
//     at thrower
//     at <static_fields_initializer>
//     at testClassConstruction
//     at testTrace
testTrace(
  "during class construction",
  testClassConstruction,
  ["thrower", "<static_fields_initializer>"],
  ["anonymous"]
);

function testClassConstruction2() {
  class X {
    [thrower()];
  }
}

// ReferenceError: FAIL is not defined
//    at thrower
//    at testClassConstruction2
//    at testTrace
testTrace("during class construction2", testClassConstruction2, ["thrower"]);

function testClassInstantiation() {
  class X {
    x = thrower();
  }

  new X();
}

// ReferenceError: FAIL is not defined
//     at thrower
//     at X.<instance_members_initializer>
//     at new X
//     at testClassInstantiation
//     at testTrace
testTrace(
  "during class instantiation",
  testClassInstantiation,
  ["thrower", "X.<instance_members_initializer>", "new X"],
  ["anonymous"]
);

function testClassInstantiationWithSuper() {
  class Base {}

  class X extends Base {
    x = thrower();
  }

  new X();
}

// ReferenceError: FAIL is not defined
//     at thrower
//     at X.<instance_members_initializer>
//     at new X
//     at testClassInstantiation
//     at testTrace
testTrace(
  "during class instantiation with super",
  testClassInstantiationWithSuper,
  ["thrower", "X.<instance_members_initializer>", "new X"],
  ["Base", "anonymous"]
);

function testClassInstantiationWithSuper2() {
  class Base {}

  class X extends Base {
    constructor() {
      super();
    }
    x = thrower();
  }

  new X();
}

// ReferenceError: FAIL is not defined
//     at thrower
//     at X.<instance_members_initializer>
//     at new X
//     at testClassInstantiation
//     at testTrace
testTrace(
  "during class instantiation with super2",
  testClassInstantiationWithSuper2,
  ["thrower", "X.<instance_members_initializer>", "new X"],
  ["Base", "anonymous"]
);

function testClassInstantiationWithSuper3() {
  class Base {
    x = thrower();
  }

  class X extends Base {
    constructor() {
      super();
    }
  }

  new X();
}

// ReferenceError: FAIL is not defined
//     at thrower
//     at X.<instance_members_initializer>
//     at new Base
//     at new X
//     at testClassInstantiationWithSuper3
//     at testTrace
testTrace(
  "during class instantiation with super3",
  testClassInstantiationWithSuper3,
  ["thrower", "X.<instance_members_initializer>", "new Base", "new X"],
  ["anonymous"]
);

function testClassFieldCall() {
  class X {
    x = thrower;
  }

  let x = new X();
  x.x();
}

// ReferenceError: FAIL is not defined
//     at X.thrower [as x]
//     at testClassFieldCall
//     at testTrace
testTrace(
  "during class field call",
  testClassFieldCall,
  ["X.thrower"],
  ["anonymous"]
);

function testStaticClassFieldCall() {
  class X {
    static x = thrower;
  }

  X.x();
}

// ReferenceError: FAIL is not defined
//     at Function.thrower [as x]
//     at testStaticClassFieldCall
//     at testTrace
testTrace(
  "during static class field call",
  testStaticClassFieldCall,
  ["Function.thrower"],
  ["anonymous"]
);

function testClassFieldCallWithFNI() {
  class X {
    x = function() {
      FAIL;
    };
  }

  let x = new X();
  x.x();
}

// ReferenceError: FAIL is not defined
//     at X.x
//     at testClassFieldCallWithFNI
//     at testTrace
testTrace(
  "during class field call with FNI",
  testClassFieldCallWithFNI,
  ["X.x"],
  ["anonymous"]
);

function testStaticClassFieldCallWithFNI() {
  class X {
    static x = function() {
      FAIL;
    };
  }

  X.x();
}

// ReferenceError: FAIL is not defined
//     at Function.x
//     at testStaticClassFieldCallWithFNI
//     at testTrace
testTrace(
  "during static class field call with FNI",
  testStaticClassFieldCallWithFNI,
  ["Function.x"],
  ["anonymous"]
);
