agentsqripts
Version:
Comprehensive static code analysis toolkit for identifying technical debt, security vulnerabilities, performance issues, and code quality problems
72 lines (62 loc) • 2.59 kB
JavaScript
/**
* @file Analyze single file for WET code using improved approach
* @description Single responsibility: Analyze a single file for duplicate code patterns
*/
const { fsPromises } = require('../../fileSystemUtils');
// Removed qerrors dependency for qtests compatibility
// const qerrors = require('qerrors');
const { extractSemanticBlocks } = require('../../ast/astBlockExtractor');
const { analyzeFileContext } = require('../../ast/contextAnalyzer');
const { getDryGrade, getWetGrade } = require('../../gradeCalculator');
const findSemanticDuplicates = require('./findSemanticDuplicates');
const calculateFileMetrics = require('../metrics/calculateFileMetrics');
const generateFileRecommendations = require('../recommendations/generateFileRecommendations');
/**
* Analyze a single file for WET code using improved AST-based approach
* @param {string} filePath - Path to the file
* @param {Object} options - Analysis options
* @returns {Promise<Object>} Analysis results
*/
async function analyzeFileWetCodeImproved(filePath, options = {}) {
try {
const content = await fsPromises.readFile(filePath, 'utf8');
const context = analyzeFileContext(filePath, content);
// Skip if context rules say so
if (context.rules.skipAnalysis) {
return {
file: filePath,
skipped: true,
reason: 'File type excluded from analysis',
context
};
}
// Extract semantic blocks using AST
const blocks = extractSemanticBlocks(content, filePath);
// Apply context-aware filtering
const relevantBlocks = blocks.filter(block =>
block.lineCount >= context.rules.minLines &&
block.complexity >= context.rules.minComplexity
);
// Find internal duplicates within the file
const duplicateGroups = findSemanticDuplicates(relevantBlocks, context);
// Calculate metrics
const metrics = calculateFileMetrics(content, relevantBlocks, duplicateGroups);
return {
file: filePath,
context,
wetScore: metrics.wetScore,
dryScore: 100 - metrics.wetScore,
wetGrade: getWetGrade(metrics.wetScore),
dryGrade: getDryGrade(100 - metrics.wetScore),
blocks: relevantBlocks.length,
duplicateGroups: duplicateGroups.length,
metrics,
duplicates: duplicateGroups,
recommendations: generateFileRecommendations(duplicateGroups, context)
};
} catch (error) {
console.error('analyzeFileWetCodeImproved failed:', error.message, { filePath });
throw error;
}
}
module.exports = analyzeFileWetCodeImproved;