Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Method cannot be accessed in Macro generated class

I have the following macro defining a class and returning an instance of that class (with Scala 2.10.2 and the macro plugin):

def test[T] = macro testImpl[T]

def testImpl[T : c.WeakTypeTag](c: Context): c.Expr[Any] = {
  import c.universe._
  val className = newTypeName("Test")

  c.Expr { q"""
    class $className  {
      def method = 1
    }
    new $className
  """}
}

When I call the macro:

case class Cat(name: String)

val t = test[Cat].method

I get the following error:

method method in class Test cannot be accessed in Test
val t = test[Cat].method
                   ^

My overall goal is to use vampire methods and to use quasi-quotes to describe the generated class. How can I solve this error?

like image 686
Eric Avatar asked Aug 28 '13 06:08

Eric


1 Answers

In my post on vampire methods I mention this workaround for this bug. For some reason you currently aren't able to see an anonymous class's methods on the instance returned from the macro unless you create a wrapper class that extends the class with the methods and return an instance of that, instead.

You're seeing the same bug from a slightly different angle. You've named the class with the methods you want to see on the returned instance's structural type, but you still need a wrapper. The following will work:

  c.Expr { q"""
    class $className  {
      def method = 1
    }
    new $className {}
  """}

Note that all I've done is add a pair of brackets to the line creating the instance, so that I get an instance of an anonymous class extending $className instead of just a $className.

I have no idea what's behind this bug, and I'm not sure if Eugene knows more. I did recently confirm that it's still around in the latest build of 2.11.

like image 138
Travis Brown Avatar answered Oct 24 '22 07:10

Travis Brown