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.

243 lines (242 loc) 9.79 kB
import { BaseLanguageHandler } from './base.js'; import { getNodeText } from '../astAnalyzer.js'; import logger from '../../../logger.js'; export class LuaHandler extends BaseLanguageHandler { getFunctionQueryPatterns() { return [ 'function_declaration', 'function_definition', 'local_function', 'function', 'anonymous_function' ]; } getClassQueryPatterns() { return [ 'table_constructor', 'assignment_statement', 'variable_declaration' ]; } getImportQueryPatterns() { return [ 'function_call', 'variable_declaration' ]; } extractFunctionName(node, sourceCode, _options) { try { if (node.type === 'function_declaration' || node.type === 'function_definition' || node.type === 'local_function' || node.type === 'function') { const nameNode = node.childForFieldName('name'); if (nameNode) { const name = getNodeText(nameNode, sourceCode); if (name.includes(':')) { const parts = name.split(':'); return `method_${parts[0]}_${parts[1]}`; } if (name.includes('.')) { const parts = name.split('.'); return `${parts[0]}_${parts[parts.length - 1]}`; } if (name.startsWith('test')) { return `test_${name.substring(4)}`; } if (name.includes('Callback') || name.includes('_callback')) { return `callback_${name}`; } return name; } } if (node.type === 'anonymous_function') { if (node.parent?.type === 'assignment_statement') { const variableNode = node.parent.childForFieldName('variables'); if (variableNode?.firstChild) { return getNodeText(variableNode.firstChild, sourceCode); } } if (node.parent?.type === 'field' && node.parent.parent?.type === 'table_constructor') { const nameNode = node.parent.childForFieldName('name'); if (nameNode) { return getNodeText(nameNode, sourceCode); } } return 'anonymous_function'; } return 'anonymous'; } catch (error) { logger.warn({ err: error, nodeType: node.type }, 'Error extracting Lua function name'); return 'anonymous'; } } extractClassName(node, sourceCode) { try { if (node.type === 'table_constructor') { if (node.parent?.type === 'assignment_statement') { const variableNode = node.parent.childForFieldName('variables'); if (variableNode?.firstChild) { return getNodeText(variableNode.firstChild, sourceCode); } } if (node.parent?.type === 'return_statement') { let current = node.parent.parent; while (current) { if (current.type === 'function_declaration' || current.type === 'function_definition' || current.type === 'local_function') { const nameNode = current.childForFieldName('name'); if (nameNode) { return `${getNodeText(nameNode, sourceCode)}_Class`; } } current = current.parent; } } } else if (node.type === 'assignment_statement') { const variableNode = node.childForFieldName('variables'); const valueNode = node.childForFieldName('values'); if (variableNode?.firstChild && valueNode?.firstChild?.type === 'table_constructor') { return getNodeText(variableNode.firstChild, sourceCode); } } else if (node.type === 'variable_declaration') { const nameNode = node.childForFieldName('name'); const valueNode = node.childForFieldName('value'); if (nameNode && valueNode?.type === 'table_constructor') { return getNodeText(nameNode, sourceCode); } } return 'AnonymousClass'; } catch (error) { logger.warn({ err: error, nodeType: node.type }, 'Error extracting Lua class name'); return 'AnonymousClass'; } } extractParentClass(node, sourceCode) { try { if (node.type === 'assignment_statement' || node.type === 'variable_declaration') { let current = node.nextNamedSibling; while (current) { if (current.type === 'function_call' && current.childForFieldName('name')?.text === 'setmetatable') { const argsNode = current.childForFieldName('arguments'); if (argsNode && argsNode.childCount && argsNode.childCount >= 2) { const parentNode = argsNode.child(1); if (parentNode) { return getNodeText(parentNode, sourceCode); } } } current = current.nextNamedSibling; } } return undefined; } catch (error) { logger.warn({ err: error, nodeType: node.type }, 'Error extracting Lua parent class'); return undefined; } } extractImportPath(node, sourceCode) { try { if (node.type === 'function_call' && node.childForFieldName('name')?.text === 'require') { const argsNode = node.childForFieldName('arguments'); if (argsNode?.firstChild) { return getNodeText(argsNode.firstChild, sourceCode); } } else if (node.type === 'variable_declaration') { const valueNode = node.childForFieldName('value'); if (valueNode?.type === 'function_call' && valueNode.childForFieldName('name')?.text === 'require') { const argsNode = valueNode.childForFieldName('arguments'); if (argsNode?.firstChild) { return getNodeText(argsNode.firstChild, sourceCode); } } } return 'unknown'; } catch (error) { logger.warn({ err: error, nodeType: node.type }, 'Error extracting Lua import path'); return 'unknown'; } } extractFunctionComment(node, sourceCode) { try { const current = node; let prev = current.previousNamedSibling; while (prev && prev.type !== 'comment') { prev = prev.previousNamedSibling; } if (prev && prev.type === 'comment') { const commentText = getNodeText(prev, sourceCode); return commentText .replace(/^--\s*/mg, '') .trim(); } return undefined; } catch (error) { logger.warn({ err: error, nodeType: node.type }, 'Error extracting Lua function comment'); return undefined; } } extractClassComment(node, sourceCode) { try { const current = node; let prev = current.previousNamedSibling; while (prev && prev.type !== 'comment') { prev = prev.previousNamedSibling; } if (prev && prev.type === 'comment') { const commentText = getNodeText(prev, sourceCode); return commentText .replace(/^--\s*/mg, '') .trim(); } return undefined; } catch (error) { logger.warn({ err: error, nodeType: node.type }, 'Error extracting Lua class comment'); return undefined; } } detectFramework(sourceCode) { try { if (sourceCode.includes('love.') || sourceCode.includes('function love.') || sourceCode.includes('love.graphics')) { return 'love2d'; } if (sourceCode.includes('display.') || sourceCode.includes('physics.') || sourceCode.includes('transition.')) { return 'corona'; } if (sourceCode.includes('lapis.') || sourceCode.includes('require("lapis")') || sourceCode.includes('app:get')) { return 'lapis'; } if (sourceCode.includes('torch.') || sourceCode.includes('nn.') || sourceCode.includes('require("torch")')) { return 'torch'; } return null; } catch (error) { logger.warn({ err: error }, 'Error detecting Lua framework'); return null; } } }