我正在尝试创建一个scalameta注释,它将在现有对象中定义一个新的case类。
我的目标是转变:
object MyObj {
case class A()
}转入:
object MyObj {
case class A()
case class B(b: Int, bb: Int)
}为此,我创建了以下注释:
import scala.annotation.StaticAnnotation
import scala.meta._
class schema extends StaticAnnotation {
inline def apply(defn: Any): Any = meta {
val q"..$mods object $ename extends $template" = defn
val generatedClass: Defn.Class =
q"""
case class B(b: Int, bb: Int)
"""
//the stats that were defined in the annotated object
val existingStats: scala.collection.immutable.Seq[Stat] = template.stats.get
//new stats
val stats = Some(existingStats :+ generatedClass)
//the new template
val newT = template.copy(stats=stats)
val res =
q"""
..$mods object $ename extends $newT
"""
println("============== result ==============")
println("res: " +res)
println("====================================")
res
}
}这个主要的类来测试它:
object Main {
def main(args: Array[String]): Unit = {
println("Hello")
val b = new MyObj.B(2,22)
val q = MyObj.A()
println(b)
}
}
@schema
object MyObj {
case class A()
}当我编译和运行主类时,代码会按照预期的方式运行。
在编译过程中打印:
============== result ==============
res: object MyObj {
case class A()
case class B(b: Int, bb: Int)
}
====================================在运行代码之后:
Hello
B(2,22)我的问题是当我尝试使用intellij来处理这段代码时。
代码从intellij编译和运行,但是新的类B无法识别,因此代码完成和提示不起作用

我正在使用最新的intellij和scala插件
我已经将整个项目上传到git:intellij/tree/master
这是我第一次尝试使用scalameta,我试图理解它是intellij中的一个bug,还是我做错了什么?
发布于 2018-08-12 16:35:35
就像旧式宏一样,需要在单独的编译单元中定义scalameta代码,以便首先编译它们,然后在编译其他源代码时调用它们。
多亏了https://www.michaelpollmeier.com/2016/12/01/scalameta-code-generation-tutorial
https://stackoverflow.com/questions/47620606
复制相似问题