agentsqripts
Version:
Comprehensive static code analysis toolkit for identifying technical debt, security vulnerabilities, performance issues, and code quality problems
83 lines (81 loc) • 4.08 kB
JavaScript
/**
* @file Detect loop patterns in JavaScript code
* @description Single responsibility: Identify lines containing loop constructs
*
* This utility identifies JavaScript loop patterns for performance and complexity
* analysis. It detects both traditional loop constructs and functional array methods
* that represent iterative operations, which is essential for algorithmic complexity
* detection and performance optimization recommendations.
*
* Design rationale:
* - Covers both imperative (for/while) and functional (forEach/map) loop patterns
* - Uses regex matching for efficient pattern detection
* - Trims whitespace to handle various formatting styles
* - Conservative pattern matching to avoid false negatives in analysis
*/
/**
* Detect JavaScript loop constructs in a single line of code
*
* Technical function: Analyzes code line for patterns indicating iterative operations
*
* Implementation rationale:
* - String.trim() normalizes whitespace formatting variations
* - Regular expression efficiently matches multiple loop patterns in single pass
* - Whitespace patterns (\s*) accommodate various coding styles
* - Parenthesis matching ensures we catch actual loop constructs, not just keywords
*
* Loop pattern coverage:
* - 'for\s*\(': Traditional for loops with any whitespace before parentheses
* - '\.forEach\s*\(': Array.forEach method calls for functional iteration
* - '\.map\s*\(': Array.map method calls that transform each element
* - 'while\s*\(': While loops for condition-based iteration
*
* Pattern matching strategy:
* - Escaped dots (\.): Match literal dots in method calls, not any character
* - \s* whitespace: Accommodates various coding styles and formatting
* - Parentheses inclusion: Ensures we match actual function calls, not variable names
* - No word boundaries: Allows matching within larger expressions
*
* Functional vs imperative coverage:
* - Imperative loops (for, while): Traditional control flow structures
* - Functional methods (forEach, map): Array methods that iterate over collections
* - Both patterns matter for performance analysis and complexity detection
* - Consistent treatment enables unified loop analysis across coding styles
*
* Performance considerations:
* - O(1) time complexity for single line analysis
* - Regex compilation cached by JavaScript engine for repeated calls
* - String.trim() minimal overhead for whitespace normalization
* - Single regex test more efficient than multiple string.includes checks
*
* Limitations and trade-offs:
* - May match loop patterns in comments or strings (conservative approach)
* - Doesn't distinguish between different types of loops for complexity
* - Simple pattern matching chosen over AST parsing for performance
* - False positives acceptable for broad pattern detection use case
*
* Missing patterns (intentionally excluded):
* - 'do...while': Less common and often spans multiple lines
* - Array.filter/reduce: Transform operations, not pure iteration
* - for...in/for...of: Often span multiple lines in formatted code
* - Recursive patterns: Require more complex analysis
*
* Alternative approaches considered:
* - AST parsing: Rejected for performance overhead in line-by-line analysis
* - Separate regex for each pattern: Rejected as less efficient
* - More comprehensive pattern list: Rejected to avoid false positives
*
* @param {string} line - Single line of JavaScript code to analyze
* @returns {boolean} True if line contains any recognized loop pattern
* @example
* isLoopPattern('for (let i = 0; i < len; i++) {') // returns true
* isLoopPattern(' items.forEach(item => {') // returns true
* isLoopPattern('while (condition) {') // returns true
* isLoopPattern('const result = array.map(x => x * 2)') // returns true
* isLoopPattern('console.log("no loops here")') // returns false
*/
function isLoopPattern(line) {
const trimmed = line.trim();
return /for\s*\(|\.forEach\s*\(|\.map\s*\(|while\s*\(/.test(trimmed);
}
module.exports = isLoopPattern;