背景
近期接到一个O,想要做一个工具,这个工具可以在客户端的代码上做静态的精准插桩,需要一个方案。
这里我们不对“精准”设计方案,后续再聊这个事情,先简要叙述静态插桩的思路。
如果想对代码静态插装,咱们首先要获取对应代码的AST(对于客户端来说这是一个麻烦事)......
麻烦的点
Android一般开发语言为Java,Kotlin(一开始想只写java,但是发现kt再新增的代码里占比较大)
IOS一般为OC,Swift
我们需要一个工具,对这四种代码一起进行插桩(真的很蛋疼)。。。
Java有JavaParser,kt也有很多,oc和swift也有很多工具。。。
2*2=4,这就是说我需要学四种Api(工作量起飞。。。)
方案
最后想了想,Java用JavaParser(因为够熟悉),kt,oc,swift都用Antlr4。
这样安排的原因是因为,这样我只用熟悉一套antlr的接口就可以用相同的思路做很多事情,并且我也不要写
很多g4文件直接抄就行。
恶心的点
有了思路,那么我们开始搭架子。
关于这个我很痛心,因为坑很多,并且其实很多业务开发人员并不熟悉如何搭架子,接入一个陌生的很少有人用
的plugin...也没人指导,同时这个plugin有很多坑...
结果
我先直接上代码结果图,然后描述流程...
<build>
<plugins>
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>4.8-1</version>
<executions>
<execution>
<id>antlr-kt</id>
<goals>
<goal>antlr4</goal>
</goals>
<configuration>
<arguments>
<argument>-package</argument>
<argument>antlr.kt</argument>
<argument>-o</argument>
<argument>src/main/java/antlr/kt</argument>
</arguments>
<sourceDirectory>
src/main/resources/antlr/grammar/kt
</sourceDirectory>
<listener>true</listener>
<visitor>true</visitor>
</configuration>
</execution>
<execution>
<id>antlr-oc</id>
<goals>
<goal>antlr4</goal>
</goals>
<configuration>
<arguments>
<argument>-package</argument>
<argument>antlr.oc</argument>
<argument>-o</argument>
<argument>src/main/java/antlr/oc</argument>
</arguments>
<sourceDirectory>
src/main/resources/antlr/grammar/oc
</sourceDirectory>
<listener>true</listener>
<visitor>true</visitor>
</configuration>
</execution>
<execution>
<id>antlr-swift5</id>
<goals>
<goal>antlr4</goal>
</goals>
<configuration>
<arguments>
<argument>-package</argument>
<argument>antlr.swift5</argument>
<argument>-o</argument>
<argument>src/main/java/antlr/swift5</argument>
</arguments>
<sourceDirectory>
src/main/resources/antlr/grammar/swift5
</sourceDirectory>
<listener>true</listener>
<visitor>true</visitor>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
流程注意点
pom参数片段和@Header
!!!注意!!!一定在argument里写package入参!!!,不要在.g4里用@header,这样会跑偏,出现can‘write file的error(定位半天发现这个插件拼了一个奇奇怪怪的写入路径,但是使用arguement注入就没问题了),写完pom文件之后,install一下就会发现生成对应的base-class了。
有些类没有自动生成
- 第一种pom引入antlr4的runtime包就解决了。
- 第二种你在抄.g4文件的过程中,会发现有些文件夹叫java进去cv一下(关于这个我就很纳闷)...为啥不自动生成...
结语
慢慢研究,越是这样的时候越是长本事的时候...有问题的时候希望大家一起探讨...
后续会逐步更新关于精准插桩“精准”这个点的设计思路...
真心希望大佬们来指教!!!
本人VX:dr-ac19981002