UNPKG

agentsqripts

Version:

Comprehensive static code analysis toolkit for identifying technical debt, security vulnerabilities, performance issues, and code quality problems

144 lines (127 loc) 5.63 kB
/** * @file Project-wide refactoring opportunity analyzer for comprehensive code organization assessment * @description Single responsibility: Coordinate export promotion analysis across entire projects * * This analyzer orchestrates comprehensive project-wide analysis to identify export promotion * opportunities and refactoring potential across all files. It provides strategic guidance * for improving code reusability, API design, and module organization by analyzing function * usage patterns, utility potential, and cross-file dependencies at scale. * * Design rationale: * - Project-wide analysis identifies systematic refactoring opportunities missed by file-level analysis * - Concurrent processing enables efficient analysis of large codebases without performance issues * - Index file analysis provides insights into existing barrel file patterns and optimization opportunities * - Priority-based recommendations enable focused refactoring efforts on highest-impact changes * - Comprehensive metrics support data-driven architectural decision making * * Analysis scope: * - Function export potential across all project files * - Utility function identification and cross-file usage patterns * - Existing barrel file analysis and optimization opportunities * - Refactoring opportunity prioritization and impact assessment * - API design improvement recommendations based on usage patterns */ const path = require('path'); // Import from atomic modules const { analyzeFileRefactoring } = require('./fileRefactoringAnalyzer'); const { findIndexFiles } = require('./indexFileFinder'); const { analyzeIndexFile } = require('./indexFileAnalyzer'); const { generateRefactoringRecommendations } = require('./refactoringRecommendationGenerator'); const { getAllFiles } = require('./getAllFilesScanner'); /** * Analyze project for refactoring opportunities * @param {string} projectPath - Project directory path * @param {Object} options - Analysis options * @returns {Object} Project analysis results */ async function analyzeProjectRefactoring(projectPath, options = {}) { const { extensions = ['.js', '.ts', '.jsx', '.tsx'], includeNonUtility = false, includeBarrelFiles = true } = options; const startTime = Date.now(); const sourceFiles = await getAllFiles(projectPath, extensions); const results = []; const indexAnalysis = []; // Analyze all source files concurrently const analyses = await Promise.all( sourceFiles.map(file => analyzeFileRefactoring(file, options)) ); // Filter and add results in single pass for (const analysis of analyses) { if (!analysis.error && (includeNonUtility || analysis.isUtility)) { results.push(analysis); } } // Analyze existing index files if (includeBarrelFiles) { const allDirectories = new Set(sourceFiles.map(f => path.dirname(f))); // Process index files in single pass const indexFilePromises = []; for (const dir of allDirectories) { const indexFiles = await findIndexFiles(dir, options); indexFilePromises.push(...indexFiles.map(indexFile => analyzeIndexFile(indexFile))); } const indexAnalyses = await Promise.all(indexFilePromises); // Filter and add valid analyses for (const analysis of indexAnalyses) { if (!analysis.error) { indexAnalysis.push(analysis); } } } // Calculate project summary const totalFiles = results.length; const filesWithOpportunities = results.filter(r => r.metrics.hasRefactoringOpportunities).length; const totalOpportunities = results.reduce((sum, r) => sum + r.metrics.promotionOpportunityCount, 0); const refactoringRate = totalFiles > 0 ? Math.round(((totalFiles - filesWithOpportunities) / totalFiles) * 100) : 100; // Opportunity type breakdown const opportunityBreakdown = { export_promotion: 0, barrel_file_creation: 0 }; // Optimized breakdown calculation with flatMap const opportunityCount = { export_promotion: 0, barrel_file_creation: 0 }; const priorityCount = { HIGH: 0, MEDIUM: 0, LOW: 0 }; // Process opportunities efficiently using index-based iteration for (let i = 0; i < results.length; i++) { const r = results[i]; const opportunities = r.promotionOpportunities; for (let j = 0; j < opportunities.length; j++) { const opp = opportunities[j]; opportunityCount[opp.type] = (opportunityCount[opp.type] || 0) + 1; priorityCount[opp.priority || 'LOW']++; } } Object.assign(opportunityBreakdown, opportunityCount); const priorityBreakdown = priorityCount; // Utility file statistics const utilityFiles = results.filter(r => r.isUtility); const utilityStats = { totalUtilityFiles: utilityFiles.length, totalUnexportedItems: utilityFiles.reduce((sum, r) => sum + r.metrics.unexportedCount, 0), totalExportedItems: utilityFiles.reduce((sum, r) => sum + r.metrics.exportedCount, 0) }; const analysisTime = Date.now() - startTime; return { timestamp: new Date().toISOString(), summary: { totalFiles, filesWithOpportunities, totalOpportunities, refactoringRate, opportunityBreakdown, priorityBreakdown, utilityStats, indexFilesFound: indexAnalysis.length }, files: results.filter(r => r.metrics.hasRefactoringOpportunities), // Only return files with opportunities indexFiles: indexAnalysis, recommendations: generateRefactoringRecommendations(opportunityBreakdown, priorityBreakdown, utilityStats), analysisTime }; } module.exports = { analyzeProjectRefactoring };