UNPKG

agentsqripts

Version:

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

178 lines (162 loc) 6.21 kB
/** * @file Context-aware threshold provider for intelligent SRP violation assessment * @description Single responsibility: Provide file-type-specific thresholds for accurate SRP analysis * * This threshold provider implements intelligent context detection and appropriate threshold * adjustment for different file types and architectural roles. It prevents false positives * by recognizing that CLI tools, configuration files, and utility modules have different * legitimate complexity patterns than general application code. * * Design rationale: * - Context detection prevents inappropriate SRP violation flagging on legitimate patterns * - File type classification enables targeted threshold application * - Flexible threshold system accommodates different architectural patterns * - Severity adjustment allows nuanced assessment based on file purpose * - Conservative approach minimizes disruptive refactoring recommendations * * Context classification logic: * - CLI scripts: Higher thresholds for argument parsing and main function patterns * - Test files: Relaxed thresholds acknowledging multiple test case patterns * - Configuration: Higher tolerance for multiple setting and constant definitions * - Library/utility: Balanced approach recognizing related function clustering * - Demo files: Relaxed thresholds for example and demonstration patterns */ /** * Detect file context for appropriate SRP thresholds * @param {string} filePath - File path to analyze * @param {string} content - File content for additional context * @returns {string} File context type */ function detectFileContext(filePath, content) { const normalizedPath = filePath.toLowerCase(); const fileName = normalizedPath.split('/').pop() || ''; // CLI script detection if (content.includes('#!/usr/bin/env node') || content.includes('process.argv') || content.includes('process.exit') || normalizedPath.includes('/cli/') || fileName.startsWith('analyze-') || fileName.includes('cli')) { return 'cli'; } // Test file detection if (normalizedPath.includes('/test/') || normalizedPath.includes('/__tests__/') || fileName.includes('.test.') || fileName.includes('.spec.') || content.includes('describe(') || content.includes('it(')) { return 'test'; } // Configuration file detection if (fileName.includes('config') || fileName.includes('settings') || fileName === 'index.js' || normalizedPath.includes('/config/')) { return 'config'; } // Utility/library file detection if (normalizedPath.includes('/lib/') || normalizedPath.includes('/utils/') || fileName.includes('utils') || fileName.includes('helpers')) { return 'library'; } // Demo/example file detection if (normalizedPath.includes('/demo/') || normalizedPath.includes('/examples/') || fileName.includes('demo') || fileName.includes('example')) { return 'demo'; } return 'general'; } /** * Get context-aware thresholds for SRP analysis * @param {string} context - File context type * @returns {Object} Threshold configuration */ function getContextualThresholds(context) { const baseThresholds = { lines: 100, functions: 2, exports: 1, methods: 5, concerns: 2 }; switch (context) { case 'cli': return { ...baseThresholds, lines: 600, // CLI scripts can be longer due to argument parsing functions: 5, // CLI scripts often have main + helper functions exports: 0, // CLI scripts typically don't export linePenalty: 0.5 // Reduced line penalty for CLI scripts }; case 'test': return { ...baseThresholds, lines: 300, // Test files can be longer functions: 10, // Many test functions are expected exports: 0, // Test files typically don't export linePenalty: 0.3 // Very reduced penalty for test files }; case 'config': return { ...baseThresholds, lines: 200, // Config files can be longer functions: 1, // Config files should be mostly data exports: 2, // Config files often export multiple objects linePenalty: 0.4 // Reduced penalty for configuration }; case 'demo': return { ...baseThresholds, lines: 400, // Demo files can be longer to show examples functions: 8, // Demo files often have multiple examples exports: 3, // Demo files may export multiple examples linePenalty: 0.2 // Very low penalty for demo files }; case 'library': return { ...baseThresholds, lines: 200, // Library files can be longer for optimized algorithms functions: 3, // Library files should have focused functionality exports: 2, // Library files can export related functions concerns: 3, // Allow more concerns for utility libraries linePenalty: 0.6 // Reduced penalty for legitimate library complexity }; default: // 'general' return { ...baseThresholds, linePenalty: 1.0 // Standard penalty }; } } /** * Get severity adjustment based on context * @param {string} context - File context type * @param {number} baseScore - Base SRP violation score * @returns {number} Adjusted score */ function getContextualSeverityAdjustment(context, baseScore) { switch (context) { case 'cli': return Math.max(0, baseScore - 2); // Reduce severity for CLI scripts case 'test': return Math.max(0, baseScore - 3); // Very lenient for test files case 'demo': return Math.max(0, baseScore - 3); // Very lenient for demo files case 'config': return Math.max(0, baseScore - 1); // Slightly reduce for config files case 'library': return baseScore + 1; // Slightly stricter for library files default: return baseScore; } } module.exports = { detectFileContext, getContextualThresholds, getContextualSeverityAdjustment };