当前位置: 首页 > 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.lryc.cn/news/614452.html

相关文章:

  • TDSQL GTS文件说明
  • Mysql与Ooracle 索引失效场景对比
  • 大语言模型提示工程与应用
  • Node.js 》》数据验证 Joi 、express-joi
  • HarmonyOS SDK助力讯飞听见App能力建设
  • node.js 学习笔记2 进程/线程、fs
  • 力扣-56.合并区间
  • 经常问的14000
  • 智能巡检机器人的进化:当传统巡检遇上Deepoc具身智能外拓开发板
  • Visual Studio 2019 + Qt + MySQL 开发调试全过程问题详解
  • Vue 3 表单数据缓存架构设计:从问题到解决方案
  • 前端基础之《Vue(29)—Vue3 路由V4》
  • ADB打印设备日志相关
  • 手机拍照识别中模糊场景准确率↑37%:陌讯动态适配算法实战解析
  • 用LaTeX优化FPGA开发:结合符号计算与Vivado工具链(二)
  • 大模型量化上溢及下溢解析
  • ESP32-menuconfig(4) -- Partition Table
  • Web Worker 性能革命:让浏览器多线程为您的应用加速
  • ChipCamp探索系列 -- 1. Soft-Core RISC-V on FPGA
  • 【10】C#实战篇——C# 调用 C++ dll(C++ 导出函数、C++导出类)
  • 华清远见25072班C语言学习day5
  • Advances and Challenges in Foundation Agents--Memory调研
  • WPF 双击行为实现详解:DoubleClickBehavior 源码分析与实战指南
  • 基于ffmpeg和rk3588的mpp编解码库多路融屏程序设计
  • 贝叶斯定理 vs 条件概率
  • Redis(⑤-线程池隔离)
  • 【从0到1制作一块STM32开发板】6. PCB布线--信号部分
  • React函数组件灵魂搭档:useEffect深度通关指南!
  • 如何实现在多跳UDP传输场景,保证单文件和多文件完整传输的成功率?
  • 三相交流电机旋转磁场产生原理