const fs = require('fs'); const path = require('path'); const targetDir = path.resolve('e:\\AllWorkProject\\drone_project\\ztzf-drone-web\\applications\\command-center-dashboard\\src\\views\\newRoutePlan'); function getAllFiles(dirPath, arrayOfFiles) { const files = fs.readdirSync(dirPath); arrayOfFiles = arrayOfFiles || []; files.forEach(function(file) { if (fs.statSync(dirPath + "/" + file).isDirectory()) { arrayOfFiles = getAllFiles(dirPath + "/" + file, arrayOfFiles); } else { if (file.endsWith('.vue') || file.endsWith('.js')) { arrayOfFiles.push(path.join(dirPath, "/", file)); } } }); return arrayOfFiles; } function extractFunctions(content, filePath) { const functions = []; // Regex is not perfect, but good enough for finding standard definitions // 1. function name(...) { // 2. const name = (...) => { // 3. const name = function(...) { // We will iterate through the file to find function starts, then balance braces. // Simple tokenizer-like approach let index = 0; const len = content.length; while (index < len) { // Find 'function' or 'const/let/var' const sub = content.substring(index); // Match function definition: function name (...) const funcMatch = sub.match(/^(async\s+)?function\s+([a-zA-Z0-9_$]+)\s*\(/); // Match arrow/expression: (const|let|var) name = ... const varMatch = sub.match(/^(const|let|var)\s+([a-zA-Z0-9_$]+)\s*=\s*/); if (funcMatch) { const name = funcMatch[2]; const startBody = content.indexOf('{', index + funcMatch[0].length); if (startBody !== -1) { const body = extractBody(content, startBody); if (body) { functions.push({ name, body, filePath }); index = startBody + body.length; continue; } } } else if (varMatch) { const name = varMatch[2]; // Check if it's a function assignment const afterVar = index + varMatch[0].length; const subAfter = content.substring(afterVar); // Look for function(...) or (...) => or async ... // This is tricky with regex. // Let's simplified: if we see 'function' or '=>' closely after. // Heuristic: Check next 100 chars for 'function' or '=>' const checkLimit = Math.min(subAfter.length, 200); const checkChunk = subAfter.substring(0, checkLimit); let isFunc = false; let bodyStartSearchIndex = afterVar; if (checkChunk.match(/^\s*(async\s+)?function/)) { isFunc = true; } else if (checkChunk.match(/^\s*(async\s+)?\(.*?\)\s*=>/)) { isFunc = true; } else if (checkChunk.match(/^\s*[a-zA-Z0-9_$]+\s*=>/)) { // single arg arrow isFunc = true; } if (isFunc) { const startBody = content.indexOf('{', afterVar); // Ensure the { is part of the function (not perfect but heuristic) if (startBody !== -1 && startBody - afterVar < 200) { const body = extractBody(content, startBody); if (body) { functions.push({ name, body, filePath }); index = startBody + body.length; continue; } } } } index++; } return functions; } function extractBody(content, startIndex) { let braceCount = 0; let inString = false; let stringChar = ''; let inComment = false; // Simplified, doesn't handle block comments perfectly for (let i = startIndex; i < content.length; i++) { const char = content[i]; if (char === '{') { if (!inString) braceCount++; } else if (char === '}') { if (!inString) { braceCount--; if (braceCount === 0) { return content.substring(startIndex, i + 1); } } } // Handle strings/comments loosely to avoid breaking on braces inside them // This is a basic parser, might fail on edge cases } return null; } const files = getAllFiles(targetDir); const allFunctions = []; files.forEach(file => { const content = fs.readFileSync(file, 'utf8'); const funcs = extractFunctions(content, file); allFunctions.push(...funcs); }); // Find duplicates // Key: name + normalized_body const map = new Map(); allFunctions.forEach(f => { // Normalize body: remove all whitespace const normBody = f.body.replace(/\s/g, ''); const key = f.name + '|||' + normBody; if (!map.has(key)) { map.set(key, []); } map.get(key).push(f.filePath); }); console.log("Checking for duplicates..."); let found = false; map.forEach((paths, key) => { if (paths.length > 1) { // Check if paths are actually different (ignore same file if scanned twice? No, unique files) // Actually user wants "identical name, identical body". // Check if the file paths are distinct const uniquePaths = [...new Set(paths)]; if (uniquePaths.length > 1) { const name = key.split('|||')[0]; if (name && name !== 'setup' && name !== 'data') { // Ignore common Vue boilerplate if any console.log(`\nDuplicate Function: ${name}`); uniquePaths.forEach(p => console.log(` - ${p}`)); found = true; } } } }); if (!found) { console.log("No duplicates found."); }