Scala 3 Macro Reflection: how to implement a method that has Expr parameters?

I am trying to define a class with an macro method using another macro. I am using the AST DefDef to define such a method. Does anyone have an example of doing this. Currently I have:

    val selectDef = DefDef(selectSym, 
      argss => 
        val argTree = argss(0)(0)
        val macroValue = argTree.symbol.asQuotes
        val expr = argTree.asExprOf[String]
        val value = macroValue.valueOrAbort(expr)
        val thisObj = This(clsX)
        Some(Select.unique(thisObj, name.valueOrAbort))

I get the the error:

[error]    |Expected a known value. 
[error]    |
[error]    |The value of: name
[error]    |could not be extracted using scala.quoted.FromExpr$PrimitiveFromExpr@402cdec9
[error]    |----------------------------------------------------------------------------


1 Like

Just a note to say that the above definition is incorrect. What I need is a macro that generates a macro. Is this even possible? I took a stab at this but failed. To avoid any further “brain drain”, I gave up on this route.

In effect I would like to allow one to “dynamically” add members to a class SelectableBase as shown below:

object Hidden3:
  import scala.quoted.*

  class SelectableBase extends Selectable:
    val name: String = "B" 
    val age: Int = 1
    transparent inline def selectDynamic(name: String): Any =
      ${selectDynamicImpl('this, 'name)}
    def applyDynamic(name: String)(args: Any*): Any = ???

  def selectDynamicImpl[A:Type](inner: Expr[A], name: Expr[String])(using quotes: Quotes): Expr[Any] =
    import quotes.reflect.*
    Select.unique(inner.asTerm, name.valueOrAbort).asExpr
  def makeRecH() =

Maybe there is another way to do this?


1 Like