编写指代代码生成器,该代码生成器指的是现有的Java类



我正在尝试评估不同的方法,以在构建项目时从特定于域的语言中自动生成的Java项目中的某些代码。过去,我已经手动编写了一个或两个代码生成器,但是我没有现有代码生成框架的经验。我们尚未决定是使用这种框架还是手工构建发电机。

我需要一个概念问题的帮助;我想了解如何构建代码生成器,这使DSL可以参考现有(手写的)Java类,方法和字段。应该可以参考与生成的Java类中相同的编译单元(例如Maven项目)中的类。这意味着在运行代码生成器之前无法编译这些手写类,并且代码生成器除了在 classpath上所需的所有内容以外的所有内容以外,必须查看Java源文件用于编译这些类。

现有框架如何处理此类情况(如果有的话)?他们是自己解析Java源文件还是重新使用Java编译器的某些机器?

我认为,如果允许其自己的代码来引用同一汇编单元中的任何(非动态)非Java语言(非动态)非Java语言,则它是同一问题。看这些编译器的工作方式也许很有帮助,除非它们本身还包括Java编译器,除非它们绕过javac

有多种原因为什么代码生成器需要访问同一汇编单元的Java文件中的类:

  • 我想提供与Java类似的语义,我可以在这里使用import <package>.*,然后使用这些类的名称,而无需完全限定每个类的名称。
  • 如果它指的是不存在或不符合某些必需条件的符号,我想拒绝代码。
  • 在某些情况下,我要生成取决于类的成员或方法签名的代码。一个示例是自动生成装饰器或构建器或实现接口,而在代码生成器不会生成基类或接口的情况下。
  • 我可能想使用生成代码中引用的符号的类型信息。例如根据方法的签名生成不同的代码。

我们的项目使用Maven。我对解决这些问题的一般方法感兴趣,但是非常感谢适用于Maven的信息或示例。

如何使用DSL扩展Java,该DSL允许DSL编译器参考外部Java元素(类,方法,字段)?

实际上不清楚您在问什么,此外,这个问题比编程更重要。

无论如何,从我自己的DSL实现的经验来看,使用java classloaders可以动态访问新生成和编译的Java类。另外,如果您使用的是maven,则必须将带有生产范围的所有依赖项加载到Main Class Loader中,并可以使用reflection加载它们。

这是一些有用的链接:

  • http://www.javaworld.com/article/2077260/learn-java/the-basics-of-java-class-loaders.html
  • http://tutorials.jenkov.com/java-reflection/dynamic-class-loading-reloading.html
  • http://docs.oracle.com/javase/tutorial/reflect/

不要解析Java程序,而是使用编译的类。参考类可以用不同的语言编写,包括其他DSL-唯一的共同点是类文件格式。

这会导致循环依赖性问题,Java程序是指DSL程序,而DSL程序则引用Java程序。可能的解决方案是:

  • 在将DSL转换为Java时,请勿分析任何其他程序。所有可能的错误都将在编译生成的Java代码

  • 时报告
  • 将引用重定向到公共接口,从而破坏依赖性循环

最新更新