phpjs
Version:
80 lines (71 loc) • 3.43 kB
JavaScript
function debug_backtrace(provide_object) {
// http://kevin.vanzonneveld.net
// + original by: Brett Zamir (http://brett-zamir.me)
// % note 1: Mozilla only
// % note 2: Since "function" is a reserved word in JavaScript (even as a property), you must use
// % note 2: the ['function'] notation to get the returned object's arrays' "function" property name
// * example 1: function test () {var b = debug_backtrace();return b[0]['function'];}
// * example 1: test();
// * returns 1: 'test'
var funcName, line, file, fileLine = '', lastColonPos = -1,
className, object, type,
args = Array.prototype.slice.call(arguments),
olderFunc,
i = 0,
backtraceArray = [], olderArgs = arguments,
stackItem = '',
lastAtPos = -1, firstParenthPos = -1;
var getFuncName = function(fn) {
var name = (/\W*function\s+([\w\$]+)\s*\(/).exec(fn);
if (!name) {
return '(Anonymous)';
}
return name[1];
};
// (void 0) is undefined in argument list
try {
throw new Error();
}
catch (e) {
var stackArr = e.stack.replace(/\n$/, '').split('\n').slice(2);
}
// a()@file:///C:/Users/Brett/Desktop/PHP_JS/debug_backtrace.xul:7,@file:///C:/Users/Brett/Desktop/PHP_JS/debug_backtrace.xul:16
for (i = 0; i < stackArr.length; i++) {
stackItem = stackArr[i];
// Will not work if parentheses (or ampersands) are in the file name! (other option would be worse, as arguments couldn't have @ or )
lastAtPos = stackItem.lastIndexOf('@') + 1;
fileLine = stackItem.slice(lastAtPos);
lastColonPos = fileLine.lastIndexOf(':') + 1;
line = fileLine.slice(lastColonPos);
file = fileLine.slice(0, lastColonPos - 1);
//firstParenthPos = stackItem.indexOf('(')-1;
//funcName = stackItem.slice(0, firstParenthPos);
if (stackItem[0] === '@') { // this is global scope (must be i >= 1)
// Fix: can add support for included/required files?
// Fix: arguments returned are mismatched? ignore the last line number/call, since is call to debug_backtrace()?
continue; // delete this when fix
}
else {
olderArgs = olderArgs.callee.caller.arguments;
args = Array.prototype.slice.call(olderArgs);
olderFunc = olderFunc ? olderFunc.caller : arguments.callee.caller;
funcName = getFuncName(olderFunc);
}
className = ''; // Not supported
type = ''; // Special '->' and '::' values not supported for method or static methods
object = ''; // Not supported
if (provide_object) {
throw 'provide_object argument is not supported in debug_backtrace';
}
backtraceArray.push({
'function': funcName, // string; The current function name. See also __FUNCTION__.
'line': line, // integer; The current line number. See also __LINE__.
'file' : file, // string; The current file name. See also __FILE__.
'className' : className, // string; The current class name. See also __CLASS__
'object' : object, // object; The current object.
'type' : type, // string; The current call type. If a method call, "->" is returned. If a static method call, "::" is returned. If a function call, nothing is returned.
'args' : args // array; If inside a function, this lists the functions arguments. If inside an included file, this lists the included file name(s).
});
}
return backtraceArray;
}