Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  commands.js   Sprache: JAVA

 
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */


import { createFrame } from "./create";
import { makeBreakpointServerLocationId } from "../../utils/breakpoint/index";

import * as objectInspector from "resource://devtools/client/shared/components/object-inspector/index.js";

let commands;
let breakpoints;

// The maximal number of stackframes to retrieve when pausing
const CALL_STACK_PAGE_SIZE = 1000;

function setupCommands(innerCommands) {
  commands = innerCommands;
  breakpoints = {};
}

function currentTarget() {
  return commands.targetCommand.targetFront;
}

function currentThreadFront() {
  return currentTarget().threadFront;
}

/**
 * Create an object front for the passed grip
 *
 * @param {Object} grip
 * @param {Object} frame: An optional frame that will manage the created object front.
 *                        if not passed, the current thread front will manage the object.
 * @returns {ObjectFront}
 */

function createObjectFront(grip, frame) {
  if (!grip.actor) {
    throw new Error("Actor is missing");
  }
  const threadFront = frame?.thread
    ? lookupThreadFront(frame.thread)
    : currentThreadFront();
  const frameFront = frame ? threadFront.getActorByID(frame.id) : null;
  return commands.client.createObjectFront(grip, threadFront, frameFront);
}

async function loadObjectProperties(root, threadActorID) {
  const { utils } = objectInspector;
  const properties = await utils.loadProperties.loadItemProperties(
    root,
    commands.client,
    undefined,
    threadActorID
  );
  return utils.node.getChildren({
    item: root,
    loadedProperties: new Map([[root.path, properties]]),
  });
}

function releaseActor(actor) {
  if (!actor) {
    return Promise.resolve();
  }
  const objFront = commands.client.getFrontByID(actor);

  if (!objFront) {
    return Promise.resolve();
  }

  return objFront.release().catch(() => {});
}

function lookupTarget(thread) {
  if (thread == currentThreadFront().actor) {
    return currentTarget();
  }

  const targets = commands.targetCommand.getAllTargets(
    commands.targetCommand.ALL_TYPES
  );
  return targets.find(target => target.targetForm.threadActor == thread);
}

function lookupThreadFront(thread) {
  const target = lookupTarget(thread);
  return target.threadFront;
}

function listThreadFronts() {
  const targets = commands.targetCommand.getAllTargets(
    commands.targetCommand.ALL_TYPES
  );
  return targets.map(target => target.threadFront).filter(front => !!front);
}

function forEachThread(iteratee) {
  // We have to be careful here to atomically initiate the operation on every
  // thread, with no intervening await. Otherwise, other code could run and
  // trigger additional thread operations. Requests on server threads will
  // resolve in FIFO order, and this could result in client and server state
  // going out of sync.

  const promises = listThreadFronts().map(
    // If a thread shuts down while sending the message then it will
    // throw. Ignore these exceptions.
    t => iteratee(t).catch(e => console.log(e))
  );

  return Promise.all(promises);
}

function resume(thread) {
  return lookupThreadFront(thread).resume();
}

function stepIn(thread, frameId) {
  return lookupThreadFront(thread).stepIn(frameId);
}

function stepOver(thread, frameId) {
  return lookupThreadFront(thread).stepOver(frameId);
}

function stepOut(thread, frameId) {
  return lookupThreadFront(thread).stepOut(frameId);
}

function restart(thread, frameId) {
  return lookupThreadFront(thread).restart(frameId);
}

function breakOnNext(thread) {
  return lookupThreadFront(thread).breakOnNext();
}

async function sourceContents({ actor, thread }) {
  const sourceThreadFront = lookupThreadFront(thread);
  const sourceFront = sourceThreadFront.source({ actor });
  const { source, contentType } = await sourceFront.source();
  return { source, contentType };
}

async function setXHRBreakpoint(path, method) {
  const hasWatcherSupport = commands.targetCommand.hasTargetWatcherSupport();
  if (!hasWatcherSupport) {
    // Without watcher support, forward setXHRBreakpoint to all threads.
    await forEachThread(thread => thread.setXHRBreakpoint(path, method));
    return;
  }
  const breakpointsFront =
    await commands.targetCommand.watcherFront.getBreakpointListActor();
  await breakpointsFront.setXHRBreakpoint(path, method);
}

async function removeXHRBreakpoint(path, method) {
  const hasWatcherSupport = commands.targetCommand.hasTargetWatcherSupport();
  if (!hasWatcherSupport) {
    // Without watcher support, forward removeXHRBreakpoint to all threads.
    await forEachThread(thread => thread.removeXHRBreakpoint(path, method));
    return;
  }
  const breakpointsFront =
    await commands.targetCommand.watcherFront.getBreakpointListActor();
  await breakpointsFront.removeXHRBreakpoint(path, method);
}

export function toggleJavaScriptEnabled(enabled) {
  return commands.targetConfigurationCommand.updateConfiguration({
    javascriptEnabled: enabled,
  });
}

async function addWatchpoint(object, property, label, watchpointType) {
  if (!currentTarget().getTrait("watchpoints")) {
    return;
  }
  const objectFront = createObjectFront(object);
  await objectFront.addWatchpoint(property, label, watchpointType);
}

async function removeWatchpoint(object, property) {
  if (!currentTarget().getTrait("watchpoints")) {
    return;
  }
  const objectFront = createObjectFront(object);
  await objectFront.removeWatchpoint(property);
}

function hasBreakpoint(location) {
  return !!breakpoints[makeBreakpointServerLocationId(location)];
}

function getServerBreakpointsList() {
  return Object.values(breakpoints);
}

async function setBreakpoint(location, options) {
  const breakpoint = breakpoints[makeBreakpointServerLocationId(location)];
  if (
    breakpoint &&
    JSON.stringify(breakpoint.options) == JSON.stringify(options)
  ) {
    return null;
  }
  breakpoints[makeBreakpointServerLocationId(location)] = { location, options };

  // Map frontend options to a more restricted subset of what
  // the server supports. For example frontend uses `hidden` attribute
  // which isn't meant to be passed to the server.
  // (note that protocol.js specification isn't enough to filter attributes,
  //  all primitive attributes will be passed as-is)
  const serverOptions = {
    condition: options.condition,
    logValue: options.logValue,
  };
  const hasWatcherSupport = commands.targetCommand.hasTargetWatcherSupport();
  if (!hasWatcherSupport) {
    // Without watcher support, unconditionally forward setBreakpoint to all threads.
    return forEachThread(async thread =>
      thread.setBreakpoint(location, serverOptions)
    );
  }
  const breakpointsFront =
    await commands.targetCommand.watcherFront.getBreakpointListActor();
  await breakpointsFront.setBreakpoint(location, serverOptions);

  // Call setBreakpoint for threads linked to targets
  // not managed by the watcher.
  return forEachThread(async thread => {
    if (
      !commands.targetCommand.hasTargetWatcherSupport(
        thread.targetFront.targetType
      )
    ) {
      return thread.setBreakpoint(location, serverOptions);
    }

    return Promise.resolve();
  });
}

async function removeBreakpoint(location) {
  delete breakpoints[makeBreakpointServerLocationId(location)];

  const hasWatcherSupport = commands.targetCommand.hasTargetWatcherSupport();
  if (!hasWatcherSupport) {
    // Without watcher support, unconditionally forward removeBreakpoint to all threads.
    return forEachThread(async thread => thread.removeBreakpoint(location));
  }
  const breakpointsFront =
    await commands.targetCommand.watcherFront.getBreakpointListActor();
  await breakpointsFront.removeBreakpoint(location);

  // Call removeBreakpoint for threads linked to targets
  // not managed by the watcher.
  return forEachThread(async thread => {
    if (
      !commands.targetCommand.hasTargetWatcherSupport(
        thread.targetFront.targetType
      )
    ) {
      return thread.removeBreakpoint(location);
    }

    return Promise.resolve();
  });
}

async function evaluateExpressions(expressions, options) {
  return Promise.all(
    expressions.map(expression => evaluate(expression, options))
  );
}

/**
 * Evaluate some JS expression in a given thread.
 *
 * @param {String} expression
 * @param {Object} options
 * @param {String} options.frameId
 *                 Optional frame actor ID into which the expression should be evaluated.
 * @param {String} options.threadId
 *                 Optional thread actor ID into which the expression should be evaluated.
 * @param {String} options.selectedNodeActor
 *                 Optional node actor ID which related to "$0" in the evaluated expression.
 * @param {Boolean} options.evalInTracer
 *                 To be set to true, if the object actors created during the evaluation
 *                 should be registered in the tracer actor Pool.
 * @return {Object}
 *                 See ScriptCommand.execute JS Doc.
 */

async function evaluate(
  expression,
  { frameId, threadId, selectedNodeActor, evalInTracer } = {}
) {
  if (!currentTarget() || !expression) {
    return { result: null };
  }

  const selectedTargetFront = threadId ? lookupTarget(threadId) : null;

  return commands.scriptCommand.execute(expression, {
    frameActor: frameId,
    selectedTargetFront,
    disableBreaks: true,
    selectedNodeActor,
    evalInTracer,
  });
}

async function autocomplete(input, cursor, frameId) {
  if (!currentTarget() || !input) {
    return {};
  }
  const consoleFront = await currentTarget().getFront("console");
  if (!consoleFront) {
    return {};
  }

  return new Promise(resolve => {
    consoleFront.autocomplete(
      input,
      cursor,
      result => resolve(result),
      frameId
    );
  });
}

async function getFrames(thread) {
  const threadFront = lookupThreadFront(thread);
  const response = await threadFront.getFrames(0, CALL_STACK_PAGE_SIZE);

  return Promise.all(
    response.frames.map((frame, i) => createFrame(thread, frame, i))
  );
}

async function getFrameScopes(frame) {
  const frameFront = lookupThreadFront(frame.thread).getActorByID(frame.id);
  return frameFront.getEnvironment();
}

async function pauseOnDebuggerStatement(shouldPauseOnDebuggerStatement) {
  await commands.threadConfigurationCommand.updateConfiguration({
    shouldPauseOnDebuggerStatement,
  });
}

async function pauseOnExceptions(
  shouldPauseOnExceptions,
  shouldPauseOnCaughtExceptions
) {
  await commands.threadConfigurationCommand.updateConfiguration({
    pauseOnExceptions: shouldPauseOnExceptions,
    ignoreCaughtExceptions: !shouldPauseOnCaughtExceptions,
  });
}

async function blackBox(sourceActor, shouldBlackBox, ranges) {
  const hasWatcherSupport = commands.targetCommand.hasTargetWatcherSupport();
  if (hasWatcherSupport) {
    const blackboxingFront =
      await commands.targetCommand.watcherFront.getBlackboxingActor();
    if (shouldBlackBox) {
      await blackboxingFront.blackbox(sourceActor.url, ranges);
    } else {
      await blackboxingFront.unblackbox(sourceActor.url, ranges);
    }
  } else {
    const sourceFront = currentThreadFront().source({
      actor: sourceActor.actor,
    });
    // If there are no ranges, the whole source is being blackboxed
    if (!ranges.length) {
      await toggleBlackBoxSourceFront(sourceFront, shouldBlackBox);
      return;
    }
    // Blackbox the specific ranges
    for (const range of ranges) {
      await toggleBlackBoxSourceFront(sourceFront, shouldBlackBox, range);
    }
  }
}

async function toggleBlackBoxSourceFront(sourceFront, shouldBlackBox, range) {
  if (shouldBlackBox) {
    await sourceFront.blackBox(range);
  } else {
    await sourceFront.unblackBox(range);
  }
}

async function setSkipPausing(shouldSkip) {
  await commands.threadConfigurationCommand.updateConfiguration({
    skipBreakpoints: shouldSkip,
  });
}

async function setEventListenerBreakpoints(ids) {
  const hasWatcherSupport = commands.targetCommand.hasTargetWatcherSupport();
  if (!hasWatcherSupport) {
    await forEachThread(thread => thread.setActiveEventBreakpoints(ids));
    return;
  }
  const breakpointListFront =
    await commands.targetCommand.watcherFront.getBreakpointListActor();
  await breakpointListFront.setActiveEventBreakpoints(ids);
}

async function getEventListenerBreakpointTypes() {
  return currentThreadFront().getAvailableEventBreakpoints();
}

async function toggleEventLogging(logEventBreakpoints) {
  await commands.threadConfigurationCommand.updateConfiguration({
    logEventBreakpoints,
  });
}

function getMainThread() {
  return currentThreadFront().actor;
}

async function getSourceActorBreakpointPositions({ thread, actor }, range) {
  const sourceThreadFront = lookupThreadFront(thread);
  const sourceFront = sourceThreadFront.source({ actor });
  return sourceFront.getBreakpointPositionsCompressed(range);
}

async function getSourceActorBreakableLines({ thread, actor }) {
  let actorLines = [];
  try {
    const sourceThreadFront = lookupThreadFront(thread);
    const sourceFront = sourceThreadFront.source({ actor });
    actorLines = await sourceFront.getBreakableLines();
  } catch (e) {
    // Exceptions could be due to the target thread being shut down.
    console.warn(`getSourceActorBreakableLines failed: ${e}`);
  }

  return actorLines;
}

function getFrontByID(actorID) {
  return commands.client.getFrontByID(actorID);
}

function fetchAncestorFramePositions(index) {
  currentThreadFront().fetchAncestorFramePositions(index);
}

const clientCommands = {
  autocomplete,
  blackBox,
  createObjectFront,
  loadObjectProperties,
  releaseActor,
  resume,
  stepIn,
  stepOut,
  stepOver,
  restart,
  breakOnNext,
  sourceContents,
  getSourceActorBreakpointPositions,
  getSourceActorBreakableLines,
  hasBreakpoint,
  getServerBreakpointsList,
  setBreakpoint,
  setXHRBreakpoint,
  removeXHRBreakpoint,
  addWatchpoint,
  removeWatchpoint,
  removeBreakpoint,
  evaluate,
  evaluateExpressions,
  getFrameScopes,
  getFrames,
  pauseOnDebuggerStatement,
  pauseOnExceptions,
  toggleEventLogging,
  getMainThread,
  setSkipPausing,
  setEventListenerBreakpoints,
  getEventListenerBreakpointTypes,
  getFrontByID,
  fetchAncestorFramePositions,
  toggleJavaScriptEnabled,
};

export { setupCommands, clientCommands };

Messung V0.5
C=82 H=94 G=88

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge