Bug 1862693 - Use 1-origin column number in debugger API. r=iain,ochameau,devtools-reviewers
This includes the following API:
* Debugger.Object.prototype.createSource
* startColumn field of the parameter object
* Debugger.Script.prototype.startColumn
* return value
* Debugger.Script.prototype.getPossibleBreakpoints
* minColumn and maxColumn property of the query
* columnNumber property of the returned array elements
* Debugger.Script.prototype.getOffsetMetadata
* columnNumber property of the returned array elements
* Debugger.Script.prototype.getOffsetLocation
* columnNumber property of the returned array elements
* Debugger.Script.prototype.getAllColumnOffsets
* columnNumber property of the returned array elements
* Debugger.Script.prototype.getOffsetsCoverage
* columnNumber property of the returned array elements
* Debugger.Source.prototype.startColumn
* return value
This patch modifies DevTools code to convert the column number from/to 1-origin,
while keep using 0-origin on their side.
One exception is the WASM's column number, which had been using 1-origin 1.
Each consumer in DevTools handles the WASM case, and the code can be removed
once DevTools internal also switches to 1-origin column number.
The other exception is to use 1-based column number in logCustomFormatterError,
which is folded from bug 1864783 patch.
Differential Revision: https://phabricator.services.mozilla.com/D193270
This commit is contained in:
@@ -27,10 +27,10 @@ export function createLocation({
|
||||
sourceActor,
|
||||
sourceActorId: sourceActor?.id,
|
||||
|
||||
// `line` is 1-based while `column` is 0-based.
|
||||
// `line` and `column` are 1-based.
|
||||
// This data is mostly coming from and driven by
|
||||
// JSScript::lineno and JSScript::column
|
||||
// https://searchfox.org/mozilla-central/rev/d81e60336d9f498ad3985491dc17c2b77969ade4/js/src/vm/JSScript.h#1544-1547
|
||||
// https://searchfox.org/mozilla-central/rev/90dce6b0223b4dc17bb10f1125b44f70951585f9/js/src/vm/JSScript.h#1545-1548
|
||||
line,
|
||||
column,
|
||||
};
|
||||
|
||||
@@ -47,7 +47,7 @@ async function testHeaderNotReturningJsonMl(hud) {
|
||||
info(`Test for "header" not returning JsonML`);
|
||||
await testCustomFormatting(hud, {
|
||||
messageText: `Custom formatter failed: devtoolsFormatters[1].header should return an array, got number`,
|
||||
source: "test-console-custom-formatters-errors.html:19:18",
|
||||
source: "test-console-custom-formatters-errors.html:19:19",
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -174,7 +174,7 @@ The functions described below may only be called with a ``this`` value referring
|
||||
The elements of the array are objects, each of which describes a single entry point, and contains the following properties:
|
||||
|
||||
- lineNumber: the line number for which offset is an entry point
|
||||
- columnNumber: the column number for which offset is an entry point
|
||||
- columnNumber: the 1-based column number for which offset is an entry point
|
||||
- offset: the bytecode instruction offset of the entry point
|
||||
|
||||
|
||||
@@ -191,10 +191,10 @@ The functions described below may only be called with a ``this`` value referring
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
[{ lineNumber: 0, columnNumber: 0, offset: 0 },
|
||||
{ lineNumber: 1, columnNumber: 5, offset: 5 },
|
||||
{ lineNumber: 1, columnNumber: 10, offset: 20 },
|
||||
{ lineNumber: 3, columnNumber: 4, offset: 10 }]
|
||||
[{ lineNumber: 0, columnNumber: 1, offset: 0 },
|
||||
{ lineNumber: 1, columnNumber: 6, offset: 5 },
|
||||
{ lineNumber: 1, columnNumber: 11, offset: 20 },
|
||||
{ lineNumber: 3, columnNumber: 5, offset: 10 }]
|
||||
|
||||
**If the instance refers to WebAssembly code**, throw a ``TypeError``.
|
||||
|
||||
@@ -205,7 +205,7 @@ The functions described below may only be called with a ``this`` value referring
|
||||
**If the instance refers to a JSScript**, return an object describing the source code location responsible for the bytecode at *offset* in this script. The object has the following properties:
|
||||
|
||||
- lineNumber: the line number for which offset is an entry point
|
||||
- columnNumber: the column number for which offset is an entry point
|
||||
- columnNumber: the 1-based column number for which offset is an entry point
|
||||
- isEntryPoint: true if the offset is a column entry point, as would be reported by getAllColumnOffsets(); otherwise false.
|
||||
|
||||
|
||||
@@ -213,7 +213,7 @@ The functions described below may only be called with a ``this`` value referring
|
||||
**If the instance refers to a JSScript**, return ``null`` or an array which contains information about the coverage of all opcodes. The elements of the array are objects, each of which describes a single opcode, and contains the following properties:
|
||||
|
||||
- lineNumber: the line number of the current opcode.
|
||||
- columnNumber: the column number of the current opcode.
|
||||
- columnNumber: the 1-based column number of the current opcode.
|
||||
- offset: the bytecode instruction offset of the current opcode.
|
||||
- count: the number of times the current opcode got executed.
|
||||
|
||||
|
||||
@@ -238,8 +238,6 @@ The functions described below may only be called with a ``this`` value referring
|
||||
The script’s ``source`` property must be equal to this value.
|
||||
``line``
|
||||
The script must at least partially cover the given source line. If this property is present, the ``url`` property must be present as well.
|
||||
``column``
|
||||
The script must include given column on the line given by the ``line`` property. If this property is present, the ``url`` and ``line`` properties must both be present as well.
|
||||
``innermost``
|
||||
If this property is present and true, the script must be the innermost script covering the given source location; scripts of enclosing code are omitted.
|
||||
``global``
|
||||
|
||||
@@ -968,8 +968,13 @@ class EventCollector {
|
||||
if (script) {
|
||||
const scriptSource = script.source.text;
|
||||
|
||||
// NOTE: Debugger.Script.prototype.startColumn is 1-based.
|
||||
// Convert to 0-based, while keeping the wasm's column (1) as is.
|
||||
// (bug 1863878)
|
||||
const columnBase = script.format === "wasm" ? 0 : 1;
|
||||
|
||||
line = script.startLine;
|
||||
column = script.startColumn;
|
||||
column = script.startColumn - columnBase;
|
||||
url = script.url;
|
||||
const actor = this.targetActor.sourcesManager.getOrCreateSourceActor(
|
||||
script.source
|
||||
|
||||
@@ -506,10 +506,15 @@ class NodeActor extends Actor {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// NOTE: Debugger.Script.prototype.startColumn is 1-based.
|
||||
// Convert to 0-based, while keeping the wasm's column (1) as is.
|
||||
// (bug 1863878)
|
||||
const columnBase = customElementDO.script.format === "wasm" ? 0 : 1;
|
||||
|
||||
return {
|
||||
url: customElementDO.script.url,
|
||||
line: customElementDO.script.startLine,
|
||||
column: customElementDO.script.startColumn,
|
||||
column: customElementDO.script.startColumn - columnBase,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -156,10 +156,14 @@ const previewers = {
|
||||
grip.isGenerator = obj.isGeneratorFunction;
|
||||
|
||||
if (obj.script) {
|
||||
// NOTE: Debugger.Script.prototype.startColumn is 1-based.
|
||||
// Convert to 0-based, while keeping the wasm's column (1) as is.
|
||||
// (bug 1863878)
|
||||
const columnBase = obj.script.format === "wasm" ? 0 : 1;
|
||||
grip.location = {
|
||||
url: obj.script.url,
|
||||
line: obj.script.startLine,
|
||||
column: obj.script.startColumn,
|
||||
column: obj.script.startColumn - columnBase,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -193,6 +193,11 @@ class SourceActor extends Actor {
|
||||
introductionType = "scriptElement";
|
||||
}
|
||||
|
||||
// NOTE: Debugger.Source.prototype.startColumn is 1-based.
|
||||
// Convert to 0-based, while keeping the wasm's column (1) as is.
|
||||
// (bug 1863878)
|
||||
const columnBase = source.introductionType === "wasm" ? 0 : 1;
|
||||
|
||||
return {
|
||||
actor: this.actorID,
|
||||
extensionName: this.extensionName,
|
||||
@@ -206,7 +211,7 @@ class SourceActor extends Actor {
|
||||
introductionType,
|
||||
isInlineSource: this._isInlineSource,
|
||||
sourceStartLine: source.startLine,
|
||||
sourceStartColumn: source.startColumn,
|
||||
sourceStartColumn: source.startColumn - columnBase,
|
||||
sourceLength: source.text?.length,
|
||||
};
|
||||
}
|
||||
@@ -411,10 +416,15 @@ class SourceActor extends Actor {
|
||||
return false;
|
||||
}
|
||||
|
||||
// NOTE: Debugger.Script.prototype.startColumn is 1-based.
|
||||
// Convert to 0-based, while keeping the wasm's column (1) as is.
|
||||
// (bug 1863878)
|
||||
const columnBase = script.format === "wasm" ? 0 : 1;
|
||||
if (
|
||||
script.startLine > endLine ||
|
||||
script.startLine + lineCount <= startLine ||
|
||||
(script.startLine == endLine && script.startColumn > endColumn)
|
||||
(script.startLine == endLine &&
|
||||
script.startColumn - columnBase > endColumn)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
@@ -422,7 +432,7 @@ class SourceActor extends Actor {
|
||||
if (
|
||||
lineCount == 1 &&
|
||||
script.startLine == startLine &&
|
||||
script.startColumn + script.sourceLength <= startColumn
|
||||
script.startColumn - columnBase + script.sourceLength <= startColumn
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
@@ -469,20 +479,25 @@ class SourceActor extends Actor {
|
||||
end: { line: endLine = Infinity, column: endColumn = Infinity } = {},
|
||||
} = query || {};
|
||||
|
||||
// NOTE: Debugger.Script.prototype.startColumn is 1-based.
|
||||
// Convert to 0-based, while keeping the wasm's column (1) as is.
|
||||
// (bug 1863878)
|
||||
const columnBase = script.format === "wasm" ? 0 : 1;
|
||||
|
||||
const offsets = script.getPossibleBreakpoints();
|
||||
for (const { lineNumber, columnNumber } of offsets) {
|
||||
if (
|
||||
lineNumber < startLine ||
|
||||
(lineNumber === startLine && columnNumber < startColumn) ||
|
||||
(lineNumber === startLine && columnNumber - columnBase < startColumn) ||
|
||||
lineNumber > endLine ||
|
||||
(lineNumber === endLine && columnNumber >= endColumn)
|
||||
(lineNumber === endLine && columnNumber - columnBase >= endColumn)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
positions.push({
|
||||
line: lineNumber,
|
||||
column: columnNumber,
|
||||
column: columnNumber - columnBase,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -610,6 +625,11 @@ class SourceActor extends Actor {
|
||||
script => !actor.hasScript(script)
|
||||
);
|
||||
|
||||
// NOTE: Debugger.Script.prototype.getPossibleBreakpoints returns
|
||||
// columnNumber in 1-based.
|
||||
// The following code uses columnNumber only for comparing against
|
||||
// other columnNumber, and we don't need to convert to 0-based.
|
||||
|
||||
// This is a line breakpoint, so we add a breakpoint on the first
|
||||
// breakpoint on the line.
|
||||
const lineMatches = [];
|
||||
@@ -644,13 +664,19 @@ class SourceActor extends Actor {
|
||||
);
|
||||
|
||||
for (const script of scripts) {
|
||||
// NOTE: getPossibleBreakpoints's minColumn/maxColumn parameters are
|
||||
// 1-based.
|
||||
// Convert to 1-based, while keeping the wasm's column (1) as is.
|
||||
// (bug 1863878)
|
||||
const columnBase = script.format === "wasm" ? 0 : 1;
|
||||
|
||||
// Check to see if the script contains a breakpoint position at
|
||||
// this line and column.
|
||||
const possibleBreakpoint = script
|
||||
.getPossibleBreakpoints({
|
||||
line,
|
||||
minColumn: column,
|
||||
maxColumn: column + 1,
|
||||
minColumn: column + columnBase,
|
||||
maxColumn: column + columnBase + 1,
|
||||
})
|
||||
.pop();
|
||||
|
||||
|
||||
@@ -2254,7 +2254,11 @@ class ThreadActor extends Actor {
|
||||
...content.substring(0, scriptStartOffset).matchAll("\n"),
|
||||
];
|
||||
const startLine = 1 + allLineBreaks.length;
|
||||
// NOTE: Debugger.Source.prototype.startColumn is 1-based.
|
||||
// Create 1-based column here for the following comparison,
|
||||
// and also the createSource call below.
|
||||
const startColumn =
|
||||
1 +
|
||||
scriptStartOffset -
|
||||
(allLineBreaks.length ? allLineBreaks.at(-1).index - 1 : 0);
|
||||
|
||||
@@ -2270,6 +2274,7 @@ class ThreadActor extends Actor {
|
||||
|
||||
try {
|
||||
const global = this.dbg.getDebuggees()[0];
|
||||
// NOTE: Debugger.Object.prototype.createSource takes 1-based column.
|
||||
this._addSource(
|
||||
global.createSource({
|
||||
text,
|
||||
|
||||
@@ -149,8 +149,20 @@ class TracerActor extends Actor {
|
||||
const { lineNumber, columnNumber } = script.getOffsetMetadata(frame.offset);
|
||||
const url = script.source.url;
|
||||
|
||||
// NOTE: Debugger.Script.prototype.getOffsetMetadata returns
|
||||
// columnNumber in 1-based.
|
||||
// Convert to 0-based, while keeping the wasm's column (1) as is.
|
||||
// (bug 1863878)
|
||||
const columnBase = script.format === "wasm" ? 0 : 1;
|
||||
|
||||
// Ignore blackboxed sources
|
||||
if (this.sourcesManager.isBlackBoxed(url, lineNumber, columnNumber)) {
|
||||
if (
|
||||
this.sourcesManager.isBlackBoxed(
|
||||
url,
|
||||
lineNumber,
|
||||
columnNumber - columnBase
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -185,7 +197,7 @@ class TracerActor extends Actor {
|
||||
this.throttledConsoleMessages.push({
|
||||
filename: url,
|
||||
lineNumber,
|
||||
columnNumber,
|
||||
columnNumber: columnNumber - columnBase,
|
||||
arguments: args,
|
||||
styles: CONSOLE_ARGS_STYLES,
|
||||
level: "logTrace",
|
||||
|
||||
@@ -228,10 +228,14 @@ class SourcesManager extends EventEmitter {
|
||||
*/
|
||||
getScriptOffsetLocation(script, offset) {
|
||||
const { lineNumber, columnNumber } = script.getOffsetMetadata(offset);
|
||||
// NOTE: Debugger.Source.prototype.startColumn is 1-based.
|
||||
// Convert to 0-based, while keeping the wasm's column (1) as is.
|
||||
// (bug 1863878)
|
||||
const columnBase = script.format === "wasm" ? 0 : 1;
|
||||
return new SourceLocation(
|
||||
this.createSourceActor(script.source),
|
||||
lineNumber,
|
||||
columnNumber
|
||||
columnNumber - columnBase
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -291,6 +291,11 @@ class JavaScriptTracer {
|
||||
// but if DevTools are closed, stdout is the only way to log the traces.
|
||||
if (shouldLogToStdout) {
|
||||
const { script } = frame;
|
||||
// NOTE: Debugger.Script.prototype.getOffsetMetadata returns
|
||||
// columnNumber in 1-based.
|
||||
// Convert to 0-based, while keeping the wasm's column (1) as is.
|
||||
// (bug 1863878)
|
||||
const columnBase = script.format === "wasm" ? 0 : 1;
|
||||
const { lineNumber, columnNumber } = script.getOffsetMetadata(
|
||||
frame.offset
|
||||
);
|
||||
@@ -305,7 +310,9 @@ class JavaScriptTracer {
|
||||
|
||||
// Use a special URL, including line and column numbers which Firefox
|
||||
// interprets as to be opened in the already opened DevTool's debugger
|
||||
const href = `${script.source.url}:${lineNumber}:${columnNumber}`;
|
||||
const href = `${script.source.url}:${lineNumber}:${
|
||||
columnNumber - columnBase
|
||||
}`;
|
||||
|
||||
// Use special characters in order to print working hyperlinks right from the terminal
|
||||
// See https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
|
||||
|
||||
@@ -1246,6 +1246,9 @@ bool DebuggerObject::CallData::createSource() {
|
||||
if (!ToUint32(cx, v, &startColumn)) {
|
||||
return false;
|
||||
}
|
||||
if (startColumn == 0) {
|
||||
startColumn = 1;
|
||||
}
|
||||
|
||||
if (!JS_GetProperty(cx, options, "sourceMapURL", &v)) {
|
||||
return false;
|
||||
@@ -1267,8 +1270,7 @@ bool DebuggerObject::CallData::createSource() {
|
||||
|
||||
JS::CompileOptions compileOptions(cx);
|
||||
compileOptions.lineno = startLine;
|
||||
compileOptions.column =
|
||||
JS::ColumnNumberOneOrigin::fromZeroOrigin(startColumn);
|
||||
compileOptions.column = JS::ColumnNumberOneOrigin(startColumn);
|
||||
|
||||
if (!JS::StringHasLatin1Chars(url)) {
|
||||
JS_ReportErrorASCII(cx, "URL must be a narrow string");
|
||||
|
||||
@@ -384,7 +384,7 @@ bool DebuggerScript::CallData::getStartColumn() {
|
||||
return JS::LimitedColumnNumberOneOrigin(
|
||||
JS::WasmFunctionIndex::DefaultBinarySourceColumnNumberOneOrigin);
|
||||
});
|
||||
args.rval().setNumber(column.zeroOriginValue());
|
||||
args.rval().setNumber(column.oneOriginValue());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -691,7 +691,7 @@ class DebuggerScript::GetPossibleBreakpointsMatcher {
|
||||
return false;
|
||||
}
|
||||
|
||||
value = NumberValue(colno.zeroOriginValue());
|
||||
value = NumberValue(colno.oneOriginValue());
|
||||
if (!DefineDataProperty(cx_, entry, cx_->names().columnNumber, value)) {
|
||||
return false;
|
||||
}
|
||||
@@ -727,12 +727,7 @@ class DebuggerScript::GetPossibleBreakpointsMatcher {
|
||||
}
|
||||
bool parseColumnValue(HandleValue value,
|
||||
JS::LimitedColumnNumberOneOrigin* result) {
|
||||
uint32_t tmp;
|
||||
if (!parseIntValueImpl(value, &tmp)) {
|
||||
return false;
|
||||
}
|
||||
*result = JS::LimitedColumnNumberOneOrigin::fromZeroOrigin(tmp);
|
||||
return true;
|
||||
return parseIntValueImpl(value, result->addressOfValueForTranscode());
|
||||
}
|
||||
bool parseSizeTValue(HandleValue value, size_t* result) {
|
||||
return parseIntValueImpl(value, result);
|
||||
@@ -942,16 +937,7 @@ class DebuggerScript::GetPossibleBreakpointsMatcher {
|
||||
|
||||
for (uint32_t i = 0; i < offsets.length(); i++) {
|
||||
uint32_t lineno = offsets[i].lineno;
|
||||
// FIXME: wasm::ExprLoc::column contains "1". which is "1 in 1-origin",
|
||||
// but currently the debugger API returns 0-origin column number,
|
||||
// and the value becomes "0 in 0-origin".
|
||||
// the existing wasm debug functionality expects the observable
|
||||
// column number be "1", so it is "1 in 0-origin".
|
||||
// Once the debugger API is rewritten to use 1-origin, this
|
||||
// part also needs to be rewritten to directly pass the
|
||||
// "1 in 1-origin" (bug 1863878).
|
||||
JS::LimitedColumnNumberOneOrigin column =
|
||||
JS::LimitedColumnNumberOneOrigin::fromZeroOrigin(offsets[i].column);
|
||||
JS::LimitedColumnNumberOneOrigin column(offsets[i].column);
|
||||
size_t offset = offsets[i].offset;
|
||||
if (!maybeAppendEntry(offset, lineno, column, true)) {
|
||||
return false;
|
||||
@@ -1030,7 +1016,7 @@ class DebuggerScript::GetOffsetMetadataMatcher {
|
||||
return false;
|
||||
}
|
||||
|
||||
value = NumberValue(r.frontColumnNumber().zeroOriginValue());
|
||||
value = NumberValue(r.frontColumnNumber().oneOriginValue());
|
||||
if (!DefineDataProperty(cx_, result_, cx_->names().columnNumber, value)) {
|
||||
return false;
|
||||
}
|
||||
@@ -1369,7 +1355,7 @@ class DebuggerScript::GetOffsetLocationMatcher {
|
||||
return false;
|
||||
}
|
||||
|
||||
value = NumberValue(column.zeroOriginValue());
|
||||
value = NumberValue(column.oneOriginValue());
|
||||
if (!DefineDataProperty(cx_, result_, cx_->names().columnNumber, value)) {
|
||||
return false;
|
||||
}
|
||||
@@ -1837,7 +1823,7 @@ class DebuggerScript::GetAllColumnOffsetsMatcher {
|
||||
return false;
|
||||
}
|
||||
|
||||
value = NumberValue(column.zeroOriginValue());
|
||||
value = NumberValue(column.oneOriginValue());
|
||||
if (!DefineDataProperty(cx_, entry, cx_->names().columnNumber, value)) {
|
||||
return false;
|
||||
}
|
||||
@@ -1906,9 +1892,7 @@ class DebuggerScript::GetAllColumnOffsetsMatcher {
|
||||
|
||||
for (uint32_t i = 0; i < offsets.length(); i++) {
|
||||
uint32_t lineno = offsets[i].lineno;
|
||||
// See the comment in GetPossibleBreakpointsMatcher::parseQuery.
|
||||
JS::LimitedColumnNumberOneOrigin column =
|
||||
JS::LimitedColumnNumberOneOrigin::fromZeroOrigin(offsets[i].column);
|
||||
JS::LimitedColumnNumberOneOrigin column(offsets[i].column);
|
||||
size_t offset = offsets[i].offset;
|
||||
if (!appendColumnOffsetEntry(lineno, column, offset)) {
|
||||
return false;
|
||||
@@ -2429,8 +2413,7 @@ bool DebuggerScript::CallData::getOffsetsCoverage() {
|
||||
|
||||
offsetValue.setNumber(double(offset));
|
||||
lineNumberValue.setNumber(double(r.frontLineNumber()));
|
||||
columnNumberValue.setNumber(
|
||||
double(r.frontColumnNumber().zeroOriginValue()));
|
||||
columnNumberValue.setNumber(double(r.frontColumnNumber().oneOriginValue()));
|
||||
countValue.setNumber(double(hits));
|
||||
|
||||
// Create a new object with the offset, line number, column number, the
|
||||
|
||||
@@ -363,7 +363,7 @@ class DebuggerSourceGetStartColumnMatcher {
|
||||
bool DebuggerSource::CallData::getStartColumn() {
|
||||
DebuggerSourceGetStartColumnMatcher matcher;
|
||||
JS::LimitedColumnNumberOneOrigin column = referent.match(matcher);
|
||||
args.rval().setNumber(column.zeroOriginValue());
|
||||
args.rval().setNumber(column.oneOriginValue());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -173,37 +173,36 @@ into the system; the entire string is not a valid URL. For
|
||||
**If the instance refers to WebAssembly code**, throw a `TypeError`.
|
||||
|
||||
### `startLine`
|
||||
**If the instance refers to a `JSScript`**, the number of the line at
|
||||
**If the instance refers to a `JSScript`**, the 1-origin number of the line at
|
||||
which this script's code starts, within the file or document named by
|
||||
`url`.
|
||||
|
||||
### `startColumn`
|
||||
**If the instance refers to a `JSScript`**, the zero-indexed number of the
|
||||
column at which this script's code starts, within the file or document
|
||||
named by `url`. For functions, this is the start of the function's
|
||||
arguments:
|
||||
**If the instance refers to a `JSScript`**, the 1-origin column number at
|
||||
which this script's code starts, within the file or document named by `url`.
|
||||
For functions, this is the start of the function's arguments:
|
||||
```js
|
||||
function f() { ... }
|
||||
// ^ start (column 10)
|
||||
// ^ start (column 11)
|
||||
let g = x => x*x;
|
||||
// ^ start (column 8)
|
||||
// ^ start (column 9)
|
||||
let h = (x) => x*x;
|
||||
// ^ start (column 8)
|
||||
// ^ start (column 9)
|
||||
```
|
||||
For default class constructors, it is the start of the `class` keyword:
|
||||
```js
|
||||
let MyClass = class { };
|
||||
// ^ start (column 14)
|
||||
// ^ start (column 15)
|
||||
```
|
||||
For scripts from other sources, such as `eval` or the `Function`
|
||||
constructor, it is typically 0:
|
||||
```js
|
||||
let f = new Function(" console.log('hello world');");
|
||||
// ^ start (column 0, from the string's perspective)
|
||||
// ^ start (column 1, from the string's perspective)
|
||||
```
|
||||
|
||||
### `lineCount`
|
||||
**If the instance refers to a `JSScript`**, the number of lines this
|
||||
**If the instance refers to a `JSScript`**, the 1-origin number of lines this
|
||||
script's code occupies, within the file or document named by `url`.
|
||||
|
||||
### `source`
|
||||
@@ -232,7 +231,7 @@ by `source`.
|
||||
**If the instance refers to WebAssembly code**, throw a `TypeError`.
|
||||
|
||||
### `mainOffset`
|
||||
**If the instance refers to a `JSScript`**, the offset of the main
|
||||
**If the instance refers to a `JSScript`**, the 0-origin offset of the main
|
||||
entry point of the script, excluding any prologue.
|
||||
|
||||
**If the instance refers to WebAssembly code**, throw a `TypeError`.
|
||||
@@ -267,9 +266,9 @@ children can be reached by walking the tree.
|
||||
### `getPossibleBreakpoints(query)`
|
||||
Query for the recommended breakpoint locations available in SpiderMonkey.
|
||||
Returns a result array of objects with the following properties:
|
||||
* `offset: number` - The offset the breakpoint.
|
||||
* `lineNumber: number` - The line number of the breakpoint.
|
||||
* `columnNumber: number` - The column number of the breakpoint.
|
||||
* `offset: number` - The 0-origin offset the breakpoint.
|
||||
* `lineNumber: number` - The 1-origin line number of the breakpoint.
|
||||
* `columnNumber: number` - The 1-origin column number of the breakpoint.
|
||||
* `isStepStart: boolean` - True if SpiderMonkey recommends that the
|
||||
breakpoint be treated as a step location when users of debuggers
|
||||
step to the next item. This _roughly_ translates to the start of
|
||||
@@ -278,13 +277,13 @@ Returns a result array of objects with the following properties:
|
||||
The `query` argument can be used to filter the set of breakpoints.
|
||||
The `query` object can contain the following properties:
|
||||
|
||||
* `minOffset: number` - The inclusive lower bound of `offset` values to include.
|
||||
* `maxOffset: number` - The exclusive upper bound of `offset` values to include.
|
||||
* `line: number` - Limit to breakpoints on the given line.
|
||||
* `minLine: number` - The inclusive lower bound of lines to include.
|
||||
* `minColumn: number` - The inclusive lower bound of the line/minLine column to include.
|
||||
* `maxLine: number` - The exclusive upper bound of lines to include.
|
||||
* `maxColumn: number` - The exclusive upper bound of the line/maxLine column to include.
|
||||
* `minOffset: number` - The inclusive lower bound of `offset` values to include (0-origin).
|
||||
* `maxOffset: number` - The exclusive upper bound of `offset` values to include (0-origin).
|
||||
* `line: number` - Limit to breakpoints on the given line (1-origin).
|
||||
* `minLine: number` - The inclusive lower bound of lines to include (1-origin).
|
||||
* `minColumn: number` - The inclusive lower bound of the line/minLine column to include (1-origin).
|
||||
* `maxLine: number` - The exclusive upper bound of lines to include (1-origin).
|
||||
* `maxColumn: number` - The exclusive upper bound of the line/maxLine column to include (1-origin).
|
||||
|
||||
### `getPossibleBreakpointOffsets(query)`
|
||||
Query for the recommended breakpoint locations available in SpiderMonkey.
|
||||
@@ -292,10 +291,10 @@ Identical to getPossibleBreakpoints except this returns an array of `offset`
|
||||
values instead of offset metadata objects.
|
||||
|
||||
### `getOffsetMetadata(offset)`
|
||||
Get metadata about a given bytecode offset.
|
||||
Get metadata about a given bytecode offset (0-origin).
|
||||
Returns an object with the following properties:
|
||||
* `lineNumber: number` - The line number of the breakpoint.
|
||||
* `columnNumber: number` - The column number of the breakpoint.
|
||||
* `lineNumber: number` - The 1-origin line number of the breakpoint.
|
||||
* `columnNumber: number` - The 1-origin column number of the breakpoint.
|
||||
* `isBreakpoint: boolean` - True if this offset qualifies as a breakpoint,
|
||||
defined using the same semantics used for `getPossibleBreakpoints()`.
|
||||
* `isStepStart: boolean` - True if SpiderMonkey recommends that the
|
||||
@@ -305,8 +304,8 @@ Returns an object with the following properties:
|
||||
|
||||
### `setBreakpoint(offset, handler)`
|
||||
**If the instance refers to a `JSScript`**, set a breakpoint at the
|
||||
bytecode instruction at <i>offset</i> in this script, reporting hits to
|
||||
the `hit` method of <i>handler</i>. If <i>offset</i> is not a valid offset
|
||||
bytecode instruction at <i>offset</i> (0-origin) in this script, reporting hits
|
||||
to the `hit` method of <i>handler</i>. If <i>offset</i> is not a valid offset
|
||||
in this script, throw an error. Also, even if <i>offset</i> is valid offset
|
||||
in this script, some instructions for engine-internal operation (e.g.
|
||||
SetAliasedVar in the generator function initialization) don't allow setting
|
||||
@@ -337,7 +336,7 @@ global's scripts.
|
||||
|
||||
### `getBreakpoints([offset])`
|
||||
**If the instance refers to a `JSScript`**, return an array containing the
|
||||
handler objects for all the breakpoints set at <i>offset</i> in this
|
||||
handler objects for all the breakpoints set at <i>offset</i> (0-origin) in this
|
||||
script. If <i>offset</i> is omitted, return the handlers of all
|
||||
breakpoints set anywhere in this script. If <i>offset</i> is present, but
|
||||
not a valid offset in this script, throw an error.
|
||||
@@ -347,24 +346,24 @@ not a valid offset in this script, throw an error.
|
||||
### `clearBreakpoint(handler, [offset])`
|
||||
**If the instance refers to a `JSScript`**, remove all breakpoints set in
|
||||
this [`Debugger`][debugger-object] instance that use <i>handler</i> as
|
||||
their handler. If <i>offset</i> is given, remove only those breakpoints
|
||||
set at <i>offset</i> that use <i>handler</i>; if <i>offset</i> is not a
|
||||
valid offset in this script, throw an error.
|
||||
their handler. If <i>offset</i> (0-origin) is given, remove only those
|
||||
breakpoints set at <i>offset</i> that use <i>handler</i>; if <i>offset</i> is
|
||||
not a valid offset in this script, throw an error.
|
||||
|
||||
Note that, if breakpoints using other handler objects are set at the
|
||||
same location(s) as <i>handler</i>, they remain in place.
|
||||
|
||||
### `clearAllBreakpoints([offset])`
|
||||
**If the instance refers to a `JSScript`**, remove all breakpoints set in
|
||||
this script. If <i>offset</i> is present, remove all breakpoints set at
|
||||
that offset in this script; if <i>offset</i> is not a valid bytecode
|
||||
this script. If <i>offset</i> (0-origin) is present, remove all breakpoints set
|
||||
at that offset in this script; if <i>offset</i> is not a valid bytecode
|
||||
offset in this script, throw an error.
|
||||
|
||||
### `getEffectfulOffsets()`
|
||||
**If the instance refers to a `JSScript`**, return an array
|
||||
containing the offsets of all bytecodes in the script which can have direct
|
||||
side effects that are visible outside the currently executing frame. This
|
||||
includes, for example, operations that set properties or elements on
|
||||
containing the 0-origin offsets of all bytecodes in the script which can have
|
||||
direct side effects that are visible outside the currently executing frame.
|
||||
This includes, for example, operations that set properties or elements on
|
||||
objects, or that may set names in environments created outside the frame.
|
||||
|
||||
This doesn't include some instructions for engine-internal operation (e.g.
|
||||
@@ -378,11 +377,11 @@ contains information about the coverage of all opcodes. The elements of
|
||||
the array are objects, each of which describes a single opcode, and
|
||||
contains the following properties:
|
||||
|
||||
* `lineNumber`: the line number of the current opcode.
|
||||
* `lineNumber`: the 1-origin line number of the current opcode.
|
||||
|
||||
* `columnNumber`: the column number of the current opcode.
|
||||
* `columnNumber`: the 1-origin column number of the current opcode.
|
||||
|
||||
* `offset`: the bytecode instruction offset of the current opcode.
|
||||
* `offset`: the 0-origin bytecode instruction offset of the current opcode.
|
||||
|
||||
* `count`: the number of times the current opcode got executed.
|
||||
|
||||
@@ -393,8 +392,8 @@ the flag `Debugger.collectCoverageInfo` should be set to `true`.
|
||||
**If the instance refers to WebAssembly code**, throw a `TypeError`.
|
||||
|
||||
### `isInCatchScope([offset])`
|
||||
**If the instance refers to a `JSScript`**, this is `true` if this offset
|
||||
falls within the scope of a try block, and `false` otherwise.
|
||||
**If the instance refers to a `JSScript`**, this is `true` if this 0-origin
|
||||
offset falls within the scope of a try block, and `false` otherwise.
|
||||
|
||||
**If the instance refers to WebAssembly code**, throw a `TypeError`.
|
||||
|
||||
@@ -407,7 +406,7 @@ in their results.
|
||||
|
||||
#### `getAllOffsets()`
|
||||
**If the instance refers to a `JSScript`**, return an array <i>L</i>
|
||||
describing the relationship between bytecode instruction offsets and
|
||||
describing the relationship between bytecode instruction offsets (0-origin) and
|
||||
source code positions in this script. <i>L</i> is sparse, and indexed by
|
||||
source line number. If a source line number <i>line</i> has no code, then
|
||||
<i>L</i> has no <i>line</i> property. If there is code for <i>line</i>,
|
||||
@@ -426,20 +425,20 @@ for (i=1; i < 10; i++)
|
||||
Calling `getAllOffsets()` on that code might yield an array like this:
|
||||
|
||||
```js
|
||||
[[0], [5, 20], , [10]]
|
||||
[, [0], [16, 75], , [52]]
|
||||
```
|
||||
|
||||
This array indicates that:
|
||||
|
||||
* the first line's code starts at offset 0 in the script;
|
||||
|
||||
* the `for` statement head has two entry points at offsets 5 and 20 (for
|
||||
* the `for` statement head has two entry points at offsets 16 and 75 (for
|
||||
the initialization, which is performed only once, and the loop test,
|
||||
which is performed at the start of each iteration);
|
||||
|
||||
* the third line has no code;
|
||||
|
||||
* and the fourth line begins at offset 10.
|
||||
* and the fourth line begins at offset 52.
|
||||
|
||||
**If the instance refers to WebAssembly code**, throw a `TypeError`.
|
||||
|
||||
@@ -453,11 +452,11 @@ all offsets that are entry points for each (line, column) pair.
|
||||
The elements of the array are objects, each of which describes a single
|
||||
entry point, and contains the following properties:
|
||||
|
||||
* lineNumber: the line number for which offset is an entry point
|
||||
* lineNumber: the 1-origin line number for which offset is an entry point
|
||||
|
||||
* columnNumber: the column number for which offset is an entry point
|
||||
* columnNumber: the 1-origin column number for which offset is an entry point
|
||||
|
||||
* offset: the bytecode instruction offset of the entry point
|
||||
* offset: the 0-origin bytecode instruction offset of the entry point
|
||||
|
||||
For example, suppose we have a script for the following source code:
|
||||
|
||||
@@ -471,10 +470,12 @@ for (i=1; i < 10; i++)
|
||||
Calling `getAllColumnOffsets()` on that code might yield an array like this:
|
||||
|
||||
```js
|
||||
[{ lineNumber: 0, columnNumber: 0, offset: 0 },
|
||||
{ lineNumber: 1, columnNumber: 5, offset: 5 },
|
||||
{ lineNumber: 1, columnNumber: 10, offset: 20 },
|
||||
{ lineNumber: 3, columnNumber: 4, offset: 10 }]
|
||||
[{ lineNumber: 1, columnNumber: 1, offset: 0 },
|
||||
{ lineNumber: 2, columnNumber: 6, offset: 16 },
|
||||
{ lineNumber: 2, columnNumber: 11, offset: 28 },
|
||||
{ lineNumber: 4, columnNumber: 5, offset: 52 },
|
||||
{ lineNumber: 4, columnNumber: 14, offset: 67 },
|
||||
{ lineNumber: 2, columnNumber: 19, offset: 75 }]
|
||||
```
|
||||
|
||||
**If the instance refers to WebAssembly code**, throw a `TypeError`.
|
||||
@@ -482,17 +483,17 @@ Calling `getAllColumnOffsets()` on that code might yield an array like this:
|
||||
#### `getLineOffsets(line)`
|
||||
**If the instance refers to a `JSScript`**, return an array of bytecode
|
||||
instruction offsets representing the entry points to source line
|
||||
<i>line</i>. If the script contains no executable code at that line, the
|
||||
array returned is empty.
|
||||
<i>line</i> (1-origin). If the script contains no executable code at that line,
|
||||
the array returned is empty.
|
||||
|
||||
#### `getOffsetLocation(offset)`
|
||||
**If the instance refers to a `JSScript`**, return an object describing the
|
||||
source code location responsible for the bytecode at <i>offset</i> in this
|
||||
script. The object has the following properties:
|
||||
|
||||
* `lineNumber`: the line number for which offset is an entry point
|
||||
* `lineNumber`: the 1-origin line number for which offset is an entry point
|
||||
|
||||
* `columnNumber`: the column number for which offset is an entry point
|
||||
* `columnNumber`: the 1-origin column number for which offset is an entry point
|
||||
|
||||
* `isEntryPoint`: true if the offset is a column entry point, as
|
||||
would be reported by getAllColumnOffsets(); otherwise false.
|
||||
|
||||
@@ -111,9 +111,9 @@ source within the file or URL it was loaded from. This is normally `1`, but
|
||||
may have another value if the source is part of an HTML document.
|
||||
|
||||
### `startColumn`
|
||||
**If the instance refers to JavaScript source**, the 0-origin start column in
|
||||
**If the instance refers to JavaScript source**, the 1-origin start column in
|
||||
UTF-16 code units of the source within the file or URL it was loaded from. This
|
||||
is normally `0`, but may have another value if the source is part of an HTML
|
||||
is normally `1`, but may have another value if the source is part of an HTML
|
||||
document.
|
||||
|
||||
### `id`
|
||||
|
||||
@@ -398,12 +398,6 @@ instances for all debuggee scripts.
|
||||
The script must at least partially cover the given source line. If this
|
||||
property is present, the `url` property must be present as well.
|
||||
|
||||
* `column`
|
||||
|
||||
The script must include given column on the line given by the `line`property.
|
||||
If this property is present, the `url` and `line` properties must both be
|
||||
present as well.
|
||||
|
||||
* `innermost`
|
||||
|
||||
If this property is present and true, the script must be the innermost
|
||||
|
||||
@@ -41,7 +41,7 @@ function assertOffsetColumns(code, expectedBpts, expectedOrdering = null) {
|
||||
const { script } = debuggeeFn;
|
||||
for (const offset of script.getAllColumnOffsets()) {
|
||||
assertEq(offset.lineNumber, 1);
|
||||
assertEq(offset.columnNumber < execCode.length, true);
|
||||
assertEq(offset.columnNumber <= execCode.length, true);
|
||||
bpts.add(offset.columnNumber);
|
||||
|
||||
script.setBreakpoint(offset.offset, {
|
||||
@@ -53,7 +53,7 @@ function assertOffsetColumns(code, expectedBpts, expectedOrdering = null) {
|
||||
global.f(3);
|
||||
|
||||
const actualBpts = Array.from(execCode, (_, i) => {
|
||||
return bpts.has(i) ? "^" : " ";
|
||||
return bpts.has(i + 1) ? "^" : " ";
|
||||
}).join("");
|
||||
|
||||
if (actualBpts.trimEnd() !== expectedBpts.trimEnd()) {
|
||||
|
||||
@@ -55,7 +55,7 @@ for (text of source.split("\n")) {
|
||||
|
||||
// Check lineno/column.
|
||||
assertEq(getStartLine(className), lineno);
|
||||
assertEq(getStartColumn(className), column);
|
||||
assertEq(getStartColumn(className), column + 1);
|
||||
|
||||
// Check sourceStart/sourceEnd.
|
||||
offset = source.indexOf("class " + className)
|
||||
|
||||
@@ -55,4 +55,4 @@ C();
|
||||
D();
|
||||
new E();
|
||||
`);
|
||||
assertEq(g.log.join(","), "A,pop(8:0),B,pop(14:0),C,pop(20:0),D,pop(26:0),E,pop(27:16),pop(34:4)");
|
||||
assertEq(g.log.join(","), "A,pop(8:1),B,pop(14:1),C,pop(20:1),D,pop(26:1),E,pop(27:17),pop(34:5)");
|
||||
|
||||
@@ -8,13 +8,13 @@ let source = gdbg.createSource({
|
||||
text: "x = 3",
|
||||
url: "foo.js",
|
||||
startLine: 3,
|
||||
startColumn: 42,
|
||||
startColumn: 43,
|
||||
sourceMapURL: "sourceMapURL",
|
||||
isScriptElement: true,
|
||||
});
|
||||
assertEq(source.text, "x = 3");
|
||||
assertEq(source.url, "foo.js");
|
||||
assertEq(source.startLine, 3);
|
||||
assertEq(source.startColumn, 42);
|
||||
assertEq(source.startColumn, 43);
|
||||
assertEq(source.sourceMapURL, "sourceMapURL");
|
||||
assertEq(source.introductionType, "inlineScript");
|
||||
|
||||
@@ -29,31 +29,31 @@ function onDebuggerStatement(frame) {
|
||||
assertBPCount({ line: 9 }, 1);
|
||||
assertBPCount({ line: 10 }, 1);
|
||||
|
||||
assertBPCount({ line: 6, minColumn: 7 }, 3);
|
||||
assertBPCount({ line: 6, maxColumn: 16 }, 3);
|
||||
assertBPCount({ line: 6, minColumn: 7, maxColumn: 16 }, 2);
|
||||
assertBPCount({ line: 6, minColumn: 8 }, 3);
|
||||
assertBPCount({ line: 6, maxColumn: 17 }, 3);
|
||||
assertBPCount({ line: 6, minColumn: 8, maxColumn: 17 }, 2);
|
||||
assertBPError({ line: 1, minLine: 1 }, "line", "not allowed alongside 'minLine'/'maxLine'");
|
||||
assertBPError({ line: 1, maxLine: 1 }, "line", "not allowed alongside 'minLine'/'maxLine'");
|
||||
assertBPError({ line: "1" }, "line", "not an integer");
|
||||
|
||||
assertBPCount({ minLine: 9 }, 2);
|
||||
assertBPCount({ minLine: 9, minColumn: 0 }, 2);
|
||||
assertBPCount({ minLine: 9, minColumn: 8 }, 1);
|
||||
assertBPCount({ minLine: 9, minColumn: 1 }, 2);
|
||||
assertBPCount({ minLine: 9, minColumn: 9 }, 1);
|
||||
assertBPError({ minLine: "1" }, "minLine", "not an integer");
|
||||
assertBPError({ minColumn: 1 }, "minColumn", "not allowed without 'line' or 'minLine'");
|
||||
assertBPError({ minLine: 1, minColumn: "1" }, "minColumn", "not an integer");
|
||||
assertBPError({ minColumn: 2 }, "minColumn", "not allowed without 'line' or 'minLine'");
|
||||
assertBPError({ minLine: 1, minColumn: "2" }, "minColumn", "not an integer");
|
||||
|
||||
assertBPCount({ maxLine: 7 }, 5);
|
||||
assertBPCount({ maxLine: 7, maxColumn: 0 }, 5);
|
||||
assertBPCount({ maxLine: 7, maxColumn: 8 }, 6);
|
||||
assertBPCount({ maxLine: 7, maxColumn: 1 }, 5);
|
||||
assertBPCount({ maxLine: 7, maxColumn: 9 }, 6);
|
||||
assertBPError({ maxLine: "1" }, "maxLine", "not an integer");
|
||||
assertBPError({ maxColumn: 1 }, "maxColumn", "not allowed without 'line' or 'maxLine'");
|
||||
assertBPError({ maxLine: 1, maxColumn: "1" }, "maxColumn", "not an integer");
|
||||
assertBPError({ maxColumn: 2 }, "maxColumn", "not allowed without 'line' or 'maxLine'");
|
||||
assertBPError({ maxLine: 1, maxColumn: "2" }, "maxColumn", "not an integer");
|
||||
|
||||
assertBPCount({ minLine: 6, maxLine: 8 }, 6);
|
||||
assertBPCount({ minLine: 6, minColumn: 8, maxLine: 8 }, 5);
|
||||
assertBPCount({ minLine: 6, maxLine: 8, maxColumn: 8 }, 7);
|
||||
assertBPCount({ minLine: 6, minColumn: 8, maxLine: 8, maxColumn: 8 }, 6);
|
||||
assertBPCount({ minLine: 6, minColumn: 9, maxLine: 8 }, 5);
|
||||
assertBPCount({ minLine: 6, maxLine: 8, maxColumn: 9 }, 7);
|
||||
assertBPCount({ minLine: 6, minColumn: 9, maxLine: 8, maxColumn: 9 }, 6);
|
||||
|
||||
assertBPCount({
|
||||
minOffset: fScript.getPossibleBreakpoints({ line: 6 })[3].offset,
|
||||
|
||||
@@ -379,6 +379,6 @@ function createOffsetLookup(code) {
|
||||
if (!lineOffsets.hasOwnProperty(line)) {
|
||||
throw new Error("Unknown line " + line + " column " + column);
|
||||
}
|
||||
return lineOffsets[line] + column;
|
||||
return lineOffsets[line] + column - 1;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -13,33 +13,33 @@ function test(f, expected) {
|
||||
g.eval(`
|
||||
function f1() { }
|
||||
`);
|
||||
test(g.f1, 11);
|
||||
test(g.f1, 12);
|
||||
|
||||
g.eval(`
|
||||
var f2 = function({ a, b, c }, d, e, ...more) { };
|
||||
`);
|
||||
test(g.f2, 17);
|
||||
test(g.f2, 18);
|
||||
|
||||
g.eval(`
|
||||
var f3 = function *() { };
|
||||
`);
|
||||
test(g.f3, 19);
|
||||
test(g.f3, 20);
|
||||
|
||||
g.eval(`
|
||||
var f4 = async function
|
||||
() { };
|
||||
`);
|
||||
test(g.f4, 2);
|
||||
test(g.f4, 3);
|
||||
|
||||
g.eval(`
|
||||
var f5 = (a, b) => a + b;
|
||||
`);
|
||||
test(g.f5, 9);
|
||||
test(g.f5, 10);
|
||||
|
||||
g.eval(`
|
||||
var f6 = a => a + 1;
|
||||
`);
|
||||
test(g.f6, 9);
|
||||
test(g.f6, 10);
|
||||
|
||||
g.eval(`
|
||||
var MyClass = class {
|
||||
@@ -47,8 +47,8 @@ var MyClass = class {
|
||||
};
|
||||
var myInstance = new MyClass();
|
||||
`);
|
||||
test(g.myInstance.method, 10);
|
||||
test(g.myInstance.constructor, 14);
|
||||
test(g.myInstance.method, 11);
|
||||
test(g.myInstance.constructor, 15);
|
||||
|
||||
const g2 = newGlobal({newCompartment: true, useWindowProxy: true});
|
||||
const dbg2 = Debugger(g2);
|
||||
@@ -60,20 +60,20 @@ function f7() { }
|
||||
});
|
||||
const f7w = g2Wrapped.makeDebuggeeValue(g2.f7);
|
||||
assertEq(f7w.callable, true);
|
||||
assertEq(f7w.script.startColumn, 11);
|
||||
assertEq(f7w.script.startColumn, 12);
|
||||
|
||||
g.eval(`
|
||||
function f8() {
|
||||
return function f8Inner() { }
|
||||
}
|
||||
`);
|
||||
test(g.f8, 11);
|
||||
test(g.f8(), 27);
|
||||
test(g.f8, 12);
|
||||
test(g.f8(), 28);
|
||||
|
||||
g.eval(`
|
||||
var f9 = new Function(\"\");
|
||||
`);
|
||||
test(g.f9, 0);
|
||||
test(g.f9, 1);
|
||||
|
||||
let hit = 0;
|
||||
let column;
|
||||
@@ -83,19 +83,19 @@ dbg.onDebuggerStatement = function (frame) {
|
||||
};
|
||||
|
||||
g.eval(` debugger;`);
|
||||
assertEq(column, 0);
|
||||
assertEq(column, 1);
|
||||
assertEq(hit, 1);
|
||||
|
||||
const location = { fileName: "column.js", lineNumber: 1, columnNumber: 1 };
|
||||
hit = 0;
|
||||
g.evaluate(` debugger;`, location);
|
||||
assertEq(column, 1);
|
||||
assertEq(column, 2);
|
||||
assertEq(hit, 1);
|
||||
|
||||
g.evaluate(`var f10 = function () { };`, location);
|
||||
test(g.f10, 20);
|
||||
test(g.f10, 21);
|
||||
|
||||
g.evaluate(`
|
||||
var f11 = function () { };
|
||||
`, location);
|
||||
test(g.f11, 19);
|
||||
test(g.f11, 20);
|
||||
|
||||
@@ -23,7 +23,12 @@ function g() {
|
||||
}
|
||||
|
||||
f();
|
||||
`, { fileName: "foobar.js", lineNumber: 3, columnNumber: 42 });
|
||||
`, {
|
||||
fileName: "foobar.js",
|
||||
lineNumber: 3,
|
||||
// NOTE: evaluate function takes 0-origin column number.
|
||||
columnNumber: 42,
|
||||
});
|
||||
|
||||
let onNewScriptCalls = 0;
|
||||
dbg.onNewScript = script => { onNewScriptCalls++; };
|
||||
@@ -34,7 +39,8 @@ assertEq(onNewScriptCalls, 0);
|
||||
|
||||
assertEq(reparsedScript.url, "foobar.js");
|
||||
assertEq(reparsedScript.startLine, 3);
|
||||
assertEq(reparsedScript.startColumn, 42);
|
||||
// NOTE: Debugger uses 1-origin column number.
|
||||
assertEq(reparsedScript.startColumn, 43);
|
||||
|
||||
// Test for the same breakpoint positions in the original and reparsed script.
|
||||
function getBreakpointPositions(script) {
|
||||
|
||||
@@ -6,8 +6,9 @@ var gw = dbg.addDebuggee(g);
|
||||
g.evaluate("function f(x) {}");
|
||||
var fw = gw.getOwnPropertyDescriptor("f").value;
|
||||
assertEq(fw.script.source.startLine, 1);
|
||||
assertEq(fw.script.source.startColumn, 0);
|
||||
assertEq(fw.script.source.startColumn, 1);
|
||||
// NOTE: evaluate function takes 0-origin column number.
|
||||
g.evaluate("function g(x) {}", { lineNumber: 10, columnNumber: 5 });
|
||||
var gw = gw.getOwnPropertyDescriptor("g").value;
|
||||
assertEq(gw.script.source.startLine, 10);
|
||||
assertEq(gw.script.source.startColumn, 5);
|
||||
assertEq(gw.script.source.startColumn, 6);
|
||||
|
||||
@@ -18,7 +18,7 @@ dbg.onExceptionUnwind = function (frame, exc) {
|
||||
assertEq(frame.older.type, "call");
|
||||
const { lineNumber, columnNumber } = frame.script.getOffsetMetadata(frame.offset);
|
||||
assertEq(lineNumber, 3);
|
||||
assertEq(columnNumber, 4);
|
||||
assertEq(columnNumber, 5);
|
||||
|
||||
const isInCatchScope = frame.script.isInCatchScope(frame.offset);
|
||||
assertEq(isInCatchScope, false);
|
||||
@@ -31,7 +31,7 @@ dbg.onExceptionUnwind = function (frame, exc) {
|
||||
assertEq(older.type, "call");
|
||||
const { lineNumber, columnNumber } = older.script.getOffsetMetadata(older.offset);
|
||||
assertEq(lineNumber, 7);
|
||||
assertEq(columnNumber, 4);
|
||||
assertEq(columnNumber, 5);
|
||||
|
||||
const isInCatchScope = older.script.isInCatchScope(older.offset);
|
||||
assertEq(isInCatchScope, false);
|
||||
|
||||
@@ -18,7 +18,7 @@ dbg.onExceptionUnwind = function (frame, exc) {
|
||||
assertEq(frame.older.type, "call");
|
||||
const { lineNumber, columnNumber } = frame.script.getOffsetMetadata(frame.offset);
|
||||
assertEq(lineNumber, 3);
|
||||
assertEq(columnNumber, 4);
|
||||
assertEq(columnNumber, 5);
|
||||
|
||||
const isInCatchScope = frame.script.isInCatchScope(frame.offset);
|
||||
assertEq(isInCatchScope, false);
|
||||
@@ -31,7 +31,7 @@ dbg.onExceptionUnwind = function (frame, exc) {
|
||||
assertEq(older.type, "call");
|
||||
const { lineNumber, columnNumber } = older.script.getOffsetMetadata(older.offset);
|
||||
assertEq(lineNumber, 8);
|
||||
assertEq(columnNumber, 6);
|
||||
assertEq(columnNumber, 7);
|
||||
|
||||
const isInCatchScope = older.script.isInCatchScope(older.offset);
|
||||
assertEq(isInCatchScope, true);
|
||||
|
||||
@@ -18,7 +18,7 @@ dbg.onExceptionUnwind = function (frame, exc) {
|
||||
assertEq(frame.older.type, "call");
|
||||
const { lineNumber, columnNumber } = frame.script.getOffsetMetadata(frame.offset);
|
||||
assertEq(lineNumber, 3);
|
||||
assertEq(columnNumber, 4);
|
||||
assertEq(columnNumber, 5);
|
||||
|
||||
const isInCatchScope = frame.script.isInCatchScope(frame.offset);
|
||||
assertEq(isInCatchScope, false);
|
||||
@@ -31,7 +31,7 @@ dbg.onExceptionUnwind = function (frame, exc) {
|
||||
assertEq(older.type, "call");
|
||||
const { lineNumber, columnNumber } = older.script.getOffsetMetadata(older.offset);
|
||||
assertEq(lineNumber, 8);
|
||||
assertEq(columnNumber, 6);
|
||||
assertEq(columnNumber, 7);
|
||||
|
||||
const isInCatchScope = older.script.isInCatchScope(older.offset);
|
||||
assertEq(isInCatchScope, true);
|
||||
|
||||
@@ -45,8 +45,8 @@ for (var i = 0; i < NumInitializers; ++i) {
|
||||
|
||||
// Check the initializer lambda has expected line/column
|
||||
assertEq(script.startLine, START + 1 + i);
|
||||
assertEq(script.startColumn, 20);
|
||||
assertEq(script.startColumn, 21);
|
||||
|
||||
// Check that source length matches expectations.
|
||||
assertEq(script.startColumn + script.sourceLength + ';'.length, lineText.length);
|
||||
assertEq(script.startColumn + script.sourceLength + ';'.length, lineText.length + 1);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ function getScriptSourceExtent(source) {
|
||||
// to test multi-line sources, this will need to be updated.
|
||||
for (let script of scripts) {
|
||||
assertEq(script.startLine, 1);
|
||||
assertEq(script.startColumn, script.sourceStart);
|
||||
assertEq(script.startColumn, script.sourceStart + 1);
|
||||
}
|
||||
|
||||
// Map each found script to a source extent string.
|
||||
@@ -334,4 +334,4 @@ testSourceExtent(` class C { static set #prop(v) { } }`,
|
||||
// Static Class Blocks
|
||||
testSourceExtent(` class C { static { 10; } }`,
|
||||
` ^-------------^ `,
|
||||
` ^-------------------------`);
|
||||
` ^-------------------------`);
|
||||
|
||||
@@ -51,7 +51,8 @@ CoverageCollector.prototype._getLinesCovered = function () {
|
||||
this._allCoverage[scriptName] = {};
|
||||
}
|
||||
|
||||
let key = [lineNumber, columnNumber, offset].join("#");
|
||||
// NOTE: columnNumber is 1-origin.
|
||||
let key = [lineNumber, columnNumber - 1, offset].join("#");
|
||||
if (!currentCoverage[scriptName][key]) {
|
||||
currentCoverage[scriptName][key] = count;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user