Getting a structural type with an anonymous class's methods from a macro

后端 未结 1 975
猫巷女王i
猫巷女王i 2020-12-07 15:20

Suppose we want to write a macro that defines an anonymous class with some type members or methods, and then creates an instance of that class that\'s statically typed as a

相关标签:
1条回答
  • 2020-12-07 16:05

    This question is answered in duplicate by Travis here. There are links to the issue in the tracker and to Eugene's discussion (in the comments and mailing list).

    In the famous "Skylla and Charybdis" section of the type checker, our hero decides what shall escape dark anonymity and see the light as a member of the structural type.

    There are a couple of ways to trick the type checker (which do not entail Odysseus's ploy of hugging a sheep). The simplest is to insert a dummy statement so that the block doesn't look like an anonymous class followed by its instantiation.

    If the typer notices that you're a public term that isn't referenced by the outside, it will make you private.

    object Mac {
      import scala.language.experimental.macros
      import scala.reflect.macros.Context
    
      /* Make an instance of a structural type with the named member. */
      def bar(name: String): Any = macro bar_impl
    
      def bar_impl(c: Context)(name: c.Expr[String]) = {
        import c.universe._
        val anon = TypeName(c.freshName)
        // next week, val q"${s: String}" = name.tree
        val Literal(Constant(s: String)) = name.tree
        val A    = TermName(s)
        val dmmy = TermName(c.freshName)
        val tree = q"""
          class $anon {
            def $A(i: Int): Int = 2 * i
          }
          val $dmmy = 0
          new $anon
        """
          // other ploys
          //(new $anon).asInstanceOf[{ def $A(i: Int): Int }]
          // reference the member
          //val res = new $anon
          //val $dmmy = res.$A _
          //res
          // the canonical ploy
          //new $anon { }  // braces required
        c.Expr(tree)
      }
    }
    
    0 讨论(0)
提交回复
热议问题