UNPKG

agentsqripts

Version:

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

96 lines (79 loc) 3.08 kB
/** * @file Duplicate grouping logic * @description Responsible for grouping duplicate and similar blocks */ const { calculateSimilarity } = require('./similarityCalculator'); const { calculateEstimatedSavings } = require('./savingsCalculator'); const { WET_CODE_CONFIG, WET_PATTERNS } = require('./wetCodeConfig'); /** * Groups duplicate and similar blocks * @param {Array} allBlocks - All blocks from all files * @returns {Array} Grouped duplicates with metadata */ function groupDuplicateBlocks(allBlocks) { const groups = []; const processed = new Set(); for (let i = 0; i < allBlocks.length; i++) { if (processed.has(i)) continue; const currentBlock = allBlocks[i]; const group = { type: 'exact_duplicate', blocks: [currentBlock], similarity: 1.0, pattern: WET_PATTERNS['exact_duplicate'], hash: currentBlock.hash, complexity: currentBlock.complexity, deduplicationOpportunity: 'HIGH' }; // Find exact duplicates first for (let j = i + 1; j < allBlocks.length; j++) { if (processed.has(j)) continue; const otherBlock = allBlocks[j]; if (currentBlock.hash === otherBlock.hash && currentBlock.content === otherBlock.content) { group.blocks.push(otherBlock); processed.add(j); } } // If no exact duplicates, look for similar blocks if (group.blocks.length === 1) { for (let j = i + 1; j < allBlocks.length; j++) { if (processed.has(j)) continue; const otherBlock = allBlocks[j]; const similarity = calculateSimilarity(currentBlock.content, otherBlock.content); if (similarity >= WET_CODE_CONFIG.minSimilarityThreshold) { if (group.blocks.length === 1) { // Convert to similar logic group group.type = 'similar_logic'; group.pattern = WET_PATTERNS['similar_logic']; group.similarity = similarity; } group.blocks.push(otherBlock); processed.add(j); } } } // Only include groups with multiple blocks or high complexity single blocks if (group.blocks.length > 1 || (group.blocks.length === 1 && currentBlock.complexity >= WET_CODE_CONFIG.minComplexityScore)) { // Determine deduplication opportunity if (group.blocks.length > 1) { const filesInvolved = new Set(group.blocks.map(b => b.file)).size; group.deduplicationOpportunity = filesInvolved > 2 ? 'HIGH' : group.blocks.length > 3 ? 'HIGH' : 'MEDIUM'; group.estimatedSavings = calculateEstimatedSavings(group); } groups.push(group); } processed.add(i); } return groups.sort((a, b) => { // Sort by impact: more blocks and higher complexity first const scoreA = a.blocks.length * a.complexity; const scoreB = b.blocks.length * b.complexity; return scoreB - scoreA; }); } module.exports = { groupDuplicateBlocks };