Using Scala reflection in Scala macros

2019-08-03 19:13发布

I'm trying to use Scala macros in order to generate some code, more specifically I would like the macro to generate a function that instantiates an abstract class. For example, if this is the abstract class:

abstract class Person {
  val name: String
  val age: Int
}

So the macro will be something like this:

  def m = macro _m
  def _m(c: Context): c.Expr[Any] = {
    import c.universe._
    c.Expr(c.parse("""
        (_name:String, _age:Int) => new Person{
            val name = _name
            val age = _age
        }   
    """))
  }

So far so good, the problem is that macro needs to be more general of course and to generate the function based on the reflection information of a given class.

I went through the Scala reflection and macros documentation and I couldn't find how to create a macro that can access the reflection information of a given class.

I would like that macro to look something like this

  def m = macro _m
  def _m(c: Context)(<Type of the class>): c.Expr[Any] = {
    import c.universe._
    c.Expr(c.parse("""
    <generate the function based on the type of the class>
    """))
  }

and the use of the macro to look something like this:

val factoryFunction = m(typeOf[Person])

1条回答
乱世女痞
2楼-- · 2019-08-03 19:38

Maybe you mean something like this:

def m[T] = macro _m[T]
def _m[T: c.WeakTypeTag](c: Context) = {
  import c.universe._
  val typeOfT = weakTypeOf[T]
  // now that you have Type representing T, you can access all information about it, e.g.
  // members, type hierarchy, etc.
  ...
}

Using this method you need to ensure that your macro is always called with concrete type, e.g. this will not work:

class Example[T] {
  val creatorOfT = m[T]
}
查看更多
登录 后发表回答