extract_function_definition
Extract complete function or method definitions from specified files, including comments and decorators, using file path and function name. Ideal for analyzing local code repositories with the Local Project Sync server.
Instructions
提取指定函数/方法的完整定义,包括注释和装饰器
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| filePath | Yes | 带前缀的完整文件路径, e.g., '[backend/src]/main.ts' | |
| functionName | Yes | 函数/方法名 | |
| includeComments | No | 是否包含上方的注释 | |
| includeDecorators | No | 是否包含装饰器 |
Input Schema (JSON Schema)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"filePath": {
"description": "带前缀的完整文件路径, e.g., '[backend/src]/main.ts'",
"type": "string"
},
"functionName": {
"description": "函数/方法名",
"type": "string"
},
"includeComments": {
"default": true,
"description": "是否包含上方的注释",
"type": "boolean"
},
"includeDecorators": {
"default": true,
"description": "是否包含装饰器",
"type": "boolean"
}
},
"required": [
"filePath",
"functionName"
],
"type": "object"
}
Implementation Reference
- src/index.ts:488-522 (handler)The tool handler function that resolves the file path, reads the file content, calls the extractFunctionDefinition helper, and formats the response.async ({ filePath, functionName, includeComments = true, includeDecorators = true }) => { const match = filePath.match(/^(\[.*?\])\/(.*)$/s); if (!match) return { content: [{ type: "text", text: "错误:文件路径格式不正确,必须包含如 '[backend/src]/' 的前缀。" }] }; const prefix = match[1]; const relativePath = match[2]; const rootPath = pathRegistry.get(prefix); if (!rootPath) return { content: [{ type: "text", text: `错误:未知的路径前缀 '${prefix}'。` }] }; const resolvedPath = path.resolve(rootPath, relativePath); if (!resolvedPath.startsWith(path.resolve(rootPath))) return { content: [{ type: "text", text: "错误:禁止访问项目目录之外的文件。" }] }; try { const fileContent = await fs.readFile(resolvedPath, "utf-8"); const lines = fileContent.split('\n'); // 查找函数定义 const functionResult = extractFunctionDefinition(lines, functionName, includeComments, includeDecorators); if (functionResult.found) { const resultText = `函数 '${functionName}' 在 '${filePath}' 中的定义:\n` + `行号 ${functionResult.startLine}-${functionResult.endLine}\n` + "---\n" + functionResult.content; return { content: [{ type: "text", text: resultText }] }; } else { return { content: [{ type: "text", text: `未在 '${filePath}' 中找到函数 '${functionName}'` }] }; } } catch (error: any) { let errorMessage = `读取文件 '${filePath}' 时发生错误。`; if (error.code === 'ENOENT') errorMessage = `错误:文件 '${filePath}' 未找到。`; console.error(errorMessage, error); return { content: [{ type: "text", text: errorMessage }] }; } }
- src/index.ts:482-487 (schema)Zod schema defining the input parameters for the tool: filePath, functionName, includeComments, includeDecorators.{ filePath: z.string().describe("带前缀的完整文件路径, e.g., '[backend/src]/main.ts'"), functionName: z.string().describe("函数/方法名"), includeComments: z.boolean().optional().default(true).describe("是否包含上方的注释"), includeDecorators: z.boolean().optional().default(true).describe("是否包含装饰器"), },
- src/index.ts:479-523 (registration)Registration of the 'extract_function_definition' tool using server.tool(), including name, description, schema, and handler.server.tool( "extract_function_definition", "提取指定函数/方法的完整定义,包括注释和装饰器", { filePath: z.string().describe("带前缀的完整文件路径, e.g., '[backend/src]/main.ts'"), functionName: z.string().describe("函数/方法名"), includeComments: z.boolean().optional().default(true).describe("是否包含上方的注释"), includeDecorators: z.boolean().optional().default(true).describe("是否包含装饰器"), }, async ({ filePath, functionName, includeComments = true, includeDecorators = true }) => { const match = filePath.match(/^(\[.*?\])\/(.*)$/s); if (!match) return { content: [{ type: "text", text: "错误:文件路径格式不正确,必须包含如 '[backend/src]/' 的前缀。" }] }; const prefix = match[1]; const relativePath = match[2]; const rootPath = pathRegistry.get(prefix); if (!rootPath) return { content: [{ type: "text", text: `错误:未知的路径前缀 '${prefix}'。` }] }; const resolvedPath = path.resolve(rootPath, relativePath); if (!resolvedPath.startsWith(path.resolve(rootPath))) return { content: [{ type: "text", text: "错误:禁止访问项目目录之外的文件。" }] }; try { const fileContent = await fs.readFile(resolvedPath, "utf-8"); const lines = fileContent.split('\n'); // 查找函数定义 const functionResult = extractFunctionDefinition(lines, functionName, includeComments, includeDecorators); if (functionResult.found) { const resultText = `函数 '${functionName}' 在 '${filePath}' 中的定义:\n` + `行号 ${functionResult.startLine}-${functionResult.endLine}\n` + "---\n" + functionResult.content; return { content: [{ type: "text", text: resultText }] }; } else { return { content: [{ type: "text", text: `未在 '${filePath}' 中找到函数 '${functionName}'` }] }; } } catch (error: any) { let errorMessage = `读取文件 '${filePath}' 时发生错误。`; if (error.code === 'ENOENT') errorMessage = `错误:文件 '${filePath}' 未找到。`; console.error(errorMessage, error); return { content: [{ type: "text", text: errorMessage }] }; } } );
- src/index.ts:137-244 (helper)Helper function that extracts the function definition from code lines using regex patterns for various function signatures, optionally includes preceding comments and decorators, and determines the end by balancing braces.function extractFunctionDefinition( lines: string[], functionName: string, includeComments: boolean, includeDecorators: boolean ): { found: boolean; content: string; startLine: number; endLine: number } { const result = { found: false, content: '', startLine: 0, endLine: 0 }; // 匹配函数定义的正则表达式 const functionPatterns = [ // async methodName( new RegExp(`^\\s*async\\s+${functionName}\\s*\\(`), // methodName( new RegExp(`^\\s*${functionName}\\s*\\(`), // private/public/protected async methodName( new RegExp(`^\\s*(private|public|protected)\\s+(async\\s+)?${functionName}\\s*\\(`), // function functionName( new RegExp(`^\\s*(export\\s+)?(async\\s+)?function\\s+${functionName}\\s*\\(`), // const functionName = new RegExp(`^\\s*(export\\s+)?const\\s+${functionName}\\s*=`), // functionName: new RegExp(`^\\s*${functionName}\\s*:`), ]; for (let i = 0; i < lines.length; i++) { const line = lines[i]; // 检查是否匹配函数定义 const isMatch = functionPatterns.some(pattern => pattern.test(line)); if (isMatch) { let startIndex = i; let endIndex = i; // 向上查找注释和装饰器 if (includeComments || includeDecorators) { let searchIndex = i - 1; while (searchIndex >= 0) { const prevLine = lines[searchIndex].trim(); // 跳过空行 if (prevLine === '') { searchIndex--; continue; } // 包含注释 if (includeComments && (prevLine.startsWith('//') || prevLine.startsWith('/*') || prevLine.startsWith('*') || prevLine.endsWith('*/'))) { startIndex = searchIndex; searchIndex--; continue; } // 包含装饰器 if (includeDecorators && prevLine.startsWith('@')) { startIndex = searchIndex; searchIndex--; continue; } // 如果不是注释或装饰器,停止向上搜索 break; } } // 向下查找函数结束位置 let braceCount = 0; let inFunction = false; for (let j = i; j < lines.length; j++) { const currentLine = lines[j]; // 计算大括号 for (const char of currentLine) { if (char === '{') { braceCount++; inFunction = true; } else if (char === '}') { braceCount--; } } endIndex = j; // 如果找到了函数开始的大括号,并且括号已经平衡,则结束 if (inFunction && braceCount === 0) { break; } // 对于箭头函数或单行函数,特殊处理 if (!inFunction && (currentLine.includes('=>') || currentLine.includes(';'))) { break; } } // 提取内容 const extractedLines = lines.slice(startIndex, endIndex + 1); result.found = true; result.content = extractedLines.join('\n'); result.startLine = startIndex + 1; result.endLine = endIndex + 1; return result; } } return result; }