agentsqripts
Version:
Comprehensive static code analysis toolkit for identifying technical debt, security vulnerabilities, performance issues, and code quality problems
122 lines (115 loc) • 4.85 kB
JavaScript
/**
* @file Code smell detection for maintainability analysis
* @description Single responsibility: Identify common code smell patterns that impact maintainability
*
* This module implements pattern-based detection of common code smells - design and implementation
* issues that, while not breaking functionality, indicate potential maintenance problems.
* It focuses on structural issues like parameter complexity, readability problems, and
* magic number usage that can accumulate technical debt over time.
*
* Design rationale:
* - Pattern-based detection enables fast analysis without AST parsing overhead
* - Severity classification helps prioritize refactoring efforts
* - Actionable recommendations provide clear improvement guidance
* - Conservative thresholds minimize false positives while catching real issues
*/
/**
* Comprehensive code smell detection using multi-pattern heuristic analysis
*
* Technical function: Line-by-line pattern matching for common maintainability issues
*
* Implementation rationale:
* - Line-based analysis maintains performance while catching most common smells
* - Regex pattern matching efficiently identifies structural problems
* - Severity classification enables prioritization of refactoring efforts
* - Specific recommendations provide actionable guidance for developers
*
* Code smell categories detected:
* - Long parameter lists: Functions with excessive parameters indicating design issues
* - Line length violations: Readability problems from overly long lines
* - Magic numbers: Unexplained numeric literals that reduce code clarity
* - Future extensions: Dead code, complex conditionals, duplicated logic
*
* Detection algorithm design:
* - Single pass through content for O(n) time complexity
* - Pattern-specific regex for accurate identification
* - Context-aware filtering to reduce false positives
* - Structured output with severity and recommendations
*
* Long parameter list detection:
* - Function signature parsing with parameter counting
* - Threshold of 5+ parameters indicates design complexity
* - Suggests object parameters or function decomposition
* - Catches both traditional and arrow function patterns
*
* Line length analysis:
* - 120-character threshold balances readability and modern screens
* - Raw line length measurement includes indentation and comments
* - Encourages code formatting and logical line breaks
* - Supports team coding standards enforcement
*
* Magic number identification:
* - Multi-digit number pattern matching (2+ digits)
* - Excludes lines with comments explaining numbers
* - Excludes constant declarations to avoid false positives
* - Promotes named constants for better code documentation
*
* Severity level rationale:
* - MEDIUM: Structural issues that impact design quality
* - LOW: Style and readability issues that accumulate over time
* - HIGH: Reserved for critical maintainability threats (future extension)
*
* @param {string} content - JavaScript file content to analyze for code smells
* @returns {Array<Object>} Array of code smell objects with type, severity, location, and recommendations
* @example
* const smells = identifyCodeSmells(`
* function processData(a, b, c, d, e, f) { return a + b + c + d + e + f + 1000; }
* `);
* // Returns: [
* // { type: 'long_parameter_list', severity: 'MEDIUM', line: 1, ... },
* // { type: 'magic_numbers', severity: 'LOW', line: 1, ... }
* // ]
*/
function identifyCodeSmells(content) {
const smells = [];
const lines = content.split('\n');
lines.forEach((line, index) => {
const trimmed = line.trim();
// Long parameter lists
const paramMatch = trimmed.match(/function\s+\w+\s*\(([^)]+)\)/);
if (paramMatch && paramMatch[1].split(',').length > 5) {
smells.push({
type: 'long_parameter_list',
severity: 'MEDIUM',
line: index + 1,
description: 'Function has too many parameters',
recommendation: 'Use object parameters or split function'
});
}
// Long lines
if (line.length > 120) {
smells.push({
type: 'long_line',
severity: 'LOW',
line: index + 1,
description: `Line is ${line.length} characters (threshold: 120)`,
recommendation: 'Break long lines for better readability'
});
}
// Magic numbers
const magicNumbers = trimmed.match(/\b\d{2,}\b/g);
if (magicNumbers && !trimmed.includes('//') && !trimmed.includes('const')) {
smells.push({
type: 'magic_numbers',
severity: 'LOW',
line: index + 1,
description: 'Magic numbers detected',
recommendation: 'Extract numbers to named constants'
});
}
});
return smells;
}
module.exports = {
identifyCodeSmells
};