有没有办法在 gradle 中进行源到源的 Java 重构



我得到了一些自动生成的Java代码。我愿意在编译之前自动重构。它主要是类重命名和包修改。

是否有任何 gradle 或 ant 任务可用于此?

我得到了一些自动生成的java代码,我想 在编译之前自动重构。它主要是类重命名 和包修改。

[题外话:你应该修复生成代码的代码。自动生成代码,然后使用其他工具对其进行修改看起来不像正确的方法。

Eclipse 提供了可以在程序中使用的重构 API(没有 eclipse)。原始工具是JDT(我用过它),我想新的解决方案是LTK - 没有尝试过。

如果您尝试控制xjc生成的包和类名,则可以提供外部绑定文件。

你会这样说:

<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:bindings schemaLocation="your.xsd" node="/xs:schema">
<jxb:schemaBindings>
<jxb:package name="the.package.name.you.want" />
</jxb:schemaBindings>
</jxb:bindings>
</jxb:bindings>

对于要自定义的每个类名,您将具有:

<jxb:bindings node="//xs:complexType[@name='UglyTypeName']">
<jxb:class name="MyNiceClass"/>
</jxb:bindings>

例如,将其保存到bindings.xjb文件中,然后像这样运行xjc

xjc your.xsd -b bindings.xjb

正如你所说,你使用"xjc"来生成代码,你想要"主要是类重命名和包修改",也许一些"xjc"选项可以做你想要的:

-p <pkg>           :  specifies the target package
-b <file/dir>      :  specify external bindings files (each <file> must have its own -b)
If a directory is given, **/*.xjb is searched

使用"-p",您可以定义生成的代码应属于的目标包。有关使用绑定选项,请查看此处以获取更多信息 http://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/2.0/tutorial/doc/JAXBUsing4.html

编辑另一种方法是:将生成的文件移动到所需的目录中,然后使用替换插件替换复制的源文件中的包规范

<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>the.directory.for.the.classes.to.move.to</outputDirectory>
<resources>
<resource>
<directory>the.directory.of.ajc.classes</directory>
... do here the appropriate settings ...
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.2</version>
<executions>
<execution>
<phase>process-sources</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
<include>**/src/main/gen/**/**.java</include>
</includes>
<token>^package the.one.you.want.to.replace</token>
<value>package you.want.the.classes.to.be</value>
<regexFlags>
<regexFlag>MULTILINE</regexFlag>
</regexFlags>
</configuration>
</plugin>

你想要的是一个程序转换系统(PTS)。

PTS 读取源代码,构建程序表示(通常是抽象语法树或 AST),将转换(通常以"如果您看到这个,请用那个"目标语言"表面"语法替换它)应用于树,并且可以从修改后的 AST 重新生成有效的源文本(通常是漂亮的打印)。 示例表面语法可以按字面意思编写如下(语法因系统而异):

x ** 2 ==>  x * x

通常需要一组由元程序控制的协同工作的转换规则来实现更复杂的结果。 元程序的编写方式在 PTS 中存在根本性差异。

您通常必须配置 PTS 来解析/美化所选的目标语言。 Stratego,TXL和DMS(我的工具)都已经有Java解析器/漂亮的打印机,并且都有表面语法重写。 如果选择 PTS,您将生成源代码,然后启动一个进程来运行该工具,使用您提供的一组转换和相应的元程序来实现所需的特定代码更改。 我相信,Stratego有一个Java实现,你可以把它集成到你的应用程序中,避免单独的过程。

复杂的是,要执行的转换通常需要名称解析、类型信息或对代码中数据流的一些了解。 Stratego 和 TXL 没有内置此信息,因此您必须通过编写其他转换来按需计算它;这实际上有点困难,因为语言语义很复杂。 我们的工具DMS已经为Java完成了这些功能,但在数据流上有一些不完整。

如果您的问题实际上只是名称替换,并且名称在生成的代码中是唯一的,那么您可能会摆脱以下转换:

uniquename1 ==> replacementpath1

例如

foo.bar ==>  baz.bar.foo

(如果这真的足够了,您可能会只使用文本字符串替换而不是 PTS。我职业生涯的大部分时间都花在发现没有什么像我希望的那样简单)。

Eclipse的JDT可能是一个替代方案。它当然有一个解析器,但没有表面语法转换,所以它不是真正的 PTS)。 相反,转换是在 Java 中通过上下移动并使用 JDT API 进行更改来编码的,因此这有点痛苦。 AFAIK,如果我理解它,它提供对名称信息的访问,但不提供对表达式类型的访问,并且对数据流没有特定的支持。 我知道将其与 Eclipse 隔离以用作模块并不容易;扬子晚报.

曾经有一个名为Spoon的独立工具,它提供Java解析,全名和类型解析,但具有过程树修改。 我不知道是否跟踪了Java的现代方言(例如,1.5及以上的模板)。

有一个名为 Spoon 的工具。此项目是开源的,使您能够使用源到源的方法转换和分析 Java 源代码。它提供了一个完整而细粒度的Java元模型,其中可以访问任何程序元素(类,方法,字段,语句,表达式...)以进行读取和修改。

您可以在其网站上获得有关它的更多信息:http://spoon.gforge.inria.fr/。

要使用 Gradle 运行 spoon,您可以在项目上插入一个插件并在其上应用 Spoon。要使用它,请克隆此项目 (https://github.com/SpoonLabs/spoon-gradle-plugin) 并将插件安装到本地存储库 (./gradlew install)。之后,您可以将其插入到您的项目中,该插件的文档(https://github.com/SpoonLabs/spoon-gradle-plugin#basic-usage)中如何解释。

我希望这可以帮助任何对java转换源代码感兴趣的新开发人员! :)

你可以在使用 proguard 编译后执行此操作。有一个渐进的任务。

最新更新