// 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.


// Test that debug-evaluate can find the correct this value for an arrow
// function, if "this" is referenced within the arrow function scope.

Debug = debug.Debug

var break_count = 0;
var exception = null;

function listener(event, exec_state, event_data, data) {
  if (event != Debug.DebugEvent.Break) return;
  try {
    for (var i = 0; i < exec_state.frameCount() - 1; i++) {
      var frame = exec_state.frame(i);
      var this_value = frame.evaluate("'' + this").value();
      var expected = frame.sourceLineText().match(/\/\/ (.*$)/)[1];
      print(expected, this_value, frame.sourceLineText());
      assertEquals(String(expected), String(this_value));
    }
    break_count++;
  } catch (e) {
    exception = e;
    print(e + e.stack);
  }
}

// Context-allocated receiver.
function f() {
  debugger;                          // foo
  return () => {
    debugger;                        // foo
    with ({}) {
      return () => {
        debugger;                    // foo
        try {
          throw new Error();
        } catch (e) {
          return () => {
            (() => this);            // bind this.
            debugger;                // foo
            return () => {
              debugger;              // undefined
              return g.call("goo");  // undefined
            }
          };
        }
      };
    }
  };
}

// Stack-allocated receiver.
function g() {
  debugger;                        // goo
  return () => {
    debugger;                      // undefined
    with ({}) {
      return () => {
        debugger;                  // undefined
        try {
          throw new Error();
        } catch (e) {
          return () => {
            debugger;              // undefined
            return f.call("foo");  // undefined
          };
        }
      };
    }
  };
}

Debug.setListener(listener);

var h = f.call("foo");
for (var i = 0; i < 20; i++) h = h();
var h = g.call("goo");
for (var i = 0; i < 20; i++) h = h();

function x() {
  (() => this);      // bind this.
  function y() {
    (() => {
      (() => this);  // bind this.
      debugger;      // Y
     })();           // Y
  }
  y.call("Y");       // X
}
x.call("X");

function u() {
  (() => this);
  function v() {
    (() => {
      debugger;      // undefined
     })();           // V
  }
  v.call("V");       // U
}
u.call("U");

(() => {
  (() => this);
  debugger;          // [object global]
})();

Debug.setListener(null);

assertEquals(55, break_count);
assertNull(exception);
