编写引用现有Java类的代码生成器

时间:2014-01-31 10:05:32

标签: java maven code-generation dsl

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

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

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

我认为这是针对JVM所面临的任何(非动态)非Java语言的相同问题,如果它允许自己的代码在相同的编译单元中引用Java类,反之亦然。也许查看这些编译器的工作原理是有帮助的,除非它们通过自己包含Java编译器来绕过javac

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

  • 我想提供类似于Java的语义,我可以import <package>.*,然后使用这些类的名称而不完全限定每个类的名称。
  • 我想拒绝DSL中的代码,如果它引用了不存在或不符合某些要求标准的符号。
  • 在某些情况下,我希望生成依赖于类成员或方法签名的代码。一个例子是自动生成装饰器或构建器或实现接口,但代码生成器不生成基类或接口。
  • 我可能想在生成代码中使用引用符号的类型信息。例如根据方法的签名生成不同的代码。

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

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

2 个答案:

答案 0 :(得分:0)

实际上不清楚你在问什么,而且这个问题比理论更具理论性。

无论如何,根据我自己的DSL实现经验,使用java classloaders动态访问新生成和编译的java类没有任何问题。此外,如果您使用maven,则必须在主类加载器中加载具有生产范围的所有依赖项,并且可以使用reflection加载它们。

以下是一些有用的链接:

答案 1 :(得分:0)

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

当java程序引用DSL程序并且同时DSL程序引用回java程序时,这会导致循环依赖性问题。可能的解决方案是:

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

  • 重定向对公共接口的引用,从而破坏依赖循环