【发布时间】:2019-10-05 18:10:03
【问题描述】:
问题:
我想用 scala 宏将带注释的类作为另一个类的子类 我有什么:
字段包装器:
class Field(fieldType: DbModelFieldType, fieldName: String)
一个抽象类(所有注释类的基类):
abstract class DatabaseModel {
def fields: Seq[Fields]
}
我有一个案例类:
Model(num: Int, sym: Char, descr: String)
如果用@GetFromDB注释该类
@GetFromDB
Model(num: Int, sym: Char, descr: String)
case class Model(num: Int, sym: Char, descr: String) extends DatabaseModel {
override def fields: Seq[Fields] =
Seq(Field(IntFieldType(), "num"),
Field(CharFieldType(), "sym"),
Field(StringFieldType(), "descr")
)
}
我想要的结果应该是这样的:
val m: DatabaseModel = Model(1, 'A', "First Name")
我看过类似的问题
Generate companion object for case class with methods (field = method)
那么我如何扩展该解决方案以达到预期的结果?
import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.language.experimental.macros
import scala.reflect.macros.whitebox
object Macros {
@compileTimeOnly("enable macro paradise")
class GenerateCompanionWithFields extends StaticAnnotation {
def macroTransform(annottees: Any*): Any = macro Macro.impl
}
object Macro {
def impl(c: whitebox.Context)(annottees: c.Tree*): c.Tree = {
import c.universe._
annottees match {
case (cls @ q"$_ class $tpname[..$_] $_(...$paramss) extends { ..$_ } with ..$_ { $_ => ..$_ }") :: Nil =>
val newMethods = paramss.flatten.map {
case q"$_ val $tname: $tpt = $_" =>
q"def $tname(): String = ${tpt.toString}"
}
q"""
$cls
object ${tpname.toTermName} {
..$newMethods
}
"""
}
}
}
}
【问题讨论】:
-
@LuisMiguelMejíaSuárez 我想在编译时这样做
-
您是否考虑过使用 Shapeless 进行推导?而只是触发它的宏。
标签: scala traits scala-macros scala-macro-paradise