How to generate case objects for every field in a Scala case class using macro?

十年热恋 提交于 2019-11-30 17:43:32

问题


I'm trying to generate case objects for every case member of every child case class of a sealed trait. I'm able to generate the code in the macro but I don't know how to use this in my code.

Example usecase:

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

It should generate the following case objects which are fields of Product.

case object ProductIdField extends Field {
  val name = "Product Id"
}
case object ProductNameField extends Field {
  val name = "Product Name"
}

Macro so far which generates the code

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"
  }
}

Here is how I am calling it

FieldGenerator.generator[Item]()

And I get the following compile time error

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

How can I import the generated code ?

来源:https://stackoverflow.com/questions/38442722/how-to-generate-case-objects-for-every-field-in-a-scala-case-class-using-macro

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!