kopia lustrzana https://github.com/c9/core
827 wiersze
31 KiB
JavaScript
827 wiersze
31 KiB
JavaScript
define(function(require, exports, module) {
|
|
main.consumes = ["Plugin", "c9", "debugger"];
|
|
main.provides = ["debugger.xdebug"];
|
|
return main;
|
|
|
|
function main(options, imports, register) {
|
|
var Plugin = imports.Plugin;
|
|
var c9 = imports.c9;
|
|
var debug = imports["debugger"];
|
|
|
|
var Frame = debug.Frame;
|
|
var Source = debug.Source;
|
|
var Breakpoint = debug.Breakpoint;
|
|
var Variable = debug.Variable;
|
|
var Scope = debug.Scope;
|
|
|
|
var url = require("url");
|
|
var path = require("path");
|
|
var DbgpClient = require("./lib/DbgpClient");
|
|
var base64Decode = require("./lib/util").base64Decode;
|
|
|
|
/***** Initialization *****/
|
|
|
|
var TYPE = "xdebug";
|
|
var PROXY = require("text!./netproxy.js");
|
|
|
|
var plugin = new Plugin("Ajax.org", main.consumes);
|
|
var emit = plugin.getEmitter();
|
|
|
|
// emit.setMaxListeners(1000);
|
|
|
|
var SCOPE_TYPES = {
|
|
"Locals": "Locals",
|
|
"Superglobals": "Globals",
|
|
"User defined constants": "Contants",
|
|
};
|
|
|
|
var socket, client, session;
|
|
|
|
var attached = false;
|
|
var state = null;
|
|
var breakOnExceptions = false;
|
|
var breakOnUncaughtExceptions = false;
|
|
|
|
/***** Event Handlers *****/
|
|
|
|
function load() {
|
|
debug.registerDebugger(TYPE, plugin);
|
|
}
|
|
|
|
function unload() {
|
|
detach();
|
|
socket = client = session = state = null;
|
|
attached = false;
|
|
breakOnExceptions = false;
|
|
breakOnUncaughtExceptions = false;
|
|
|
|
debug.unregisterDebugger(TYPE, plugin);
|
|
}
|
|
|
|
function onBreak() {
|
|
plugin.getFrames(function(err, frames) {
|
|
emit("frameActivate", { frame: frames[0] });
|
|
emit("break", { frame: frames[0], frames: frames });
|
|
setState("stopped");
|
|
});
|
|
}
|
|
|
|
function onStatus(status) {
|
|
switch (status) {
|
|
case "starting":
|
|
case "stopping":
|
|
case "stopped":
|
|
setState(null);
|
|
break;
|
|
|
|
case "running":
|
|
setState("running");
|
|
break;
|
|
|
|
case "break":
|
|
// handled by onBreak
|
|
break;
|
|
|
|
default:
|
|
throw new TypeError("Unknown debugger status: " + status);
|
|
}
|
|
}
|
|
|
|
/***** Helper Functions *****/
|
|
|
|
function formatType(property) {
|
|
if (property["@type"] === "uninitialized") {
|
|
return null;
|
|
}
|
|
|
|
if (property["@type"] === "object" && property["@classname"] === "Closure") {
|
|
return "callable";
|
|
}
|
|
|
|
return property["@type"];
|
|
}
|
|
|
|
function formatValue(property, value) {
|
|
if (property["@encoding"] === "base64") {
|
|
value = base64Decode(value);
|
|
}
|
|
|
|
switch (property["@type"]) {
|
|
case "null":
|
|
return property["@type"];
|
|
|
|
case "array":
|
|
return "array(" + property["@numchildren"] + ")";
|
|
|
|
case "bool":
|
|
return (value ? "true" : "false");
|
|
|
|
case "int":
|
|
return parseInt(value, 10) + "";
|
|
|
|
case "float":
|
|
return parseFloat(value) + "";
|
|
|
|
case "string":
|
|
return JSON.stringify(value);
|
|
|
|
case "object":
|
|
if (property["@classname"] === "Closure") {
|
|
return "callable";
|
|
}
|
|
|
|
return property["@classname"];
|
|
|
|
default:
|
|
return value;
|
|
}
|
|
}
|
|
|
|
function createVariable(property) {
|
|
var children = property["property"];
|
|
|
|
if (children && !Array.isArray(children))
|
|
children = [children];
|
|
|
|
return new Variable({
|
|
name: property["@name"],
|
|
value: formatValue(property, property["$"]),
|
|
type: formatType(property),
|
|
ref: property["@fullname"],
|
|
children: !!property["@children"],
|
|
properties: children && children.map(function(child) {
|
|
return createVariable(child);
|
|
})
|
|
});
|
|
}
|
|
|
|
function findScope(variable) {
|
|
if (variable.scope)
|
|
return variable.scope;
|
|
else if (variable.parent)
|
|
return findScope(variable.parent);
|
|
else
|
|
throw new Error("Could not find scope in variable or parents");
|
|
}
|
|
|
|
function setState(state_) {
|
|
if (state === state_)
|
|
return;
|
|
|
|
// console.info(state_);
|
|
|
|
state = state_;
|
|
emit("stateChange", { state: state });
|
|
}
|
|
|
|
function filesystemPath(workspacePath) {
|
|
return path.join(c9.workspaceDir, path.relative("/", workspacePath));
|
|
}
|
|
|
|
function workspacePath(filesystemPath) {
|
|
return path.resolve("/", path.relative(c9.workspaceDir, filesystemPath));
|
|
}
|
|
|
|
/***** Methods *****/
|
|
|
|
function attach(socket_, reconnect, callback) {
|
|
socket = socket_;
|
|
|
|
client = new DbgpClient();
|
|
|
|
client.on("session", function(session_) {
|
|
session = session_;
|
|
|
|
session.setFeature("max_depth", 0);
|
|
session.setFeature("max_data", 1024);
|
|
session.setFeature("max_children", 150);
|
|
|
|
session.on("status", onStatus);
|
|
session.on("break", onBreak);
|
|
|
|
setBreakpoints(emit("getBreakpoints"), function(breakpoints) {
|
|
if (!attached) {
|
|
attached = true;
|
|
emit("attach", { breakpoints: breakpoints });
|
|
}
|
|
|
|
callback();
|
|
|
|
session.run();
|
|
});
|
|
});
|
|
|
|
client.on("error", function(err) {
|
|
emit("error", err);
|
|
}, plugin);
|
|
|
|
client.once("listening", function() {
|
|
emit("connect");
|
|
}, plugin);
|
|
|
|
client.listen(socket);
|
|
|
|
socket.on("end", function() {
|
|
setState("running");
|
|
});
|
|
|
|
socket.on("connect", function() {
|
|
if (client && !client.listening)
|
|
client.listen(socket);
|
|
});
|
|
}
|
|
|
|
function detach() {
|
|
if (session) session.stop();
|
|
if (client) client.close();
|
|
if (socket) socket.close();
|
|
|
|
emit("frameActivate", { frame: null });
|
|
setState(null);
|
|
|
|
socket = null;
|
|
client = null;
|
|
session = null;
|
|
attached = false;
|
|
|
|
emit("detach");
|
|
}
|
|
|
|
function getSources(callback) {
|
|
callback && callback(new Error("Not implemented"));
|
|
}
|
|
|
|
function getSource(source, callback) {
|
|
session.getSource(source.id, callback);
|
|
}
|
|
|
|
function getFrames(callback, silent) {
|
|
session.getStackFrames(null, function(err, data) {
|
|
if (err) return callback(err);
|
|
|
|
var frames = data.map(function(frame) {
|
|
var scriptURI = frame["@filename"]
|
|
, parts = url.parse(scriptURI);
|
|
|
|
var scriptPath
|
|
, scriptName;
|
|
|
|
if (parts.protocol === "file:") {
|
|
// resolve absolute file path to workspace path
|
|
scriptPath = workspacePath(parts.pathname);
|
|
scriptName = path.basename(scriptPath);
|
|
} else {
|
|
// FIXME: causes metadata errors
|
|
scriptPath = scriptURI;
|
|
scriptName = scriptURI;
|
|
|
|
// TODO: push "fake" sources to avoid metadata error
|
|
//var sources = [
|
|
//new Source({
|
|
//id: scriptURI,
|
|
//name: parts.protocol + path.basename(parts.pathname),
|
|
////path: parts.protocol + path.basename(parts.pathname),
|
|
//debug: true
|
|
//})
|
|
//];
|
|
//emit("sources", { sources: sources });
|
|
}
|
|
|
|
var level = frame["@level"];
|
|
var line = frame["@lineno"] - 1;
|
|
|
|
return new Frame({
|
|
index: level,
|
|
name: frame["@where"],
|
|
line: line,
|
|
column: 0, // TODO: cmdbegin = line:col
|
|
id: null,
|
|
script: scriptName,
|
|
path: scriptPath,
|
|
sourceId: scriptURI,
|
|
scopes: [
|
|
new Scope({ index: 0, type: "Locals", frameIndex: level }),
|
|
new Scope({ index: 1, type: "Superglobals", frameIndex: level }),
|
|
|
|
/* FIXME: Xdebug 2.3.0+ only */
|
|
// new Scope({ index: 2, type: "Contants", frameIndex: level })
|
|
],
|
|
variables: [],
|
|
istop: (level === 0)
|
|
});
|
|
});
|
|
|
|
emit("getFrames", { frames: frames });
|
|
callback(null, frames);
|
|
});
|
|
}
|
|
|
|
function getScope(frame, scope, callback) {
|
|
session.getContextProperties(frame.index, scope.index, function(err, data) {
|
|
if (err) return callback(err);
|
|
|
|
var variables = data.map(function(prop) {
|
|
var result = createVariable(prop);
|
|
result.scope = scope;
|
|
return result;
|
|
});
|
|
|
|
scope.variables = variables;
|
|
|
|
callback(null, variables, scope, frame);
|
|
});
|
|
}
|
|
|
|
function getProperties(variable, callback) {
|
|
var scope = findScope(variable);
|
|
|
|
session.getPropertyChildren(variable.ref, scope.frameIndex, scope.index, function(err, data) {
|
|
if (err) return callback(err);
|
|
|
|
var properties = data.map(function(prop) {
|
|
var result = createVariable(prop);
|
|
result.parent = variable;
|
|
return result;
|
|
});
|
|
|
|
variable.properties = properties;
|
|
|
|
callback(null, properties, variable);
|
|
});
|
|
}
|
|
|
|
function stepInto(callback) {
|
|
session.stepInto(callback);
|
|
}
|
|
|
|
function stepOver(callback) {
|
|
session.stepOver(callback);
|
|
}
|
|
|
|
function stepOut(callback) {
|
|
session.stepOut(callback);
|
|
}
|
|
|
|
function resume(callback) {
|
|
session.run(callback);
|
|
}
|
|
|
|
function suspend(callback) {
|
|
callback && callback(new Error("FIXME: command 'break' is not supported by PHP Xdebug"));
|
|
}
|
|
|
|
function evaluate(expression, frame, global, disableBreak, callback) {
|
|
expression = expression.trim();
|
|
|
|
if (state !== "stopped")
|
|
return callback(null, new Variable({ name: expression }));
|
|
|
|
session.eval(expression, function(err, data) {
|
|
if (err) return callback(err);
|
|
|
|
var variable = createVariable(data);
|
|
variable.name = expression;
|
|
variable.ref = expression;
|
|
variable.scope = frame.scopes[0];
|
|
|
|
callback(null, variable);
|
|
});
|
|
}
|
|
|
|
function setBreakpoint(bp, callback) {
|
|
if (!bp.path) return; // this can happen for serverOnly breakpoints
|
|
var path = filesystemPath(bp.path);
|
|
|
|
var options = {
|
|
line: (bp.line + 1),
|
|
enabled: bp.enabled,
|
|
condition: bp.condition,
|
|
ignoreCount: bp.ignoreCount
|
|
};
|
|
|
|
session.setBreakpoint(path, options, function(err, breakpointId) {
|
|
if (!err) bp.id = breakpointId;
|
|
callback && callback(err, bp);
|
|
});
|
|
}
|
|
|
|
function changeBreakpoint(bp, callback) {
|
|
var options = {
|
|
line: (bp.line + 1),
|
|
enabled: bp.enabled,
|
|
condition: bp.condition,
|
|
ignoreCount: bp.ignoreCount,
|
|
};
|
|
|
|
session.updateBreakpoint(bp.id, options, function(err) {
|
|
callback && callback(err, bp);
|
|
});
|
|
}
|
|
|
|
function clearBreakpoint(bp, callback) {
|
|
session.removeBreakpoint(bp.id, function(err) {
|
|
callback && callback(err, bp);
|
|
});
|
|
}
|
|
|
|
function listBreakpoints(callback) {
|
|
// normally we'd send breakpoint_list, but since breakpoint state
|
|
// is entirely dependent on UI, we'll manage it globally
|
|
callback(null, emit("getBreakpoints"));
|
|
}
|
|
|
|
function setVariable(variable, value, frame, callback) {
|
|
var scope = findScope(variable);
|
|
|
|
session.setPropertyValue(variable.ref, frame.index, scope.index, value, function(err) {
|
|
if (err) return callback(err);
|
|
|
|
session.getProperty(variable.ref, frame.index, scope.index, function(err, property) {
|
|
if (err) return callback(err);
|
|
|
|
variable.type = formatType(property);
|
|
variable.value = formatValue(property, property["$"]);
|
|
variable.children = !!property["@children"];
|
|
variable.properties = undefined;
|
|
|
|
variable.status = "pending"; // force a refresh of tree view
|
|
|
|
callback(null, variable);
|
|
});
|
|
});
|
|
}
|
|
|
|
function getProxySource(process) {
|
|
var socketPath = c9.home + "/.c9/xdebug.sock";
|
|
if (c9.platform == "win32")
|
|
socketPath = "\\\\.\\pipe\\" + socketPath.replace(/\//g, "\\");
|
|
return {
|
|
source: PROXY
|
|
.replace(/^\s*\/\/.*/gm, "")
|
|
.replace(/[\n\r]/g, "")
|
|
.replace(/\{HOST\}/, process.runner.debughost || "")
|
|
.replace(/\{PORT\}/, process.runner.debugport),
|
|
port: socketPath
|
|
};
|
|
}
|
|
|
|
function setBreakpoints(breakpoints, callback) {
|
|
function _setBPs(breakpoints, callback, i) {
|
|
// run callback once we've exhausted setting breakpoints
|
|
if (i == breakpoints.length) {
|
|
callback(breakpoints);
|
|
return;
|
|
}
|
|
|
|
var bp = breakpoints[i];
|
|
|
|
plugin.setBreakpoint(bp, function() {
|
|
_setBPs(breakpoints, callback, i + 1);
|
|
});
|
|
}
|
|
|
|
_setBPs(breakpoints, callback, 0);
|
|
}
|
|
|
|
function setBreakBehavior(type, enabled, callback) {
|
|
breakOnExceptions = enabled ? type == "all" : false;
|
|
breakOnUncaughtExceptions = enabled ? type == "uncaught" : false;
|
|
|
|
// session.sendCommand("breakpoint_set", { t: "exception", x: "*", s: "enabled" }, null, function(err, args, data, raw) {
|
|
// TODO: store args.id and use it to toggle exception bp on/off
|
|
// callback && callback();
|
|
// });
|
|
}
|
|
|
|
/***** Register and define API *****/
|
|
|
|
plugin.on("load", load);
|
|
plugin.on("unload", unload);
|
|
|
|
/**
|
|
* Xdebug (DBGP) debugger implementation for Cloud9. This debugger
|
|
* implements the DBGP protocol, which can be used with several
|
|
* different language engines, such as PHP, or Python.
|
|
*
|
|
* @class debugger.xdebug
|
|
* @extends debugger.implementation
|
|
*/
|
|
plugin.freezePublicAPI({
|
|
/**
|
|
* Specifies the features that this debugger implementation supports
|
|
* @property {Object} features
|
|
* @property {Boolean} features.scripts Able to download code (disable the scripts button)
|
|
* @property {Boolean} features.conditionalBreakpoints Able to have conditional breakpoints (disable menu item)
|
|
* @property {Boolean} features.liveUpdate Able to update code live (don't do anything when saving)
|
|
* @property {Boolean} features.updateWatchedVariables Able to edit variables in watches (don't show editor)
|
|
* @property {Boolean} features.updateScopeVariables Able to edit variables in variables panel (don't show editor)
|
|
* @property {Boolean} features.setBreakBehavior Able to configure break behavior (disable break behavior button)
|
|
* @property {Boolean} features.executeCode Able to execute code (disable REPL)
|
|
*/
|
|
features: {
|
|
scripts: false,
|
|
conditionalBreakpoints: true,
|
|
liveUpdate: false,
|
|
updateWatchedVariables: true,
|
|
updateScopeVariables: true,
|
|
setBreakBehavior: false,
|
|
executeCode: true,
|
|
listeningDebugger: true
|
|
|
|
// TODO: flag to disable "suspend" command
|
|
},
|
|
|
|
/**
|
|
* The type of the debugger implementation. This is the identifier
|
|
* with which the runner selects the debugger implementation.
|
|
* @property {String} type
|
|
* @readonly
|
|
*/
|
|
type: TYPE,
|
|
|
|
/**
|
|
* @property {null|"running"|"stopped"} state The state of the debugger process
|
|
* <table>
|
|
* <tr><td>Value</td><td> Description</td></tr>
|
|
* <tr><td>null</td><td> process doesn't exist</td></tr>
|
|
* <tr><td>"stopped"</td><td> paused on breakpoint</td></tr>
|
|
* <tr><td>"running"</td><td> process is running</td></tr>
|
|
* </table>
|
|
* @readonly
|
|
*/
|
|
get state() { return state; },
|
|
|
|
/**
|
|
*
|
|
*/
|
|
get attached() { return attached; },
|
|
|
|
/**
|
|
* Whether the debugger will break when it encounters any exception.
|
|
* This includes exceptions in try/catch blocks.
|
|
* @property {Boolean} breakOnExceptions
|
|
* @readonly
|
|
*/
|
|
get breakOnExceptions() { return breakOnExceptions; },
|
|
|
|
/**
|
|
* Whether the debugger will break when it encounters an uncaught
|
|
* exception.
|
|
* @property {Boolean} breakOnUncaughtExceptions
|
|
* @readonly
|
|
*/
|
|
get breakOnUncaughtExceptions() { return breakOnUncaughtExceptions; },
|
|
|
|
_events: [
|
|
/**
|
|
* Fires when the debugger hits a breakpoint.
|
|
* @event break
|
|
* @param {Object} e
|
|
* @param {debugger.Frame} e.frame The frame where the debugger has breaked at.
|
|
* @param {debugger.Frame[]} [e.frames] The callstack frames.
|
|
*/
|
|
"break",
|
|
|
|
/**
|
|
* Fires when the {@link #state} property changes
|
|
* @event stateChange
|
|
* @param {Object} e
|
|
* @param {debugger.Frame} e.state The new value of the state property.
|
|
*/
|
|
"stateChange",
|
|
|
|
/**
|
|
* Fires when the debugger hits an exception.
|
|
* @event exception
|
|
* @param {Object} e
|
|
* @param {debugger.Frame} e.frame The frame where the debugger has breaked at.
|
|
* @param {Error} e.exception The exception that the debugger breaked at.
|
|
*/
|
|
"exception",
|
|
|
|
/**
|
|
* Fires when a frame becomes active. This happens when the debugger
|
|
* hits a breakpoint, or when it starts running again.
|
|
* @event frameActivate
|
|
* @param {Object} e
|
|
* @param {debugger.Frame/null} e.frame The current frame or null if there is no active frame.
|
|
*/
|
|
"frameActivate",
|
|
|
|
/**
|
|
* Fires when the result of the {@link #method-getFrames} call comes in.
|
|
* @event getFrames
|
|
* @param {Object} e
|
|
* @param {debugger.Frame[]} e.frames The frames that were retrieved.
|
|
*/
|
|
"getFrames",
|
|
|
|
/**
|
|
* Fires when the result of the {@link #getSources} call comes in.
|
|
* @event sources
|
|
* @param {Object} e
|
|
* @param {debugger.Source[]} e.sources The sources that were retrieved.
|
|
*/
|
|
"sources",
|
|
|
|
/**
|
|
* Fires when a source file is (re-)compiled. In your event
|
|
* handler, make sure you check against the sources you already
|
|
* have collected to see if you need to update or add your source.
|
|
* @event sourcesCompile
|
|
* @param {Object} e
|
|
* @param {debugger.Source} e.file the source file that is compiled.
|
|
**/
|
|
"sourcesCompile"
|
|
],
|
|
|
|
/**
|
|
* Attaches the debugger to the started process.
|
|
* @param {Object} runner A runner as specified by {@link run#run}.
|
|
* @param {debugger.Breakpoint[]} breakpoints The set of breakpoints that should be set from the start
|
|
*/
|
|
attach: attach,
|
|
|
|
/**
|
|
* Detaches the debugger from the started process.
|
|
*/
|
|
detach: detach,
|
|
|
|
/**
|
|
* Loads all the active sources from the process
|
|
*
|
|
* @param {Function} callback Called when the sources are retrieved.
|
|
* @param {Error} callback.err The error object if an error occured.
|
|
* @param {debugger.Source[]} callback.sources A list of the active sources.
|
|
* @fires sources
|
|
*/
|
|
getSources: getSources,
|
|
|
|
/**
|
|
* Retrieves the contents of a source file
|
|
* @param {debugger.Source} source The source to retrieve the contents for
|
|
* @param {Function} callback Called when the contents is retrieved
|
|
* @param {Error} callback.err The error object if an error occured.
|
|
* @param {String} callback.contents The contents of the source file
|
|
*/
|
|
getSource: getSource,
|
|
|
|
/**
|
|
* Retrieves the current stack of frames (aka "the call stack")
|
|
* from the debugger.
|
|
* @param {Function} callback Called when the frame are retrieved.
|
|
* @param {Error} callback.err The error object if an error occured.
|
|
* @param {debugger.Frame[]} callback.frames A list of frames, where index 0 is the frame where the debugger has breaked in.
|
|
* @fires getFrames
|
|
*/
|
|
getFrames: getFrames,
|
|
|
|
/**
|
|
* Retrieves the variables from a scope.
|
|
* @param {debugger.Frame} frame The frame to which the scope is related.
|
|
* @param {debugger.Scope} scope The scope from which to load the variables.
|
|
* @param {Function} callback Called when the variables are loaded
|
|
* @param {Error} callback.err The error object if an error occured.
|
|
* @param {debugger.Variable[]} callback.variables A list of variables defined in the `scope`.
|
|
* @param {debugger.Scope} callback.scope The scope to which these variables belong
|
|
* @param {debugger.Frame} callback.frame The frame related to the scope.
|
|
*/
|
|
getScope: getScope,
|
|
|
|
/**
|
|
* Retrieves and sets the properties of a variable.
|
|
* @param {debugger.Variable} variable The variable for which to retrieve the properties.
|
|
* @param {Function} callback Called when the properties are loaded
|
|
* @param {Error} callback.err The error object if an error occured.
|
|
* @param {debugger.Variable[]} callback.properties A list of properties of the variable.
|
|
* @param {debugger.Variable} callback.variable The variable to which the properties belong.
|
|
*/
|
|
getProperties: getProperties,
|
|
|
|
/**
|
|
* Step into the next statement.
|
|
*/
|
|
stepInto: stepInto,
|
|
|
|
/**
|
|
* Step over the next statement.
|
|
*/
|
|
stepOver: stepOver,
|
|
|
|
/**
|
|
* Step out of the current statement.
|
|
*/
|
|
stepOut: stepOut,
|
|
|
|
/**
|
|
* Continues execution of a process after it has hit a breakpoint.
|
|
*/
|
|
resume: resume,
|
|
|
|
/**
|
|
* Pauses the execution of a process at the next statement.
|
|
*/
|
|
suspend: suspend,
|
|
|
|
/**
|
|
* Evaluates an expression in a frame or in global space.
|
|
* @param {String} expression The expression.
|
|
* @param {debugger.Frame} frame The stack frame which serves as the contenxt of the expression.
|
|
* @param {Boolean} global Specifies whether to execute the expression in global space.
|
|
* @param {Boolean} disableBreak Specifies whether to disabled breaking when executing this expression.
|
|
* @param {Function} callback Called after the expression has executed.
|
|
* @param {Error} callback.err The error if any error occured.
|
|
* @param {debugger.Variable} callback.variable The result of the expression.
|
|
*/
|
|
evaluate: evaluate,
|
|
|
|
/**
|
|
* Change a live running source to the latest code state
|
|
* @param {debugger.Source} source The source file to update.
|
|
* @param {String} value The new contents of the source file.
|
|
* @param {Boolean} previewOnly
|
|
* @param {Function} callback Called after the expression has executed.
|
|
* @param {Error} callback.err The error if any error occured.
|
|
*/
|
|
// setScriptSource: setScriptSource,
|
|
|
|
/**
|
|
* Adds a breakpoint to a line in a source file.
|
|
* @param {debugger.Breakpoint} breakpoint The breakpoint to add.
|
|
* @param {Function} callback Called after the expression has executed.
|
|
* @param {Error} callback.err The error if any error occured.
|
|
* @param {debugger.Breakpoint} callback.breakpoint The added breakpoint
|
|
* @param {Object} callback.data Additional debugger specific information.
|
|
*/
|
|
setBreakpoint: setBreakpoint,
|
|
|
|
/**
|
|
* Updates properties of a breakpoint
|
|
* @param {debugger.Breakpoint} breakpoint The breakpoint to update.
|
|
* @param {Function} callback Called after the expression has executed.
|
|
* @param {Error} callback.err The error if any error occured.
|
|
* @param {debugger.Breakpoint} callback.breakpoint The updated breakpoint
|
|
*/
|
|
changeBreakpoint: changeBreakpoint,
|
|
|
|
/**
|
|
* Removes a breakpoint from a line in a source file.
|
|
* @param {debugger.Breakpoint} breakpoint The breakpoint to remove.
|
|
* @param {Function} callback Called after the expression has executed.
|
|
* @param {Error} callback.err The error if any error occured.
|
|
* @param {debugger.Breakpoint} callback.breakpoint The removed breakpoint
|
|
*/
|
|
clearBreakpoint: clearBreakpoint,
|
|
|
|
/**
|
|
* Retrieves a list of all the breakpoints that are set in the
|
|
* debugger.
|
|
* @param {Function} callback Called when the breakpoints are retrieved.
|
|
* @param {Error} callback.err The error if any error occured.
|
|
* @param {debugger.Breakpoint[]} callback.breakpoints A list of breakpoints
|
|
*/
|
|
listBreakpoints: listBreakpoints,
|
|
|
|
/**
|
|
* Sets the value of a variable.
|
|
* @param {debugger.Variable} variable The variable to set the value of.
|
|
* @param {Mixed} value The new value of the variable.
|
|
* @param {debugger.Frame} frame The frame to which the variable belongs.
|
|
* @param {Function} callback
|
|
* @param {Function} callback Called when the breakpoints are retrieved.
|
|
* @param {Error} callback.err The error if any error occured.
|
|
* @param {Object} callback.data Additional debugger specific information.
|
|
*/
|
|
setVariable: setVariable,
|
|
|
|
/**
|
|
*
|
|
*/
|
|
// restartFrame: restartFrame,
|
|
|
|
/**
|
|
*
|
|
*/
|
|
// serializeVariable: serializeVariable,
|
|
|
|
/**
|
|
* Defines how the debugger deals with exceptions.
|
|
* @param {"all"/"uncaught"} type Specifies which errors to break on.
|
|
* @param {Boolean} enabled Specifies whether to enable breaking on exceptions.
|
|
* @param {Function} callback Called after the setting is changed.
|
|
* @param {Error} callback.err The error if any error occured.
|
|
*/
|
|
setBreakBehavior: setBreakBehavior,
|
|
|
|
/**
|
|
* Returns the source of the proxy
|
|
*/
|
|
getProxySource: getProxySource
|
|
});
|
|
|
|
register(null, {
|
|
"debugger.xdebug": plugin
|
|
});
|
|
}
|
|
});
|