Skip to content

Instantly share code, notes, and snippets.

@hunghg255
Last active July 19, 2024 07:45
Show Gist options
  • Save hunghg255/523f00b5eefffe56aedaefa1fc7aa5c9 to your computer and use it in GitHub Desktop.
Save hunghg255/523f00b5eefffe56aedaefa1fc7aa5c9 to your computer and use it in GitHub Desktop.
detect-recursion-functions.js
// npm i @babel/parser @babel/traverse -D
const fs = require('node:fs');
const path = require('node:path');
const traverse = require('@babel/traverse').default;
const parser = require('@babel/parser');
// Change dir folder
const DIR = './src';
// Function to read directory contents
const readdir = fs.promises.readdir;
const resolve = path.resolve;
// Async generator to get all files in a directory recursively
async function* getFiles(dir) {
const dirents = await readdir(dir, { withFileTypes: true });
for (const dirent of dirents) {
const res = resolve(dir, dirent.name);
if (dirent.isDirectory()) {
yield* getFiles(res);
} else {
yield res;
}
}
}
// Function to check if a function is recursive
const isRecursive = (path, functionName) => {
let recursive = false;
traverse(
path.node,
{
CallExpression(innerPath) {
if (innerPath.node.callee.name === functionName) {
recursive = true;
}
},
},
path.scope,
path,
);
return recursive;
};
(async () => {
console.log('=========START DETECT RECURSION FUNCTIONS=========');
for await (const fileName of getFiles(DIR)) {
if (
fileName.endsWith('.js') ||
fileName.endsWith('.jsx') ||
fileName.endsWith('.ts') ||
fileName.endsWith('.tsx')
) {
const code = fs.readFileSync(fileName, 'utf8');
// Parse the code to generate the AST
const ast = parser.parse(code, {
sourceType: 'module',
plugins: ['jsx', 'typescript'],
});
// Traverse the AST to find function declarations
traverse(ast, {
FunctionDeclaration(path) {
const functionName = path.node.id.name;
if (isRecursive(path, functionName)) {
console.log('Checking recursion function:', functionName, '----->', '❌');
console.log('Path:', fileName);
}
},
ArrowFunctionExpression(path) {
const functionName = path.parent.id ? path.parent.id.name : 'Anonymous';
if (isRecursive(path, functionName)) {
console.log('Checking recursion function:', functionName, '----->', '❌');
console.log('Path:', fileName);
}
},
});
}
}
})();
@hunghg255
Copy link
Author

Screenshot 2024-07-19 at 14 42 38

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