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

相关文章:

  • V4L2摄像头采集 + WiFi实时传输实战全流程
  • 汇编语言和高级语言的差异
  • 【从0到1制作一块STM32开发板】6. PCB布线--信号部分
  • 【ESP32-menuconfig(1) -- Build Type及Bootloader config】
  • FreeRTOS入门知识(初识RTOS)(一)
  • WinForm 实战 (进度条):用 ProgressBar+Timer 打造动态进度展示功能
  • BBH详解:面向大模型的高阶推理评估基准与数据集分析
  • TyDi QA:面向语言类型多样性的信息检索问答基准
  • 柠檬笔试——野猪骑士
  • Python的七大框架对比分析
  • 若依前后端分离版学习笔记(七)—— Mybatis,分页,数据源的配置及使用
  • Day01 项目概述,环境搭建
  • 【代码随想录day 14】 力扣 104.二叉树的最大深度
  • 【Nginx基础①】 | VS Code Remote SSH 环境下的静态资源与反向代理配置实践
  • 防御保护09
  • 【Unity3D实例-功能-跳跃】角色跳跃
  • 文件结构树的├、└、─ 符号
  • 机器学习及其KNN算法
  • 力扣 hot100 Day69
  • ISL9V3040D3ST-F085C一款安森美 ON生产的汽车点火IGBT模块,绝缘栅双极型晶体管ISL9V3040D3ST汽车点火电路中的线圈驱动器
  • P1044 [NOIP 2003 普及组] 栈
  • 项目一系列-第4章 在线接口文档 代码模板改造
  • day070-Jenkins自动化与部署java、前端代码
  • 深入解析K-means聚类:从原理到调优实战
  • 第七章:数据持久化 —— `chrome.storage` 的记忆魔法
  • Netty-Rest搭建笔记
  • 【感知机】感知机(perceptron)学习算法例题及详解
  • 在 Elasticsearch/Kibana (ELK Stack) 中搜索包含竖线 (|)​​ 这类特殊字符的日志消息 (msg 字段) ​确实需要转义
  • 基于LLM的Chat应用测试方法探索:系统化评估与持续优化
  • java分布式定时任务