TL; DR
我正在寻找javac
插件API,它允许我记录Java编译器为特定源文件所需的所有类。
更多背景信息:
我正在编写一个工具,可以从Maven
迁移到Bazel
,其中一个挑战(和机遇)允许Bazel
允许,并从中获得更精细的粒度“模块”。另外,依赖关系对于编译类路径是不可传递的。
我正在尝试构建代码的依赖关系图,并在源代码上使用字节码和启发式方法(对于常量,导入等)但是偶然发现了我担心的边缘情况,只能是通过使用编译器插件解决。
鉴于类Foo
中的方法Concrete
接受扩展SomeInterface
的接口ParentInterface
,javac
同时需要SomeInterface
和{{}虽然ParentInterface
没有出现在字节码或源代码中,但在编译类路径中却没有出现。
这在ParentInterface
中得到解决,因为依赖关系 相对于编译类路径是传递的,但是我想避免这种情况,因为这大大扩展了类路径(主要是关于源的有趣)依赖性和构建触发)。
我正在尝试查看是否可以使用compiler plugins来识别编译器对给定源文件所需的所有类。这将对我有所帮助,因为我可以运行我的maven构建一次以收集信息,然后根据此信息生成图表。问题是我对API有点失落。
谢谢!
答案 0 :(得分:0)
那么,编译所需的类是传递的问题。所以,除非你在同一个模块中提取所有这些,否则无法在非传递依赖系统上映射它。
你最终得到的是一个图,其中节点是类,A和B之间的边描绘了A在B中使用。现在每个可以从A到达的类需要处于A的依赖关系。你应该能够将模块构建为连接的子图。
因此,对于您的示例,在分析Concrete之后,您将分析SomeInterface,然后分析ParentInterface。您可以随意构建直接依赖关系图,并自己计算传递依赖关系。
当您自己解决传递性时,除了字节码分析(例如通过ASM)之外,无需执行任何操作来查找所需的类。在编译中将丢失的唯一依赖是未使用的导入,可以将其删除(并且许多java样式指南甚至说它必须被删除)。
PS:在不知道bazel的情况下,这听起来像是在为小模块做出贡献。