当前位置: 首页 > news >正文

使用 ast-grep 精准匹配指定类的方法调用(以 Java 为例)

使用 ast-grep 精准匹配指定类的方法调用(以 Java 为例)

在代码重构、安全审计或静态分析的场景中,我们常常需要匹配某个特定类中定义的方法调用。而 ast-grep 作为一款基于语法树的代码搜索工具,提供了强大的模式匹配功能,可以帮助我们高效实现这一目标。

本文将以 Java 为例,介绍如何使用 ast-grep 匹配一个给定类的实例所调用的特定方法。我们的问题是:如何只匹配 Class_A 类型对象上调用的 add() 方法,而不误匹配其它类的 add() 方法?

问题示例

考虑下面的 Java 代码片段:

class Class_A {public Class_A(int a, int b) {}public int add() {return this.a + this.b;}
}Class_A aaaa = new Class_A(foo, bar);
Object bbbb = new Object();print(aaaa.add());
bbbb.add();

我们的目标是仅匹配 print(aaaa.add());,而不匹配 bbbb.add();,因为后者并非调用 Class_A 的方法。


ast-grep 基础规则回顾

在 ast-grep 中,我们可以使用 YAML 编写规则,对语法结构进行匹配。例如:

rule:pattern: $VARNAME.add()

但这会匹配所有调用 add() 的代码行,无论对象是哪个类的实例。


加入上下文约束:inside + has

为了解决这个问题,我们需要添加上下文限制:

  • 目标调用必须出现在一个作用域中
  • 该作用域中要有对象是由 Class_A 创建的

完整规则如下:

rule:pattern: $VARNAME.add()inside:pattern: $DBstopBy: endhas:pattern: $TY $VARNAME = new Class_A($$$CARGS)

解释:

  • pattern: $VARNAME.add():匹配任何调用 add() 方法的表达式,并将调用对象赋值给 $VARNAME
  • inside: pattern: $DB:该调用要出现在某个作用域(例如代码块)中
  • has: pattern: $TY $VARNAME = new Class_A(...):这个作用域中,必须有 $VARNAME 是通过 new Class_A(...) 初始化的
  • stopBy: end:防止向上搜索超出当前代码块

实际效果

应用该规则后:

  • ✅ 匹配到:print(aaaa.add());
  • ❌ 不匹配:bbbb.add();(因为 bbbbObject 类型)

小结与提示

通过 ast-grep 的 YAML 配置语言,我们可以实现复杂的语法结构匹配,而不仅仅是文本替换。

如果你也有类似的需求,比如:

  • 只匹配某个类的构造函数
  • 检查 API 使用是否符合约定
  • 对某一类实例调用方法进行重构或审计

那么不妨尝试用 pattern + inside + has 的组合方式,实现精确的匹配。


延伸阅读

  • 官方文档:https://ast-grep.github.io/
  • 规则配置指南:https://ast-grep.github.io/guide/rule-config.html

欢迎在评论区分享你对 ast-grep 的使用经验和问题,一起交流更高效的代码分析技巧!


想要深入讨论?我正在「不宽也不深」和朋友们讨论有趣的话题,你⼀起来吧?
https://t.zsxq.com/oFMwJ

http://www.dtcms.com/a/322215.html

相关文章:

  • [GESP2023012 五级] 2023年12月GESP C++五级上机题题解,附带讲解视频!
  • 95、【OS】【Nuttx】【构建】cmake 配置实操
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘transformers’问题
  • FreeRTOS---基础知识5
  • Dixon‘s 因子分解法——C语言实现
  • KLA/TENCOR ALTAIR 8900
  • [Shell编程] Shell 循环结构入门
  • VMware使用NAT模式,使本机与虚拟机在不同的网络,并且虚拟机可以上网
  • 洛谷 P1433 吃奶酪-普及+/提高
  • 嵌入式第二十三课 !!!树结构与排序(时间复杂度)
  • 浅试A2A
  • 01数据结构-图的概念和图的存储结构
  • PCA多变量离群点检测:Hotelling‘s T2与SPE方法原理及应用指南
  • ABP VNext + Fody AOP:编译期织入与性能监控
  • 嵌入式学习 day47 LED
  • ctfshow_萌新web9-web15-----rce
  • AJAX与axios框架
  • Vuex 数据共享
  • v-model双向绑定指令
  • Overleaf单栏双栏排版技巧
  • MWORKS 2025b:里程碑升级,Sysblock全栈替代,开启AI4MWORKS智能工程
  • F I R S T Q U A R T E R 2 0 2 5 - - M a y 2 2 2 0 2 5
  • 什么是Serverless(无服务器架构)
  • 数据结构---二叉树(概念、特点、分类、特性、读取顺序、例题)、gdb调试指令、时间复杂度(概念、大O符号法、分类)
  • Qwen Agent 入门介绍与简单使用示例
  • 基于STM32单片机的OneNet物联网环境检测系统
  • Vue 路由跳转
  • Vue3生命周期
  • ZK首次连接失败,第二次连接成功的问题解决方案
  • AI入门学习--如何对RAG测试