在Scala中使用SBT工具链时,是否可以编写一个任务来读取项目源代码的特殊部分,以便在编译时生成scala代码。使用Scala代码生成
任何想法,甚至文章/教程呢?我正在寻找类似于模板哈斯克尔的东西。
在Scala中使用SBT工具链时,是否可以编写一个任务来读取项目源代码的特殊部分,以便在编译时生成scala代码。使用Scala代码生成
任何想法,甚至文章/教程呢?我正在寻找类似于模板哈斯克尔的东西。
treehugger.scala是设计用于代码生成的库。
import treehugger.forest._
import definitions._
import treehuggerDSL._
val tree: Tree = Predef_println APPLY LIT("Hello, world!")
println(tree)
println(treeToString(tree))
上面代码打印两行:
Apply(Ident(println),List(Literal(Constant(Hello, world!))))
println("Hello, world!")
treehugger不会产生AST,但非符合scalac的AST。
Scala 2.10为宏提供了实验性的支持,这些宏同样也是复杂的编译时代码生成。有关更多详细信息,请参阅here。
有贾森Zaugg的的macrocosm Git仓库中一些有趣的例子,在LINQ样的方式来表达的SLICK库,是ScalaQuery SQL DSL实现类型安全的数据库(和收集)查询的演变。
而这个示例中,从断言expecty库:
import org.expecty.Expecty
case class Person(name: String = "Fred", age: Int = 42) {
def say(words: String*) = words.mkString(" ")
}
val person = Person()
val expect = new Expecty()
...
val word1 = "ping"
val word2 = "pong"
expect {
person.say(word1, word2) == "pong pong"
}
产量:
java.lang.AssertionError:
person.say(word1, word2) == "pong pong"
| | | | |
| | ping pong false
| ping pong
Person(Fred,42)
他们什么时候有望成为一个完整的功能? – Lanbo 2012-07-09 18:21:13
我相信编译器开发团队正在2.10试用它们,看看社区发现它们有多么有用。目前的想法(就在我几个星期前阅读内部邮件列表的最后一次)是,他们仍然没有把它们视为试验性的可能性。但是,如果社区支持非常积极,我想他们会被采纳。虽然这个网站上还有其他人可能会给你一个更明确的答案。 – 2012-07-09 18:26:14
它们看起来非常像Template Haskell,并且被广泛使用。尽管很多情况下Scala可以在没有这个的情况下很好地服务(比如复杂类的自动扩展)。但为了我的目的,在编译前预处理资产,这是合适的。 – Lanbo 2012-07-09 18:29:41
是的,这是可能的。我很确定有插件可以做到这一点。你看过现有插件列表吗? – 2012-07-09 20:17:38