Skip to main content
Glama
codeAnalyzer.js4.24 kB
export function analyzeCodeStructure(code) { const structure = { widgetTreeDepth: 0, methodLength: 0, stateUpdateCount: 0, hasStatelessWidgets: false, hasInteractiveWidgets: false, hasTextWidgets: false, hasComplexCallbacks: false, duplicatedCode: [], hasPublicMethods: false, hasBusinessLogicInUI: false, hasProperSeparation: false, tightCoupling: 0, hasDataFetching: false, hasStateManagement: false, hasComplexObjectCreation: false, }; structure.widgetTreeDepth = calculateMaxDepth(code); structure.methodLength = calculateAverageMethodLength(code); structure.stateUpdateCount = (code.match(/setState/g) || []).length; structure.hasStatelessWidgets = /extends\s+StatelessWidget/.test(code); structure.hasInteractiveWidgets = /GestureDetector|InkWell|Button|onTap|onPressed/.test(code); structure.hasTextWidgets = /Text\s*\(/.test(code); structure.hasComplexCallbacks = /Function\s*\([^)]{20,}\)/.test(code); structure.duplicatedCode = findDuplicatedCode(code); structure.hasPublicMethods = /^\s*(?!_)\w+\s*\(/m.test(code); structure.hasBusinessLogicInUI = detectBusinessLogicInUI(code); structure.hasProperSeparation = checkLayerSeparation(code); structure.tightCoupling = calculateCoupling(code); structure.hasDataFetching = /http\.|dio\.|fetch|repository/i.test(code); structure.hasStateManagement = /setState|ChangeNotifier|ValueNotifier|Stream/.test(code); structure.hasComplexObjectCreation = /factory|fromJson|toJson/.test(code); return structure; } function calculateMaxDepth(code) { let maxDepth = 0; let currentDepth = 0; for (const char of code) { if (char === '{' || char === '(' || char === '[') { currentDepth++; maxDepth = Math.max(maxDepth, currentDepth); } else if (char === '}' || char === ')' || char === ']') { currentDepth--; } } return maxDepth; } function calculateAverageMethodLength(code) { const methods = code.match(/\w+\s*\([^)]*\)\s*(?:async\s*)?\{[^}]*\}/g) || []; if (methods.length === 0) return 0; const totalLength = methods.reduce((sum, method) => sum + method.length, 0); return Math.round(totalLength / methods.length); } function findDuplicatedCode(code) { const lines = code.split('\n'); const duplicates = []; const seen = new Map(); lines.forEach((line, index) => { const trimmed = line.trim(); if (trimmed.length > 20 && !trimmed.startsWith('//') && !trimmed.startsWith('import')) { if (seen.has(trimmed)) { duplicates.push({ line: trimmed, locations: [seen.get(trimmed), index + 1], }); } else { seen.set(trimmed, index + 1); } } }); return duplicates; } function detectBusinessLogicInUI(code) { const businessLogicPatterns = [ /calculate|compute|process|transform|validate/i, /http\.|dio\.|fetch.*\(/, /SELECT|INSERT|UPDATE|DELETE/i, /\.(save|load|delete|update)\s*\(/, ]; const inBuildMethod = code.includes('Widget build'); if (!inBuildMethod) return false; const buildMethodMatch = code.match(/Widget\s+build[^{]*\{([^}]*)\}/s); if (!buildMethodMatch) return false; const buildContent = buildMethodMatch[1]; return businessLogicPatterns.some(pattern => pattern.test(buildContent)); } function checkLayerSeparation(code) { const hasModels = /class\s+\w+Model/.test(code); const hasServices = /class\s+\w+Service/.test(code); const hasRepositories = /class\s+\w+Repository/.test(code); const hasControllers = /class\s+\w+Controller/.test(code); const separationScore = (hasModels ? 1 : 0) + (hasServices ? 1 : 0) + (hasRepositories ? 1 : 0) + (hasControllers ? 1 : 0); return separationScore >= 2; } function calculateCoupling(code) { const classes = (code.match(/class\s+\w+/g) || []).length; if (classes === 0) return 0; const directDependencies = (code.match(/new\s+\w+|=\s*\w+\(/g) || []).length; const injectedDependencies = (code.match(/\w+\s+\w+\s*[,)]|required\s+this\.\w+/g) || []).length; const couplingRatio = directDependencies / (directDependencies + injectedDependencies + 1); return Math.min(1, couplingRatio); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dvillegastech/flutter_mcp_2'

If you have feedback or need assistance with the MCP directory API, please join our Discord server