使用Scala生成代码

Lan*_*nbo 13 code-generation scala template-haskell

在Scala中使用SBT工具链时,是否可以编写一个任务来读取项目源的特殊部分,以便在编译时生成scala-code.

关于这个的任何想法甚至文章/教程?我正在寻找与Template Haskell相似的东西.

Eug*_*ota 13

treehugger.scala是一个专为代码生成而设计的库.

import treehugger.forest._
import definitions._
import treehuggerDSL._

val tree: Tree = Predef_println APPLY LIT("Hello, world!")

println(tree)
println(treeToString(tree))
Run Code Online (Sandbox Code Playgroud)

上面的代码打印两行:

Apply(Ident(println),List(Literal(Constant(Hello, world!))))
println("Hello, world!")
Run Code Online (Sandbox Code Playgroud)

treehugger会生成AST,但不符合scalac的AST.

  • 只是为了澄清:treehugger =源代码生成; 宏= AST生成.前者是低技术,实际上可以是一个优势:) (5认同)

Ale*_*son 7

Scala 2.10具有对宏的实验性支持,类似于复杂的编译时代码生成.请参阅此处了解更多详情.

有贾森Zaugg的的一些有趣的例子宏观 git仓库,以及SLICK库,是ScalaQuery SQL DSL实现类型安全的数据库(和收集)查询的演变在LINQ样的方式来表达.

这个例子来自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"
}
Run Code Online (Sandbox Code Playgroud)

产量:

java.lang.AssertionError:

person.say(word1, word2) == "pong pong"
|      |   |      |      |
|      |   ping   pong   false
|      ping pong
Person(Fred,42)
Run Code Online (Sandbox Code Playgroud)


小智 5

我最近做了一些研究.几乎有3种选择:

  1. 字符串模板.
  2. 环境保护狂
  3. Scala Macros

更多细节在这里:http://yefremov.net/blog/scala-code-generation/