Skip to content

feat: [OSS26] 按方法体模式搜代码 search_code_by_body_pattern (#135) - #157

Closed
lsr-05 wants to merge 4 commits into
antgroup:mainfrom
lsr-05:issue-135-implementation
Closed

feat: [OSS26] 按方法体模式搜代码 search_code_by_body_pattern (#135)#157
lsr-05 wants to merge 4 commits into
antgroup:mainfrom
lsr-05:issue-135-implementation

Conversation

@lsr-05

@lsr-05 lsr-05 commented Aug 3, 2026

Copy link
Copy Markdown

概述

实现 search_code_by_body_pattern MCP 工具,在 Java 方法体内按正则模式搜索代码片段,并返回命中位置所属方法的全限定名。

与签名级搜索(#134)的核心区别是:本工具能够确定代码命中点属于哪个方法,同时排除 import、字段初始化和注释等非方法体内容。

Depends on #151. This PR is stacked on the MCP framework and signature-search implementation. After #151 is merged, the diff will narrow to the #135 implementation.

实现

方法体边界识别

  • 复用 _compute_line_depths() 的 O(n) 花括号深度状态机。
  • 使用 _compute_brace_metadata() 一次计算花括号配对、打开深度和声明起始位置。
  • 注释、字符串、字符字面量和 Java text block 中的花括号不会影响结构计算。
  • 词法遮罩保持源码长度和换行位置不变,确保偏移量及行号准确。
  • 类范围、方法范围共享同一份深度、花括号和行偏移数据,避免重复全文扫描。

方法范围确定

  • _extract_method_ranges() 仅提取类体级别的方法。
  • 支持普通方法、构造方法、单行方法和跨多行的方法签名。
  • 使用精确花括号配对确定方法体起止偏移和方法结束行。
  • 支持具名内部类,返回如 com.example.Outer.Inner.run 的全限定方法名。
  • 忽略 lambda、匿名类和局部类内部的方法声明。

嵌套方法处理

  • Lambda 表达式中的命中归属外层方法。
  • 匿名类方法中的命中归属创建匿名类的外层方法。
  • 不会错误返回匿名类中的 runcall 等方法名。
  • 具名成员内部类的方法仍按内部类自身的方法处理。

方法体内搜索

  • multi_line=True 时启用 re.DOTALL,支持跨行匹配。
  • multi_line=False. 不匹配换行符。
  • 返回每个匹配结果,而不仅是每个方法的首个结果。
  • 根据匹配偏移量计算精确 match_line
  • 返回 match_snippet 和命中行前后各 2 行的 snippet_with_context
  • 支持 max_results 截断和 path_prefix 范围过滤。
  • 拒绝越过仓库根目录的 path_prefix
  • 当前明确限制为 language=java

排除非方法体内容

  • import 语句位于文件顶层,不属于任何方法范围。
  • 字段初始化位于类体级别,不属于方法体。
  • 搜索前遮罩行注释和块注释,注释内容不会命中。
  • 字符串中的 ///* 不会被误判为注释。
  • 字符串、字符和 text block 中的花括号不会破坏方法边界。

复用 #134 的核心组件

  • _compute_line_depths()
  • _compute_brace_metadata()
  • _build_class_ranges_by_depth()
  • _CLASS_PATTERN
  • _strip_comments() 及共享 Java 词法遮罩
  • _CONTROL_FLOW_KEYWORDS
  • _MODIFIERS
  • _EXCLUDED_DIRS
  • _is_binary()
  • _MAX_RESULTS_LIMIT

方法声明部分增加了多行 header 解析,以覆盖单行 _METHOD_LINE_PATTERN 无法识别的长参数列表。

测试

单元测试

覆盖基本搜索、全限定方法名、方法起止行号、上下文片段、多次命中、非方法体内容排除、Lambda、匿名类、具名内部类、单行方法、多行签名、跨行正则、异常参数、结果截断、路径过滤和 MCP 注册。

集成测试

  • java-design-patterns:1,902 个 Java 文件,Runtime、getLogger、catch Exception 搜索通过,性能满足 <5s
  • spring-framework:9,240 个 Java 文件,catch Exception 和 System.out.println 搜索通过。
  • 完整 MCP 测试:131 passed in 61.40s

Closes #135

wangrenyu.wry and others added 4 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.
Implement search_code_by_body_pattern with Java-aware method ranges, nested-code attribution, context snippets, path filtering, and integration coverage for issue antgroup#135.
@lsr-05 lsr-05 changed the title feat: [OSS26] 鎸夋柟娉曚綋妯″紡鎼滀唬鐮?search_code_by_body_pattern (#135) feat: [OSS26] 按方法体模式搜代码 search_code_by_body_pattern (#135) Aug 3, 2026
@lsr-05

lsr-05 commented Aug 3, 2026

Copy link
Copy Markdown
Author

#135

@lsr-05 lsr-05 closed this Aug 3, 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] 按方法体模式搜代码 search_code_by_body_pattern

1 participant