Scala Macros: Getting a List of TypeSymbols to be used at runtime

前端 未结 1 1211
情书的邮戳
情书的邮戳 2021-02-09 08:06

Is there a way to return a List of TypeSymbols for each class under a package using macros?

What I am trying to achieve is to write a macro tha

1条回答
  •  死守一世寂寞
    2021-02-09 09:04

    You have to use reifyType to create reflection artifacts in the runtime universe:

    import scala.language.experimental.macros
    import scala.reflect.macros.Context
    
    object PackageMacros {
      def allTypeSymbols[T](packageName: String) = macro allTypeSymbols_impl[T]
    
      def allTypeSymbols_impl[T: c.WeakTypeTag](c: Context)(
        packageName: c.Expr[String]
      ) = {
        import c.universe._
    
        val pkg = packageName.tree match {
          case Literal(Constant(name: String)) => c.mirror.staticPackage(name)
        }
    
        val types = pkg.typeSignature.members.collect {
          case sym: ClassSymbol =>
            c.reifyType(treeBuild.mkRuntimeUniverseRef, EmptyTree, sym.toType)
        }.toList
    
        val listApply = Select(reify(List).tree, newTermName("apply"))
    
        c.Expr[List[Any]](Apply(listApply, types))
      }
    }
    

    This will give you a list of type tags, not symbols, but you can pretty easily get the symbols, either like this:

    scala> PackageMacros.allTypeSymbols("foo").map(_.tpe.typeSymbol) foreach println
    class Baz$
    class Bar
    class Baz
    trait FooTrait
    class Bar$
    

    Or in the macro itself.

    0 讨论(0)
提交回复
热议问题