如何使用Scala宏创建对象?

时间:2015-06-18 21:01:52

标签: scala macros code-generation

我正在尝试创建一个生成对象的Scala宏 - 类似于

object SomeEnum {
  sealed abstract class Enum(name: String)
  case object Option1 extends Enum("option1")
  case object Option2 extends Enum("option2")
  private val elements: Seq[Enum] = Seq(Option1, Option2)
  def apply(code: String): Enum = {
    ...
  }
} 

我以为我可以创建一个宏createEnum,所以我可以放 createEnum("SomeEnum", "Option1", "Option2")进入我的代码并让它生成。好像它正在呼唤一个宏。

但我不能理解宏。我正在使用Scala 2.11.6,只是为了尝试让某些东西工作,我创建了以下内容:

object createEnumObj {
  def createEnumImpl(c: scala.reflect.macros.whitebox.Context)(ename: c.Expr[String]): c.universe.ModuleDef = {
    import c.universe._

    val Literal(Constant(s_ename: String)) = ename.tree
    val oname = TermName(s_ename)

    val barLine = q"val bar: Int = 5"
    q"object $oname { $barLine }"
  }

  def createEnum(ename: String): Unit = macro createEnumImpl
}

这是一个单独的项目 - 一切似乎都在编译好了。

如果我将createEnumObj.createEnum的调用粘贴到某个源代码并尝试编译它,我得到十亿行(给出或采取一些)异常输出,这似乎重复这样的事情:

[error] (main/compile:compile) java.lang.AssertionError: assertion failed:
[error]   object foo extends scala.AnyRef {
[error]   def <init>() = {
[error]     super.<init>();
[error]     ()
[error]   };
[error]   val bar: Int = 5
[error] }
[error]      while compiling: /Users/bob/ICL/ironcore-id/src/main/scala/package.scala
[error]         during phase: typer
[error]      library version: version 2.11.6
[error]     compiler version: version 2.11.6
[error]   reconstructed args: -Xfuture ...
error]
[error]   last tree to typer: term foo
[error]        tree position: line 8 of /Users/bob/ICL/ironcore-id/src/main/scala/package.scala
[error]               symbol: <none>
[error]    symbol definition: <none> (a NoSymbol)
[error]       symbol package: <none>
[error]        symbol owners:
[error]            call site: <none> in <none>
[error]
[error] == Source file context for tree position ==
[error]
[error]      5   type DateTime = Int
[error]      6
[error]      7   createEnumObj.createEnum("foo")
[error]      8
[error]      9 }
[error] Total time: 2 s, completed Jun 18, 2015 2:46:05 PM

我想做的事情与question似乎并不太相似,但我显然错过了一些东西。任何关于如何实现这一点的想法都将被感激地接受。

谢谢, 鲍勃

0 个答案:

没有答案