我正在尝试创建一个生成对象的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似乎并不太相似,但我显然错过了一些东西。任何关于如何实现这一点的想法都将被感激地接受。
谢谢, 鲍勃