Bug 1106919 - Add Debugger.Script.prototype.displayName; r=ejpbruel

This commit is contained in:
Nick Fitzgerald 2014-12-10 14:31:12 -08:00
parent d8d2b7ff19
commit aff5dff6d6
3 changed files with 74 additions and 0 deletions

View File

@ -46,6 +46,42 @@ evaluated in the same lexical environment.
A `Debugger.Script` instance inherits the following accessor properties
from its prototype:
`displayName`
: The script's display name, if it has one. If the script has no display name
— for example, if it is a top-level `eval` script — this is
`undefined`.
If the script's function has a given name, its display name is the same as
its function's given name.
If the script's function has no name, SpiderMonkey attempts to infer an
appropriate name for it given its context. For example:
```language-js
function f() {} // display name: f (the given name)
var g = function () {}; // display name: g
o.p = function () {}; // display name: o.p
var q = {
r: function () {} // display name: q.r
};
```
Note that the display name may not be a proper JavaScript identifier,
or even a proper expression: we attempt to find helpful names even when
the function is not immediately assigned as the value of some variable
or property. Thus, we use <code><i>a</i>/<i>b</i></code> to refer to
the <i>b</i> defined within <i>a</i>, and <code><i>a</i>&lt;</code> to
refer to a function that occurs somewhere within an expression that is
assigned to <i>a</i>. For example:
```language-js
function h() {
var i = function() {}; // display name: h/i
f(function () {}); // display name: h/<
}
var s = f(function () {}); // display name: s<
```
`url`
: The filename or URL from which this script's code was loaded. If the
`source` property is non-`null`, then this is equal to `source.url`.

View File

@ -0,0 +1,17 @@
// Debugger.Script.prototype.displayName
var g = newGlobal();
var dbg = Debugger(g);
var name;
dbg.onDebuggerStatement = f => { name = f.callee.script.displayName; };
g.eval("(function f() { debugger; })();");
assertEq(name, "f");
g.eval("(function () { debugger; })();");
assertEq(name, undefined);
g.eval("Function('debugger;')();");
assertEq(name, "anonymous");
g.eval("var f = function() { debugger; }; f()");
assertEq(name, "f");
g.eval("var a = {}; a.f = function() { debugger; }; a.f()");
assertEq(name, "a.f");

View File

@ -3909,6 +3909,26 @@ DebuggerScript_checkThis(JSContext *cx, const CallArgs &args, const char *fnname
return false; \
Rooted<JSScript*> script(cx, GetScriptReferent(obj))
static bool
DebuggerScript_getDisplayName(JSContext *cx, unsigned argc, Value *vp)
{
THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "(get displayName)", args, obj, script);
Debugger *dbg = Debugger::fromChildJSObject(obj);
JSFunction *func = script->functionNonDelazifying();
JSString *name = func ? func->displayAtom() : nullptr;
if (!name) {
args.rval().setUndefined();
return true;
}
RootedValue namev(cx, StringValue(name));
if (!dbg->wrapDebuggeeValue(cx, &namev))
return false;
args.rval().set(namev);
return true;
}
static bool
DebuggerScript_getUrl(JSContext *cx, unsigned argc, Value *vp)
{
@ -4717,6 +4737,7 @@ DebuggerScript_construct(JSContext *cx, unsigned argc, Value *vp)
}
static const JSPropertySpec DebuggerScript_properties[] = {
JS_PSG("displayName", DebuggerScript_getDisplayName, 0),
JS_PSG("url", DebuggerScript_getUrl, 0),
JS_PSG("startLine", DebuggerScript_getStartLine, 0),
JS_PSG("lineCount", DebuggerScript_getLineCount, 0),