<commit_before>'use strict';

const Module = require('module');
const vm = require('vm');

const debug = require('debug')('embedded-agents:debugger');
const _ = require('lodash');

const BaseAgent = require('../base');
const ObjectGroup = require('../object-group');

const UrlMapper = require('../../url-mapper');

const Debug = vm.runInDebugContext('Debug');

const WRAPPER_EXPRESSION = new RegExp([
  '^',
  _.escapeRegExp(Module.wrapper[0]),
  '([\\s\\S]*)',
  _.escapeRegExp(Module.wrapper[1]),
  '$',
].join(''));
function isHostScript(raw) {
  return raw.compilationType() === Debug.ScriptCompilationType.Host;
}
function extractScriptSource(raw) {
  const source = raw.source();
  if (source === undefined || !isHostScript(raw) || raw.name() === 'node.js') {
    return source;
  }
  const matched = source.match(WRAPPER_EXPRESSION);
  if (matched === null) {
    /* eslint no-console: 0 */
    console.error('Warning: script without module wrapper found', raw);
    return source;
  }
  return matched[1];
}

const ScopeTypes = [ 'global', 'local', 'with', 'closure', 'catch', 'block', 'script' ];
function exportScope(objectGroup, scope) {
  return {
    type: ScopeTypes[scope.scopeType()],
    object: ObjectGroup.add('@break', scope.scopeObject().value()),
  };
}

function exportFrame(raw) {
  const f = raw.func();
  const sourceLocation = raw.sourceLocation();

  const scopes = raw.allScopes()
    .map(_.partial(exportScope, '@break'));

  return {
    callFrameId: '' + raw.index(),
    functionName: (f && f.name()) || '(unknown)',
    location: {
      scriptId: sourceLocation && ('' + sourceLocation.script.id),
      lineNumber: sourceLocation && sourceLocation.line,
      columnNumber: sourceLocation && sourceLocation.column,
    },
    scopeChain: scopes,
    this: ObjectGroup.add('@break', raw.receiver().value()),
  };
}

class DebuggerAgent extends BaseAgent {
  constructor() {
    super();
    this._scriptCache = {};
    this._state = null;
  }

  _onAfterCompile(event) {
    this._registerScript(event.script());
  }

  _buildCallStack() {
    const frameCount = this._state.frameCount();
    const frames = new Array(frameCount);
    for (let i = 0; i < frameCount; ++i) {
      frames[i] = exportFrame(this._state.frame(i), i);
    }
    return frames;
  }

  _onBreak(event, state) {
    this._state = state;
    const callFrames = this._buildCallStack();
    this.emit('paused', { callFrames, reason: 'other' });
  }

  _registerScript(raw) {
    const context = null;
    const script = {
      scriptId: '' + raw.id(),
      url: UrlMapper.scriptUrlFromName(raw.name()),
      lineCount: raw.lineCount(),
      sourceOffset: { line: raw.lineOffset(), column: raw.columnOffset() },
      context: context,
      evalContext: null,
    };
    this._scriptCache[script.scriptId] = raw;
    debug('Found script', raw.name(), script.url || script.scriptId);
    this.emit('scriptParsed', script);
  }

  /**
   * Enables debugger for the given page.
   * Clients should not assume that the debugging has been enabled until the result for this command is received.
   */
  enable() {
    const scripts = Debug.scripts().map(Debug.MakeMirror);
    debug('Dispatching %d scripts', scripts.length);
    scripts.forEach(this._registerScript, this);
  }

  /**
   * Disables debugger for given page.
   */
  disable() {
  }

  /**
   * Activates / deactivates all breakpoints on the page.
   *
   * @param {boolean} active New value for breakpoints active state.
   */
  setBreakpointsActive() {
    throw new Error('Not implemented');
  }

  /**
   * Makes page not interrupt on any pauses (breakpoint, exception, dom exception etc).
   *
   * @param {boolean} skipped New value for skip pauses state.
   */
  setSkipAllPauses() {
    throw new Error('Not implemented');
  }

  /**
   * Sets JavaScript breakpoint at given location specified either by URL or URL regex.<commit_msg>Fix reconnect in paused state<commit_after>'use strict';

const Module = require('module');
const vm = require('vm');

const debug = require('debug')('embedded-agents:debugger');
const _ = require('lodash');

const BaseAgent = require('../base');
const ObjectGroup = require('../object-group');

const UrlMapper = require('../../url-mapper');

const Debug = vm.runInDebugContext('Debug');

const WRAPPER_EXPRESSION = new RegExp([
  '^',
  _.escapeRegExp(Module.wrapper[0]),
  '([\\s\\S]*)',
  _.escapeRegExp(Module.wrapper[1]),
  '$',
].join(''));
function isHostScript(raw) {
  return raw.compilationType() === Debug.ScriptCompilationType.Host;
}
function extractScriptSource(raw) {
  const source = raw.source();
  if (source === undefined || !isHostScript(raw) || raw.name() === 'node.js') {
    return source;
  }
  const matched = source.match(WRAPPER_EXPRESSION);
  if (matched === null) {
    /* eslint no-console: 0 */
    console.error('Warning: script without module wrapper found', raw);
    return source;
  }
  return matched[1];
}

const ScopeTypes = [ 'global', 'local', 'with', 'closure', 'catch', 'block', 'script' ];
function exportScope(objectGroup, scope) {
  return {
    type: ScopeTypes[scope.scopeType()],
    object: ObjectGroup.add('@break', scope.scopeObject().value()),
  };
}

function exportFrame(raw) {
  const f = raw.func();
  const sourceLocation = raw.sourceLocation();

  const scopes = raw.allScopes()
    .map(_.partial(exportScope, '@break'));

  return {
    callFrameId: '' + raw.index(),
    functionName: (f && f.name()) || '(unknown)',
    location: {
      scriptId: sourceLocation && ('' + sourceLocation.script.id),
      lineNumber: sourceLocation && sourceLocation.line,
      columnNumber: sourceLocation && sourceLocation.column,
    },
    scopeChain: scopes,
    this: ObjectGroup.add('@break', raw.receiver().value()),
  };
}

class DebuggerAgent extends BaseAgent {
  constructor() {
    super();
    this._scriptCache = {};
    this._state = null;
  }

  _onAfterCompile(event) {
    this._registerScript(event.script());
  }

  _buildCallStack() {
    const frameCount = this._state.frameCount();
    const frames = new Array(frameCount);
    for (let i = 0; i < frameCount; ++i) {
      frames[i] = exportFrame(this._state.frame(i), i);
    }
    return frames;
  }

  _sendPausedEvent() {
    const callFrames = this._buildCallStack();
    this.emit('paused', { callFrames, reason: 'other' });
  }

  _onBreak(event, state) {
    this._state = state;
    this._sendPausedEvent();
  }

  _registerScript(raw) {
    const context = null;
    const script = {
      scriptId: '' + raw.id(),
      url: UrlMapper.scriptUrlFromName(raw.name()),
      lineCount: raw.lineCount(),
      sourceOffset: { line: raw.lineOffset(), column: raw.columnOffset() },
      context: context,
      evalContext: null,
    };
    this._scriptCache[script.scriptId] = raw;
    debug('Found script', raw.name(), script.url || script.scriptId);
    this.emit('scriptParsed', script);
  }

  /**
   * Enables debugger for the given page.
   * Clients should not assume that the debugging has been enabled until the result for this command is received.
   */
  enable() {
    const scripts = Debug.scripts().map(Debug.MakeMirror);
    debug('Dispatching %d scripts', scripts.length);
    scripts.forEach(this._registerScript, this);

    if (this._state !== null) {
      this._sendPausedEvent();
    }
  }

  /**
   * Disables debugger for given page.
   */
  disable() {
  }

  /**
   * Activates / deactivates all breakpoints on the page.
   *
   * @param {boolean} active New value for breakpoints active state.
   */
  setBreakpointsActive() {
    throw new Error('Not implemented');
  }

  /**
   * Makes page not interrupt on any pauses (breakpoint, exception, dom exception etc).
   *
   * @param {boolean} skipped New value for skip pauses state.
   */
  setSkipAllPauses() {
    throw new Error('Not implemented');
  }

  /**
   * Sets JavaScript breakpoint at given location specified either by URL or URL regex.
{'fraction_non_alphanumeric': 0.15606573830134238, 'fraction_numerical': 0.0012545477355413374, 'mean_word_length': 3.486212718064153, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5081687', 'n_tokens_mistral': 2484, 'n_tokens_neox': 2430, 'n_words': 601}