agentsqripts
Version:
Comprehensive static code analysis toolkit for identifying technical debt, security vulnerabilities, performance issues, and code quality problems
64 lines (53 loc) • 2.19 kB
JavaScript
/**
* @file Analyze type of recursion
* @description Single responsibility: Determine recursion pattern type
*/
/**
* Analyze type of recursion
*/
function analyzeRecursionType(funcContent, funcName) {
// More sophisticated base case detection
const lines = funcContent.split('\n');
let hasConditionalReturn = false;
let hasRecursiveCall = false;
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
// Check for conditional returns (likely base cases)
if (/if\s*\([^)]+\)\s*{?\s*return/.test(line) ||
/\?\s*[^:]+:\s*return/.test(line) ||
/if\s*\([^)]+\)\s*return/.test(line)) {
// Make sure this return doesn't contain a recursive call
if (funcName === 'anonymous' || funcName === 'arrow' || !line.includes(funcName + '(')) {
hasConditionalReturn = true;
}
}
// Check if function actually has recursive calls
if (funcName !== 'anonymous' && funcName !== 'arrow' && line.includes(funcName + '(')) {
hasRecursiveCall = true;
}
}
// Only flag missing base case if there's actually recursion AND no returns at all
// This is very conservative to avoid false positives
const hasAnyReturn = /return/.test(funcContent);
if (hasRecursiveCall && !hasAnyReturn) {
return 'no_base_case';
}
// Check for multiple recursive calls (exponential)
const recursiveCallCount = (funcContent.match(new RegExp(`\\b${funcName}\\s*\\(`, 'g')) || []).length;
if (recursiveCallCount > 2) { // Changed from > 1 to > 2 to reduce false positives
return 'exponential';
}
// Check for nested loops with recursion (quadratic)
const hasLoopsWithRecursion = /for.*{.*recurse|while.*{.*recurse/i.test(funcContent.replace(/\n/g, ' '));
if (hasLoopsWithRecursion) {
return 'quadratic';
}
// Check for inefficient patterns
const hasStringConcatenation = /\+.*string|concat.*recurse/i.test(funcContent);
const hasArrayOperations = /push.*recurse|concat.*recurse/i.test(funcContent);
if (hasStringConcatenation || hasArrayOperations) {
return 'linear_inefficient';
}
return 'linear_efficient';
}
module.exports = analyzeRecursionType;