mirror of https://github.com/axmolengine/axmol.git
277 lines
7.2 KiB
JavaScript
277 lines
7.2 KiB
JavaScript
/**
|
|
* An OriginalLocation represents a location in an original source.
|
|
*
|
|
* @param SourceActor actor
|
|
* A SourceActor representing an original source.
|
|
* @param Number line
|
|
* A line within the given source.
|
|
* @param Number column
|
|
* A column within the given line.
|
|
* @param String name
|
|
* The name of the symbol corresponding to this OriginalLocation.
|
|
*/
|
|
|
|
function OriginalLocation(actor, line, column, name) {
|
|
this._connection = actor ? actor.conn : null;
|
|
this._actorID = actor ? actor.actorID : undefined;
|
|
this._line = line;
|
|
this._column = column;
|
|
this._name = name;
|
|
}
|
|
|
|
OriginalLocation.fromGeneratedLocation = function (generatedLocation) {
|
|
return new OriginalLocation(
|
|
generatedLocation.generatedSourceActor,
|
|
generatedLocation.generatedLine,
|
|
generatedLocation.generatedColumn
|
|
);
|
|
};
|
|
|
|
OriginalLocation.prototype = {
|
|
get originalSourceActor() {
|
|
return this._connection ? this._connection.getActor(this._actorID) : null;
|
|
},
|
|
|
|
get originalUrl() {
|
|
let actor = this.originalSourceActor;
|
|
let source = actor.source;
|
|
return source ? source.url : actor._originalUrl;
|
|
},
|
|
|
|
get originalLine() {
|
|
return this._line;
|
|
},
|
|
|
|
get originalColumn() {
|
|
return this._column;
|
|
},
|
|
|
|
get originalName() {
|
|
return this._name;
|
|
},
|
|
|
|
get generatedSourceActor() {
|
|
throw new Error("Shouldn't access generatedSourceActor from an OriginalLocation");
|
|
},
|
|
|
|
get generatedLine() {
|
|
throw new Error("Shouldn't access generatedLine from an OriginalLocation");
|
|
},
|
|
|
|
get generatedColumn() {
|
|
throw new Error("Shouldn't access generatedColumn from an Originallocation");
|
|
},
|
|
|
|
equals: function (other) {
|
|
return this.originalSourceActor.url == other.originalSourceActor.url &&
|
|
this.originalLine === other.originalLine &&
|
|
(this.originalColumn === undefined ||
|
|
other.originalColumn === undefined ||
|
|
this.originalColumn === other.originalColumn);
|
|
},
|
|
|
|
toJSON: function () {
|
|
return {
|
|
source: this.originalSourceActor.form(),
|
|
line: this.originalLine,
|
|
column: this.originalColumn
|
|
};
|
|
}
|
|
};
|
|
|
|
/**
|
|
* A GeneratedLocation represents a location in a generated source.
|
|
*
|
|
* @param SourceActor actor
|
|
* A SourceActor representing a generated source.
|
|
* @param Number line
|
|
* A line within the given source.
|
|
* @param Number column
|
|
* A column within the given line.
|
|
*/
|
|
function GeneratedLocation(actor, line, column, lastColumn) {
|
|
this._connection = actor ? actor.conn : null;
|
|
this._actorID = actor ? actor.actorID : undefined;
|
|
this._line = line;
|
|
this._column = column;
|
|
this._lastColumn = (lastColumn !== undefined) ? lastColumn : column + 1;
|
|
}
|
|
|
|
GeneratedLocation.fromOriginalLocation = function (originalLocation) {
|
|
return new GeneratedLocation(
|
|
originalLocation.originalSourceActor,
|
|
originalLocation.originalLine,
|
|
originalLocation.originalColumn
|
|
);
|
|
};
|
|
|
|
GeneratedLocation.prototype = {
|
|
get originalSourceActor() {
|
|
throw new Error();
|
|
},
|
|
|
|
get originalUrl() {
|
|
throw new Error("Shouldn't access originalUrl from a GeneratedLocation");
|
|
},
|
|
|
|
get originalLine() {
|
|
throw new Error("Shouldn't access originalLine from a GeneratedLocation");
|
|
},
|
|
|
|
get originalColumn() {
|
|
throw new Error("Shouldn't access originalColumn from a GeneratedLocation");
|
|
},
|
|
|
|
get originalName() {
|
|
throw new Error("Shouldn't access originalName from a GeneratedLocation");
|
|
},
|
|
|
|
get generatedSourceActor() {
|
|
return this._connection ? this._connection.getActor(this._actorID) : null;
|
|
},
|
|
|
|
get generatedLine() {
|
|
return this._line;
|
|
},
|
|
|
|
get generatedColumn() {
|
|
return this._column;
|
|
},
|
|
|
|
get generatedLastColumn() {
|
|
return this._lastColumn;
|
|
},
|
|
|
|
equals: function (other) {
|
|
return this.generatedSourceActor.url == other.generatedSourceActor.url &&
|
|
this.generatedLine === other.generatedLine &&
|
|
(this.generatedColumn === undefined ||
|
|
other.generatedColumn === undefined ||
|
|
this.generatedColumn === other.generatedColumn);
|
|
},
|
|
|
|
toJSON: function () {
|
|
return {
|
|
source: this.generatedSourceActor.form(),
|
|
line: this.generatedLine,
|
|
column: this.generatedColumn,
|
|
lastColumn: this.generatedLastColumn
|
|
};
|
|
}
|
|
};
|
|
|
|
getOffsetColumn = function getOffsetColumn(aOffset, aScript) {
|
|
let bestOffsetMapping = null;
|
|
for (let offsetMapping of aScript.getAllColumnOffsets()) {
|
|
if (!bestOffsetMapping ||
|
|
(offsetMapping.offset <= aOffset &&
|
|
offsetMapping.offset > bestOffsetMapping.offset)) {
|
|
bestOffsetMapping = offsetMapping;
|
|
}
|
|
}
|
|
|
|
if (!bestOffsetMapping) {
|
|
// XXX: Try not to completely break the experience of using the debugger for
|
|
// the user by assuming column 0. Simultaneously, report the error so that
|
|
// there is a paper trail if the assumption is bad and the debugging
|
|
// experience becomes wonky.
|
|
reportError(new Error("Could not find a column for offset " + aOffset
|
|
+ " in the script " + aScript));
|
|
return 0;
|
|
}
|
|
|
|
return bestOffsetMapping.columnNumber;
|
|
}
|
|
|
|
/**
|
|
* Construct an ActorPool.
|
|
*
|
|
* ActorPools are actorID -> actor mapping and storage. These are
|
|
* used to accumulate and quickly dispose of groups of actors that
|
|
* share a lifetime.
|
|
*/
|
|
function ActorPool(aConnection)
|
|
{
|
|
this.conn = aConnection;
|
|
this._cleanups = {};
|
|
this._actors = {};
|
|
}
|
|
|
|
ActorPool.prototype = {
|
|
/**
|
|
* Add an actor to the actor pool. If the actor doesn't have an ID,
|
|
* allocate one from the connection.
|
|
*
|
|
* @param aActor object
|
|
* The actor implementation. If the object has a
|
|
* 'disconnect' property, it will be called when the actor
|
|
* pool is cleaned up.
|
|
*/
|
|
addActor: function AP_addActor(aActor) {
|
|
aActor.conn = this.conn;
|
|
if (!aActor.actorID) {
|
|
let prefix = aActor.actorPrefix;
|
|
if (!prefix && typeof aActor == "function") {
|
|
// typeName is a convention used with protocol.js-based actors
|
|
prefix = aActor.prototype.actorPrefix || aActor.prototype.typeName;
|
|
}
|
|
aActor.actorID = this.conn.allocID(prefix || undefined);
|
|
}
|
|
|
|
if (aActor.registeredPool) {
|
|
aActor.registeredPool.removeActor(aActor);
|
|
}
|
|
aActor.registeredPool = this;
|
|
|
|
this._actors[aActor.actorID] = aActor;
|
|
if (aActor.disconnect) {
|
|
this._cleanups[aActor.actorID] = aActor;
|
|
}
|
|
},
|
|
|
|
get: function AP_get(aActorID) {
|
|
return this._actors[aActorID] || undefined;
|
|
},
|
|
|
|
has: function AP_has(aActorID) {
|
|
return aActorID in this._actors;
|
|
},
|
|
|
|
/**
|
|
* Returns true if the pool is empty.
|
|
*/
|
|
isEmpty: function AP_isEmpty() {
|
|
return Object.keys(this._actors).length == 0;
|
|
},
|
|
|
|
/**
|
|
* Remove an actor from the actor pool.
|
|
*/
|
|
removeActor: function AP_remove(aActor) {
|
|
delete this._actors[aActor.actorID];
|
|
delete this._cleanups[aActor.actorID];
|
|
},
|
|
|
|
/**
|
|
* Match the api expected by the protocol library.
|
|
*/
|
|
unmanage: function(aActor) {
|
|
return this.removeActor(aActor);
|
|
},
|
|
|
|
/**
|
|
* Run all actor cleanups.
|
|
*/
|
|
cleanup: function AP_cleanup() {
|
|
for (let id in this._cleanups) {
|
|
this._cleanups[id].disconnect();
|
|
}
|
|
this._cleanups = {};
|
|
},
|
|
|
|
forEach: function(callback) {
|
|
for (let name in this._actors) {
|
|
callback(this._actors[name]);
|
|
}
|
|
},
|
|
} |