最近基于 javaParser ,也算是做了一部分扫描调用链的工作,但是实际用起来的时候,发现回溯上游调用的时候,最终得出来的调用链实际会很多。里面会有一些无关的调用。比如我虽然 A 调用了 B,但是只是某个逻辑判断下才会去调 B,当然这是需要动态执行的时候才知道的。
1、请问大家如何处理这种无关调用的?
2、我也有实现根据差异代码,获取改动方法的调用链,那么如何结合覆盖率数据,去判断这条调用链有覆盖?
3、运行期才出现的、通过反射等方式的调用大家是怎么分析调用的。
1、A 的某个判断里调用了 B,那么为什么是无关调用?这就是 B 的影响面
2、将增量代码扩展至这条调用链里的方法
1、楼主这个回溯上游调用,我理解和 idea 自带的 find usages 其实是类似的方式?如果是,那通过静态分析获取调用关系。这个原理上就无法准确到你例子说的 if else 程度,毕竟并非运行时的话,没人知道是否走到调用 B 的逻辑,那宁滥勿缺,肯定要把这条调用链带上。
2、不知道增量代码覆盖率数据,即直接统计有改动的代码对应行是否又被覆盖,是不是可以满足?或者可以把你这里的 “调用链” 举个具体的代码例子说明下,你的调用链定义具体是什么?从有足够细节的定义去扩展,会比从 “调用链” 这个名字去扩展要方便很多。
第一点的确是这样的
第二点,我的调用链是指的服务入口方法到改动方法的链路。其实这个问题可以换个说法:分析出来的这条链路如何定义它是有被覆盖的。
举个例子,比如说你的增量调用链最后是 B->C->D,你通过覆盖率拿到你测试后的调用链是 A->B->C->D->E->F ,这样不就能理解你的的测试已经覆盖了你的增量链路么? 也就是判断子集的操作
首先,我理解你的链路每个节点,具象到代码层面,应该就是每个函数的入口了吧。那确认链路是否有被覆盖,你得用会记录每个函数入口信息组合的链路跟踪工具(比如一些服务端 APM 工具),记录每个从服务入口进来后的链路。
代码覆盖率工具一般关注的只是是否覆盖这个结果,不关注通过什么链路覆盖这个过程,也不会记录这种信息。
运行期才出现的、通过反射等方式的调用大家是怎么分析调用的。
前面忘了回答,这种原理上就无法通过静态分析来做了,只能通过运行时的动态调用链路记录来做,而且没法保障是否全(没跑到就不会被记录),只能作为补充。
从严格意义上说,这种不能反推调用链就覆盖到了,也可能实际这几个节点是在好几个调用链里分别覆盖到的,不是真的有走过一条直接就是这几个节点的调用链
不过从工程角度,要真的那么细成本很高也很难,做到这个也足够了。
如果加上 asm 对 class 进行遍历 visit 那是可以找到更准确的对应的调用链路。ast 解析后,再通过一些手段拿到 signature,和 asm 的分析组合使用,应该能解决大部分遇到的难题。