Skip to content

[OSS26] 查找方法被调用点 find_callers_by_method_name #139

Open

Description

@ponyha

接口介绍

反向引用查询:给定一个方法的全限定名,返回仓库内所有调用该方法的位置 — 包括调用方所在方法、行号、调用表达式片段;支持把通过父类/接口间接调用到该方法的位置也算上。

工具名

find_callers_by_method_name

背景与目标

调用关系是程序分析的核心。从安全审计角度看:

  • 找到所有调用 Runtime.exec 的位置 → 命令注入入口
  • 找到所有调用 Cipher.getInstance("DES") 的位置 → 弱加密风险定位
  • 修一个 API 时确认所有上游调用都更新了

这是 YASA 跨仓审计的基础能力之一,本任务先做单仓库版,后续可扩展跨仓。

输入参数

参数 类型 必填 说明
method_full_name string 是 被调方法全限定名
parameter_types string[] 否 形参类型,重载消歧
repository_path string 是 仓库本地绝对路径
include_test_code bool 否 默认 false
include_inherited_callers bool 否 默认 true。true 时:调用方法的实际类型是子类,但目标解析到父类方法也算上
max_results int 否 默认 200

输出结构

{
  "target_method": "com.example.dao.UserDao.findById",
  "total_callers": 12,
  "callers": [
    {
      "caller_method_full_name": "com.example.service.UserService.getUserOrThrow",
      "file_path": "src/main/java/com/example/service/UserService.java",
      "line_number": 47,
      "call_expression_snippet": "User user = userDao.findById(id);",
      "caller_class": "com.example.service.UserService",
      "is_test_code": false
    }
  ]
}

验收标准

  • 正确解析以下调用形式:
    • 普通实例调用 obj.method(...)
    • 静态调用 Cls.method(...)
    • 链式调用 a.b().method(...)
    • 方法引用 Foo::method
    • 通过接口/父类调用(由 include_inherited_callers 控制)
  • 跳过注释、字符串内的伪命中
  • 单元测试覆盖:静态/实例/方法引用/链式/匿名类内调用
  • 中等仓库(~5k Java 文件)响应 < 10s
  • 必要时建立调用图索引(可作为后续上游链路工具的底座)

预估工作量

7-10 人日(团队协作:索引构建 + 类型解析 + 调用点提取分头做)

Activity

  1. wryyyds7 commented on Jul 30, 2026

    @wryyyds7

    I can try it.

  2. wryyyds7 commented on Jul 30, 2026

    @wryyyds7

    Claiming #139. Implementing find_callers_by_method_name with a three-step architecture: (1) Index building — scan all Java files to build method_index (method FQN → info) and class_index (class FQN → extends/implements/all_parents), reusing #137 method extraction and #138 class metadata; (2) Call site extraction — regex search for receiver.methodName( and Receiver::methodName patterns, skip method declarations and comments; (3) Type resolution — infer receiver type from field declarations, method parameters, local variables, import map, and class index. Supports instance/static calls, method references, include_inherited_callers (expand to parent/child class methods), include_test_code filter, and max_results truncation. Test data: java-design-patterns (~1900 files, < 10s).

  3. wryyyds7 commented on Jul 30, 2026

    @wryyyds7

    Update: Implementation progress for find_callers_by_method_name (#139)

    Summary

    Implemented find_callers_by_method_name as an MCP tool that finds all call sites of a Java method by its fully qualified name, using a three-step architecture (index building → call site extraction → type resolution).

    Three-step architecture

    Step Function What it does
    1. Index building _build_method_index() Scan all Java files, build method_index (method FQN → info) + class_index (class FQN → extends/implements/all_parents)
    2. Call site extraction _find_call_sites() Regex search for receiver.methodName( and Receiver::methodName, skip declarations and comments
    3. Type resolution _resolve_receiver_type() Infer receiver type from field/param/local var declarations + import map

    Call form support

    Form Pattern Status
    Instance call obj.method() (\w+)\.methodName\( PASS
    Static call Cls.method() same regex, receiver uppercase PASS
    Method reference Foo::method (\w+)::methodName PASS
    Chained call a.b().method() matches .method(, receiver type not resolved (loose match) PASS (loose)
    Interface/parent call include_inherited_callers expands target method set PASS

    Type resolution priority

    1. this → current class
    2. super → parent class
    3. Uppercase receiver → class name (check import map / class_index)
    4. Lowercase receiver → variable name (check method params → field declarations → local variables)
    5. Unknown → loose match (accept as candidate)

    Verification

    Criterion Status Result
    Instance call PASS userDao.findById(id) found
    Static call PASS UserDao.getInstance() found
    Method reference PASS userDao::findById found
    Comment filtering PASS Comments/strings not matched
    Test code filter PASS include_test_code=false skips test files
    max_results PASS Truncation works
    Medium repo < 10s PASS JDP (1900 files): 3.87s

    Test coverage

    Category Tests
    Basic callers 4 (instance call, snippet, caller class, line number)
    Comment filtering 1 (comments + strings not matched)
    Method reference 1 (:: pattern)
    Switches 3 (test code filter, max_results)
    Edge cases 3 (not found, empty name, invalid repo)
    MCP registration 1
    Integration (JDP) 2 (find callers, performance < 10s)

    PR

    #156

  4. added 5 commits that reference this issue on Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

OSS26-TeamOSS26 需要团队协作的复杂任务

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions