I'm, um, a very naive Scala 3 metaprogrammer. Apologies in advance.
I'm trying to canonicalize type names. Calling _.dealias.simplified.show
on a TypeRepr
does the job just fine on the base type, but it doesn't touch the type parameters. So, I'd like to iterate through the type params and call my canonicalizer on them recursively. After some trial and error and reading great intros by Adam Warsky and Eugene Yokota I've managed to iterate through the type params, but I can't figure out how to make the recursive call.
object Playpen:
import scala.quoted.*
inline def recursiveCanonicalName[T]: String = ${Playpen.recursiveCanonicalNameImpl[T]}
def recursiveCanonicalNameImpl[T](using q : Quotes)( using tt : Type[T]) : Expr[String] =
import quotes.reflect.*
val repr = TypeRepr.of[T]
repr.widenTermRefByName.dealias match
case AppliedType(name, args) =>
Expr(name.dealias.simplified.show + "[" + args.map(a => a.dealias.simplified.show /*(recursiveCanonicalNameImpl(q)(a.asType)*/).mkString(",") + "]")
case _ =>
Expr(repr.dealias.simplified.show)
The current version "works" to canonicalize one level of type params, but without recursion can't go deeper.
@ macroplay.Playpen.recursiveCanonicalName[Map[String,String]]
res1: String = "scala.collection.immutable.Map[java.lang.String,java.lang.String]"
@ macroplay.Playpen.recursiveCanonicalName[Map[Seq[String],Seq[String]]]
res3: String = "scala.collection.immutable.Map[scala.collection.immutable.Seq[scala.Predef.String],scala.collection.immutable.Seq[scala.Predef.String]]"
Any help (and your patience, scalameta makes me feel dumb) is greatly appreciated!