Quarktum
Quarktum

Reputation: 709

Call implicit before macro getting expanded

I was wondering how can Play Json achieve the following:

case class A(s: String, b: B)
object A {
  implicit val format = Json.writes[A]
}

case class B(i: Int)
object B {
  implicit val format = Json.writes[B]
}

The funny about it is that the expansion of Json.writes[A] is using the implicit writer of B.

In my case, I wrote something similar to:

case class MyWriter[T](f: (T) => String)

def myMacro[T]: c.Expr[MyWriter[T]] = ... {
  q"""
    val i = implicitly[typeOf[MyWriter[$tpe]]
    ...
  """
}

But I obtain couldn't find implicit value for. I've realized that if a declare B and its object before declaring A, it works, but surely it's not why I expect.

Upvotes: 1

Views: 50

Answers (1)

Andriy Plokhotnyuk
Andriy Plokhotnyuk

Reputation: 7989

You can use an expression like this:

def getType(typeTree: Tree): Type = c.typecheck(typeTree, c.TYPEmode).tpe

c.inferImplicitValue(getType(tq"_root_.my_package.MyWriter[$tpe]"), silent = false))

An example of usage for inferring of implicit JSON codecs is here.

Upvotes: 1

Related Questions