UNPKG

vibe-coder-mcp

Version:

Production-ready MCP server with complete agent integration, multi-transport support, and comprehensive development automation tools for AI-assisted workflows.

169 lines (168 loc) 6.72 kB
import { BaseLanguageHandler } from './base.js'; import { getNodeText } from '../astAnalyzer.js'; import logger from '../../../logger.js'; export class DefaultLanguageHandler extends BaseLanguageHandler { getFunctionQueryPatterns() { return [ 'function_declaration', 'function_definition', 'method_declaration', 'method_definition', 'function', 'arrow_function', 'lambda', 'lambda_expression', 'function_item', 'method', 'subroutine', 'procedure_declaration', 'procedure', 'sub', 'def' ]; } getClassQueryPatterns() { return [ 'class_declaration', 'class_definition', 'class', 'class_item', 'struct_declaration', 'struct_definition', 'struct', 'interface_declaration', 'interface_definition', 'interface' ]; } getImportQueryPatterns() { return [ 'import_declaration', 'import_statement', 'import', 'include_statement', 'include', 'require', 'using_declaration', 'using_directive', 'using' ]; } extractFunctionName(node, sourceCode, _options) { try { const nameNode = node.childForFieldName('name'); if (nameNode) { return getNodeText(nameNode, sourceCode); } if (node.parent?.type === 'variable_declarator' || node.parent?.type === 'variable_declaration' || node.parent?.type === 'assignment_expression') { const parentNameNode = node.parent.childForFieldName('name') || node.parent.childForFieldName('left'); if (parentNameNode) { return getNodeText(parentNameNode, sourceCode); } } if (node.parent?.type === 'pair' || node.parent?.type === 'property_definition' || node.parent?.type === 'property') { const keyNode = node.parent.childForFieldName('key') || node.parent.childForFieldName('name'); if (keyNode) { return getNodeText(keyNode, sourceCode); } } if (node.parent?.type === 'arguments' && node.parent.parent?.type === 'call_expression') { const callExprNode = node.parent.parent; const funcNameNode = callExprNode.childForFieldName('function'); if (funcNameNode) { const funcName = getNodeText(funcNameNode, sourceCode); if (['map', 'filter', 'reduce', 'forEach', 'find', 'findIndex', 'some', 'every'].includes(funcName)) { return `${funcName}_callback`; } if (['describe', 'it', 'test', 'beforeEach', 'afterEach', 'beforeAll', 'afterAll'].includes(funcName)) { const args = callExprNode.childForFieldName('arguments'); if (args && args.firstChild && (args.firstChild.type === 'string' || args.firstChild.type === 'string_literal')) { const testDesc = getNodeText(args.firstChild, sourceCode); const cleanDesc = testDesc.replace(/^["']|["']$/g, '').substring(0, 30); return `${funcName}_${cleanDesc}`; } return `${funcName}_handler`; } } } const context = this.contextTracker.getCurrentContext(); if (context && context.parent) { if (context.parent.type === 'class' && context.parent.name) { return `${context.parent.name}_method`; } else if (context.parent.type === 'function' && context.parent.name) { return `${context.parent.name}_inner`; } } return 'anonymous'; } catch (error) { logger.warn({ err: error, nodeType: node.type }, 'Error extracting function name'); return 'anonymous'; } } extractClassName(node, sourceCode) { try { const nameNode = node.childForFieldName('name'); if (nameNode) { return getNodeText(nameNode, sourceCode); } return 'AnonymousClass'; } catch (error) { logger.warn({ err: error, nodeType: node.type }, 'Error extracting class name'); return 'AnonymousClass'; } } extractImportPath(node, sourceCode) { try { const sourceNode = node.childForFieldName('source'); if (sourceNode) { return getNodeText(sourceNode, sourceCode).replace(/^["']|["']$/g, ''); } const pathNode = node.childForFieldName('path'); if (pathNode) { return getNodeText(pathNode, sourceCode).replace(/^["']|["']$/g, ''); } for (let i = 0; i < node.childCount; i++) { const child = node.child(i); if (child && (child.type === 'string' || child.type === 'string_literal')) { return getNodeText(child, sourceCode).replace(/^["']|["']$/g, ''); } } return 'unknown'; } catch (error) { logger.warn({ err: error, nodeType: node.type }, 'Error extracting import path'); return 'unknown'; } } extractFunctionComment(node, sourceCode) { try { const startPosition = node.startPosition; const startIndex = startPosition.row > 0 ? sourceCode.lastIndexOf('\n', sourceCode.indexOf('\n', 0) + startPosition.row) : 0; if (startIndex >= 0) { const textBeforeNode = sourceCode.substring(0, startIndex); const commentMatch = textBeforeNode.match(/\/\*\*([\s\S]*?)\*\/\s*$/) || textBeforeNode.match(/\/\/(.*)\s*$/); if (commentMatch) { return commentMatch[1].trim(); } } return undefined; } catch (error) { logger.warn({ err: error, nodeType: node.type }, 'Error extracting function comment'); return undefined; } } }