Skip to content

feat: [OSS26] 按方法名读取方法源码 read_method_source_by_method_name (#137) - #154

Open
wryyyds7 wants to merge 6 commits into
antgroup:mainfrom
wryyyds7:feat/oss26-read-method-source-137
Open

feat: [OSS26] 按方法名读取方法源码 read_method_source_by_method_name (#137)#154
wryyyds7 wants to merge 6 commits into
antgroup:mainfrom
wryyyds7:feat/oss26-read-method-source-137

Conversation

@wryyyds7

Copy link
Copy Markdown

概述

实现 read_method_source_by_method_name MCP 工具,给定方法的全限定名(可选形参类型用于重载消歧),精准返回该方法的源码片段(可选携带 Javadoc 与注解),不带文件其他部分。

实现

方法体边界识别

复用 #134 的 O(n) 花括号深度状态机 (_compute_line_depths),一次遍历计算每行的花括号嵌套深度,跟踪字符串/字符/注释状态。修复了 _strip_comments 的 bug:原来块注释替换时把换行符也替换为空格,导致行号偏移;现在保留换行符,只替换非换行字符。

方法范围提取 (_extract_all_method_ranges)

  • 逐行扫描,用 _METHOD_LINE_PATTERN 匹配 methodName(params) {;
  • 通过 depth == class_depth + 1 过滤,只接受类体级别的方法定义,排除方法体内的方法调用
  • 同时接受 { 结尾(有方法体)和 ; 结尾(抽象方法/接口声明)
  • 额外检测 static { ... } 静态初始化块 (_STATIC_INIT_PATTERN)

重载消歧

  • method_name + containing_class 筛选候选方法
  • 如果候选数 > 1 且未提供 parameter_types:返回 ambiguous: true + 候选签名列表
  • 如果提供了 parameter_types:按参数类型精确匹配消歧
  • 候选签名格式:getUser(HttpServletRequest, String): ResponseEntity<User>

Javadoc 和注解控制

  • include_javadoc=true (默认): 从方法声明行向上搜索 /** ... */,作为独立 javadoc 字段返回
  • include_javadoc=false: 不返回 javadoc 字段
  • include_annotations=true (默认): source 包含方法上方的 @xxx 注解行
  • include_annotations=false: source 从方法声明行开始

特殊方法类型支持

  • 构造器: 无返回类型时识别为构造器,User.User 返回所有构造器重载
  • 抽象方法: ; 结尾,start_line == end_line(单行声明)
  • 静态初始化块: static { ... } 通过 _STATIC_INIT_PATTERN 检测,方法名为 <static_init>
  • 嵌套 lambda/匿名类: 包含在父方法 source 中(depth 跟踪确保正确边界)

参数类型解析 (_parse_param_types)

  • 去掉注解 (@PathVariable)、final 修饰符、可变参数 ...
  • 按顶层逗号分割 (_split_params),忽略泛型尖括号内的逗号
  • 支持 List<String>Map<String, Object> 等泛型参数

文件定位 (_find_class_file)

  • 策略1: 按包路径约定拼接,尝试 src/main/java/src/、根目录
  • 策略2: 遍历所有 Java 文件,用正则匹配类名

复用 #134/#135 的核心组件

  • _compute_line_depths(): O(n) 花括号深度状态机
  • _build_class_ranges_by_depth(): 利用 depth 确定类范围
  • _METHOD_LINE_PATTERN: 逐行匹配方法声明
  • _CLASS_PATTERN: 逐行匹配类声明
  • _strip_comments(): 注释移除(已修复换行符保留 bug)
  • _MODIFIERS / _CONTROL_FLOW_KEYWORDS: 关键字过滤

验收标准对照

标准 状态 结果
完整源码含嵌套 lambda/匿名类 PASS lambda=True, anon=True, complete=True
重载返回 ambiguous + 候选 PASS ambiguous=True, 2 candidates
注解/Javadoc 控制开关 PASS include_javadoc=False omits, include_annotations=False omits
构造器 PASS 2 constructor candidates
静态初始化块 PASS <static_init> returns static { ... }
抽象方法只声明 PASS Single line, start==end, has abstract
中等仓库 < 3s PASS JDP: 0.43s

测试

单元测试

  • 全限定名解析: 普通、内部类 $、无包名、空
  • 参数类型解析: 简单、多参数、注解、final、可变参数、空、泛型
  • 基本源码读取: 简单方法、行范围、签名、完整方法体、相对路径
  • 重载: ambiguous、消歧第一个、消歧第二个
  • Javadoc/注解: 包含/排除 javadoc、包含/排除注解
  • 构造器: 无参、ambiguous、消歧
  • 静态初始化块: 源码内容、行范围
  • 抽象方法: 只声明、抽象类中的具体方法
  • 嵌套结构: lambda + 匿名类
  • 边界: 不存在、类不存在、空名、无效仓库
  • MCP 注册: 自动发现、MCP 调用

集成测试

  • java-design-patterns (~1900 文件): 读取方法、toString、性能 < 3s
  • spring-framework (~9200 文件): 读取方法、性能 < 5s

Closes #137

wangrenyu.wry and others added 5 commits July 21, 2026 14:03
Implement the unified MCP Server framework as the runtime base for
all upcoming YASA MCP tools (Issue antgroup#129).

Framework:
- Dual transport: stdio (default) / streamable-http
- Tool registration via @mcp_tool decorator + auto-discovery
- Unified input validation (Pydantic), error handling, logging (stderr)
- Health check endpoint GET /healthz in HTTP mode
- Built-in demo tool ping returning server status

Modules:
- yasa_mcp/config.py: CLI args + env var parsing
- yasa_mcp/server.py: FastMCP lifecycle management
- yasa_mcp/registry.py: decorator-based tool auto-registration
- yasa_mcp/transport/http.py: streamable-http + /healthz
- yasa_mcp/tools/ping.py: demo health-check tool
- yasa_mcp/errors.py: unified error codes
- yasa_mcp/logging_config.py: stderr logging with level control

Tests (44 passing):
- test_registry.py: tool registration, auto-discovery, schema
- test_validation.py: param validation, error handling
- test_logging.py: stderr output, format, level filtering
- test_config.py: CLI parsing, env vars, error exit

Docs:
- docs/mcp/requirements.md: functional/non-functional requirements
- docs/mcp/system-design.md: architecture, module design, data flow
- docs/mcp/development-guide.md: step-by-step implementation guide
- yasa_mcp/README.md: usage + Claude Desktop/Cline config examples
- registry.py: prevent duplicate tool registration via __module__ check
- http.py: use app.add_route() instead of direct app.routes manipulation
- http.py: remove unused Route import
- http.py + server.py: pass log_level to uvicorn instead of hardcoding
- errors.py: fix empty string message fallback bug
- test_registry.py: use asyncio.run() instead of deprecated get_event_loop()
- test_validation.py: remove unused imports
- config.py: convert repo_root to absolute path
- logging_config.py: precise logger namespace check
- pyproject.toml: fix build-backend to setuptools.build_meta
- .gitignore: add .venv/ and Python project ignore rules
…ture pattern

Implement MCP tool that matches regex patterns against code element
signatures (methods, classes, fields) in Java repositories.

Key features:
- Supports element_kind: method, class, field, any
- Comment filtering (line + block comments stripped before matching)
- Field vs local variable disambiguation via brace-depth tracking
- Control flow keyword filtering (if/throw/return not matched as methods)
- Performance: O(n) single-pass depth computation with string/char/comment
  state machine

Test data: java-design-patterns (~1900 files) + spring-framework (~9200 files)
Performance: medium repo < 3s, large repo < 5s

All 51 tests passed.
… bodies

Reuse the O(n) brace-depth state machine from antgroup#134 to locate method body
boundaries, then apply regex search within each method's body lines to
return matches with their containing method's fully qualified name.

Key features:
- Returns containing_method (fully qualified name) for each match
- Multi-line matching (multi_line=true by default, re.DOTALL)
- Excludes field initializations, imports, and comments
- Lambda/anonymous class matches attributed to outer method
- Supports path_prefix to limit search scope
- Performance: medium repo (JDP ~1900 files) < 5s

Test data: java-design-patterns (~1900 files) + spring-framework (~9200 files)
All tests passed.
…by fully qualified name

Implement MCP tool to read the complete source code of a Java method by
its fully qualified name, with overload disambiguation and Javadoc/annotation
control.

Key features:
- Overload disambiguation via parameter_types; returns ambiguous + candidates
- include_javadoc / include_annotations control switches
- Supports constructors, abstract methods (declaration only), static init blocks
- Nested lambda/anonymous class bodies included in parent method source
- Reuses O(n) brace-depth state machine from antgroup#134 and method ranges from antgroup#135
- Fixes _strip_comments to preserve newlines (was collapsing multi-line comments)

Test data: java-design-patterns (~1900 files) + spring-framework (~9200 files)
Performance: JDP < 3s (0.43s measured)
All acceptance criteria verified.
@wryyyds7 wryyyds7 changed the title [OSS26] 按方法名读取方法源码 read_method_source_by_method_name (#137) feat: [OSS26] 按方法名读取方法源码 read_method_source_by_method_name (#137) Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[OSS26] 按方法名读取方法源码 read_method_source_by_method_name

1 participant