Determining Source Line and File of function refer

2019-02-10 18:14发布

问题:

Brief introduction:

I'm attempting to get at line number of function definition for parsing documentation comments on only public stuff. I've gotten to the point where I can find the name of the function and if I so wanted I could execute the function, but I can't seem to figure out any way to pull out line number information. Note: this is purely for documentation purposes so cross-browser isn't necessary.

I know firebug (but not firebug lite so I don't know how possible this is) shows you the line number and script location of a referenced function on mouseover. I looked through the firebug source and got as far as finding they call (domPanel.js:536), but can't seem to find this "addMember" function anywhere in their source:

this.addMember(object, "userFunction", userFuncs, name, val, level, 0, context);

It may be that this just isn't possible to determine. My fallbacks are using [userfunction].name and [userfunction].toSource() and then attempt to match source to source. But I would like to avoid these if possible since the name could be non-unique and the toSource() gives the source post-processing. Maybe there is a way to tie into the firebug api?

Minimal Explanation Code:

[Note the goal would be to get this information: window.MyWindowObject.PublicFunction: script.js line 3]

script.js

(function () {

    function referencedFunction() {
       ///<summary>Sample XML Doc Comment</summary>
       alert('well hello there!');
    }

    var publicObject = window.MyWindowObject || {};
    publicObject.PublicFunction = referencedFunction;

    window.MyWindowObject = publicObject;
}());

index.htm

<!DOCTYPE html>
<html>
  <script src="script.js"></script>
</html>

EDIT: for anyone who finds this on a search later here is some other useful related info that I've found:

Stacktrace.js: https://github.com/eriwen/javascript-stacktrace - Pretty close but not quite what I want since it doesn't seem to get the final function's location. The example on their website is not correct (though the demo "looks" like what I wanted)

In chrome (and IE9): [userfunction].toString() preserves comments (does not in firefox), which is what I will probably end up using. I was going to use firefox's [userfunction].toSource() but this looks like browser-manipulated source of the function. firefox's [userfunction].toString() appears to preserve code, but strips comments

回答1:

Firebug has access to protected Chrome features that ordinary JS does not.

But, JS can still access, the raw <script> source, with comments intact, as long as the same-origin policy does not block access.

For example, this code will get the raw source of all embedded scripts and any scripts loaded from the same domain. :

var scipts = document.querySelectorAll ('script');

for (var J = 0, L = scipts.length;  J < L;  ++J) {
    console.log ('Number: ', J);
    var node    = scipts[J];
    if (!node)  continue;

    if (node.src) {
        //$.get (node.src, function (data) {console.log ('Text: ', data); } );
        try {
            var req = new XMLHttpRequest();
            req.open ('GET', node.src, false);
            req.send (null);
            if (req.status == 200  ||  req.status == 304)
                console.log ('Text: ', req.responseText);
        }
        catch (err) {
            console.log (err);
        }
    }
    else if (node.innerHTML) {
        console.log ('Text: ', node.innerHTML);
    }
}

The raw script can then be parsed for line numbers and function definitions, etc.



回答2:

Here's a potential solution that I haven't tested. A couple years ago, there was a security exploit that allowed JavaScript to redeclare constructors of native objects. John Walker gave this example:

function Array() {
    this[1] = 50;
}
var a = [40];
alert(a[0] + a[1]); // Gives 90

In the same vein, perhaps it's possible to redeclare the function declaration in the browsers where the exploit exists?

function Function() {
    // Should give the stack trace, complete with line number?
    alert(new Error().stack); 
}

window.x = function () {}

I don't have the necessary browsers (John Resig cites Firefox 2, Opera 9, and Safari 3 as browsers where the Array exploit works), so I can't test it, but maybe this is a place to start?