2011-04-21 163 views
4

我正在寻找一种方法,根据类中定义的字段自动生成现有Java源代码文件中的新方法的源代码。自动生成Java源代码

从本质上说,我期待执行下列步骤:通过源代码中定义的所有字段

  1. 读取并解析SomeClass.java
  2. 迭代
  3. 添加源代码方法someMethod()
  4. 保存SomeClass.java(理想情况下,保留现有代码的格式)

什么工具和技术最适合完成这个工作?

编辑

我不想在运行时生成的代码;我想扩充现有的Java 源代码

+0

或者,您可以编写一个更好的界面。代码生成是非常少见的,因为大部分时间它可以被更好的界面取代。例如,你可以让'SomeClass.java'实现一个提供'someMethod()'的接口,或者你可以扩展一个抽象类,从而为你提供所需的'someMethod()'实现。如果'someMethod()'在任何地方都是一样的,那么你也可以添加一个独立的接口和实现,以便在你希望能够使用它的任何地方使用它。 – ThePyroEagle 2016-05-01 14:58:10

回答

2

使用自动生成的代码修改相同的java源文件是维护的噩梦。考虑生成一个新的类来扩展你当前的类并添加所需的方法。使用反射从用户定义的类中读取并为自动生成的类创建速度模板。然后为每个用户定义的类生成其扩展类。在您的构建生命周期中集成代码生成阶段。

或者您可以使用'字节码增强'技术来增强类而不必修改源代码。

更新:

  1. 混合自动生成的代码总是有人提出将来修改它只是调整一个小行为的风险。这只是下一次构建的问题,当这种变化将会丢失。
  2. 您将不得不完全依靠自动生成源代码的评论来阻止开发人员这样做。
  3. 版本控制 - 假设您更新someMethod()的模板,现在所有源文件的版本都会更新,即使源更新是自动生成的。你会看到多余的历史。
+2

谢谢。我的想法是,注入自动生成的代码比字节码增强的“隐形魔术”更清晰,更易维护,但我会对我提议的方法的可维护性的具体问题感到好奇 – 2011-04-21 15:04:51

+0

我把它作为一个新问题提出:http ://stackoverflow.com/questions/5746099/automatic-source-code-generation-good-idea-or-potential-nightmare – 2011-04-21 15:17:06

2

您可以使用cglib在运行时生成代码。

+0

+1:和Objectweb ASM – 2011-04-21 14:51:44

+0

谢谢,但寻找*源代码*代 – 2011-04-21 14:55:56

1

遍历字段并定义someMethod是一个非常模糊的问题陈述,所以很难给你一个非常有用的答案,但是Eclipse的重构支持提供了一些优秀的工具。它会给你构造函数初始化一组选定的成员,它也会为你定义一个toString方法。

我不知道其他someMethod()是你想要考虑的,但是有一个开始。

4

看一看Java发射模板。它们允许您使用标记语言创建Java源文件。这与您如何使用脚本语言来吐出HTML除非您吐出可编译的源代码类似。 JET的语法与JSP非常相似,因此不太难处理。然而,这可能是你想要完成的事情的矫枉过正。这里有一些资源,如果你决定走这条路:

1

我会非常谨慎的注入生成的代码转换成包含手写代码的文件。应该将手写代码检入到版本控制中,但生成的代码不应该是;代码生成应作为构建过程的一部分来完成。您必须构建构建过程,以便为每个文件创建一个临时副本,将生成的源代码注入其中,并编译结果,而不触及开发人员处理的原始源文件。

+0

谢谢!我正在寻找为模型类生成持久性代码,只有在类代码本身发生更改时才会更改。 (不幸的是,在Java中没有'partial'类) – 2011-04-21 15:36:18

+0

@Jen,它是否有意义使用反射,可能通过模型​​类上的注释指导,而不是实际修改每个需要被持久化的类? – Wyzard 2011-04-21 15:40:35

+1

是的,这也是一种有效的方法,但我正在寻找a)更高的性能和b)更高的代码清晰度(我的想法是,通过阅读生成的代码比解决问题更容易了解发生的事情不同的约定/注释) – 2011-04-21 15:44:53

11

你想要的是一个Program Transformation系统。

好的分析器为您所关心的语言提供解析器,构建代表解析代码的程序的AST代码,为您提供对AST进行分析和修改的权限,并且可以从AST中重新生成源代码文本。你关于“扫描字段”的评论只是代表程序的AST的一种遍历。对于你产生的每一个有趣的分析结果,你想要改变AST,也许在其他地方,但在AST中。 当所有的chagnes都被创建后,您想要使用注释重新生成文本(如最初输入的那样,或者如您在新代码中构建的那样)。

有几种工具可以专门用于Java。

Jackpot提供了一个解析器,构建AST,并让您编写Java过程来完成您想要的树。上行:概念上简单。下行:你写了更多的Java代码来绕过/砍树,比你想象的要多。积宝只适用于Java。

StrategoTXL解析代码,构建AST,并让您编写“surce-to-source”转换(使用目标语言的语法,例如本例中的Java)来表示模式和修复。额外的好消息是:您可以将任何您喜欢的编程语言定义为要处理的目标语言,并且这两种语言都具有Java定义。但它们在分析上很薄弱:通常你需要符号表和数据流分析来真正做出你需要的分析和改变。他们坚持认为的一切是一个重写规则,无论是否帮助你;这有点像坚持你只需要一把工具箱中的锤子;毕竟,一切都可以像一个钉子对待,对吗?

我们DMS Software Reengineering Toolkit允许abitrary目标语言的定义(并且具有many predefined langauges including Java),包括西洋陆军棋,TXL,累积奖金, 的程序能力的所有的源极 - 到 - 源极转换功能,并且另外提供了符号表,控制和数据流分析信息。编译器的家伙告诉我们,这些东西是必要的,建立强大的编译器(=“分析+优化+精”),它是代码生成系统来说也是一样。对于完全相同的原因。使用这种方法,您可以生成代码并在您已掌握知识的情况下对其进行优化。一个例子,类似的系列化的想法,是产生特定XML DTD的快速XML读者和作家;我们已经使用DMS for Java和COBOL完成了这项工作。

DMS已用于读取/修改/写入多种源文件。在这篇技术文章中,可以找到一个很好的例子,可以让你明白这个想法,该文章展示了如何修改代码以插入仪表探针:Branch Coverage Made Easy。 使用相同的想法可以在How to transform Algebra找到一个更简单但更完整的例子,定义一个适用于它的任意颜色和变换。

1

Antlr真的是一个非常好的工具,可以非常方便地将Java源代码转换为Java源代码。