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

anorm.macros.ValueToStatementImpl.scala Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) from 2022 The Play Framework Contributors , 2011-2021 Lightbend Inc. 
 */

package anorm.macros

import scala.reflect.macros.whitebox

import anorm.Macro.debugEnabled
import anorm.ToStatement
import anorm.macros.Inspect.pretty

private[anorm] object ValueToStatement {
  def apply[T <: AnyVal: c.WeakTypeTag](c: whitebox.Context): c.Expr[ToStatement[T]] = {
    @inline def abort(msg: String) = c.abort(c.enclosingPosition, msg)

    val tpe  = c.weakTypeTag[T].tpe
    val ctor = tpe.decl(c.universe.termNames.CONSTRUCTOR).asMethod

    import c.universe._

    ctor.paramLists match {
      case List(term: TermSymbol) :: Nil => {
        val tsTpe = c.weakTypeTag[ToStatement[_]].tpe

        val forwardName = TermName(c.freshName("forward"))
        val resolveImplicit: (Name, Type, Type) => Implicit[Type, Name, Tree] =
          ImplicitResolver(c)(tpe, Map.empty, forwardName)

        // Try to resolve `ToStatement[..]`
        resolveImplicit(term.name, term.info, tsTpe) match {
          case Implicit.Unresolved() => { // No `ToStatement[..]` ...
            abort(s"cannot find $tsTpe for ${term.name}:${term.info} in $ctor")
          }

          case Implicit(_, _, toStmt, _, _) => {
            val generated = q"""new _root_.anorm.ToStatement[$tpe] {
              def set(s: java.sql.PreparedStatement, i: Int, v: $tpe): Unit = 
                ${toStmt}.set(s, i, v.${term.name})
            }"""

            if (debugEnabled) {
              c.echo(c.enclosingPosition, s"ToStatement for $tpe: ${pretty(c)(generated)}")
            }

            c.Expr[ToStatement[T]](generated)
          }
        }
      }

      case _ =>
        abort(s"cannot supported ${show(ctor)} for ${tpe}")
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy