Add support for the function name property.

This resolves #78.

Merged remote-tracking branch 'janek/js_function_name_1'
This commit is contained in:
wolfbeast
2018-03-20 10:08:54 +01:00
67 changed files with 1085 additions and 222 deletions
+45 -31
View File
@@ -91,44 +91,58 @@ var parsers = [
return jQueryLiveGetListeners(node, false);
},
normalizeHandler: function (handlerDO) {
let paths = [
[".event.proxy/", ".event.proxy/", "*"],
[".proxy/", "*"]
];
function isFunctionInProxy(funcDO) {
// If the anonymous function is inside the |proxy| function and the
// function only has guessed atom, the guessed atom should starts with
// "proxy/".
let displayName = funcDO.displayName;
if (displayName && displayName.startsWith("proxy/")) {
return true;
}
let name = handlerDO.displayName;
// If the anonymous function is inside the |proxy| function and the
// function gets name at compile time by SetFunctionName, its guessed
// atom doesn't contain "proxy/". In that case, check if the caller is
// "proxy" function, as a fallback.
let calleeDO = funcDO.environment.callee;
if (!calleeDO) {
return false;
}
let calleeName = calleeDO.displayName;
return calleeName == "proxy";
}
if (!name) {
function getFirstFunctionVariable(funcDO) {
// The handler function inside the |proxy| function should point the
// unwrapped function via environment variable.
let names = funcDO.environment.names();
for (let varName of names) {
let varDO = handlerDO.environment.getVariable(varName);
if (!varDO) {
continue;
}
if (varDO.class == "Function") {
return varDO;
}
}
return null;
}
if (!isFunctionInProxy(handlerDO)) {
return handlerDO;
}
for (let path of paths) {
if (name.includes(path[0])) {
path.splice(0, 1);
const MAX_NESTED_HANDLER_COUNT = 2;
for (let i = 0; i < MAX_NESTED_HANDLER_COUNT; i++) {
let funcDO = getFirstFunctionVariable(handlerDO);
if (!funcDO)
return handlerDO;
for (let point of path) {
let names = handlerDO.environment.names();
for (let varName of names) {
let temp = handlerDO.environment.getVariable(varName);
if (!temp) {
continue;
}
let displayName = temp.displayName;
if (!displayName) {
continue;
}
if (temp.class === "Function" &&
(displayName.includes(point) || point === "*")) {
handlerDO = temp;
break;
}
}
}
break;
handlerDO = funcDO;
if (isFunctionInProxy(handlerDO)) {
continue;
}
break;
}
return handlerDO;
@@ -52,7 +52,7 @@ function test_inferred_name_function() {
do_check_eq(args[0].class, "Function");
// No name for an anonymous function, but it should have an inferred name.
do_check_eq(args[0].name, undefined);
do_check_eq(args[0].displayName, "o.m");
do_check_eq(args[0].displayName, "m");
let objClient = gThreadClient.pauseGrip(args[0]);
objClient.getParameterNames(function (aResponse) {