如何使用宏为Scala案例类中的每个字段生成案例对象?

时间:2016-07-18 17:29:58

标签: scala scala-macros

我正在尝试为密封特征的每个孩子case object中的每个case member生成case class个。我能够在宏中生成代码,但我不知道如何在我的代码中使用它。

示例用例:

sealed trait Item
sealed trait Field {
  val name: String
}
case class Product(id: String, name: String) extends Item

它应生成以下case object个字段Product

case object ProductIdField extends Field {
  val name = "Product Id"
}
case object ProductNameField extends Field {
  val name = "Product Name"
}
到目前为止

宏生成代码

import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context

object FieldGenerator {

  def generator[A](): Product = macro generate[A]

  def generate[A: c.WeakTypeTag](c: Context)(): c.Tree = {
    import c.universe._

    val subclasses: Set[c.universe.Symbol] = c.weakTypeOf[A].typeSymbol.asClass.knownDirectSubclasses

    val fieldObjects: Set[String] = subclasses.flatMap {
      (subClass: c.universe.Symbol) =>
        val itemName = subClass.name.toString
        val sealedTraitName = s"${itemName}Field"
        val fieldSealedTrait: String = s"sealed trait $sealedTraitName extends Field"
        val fieldCaseObjects: Iterable[String] = subClass.info.decls.collect {
          case m: MethodSymbol if m.isCaseAccessor =>
            val fieldName = m.name.toString.capitalize
            s"""case object ${itemName + fieldName}Field extends $sealedTraitName {
                  val name = "$itemName $fieldName"
               }
             """.stripMargin
        }
        List(fieldSealedTrait) ++ fieldCaseObjects
    }

    fieldObjects.foreach(println)

    q"..$fieldObjects"
  }
}

以下是我如何称呼它

FieldGenerator.generator[Item]()

我得到以下编译时错误

a pure expression does nothing in statement position; you may be omitting necessary parentheses

如何导入生成的代码?

0 个答案:

没有答案