我正在尝试编写一个可以使用有关某个类的字段信息来生成模式的宏。例如,假设我有一个名为SchemaWriter[T]
的类型类,我希望使用宏来生成实现。Scala宏升降符号或类型
trait SchemaWriter[T] {
def schema: org.bibble.MsonSchema
}
case class MsonSchema(fields: Seq[MsonType])
case class MsonType(name: String, `type`: Class[_]) // might want other stuff here too, derived from a symbol or type-signature
object MsonType {
def apply(symbol:Symbol): MsonType = ...
}
的想法是,我的宏将吐出类似代码:
class FooSchemaWriter extends SchemaWriter[Foo] {
def schema : org.bibble.MsonSchema= {
val fields = for (symbol <- fields of class) yield {
MsonType(symbol)
}
org.bibble.MsonSchema(fields)
}
}
我可以实现宏如:
object Macros {
def writerImpl[T: c.WeakTypeTag](c: Context): c.Expr[SchemaWriter[T]] = {
import c.universe._
val T = weakTypeOf[T]
val fields = T.declarations.collectFirst {
case m: MethodSymbol if m.isPrimaryConstructor => m
}.get.paramss.head
val fieldTrees: [Tree] = fields.map { f =>
q"""org.bibble.MsonType(${f})"""
}
c.Expr[SchemaWriter[T]](q"""
new SchemaWriter[$T] {
def schema = {
val fields = Seq(..$fieldTrees)
org.bibble.MsonSchema(fields)
}
}
""")
}
}
但是,创造一个领域的原因QQS可升降的错误或不确定的错误。我问了一个类似的问题,昨天Scala macros Type or Symbol lifted得到了一个很好的答案,但我的实现不能局限于传递字符串,因为我需要更多的类型信息来生成模式的细节,这是我认为我的困惑所在。
几乎不可能在不知道“Field”的定义的情况下提供帮助。特别是,Field的构造函数的签名是什么。一般来说,在发布问题时,您应该努力发布[最小,完整和可验证的示例](http://stackoverflow.com/help/mcve)。是的,我知道你不能真正发布一个编译的例子,因为你确实要求如何修正你的代码,但至少提供了所有必需的依赖关系。 –
我将使用Schema和Field的适当定义进行更新 – monkjack
已针对具体架构类型进行了更新。什么进入这个Mson模式不是关键,但如果我现在可以得到怎么了编译,其余的应该很容易。 – monkjack