// Copyright 2015 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: --strong-mode
"use strict"

let prologue_dead = "(function outer() { if (false) { ";
let epilogue_dead = " } })();";

let prologue_live = "(function outer() { ";
let epilogue_live = "})();";

// For code which already throws a run-time error in non-strong mode; we assert
// that we now get the error already compilation time.
function assertLateErrorsBecomeEarly(code) {
  assertThrows("'use strong'; " + prologue_dead + code + epilogue_dead,
               ReferenceError);

  // Make sure the error happens only in strong mode (note that we need strict
  // mode here because of let).
  assertDoesNotThrow("'use strict'; " + prologue_dead + code + epilogue_dead);

  // But if we don't put the references inside a dead code, it throws a run-time
  // error (also in strict mode).
  assertThrows("'use strong'; " + prologue_live + code + epilogue_live,
               ReferenceError);
  assertThrows("'use strict'; " + prologue_live + code + epilogue_live,
               ReferenceError);
}

// For code which doesn't throw an error at all in non-strong mode.
function assertNonErrorsBecomeEarly(code) {
  assertThrows("'use strong'; " + prologue_dead + code + epilogue_dead,
               ReferenceError);
  assertDoesNotThrow("'use strict'; " + prologue_dead + code + epilogue_dead);

  assertThrows("'use strong'; " + prologue_live + code + epilogue_live,
               ReferenceError);
  assertDoesNotThrow("'use strict'; " + prologue_live + code + epilogue_live,
                     ReferenceError);
}

(function InitTimeReferenceForward() {
  // It's never OK to have an init time reference to a class which hasn't been
  // declared.
  assertLateErrorsBecomeEarly(
      `class A extends B { }
      class B {}`);

  assertLateErrorsBecomeEarly(
      `class A {
        [B.sm()]() { }
      }
      class B {
        static sm() { return 0; }
      }`);
})();

(function InitTimeReferenceBackward() {
  // Backwards is of course fine.
  "use strong";
  class A {
    static sm() { return 0; }
  }
  let i = "making these classes non-consecutive";
  class B extends A {};
  "by inserting statements and declarations in between";
  class C {
    [A.sm()]() { }
  };
})();

(function BasicMutualRecursion() {
  "use strong";
  class A {
    m() { B; }
    static sm() { B; }
  }
  // No statements or declarations between the classes.
  class B {
    m() { A; }
    static sm() { A; }
  }
})();

(function MutualRecursionWithMoreClasses() {
  "use strong";
  class A {
    m() { B; C; }
    static sm() { B; C; }
  }
  class B {
    m() { A; C; }
    static sm() { A; C; }
  }
  class C {
    m() { A; B; }
    static sm() { A; B; }
  }
})();

(function ReferringForwardInDeeperScopes() {
  "use strong";

  function foo() {
    class A1 {
      m() { B1; }
    }
    class B1 { }
  }

  class Outer {
    m() {
      class A2 {
        m() { B2; }
      }
      class B2 { }
    }
  }

  for (let i = 0; i < 1; ++i) {
    class A3 {
      m() { B3; }
    }
    class B3 { }
  }

  (a, b) => {
    class A4 {
      m() { B4; }
    }
    class B4 { }
  }
})();

(function ReferringForwardButClassesNotConsecutive() {
  assertNonErrorsBecomeEarly(
      `class A {
        m() { B; }
      }
      ;
      class B {}`);

  assertNonErrorsBecomeEarly(
      `let A = class {
        m() { B; }
      }
      class B {}`);

  assertNonErrorsBecomeEarly(
      `class A {
        m() { B1; } // Just a normal use-before-declaration.
      }
      let B1 = class B2 {}`);

  assertNonErrorsBecomeEarly(
      `class A {
        m() { B; }
      }
      let i = 0;
      class B {}`);

  assertNonErrorsBecomeEarly(
      `class A {
        m() { B; }
      }
      function foo() {}
      class B {}`);

  assertNonErrorsBecomeEarly(
      `function foo() {
        class A {
          m() { B; }
        }
      }
      class B {}`);

  assertNonErrorsBecomeEarly(
      `class A extends class B { m() { C; } } {
      }
      class C { }`);

  assertLateErrorsBecomeEarly(
      `class A extends class B { [C.sm()]() { } } {
      }
      class C { static sm() { return 'a';} }`);

  assertLateErrorsBecomeEarly(
      `class A extends class B extends C { } {
      }
      class C { }`);
})();


(function RegressionForClassResolution() {
  assertNonErrorsBecomeEarly(
      `let A = class B {
        m() { C; }
      }
      ;;;;
      class C {}
      class B {}`);
})();


(function TestMultipleMethodScopes() {
  "use strong";

  // Test cases where the reference is inside multiple method scopes.
  class A1 {
    m() {
      class C1 {
        m() { B1; }
      }
    }
  }
  class B1 { }

  ;

  class A2 {
    m() {
      class C2 extends B2 {
      }
    }
  }
  class B2 { }
})();
