Skip to content

Instantly share code, notes, and snippets.

@leolovenet
Last active December 27, 2025 08:05
Show Gist options
  • Select an option

  • Save leolovenet/4ba18f920c606260c3e994675b62c34a to your computer and use it in GitHub Desktop.

Select an option

Save leolovenet/4ba18f920c606260c3e994675b62c34a to your computer and use it in GitHub Desktop.
Babel binding reference test for function declaration and expression scopes
import { parse } from "@babel/parser";
import _traverse from "@babel/traverse";
const traverse = _traverse.default ?? _traverse;
function findNearestLeadingCommentPath(path) {
let cur = path;
while (cur) {
const node = cur.node;
if (node && node.leadingComments && node.leadingComments.length > 0) {
return cur;
}
cur = cur.parentPath;
}
return null;
}
function test(id, path) {
const bd = id.scope.getBinding(id.node.name);
const pbd = id.scope.parent.getBinding(id.node.name);
const comment =
findNearestLeadingCommentPath(path)
?.node.leadingComments?.map((ele) => ele.value)
.join("\n") ?? "";
bd?.referencePaths.forEach((ele) => {
console.log(
`${comment} ${id.node.name} - scope reference:`,
ele.parentPath.toString(),
);
});
pbd?.referencePaths.forEach((ele) => {
console.log(
`${comment} ${id.node.name} - parent scope reference:`,
ele.parentPath.toString(),
);
});
}
const code = `
function test(n) {
//FunctionDeclaration
function a(a) {
return a+a+a+a;
}
//FunctionExpression(without name)
var b = function (b) {
return b+b+b+b;
}
//FunctionExpression(with name)
var c = function c(c) {
return c+c+c+c;
}
return a(n) + a(n+1) + b(n) + b(n+1) + c(n) + c(n+1);
}
`;
const ast = parse(code);
traverse(ast, {
FunctionDeclaration(path) {
const id = path.get("id");
if (!id) return;
test(id, path);
},
FunctionExpression(path) {
const id = path.node.id ? path.get("id") : path.parentPath.get("id");
if (!id) return;
test(id, path);
},
});
@leolovenet
Copy link
Author

"@babel/parser": 7.28.5, output:

FunctionDeclaration a - scope reference: a + a
FunctionDeclaration a - scope reference: a + a
FunctionDeclaration a - scope reference: a + a + a
FunctionDeclaration a - scope reference: a + a + a + a
FunctionDeclaration a - parent scope reference: a(n)
FunctionDeclaration a - parent scope reference: a(n + 1)
FunctionExpression(without name) b - scope reference: b(n)
FunctionExpression(without name) b - scope reference: b(n + 1)
FunctionExpression(with name) c - scope reference: c + c
FunctionExpression(with name) c - scope reference: c + c
FunctionExpression(with name) c - scope reference: c + c + c
FunctionExpression(with name) c - scope reference: c + c + c + c
FunctionExpression(with name) c - parent scope reference: c(n)
FunctionExpression(with name) c - parent scope reference: c(n + 1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment