I'm trying to generate case object
s 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 object
s 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 ?