All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tethys.derivation.impl.MacroUtils.scala Maven / Gradle / Ivy

The newest version!
package tethys.derivation.impl

import scala.reflect.macros.blackbox

/**
  * Created by eld0727 on 22.04.17.
  */
trait MacroUtils extends BaseMacroDefinitions
    with CaseClassUtils
    with LoggingUtils {
  val c: blackbox.Context
  import c.universe._

  def eval[T](expr: Expr[T]): Option[T] = {
    util.Try(c.eval(c.Expr[T](c.untypecheck(expr.tree)))).toOption
  }

  case class SelectChain(chain: Seq[String])

  implicit lazy val selectChainUnliftable: Unliftable[SelectChain] = Unliftable[SelectChain] {
    case Ident(name) => SelectChain(Seq(name.decodedName.toString))
    case select: Select =>
      def selectAllNames(s: Tree): Seq[String] = s match {
        case Select(rest, name) => selectAllNames(rest) :+ name.decodedName.toString
        case Ident(name) => Seq(name.decodedName.toString)
      }

      SelectChain(selectAllNames(select))
  }


  case class BuilderField(name: String, tpe: Type)

  implicit lazy val builderFieldUnliftable: Unliftable[BuilderField] = Unliftable[BuilderField] {
    case lambda@q"((${ValDef(_, name, _, _)}) => ${b: SelectChain})"
      if b.chain.size == 2 && name.decodedName.toString == b.chain.head =>
      val tpe = lambda match {
        case q"($_ => ${body: Tree})" => body.tpe
      }
      BuilderField(b.chain(1), tpe)
  }

  object Untyped {
    def unapply(arg: Tree): Option[Tree] = arg match {
      case Typed(t, _) => Untyped.unapply(t)
      case _ => Some(arg)
    }
  }

  implicit lazy val optionTreeUnliftable: Unliftable[Option[Tree]] = Unliftable[Option[Tree]] {
    case q"$col.Some.apply[$_](${res: Tree})" => Some(res)
    case q"$col.None" => None
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy