(node, c, defun)
| 290 | } |
| 291 | |
| 292 | function handleFunction(node, c, defun) { |
| 293 | // defun names matter - function names (the y in var x = function y() {..}) are just for stack traces. |
| 294 | if (defun) { |
| 295 | ensureData(scopes[scopes.length - 1], node.id.name).def = 1; |
| 296 | } |
| 297 | const scope = {}; |
| 298 | scopes.push(scope); |
| 299 | for (const param of node.params) { |
| 300 | walkPattern(param, c, (name) => { |
| 301 | ensureData(scope, name).def = 1; |
| 302 | scope[name].param = 1; |
| 303 | }); |
| 304 | } |
| 305 | c(node.body); |
| 306 | // we can ignore self-references, i.e., references to ourselves inside |
| 307 | // ourselves, for named defined (defun) functions |
| 308 | const ownName = defun ? node.id.name : ''; |
| 309 | const names = new Set(); |
| 310 | for (const name in scopes.pop()) { |
| 311 | if (name === ownName) continue; |
| 312 | const data = scope[name]; |
| 313 | if (data.use && !data.def) { |
| 314 | // this is used from a higher scope, propagate the use down |
| 315 | ensureData(scopes[scopes.length - 1], name).use = 1; |
| 316 | continue; |
| 317 | } |
| 318 | if (data.def && !data.use && !data.param) { |
| 319 | // this is eliminatable! |
| 320 | names.add(name); |
| 321 | } |
| 322 | } |
| 323 | cleanUp(node.body, names); |
| 324 | } |
| 325 | |
| 326 | recursiveWalk(ast, { |
| 327 | VariableDeclarator(node, c) { |
no test coverage detected