我如何在 Ceylon 中编写代码生成器
How can I write a code generator in Ceylon
我想编写一个代码生成器,根据另一个锡兰 class 的元模型生成一个 class。我希望代码生成器在编译时 运行。对我来说最好的方法是什么。我可能可以通过为 gradle 或锡兰构建系统编写一个插件来实现这一点,但我希望有一个更简单的解决方案。不幸的是,我在锡兰没有看到任何对代码生成器的支持。另外,锡兰有代码生成器的计划吗?
我想编写这个代码生成器,因为我正在考虑为 Ceylon 编写一个简单的 Web 框架,它使用元模型查看 class 如下所示:
控制器
shared class Controller() {
shared void doSomething() => print("did it!");
}
我打算让它像 Spring MVC。该框架将从控制器 class 生成一个 restful API,允许某人像这样编写一个 AJAX 调用:
$http.get("/Controller/doSomething");
我想通过 GWT 之类的东西让事情变得更方便、更高级、更简单。我想创建一个自动生成 class 的代码生成器,如下所示:
shared class RemoteController() {
shared void doSomething() {
$http.get("/Controller/doSomething");
}
}
RemoteController 在用户浏览器中将 运行 作为 javaScript 并允许客户端 Ceylon 代码执行这样的 Ajax 调用:
RemoteController().doSomething();
这最终会在服务器上调用 Controller().doSomething() 以便打印 "did it!"。
AST Transformers已被提出,但仍处于早期设计阶段。现在,要进行编译时代码生成,您必须自己组装一些东西。
要实际生成代码,我建议使用 ceylon.ast
and ceylon.formatter
。工作流程大致是:
- 分析源代码 –
- 要么用
ceylon.ast
(ceylon.ast.redhat::compileAnyCompilationUnit
) 解析它,然后在不进行类型检查的情况下分析它,
- 或使用编译器解析它,运行类型检查器,然后将其转换为
ceylon.ast
(ceylon.ast.redhat::anyCompilationUnitToCeylon
),使用新的update hooks保留类型检查器信息即将发布的 1.2.0 版本
- 编辑源代码 AST 以添加新代码(使用将新的 class 定义注入
CompilationUnit
的自定义 ceylon.ast.core::Editor
),或者创建全新的编译单元如果 RemoteController
住在不同的模块中
- 将
ceylon.ast
AST 转换为编译器 AST 并将其输入 ceylon.formatter
以再次将 AST 转换为代码(参见 here 的示例)
或者,如果将其集成到构建步骤中,则可以跳过步骤 3 的 ceylon.formatter
部分,而是将转换后的编译器 AST 直接输入类型检查器和编译器的其余部分。
我想编写一个代码生成器,根据另一个锡兰 class 的元模型生成一个 class。我希望代码生成器在编译时 运行。对我来说最好的方法是什么。我可能可以通过为 gradle 或锡兰构建系统编写一个插件来实现这一点,但我希望有一个更简单的解决方案。不幸的是,我在锡兰没有看到任何对代码生成器的支持。另外,锡兰有代码生成器的计划吗?
我想编写这个代码生成器,因为我正在考虑为 Ceylon 编写一个简单的 Web 框架,它使用元模型查看 class 如下所示: 控制器
shared class Controller() {
shared void doSomething() => print("did it!");
}
我打算让它像 Spring MVC。该框架将从控制器 class 生成一个 restful API,允许某人像这样编写一个 AJAX 调用:
$http.get("/Controller/doSomething");
我想通过 GWT 之类的东西让事情变得更方便、更高级、更简单。我想创建一个自动生成 class 的代码生成器,如下所示:
shared class RemoteController() {
shared void doSomething() {
$http.get("/Controller/doSomething");
}
}
RemoteController 在用户浏览器中将 运行 作为 javaScript 并允许客户端 Ceylon 代码执行这样的 Ajax 调用:
RemoteController().doSomething();
这最终会在服务器上调用 Controller().doSomething() 以便打印 "did it!"。
AST Transformers已被提出,但仍处于早期设计阶段。现在,要进行编译时代码生成,您必须自己组装一些东西。
要实际生成代码,我建议使用 ceylon.ast
and ceylon.formatter
。工作流程大致是:
- 分析源代码 –
- 要么用
ceylon.ast
(ceylon.ast.redhat::compileAnyCompilationUnit
) 解析它,然后在不进行类型检查的情况下分析它, - 或使用编译器解析它,运行类型检查器,然后将其转换为
ceylon.ast
(ceylon.ast.redhat::anyCompilationUnitToCeylon
),使用新的update hooks保留类型检查器信息即将发布的 1.2.0 版本
- 要么用
- 编辑源代码 AST 以添加新代码(使用将新的 class 定义注入
CompilationUnit
的自定义ceylon.ast.core::Editor
),或者创建全新的编译单元如果RemoteController
住在不同的模块中 - 将
ceylon.ast
AST 转换为编译器 AST 并将其输入ceylon.formatter
以再次将 AST 转换为代码(参见 here 的示例)
或者,如果将其集成到构建步骤中,则可以跳过步骤 3 的 ceylon.formatter
部分,而是将转换后的编译器 AST 直接输入类型检查器和编译器的其余部分。