Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate a static member and add it to a class within a type macro?

I would like to add a static field (named bar in this example) to a class (named Foo) with a type macro (named Static).

This is how I'm currently trying to do it:

Macro

import language.experimental.macros
import scala.reflect.macros.Context

package object statics {

  type Static = macro Statics.addStaticField

  object Statics {

    def addStaticField(c: Context): c.Tree = {
      import c.universe._

      val STATIC = 1 << 23
      type CompilerSymbol = scala.tools.nsc.Global#Symbol
      def setFlag(symbol: Symbol, flag: Long) {
        val compilerSymbol = symbol.asInstanceOf[CompilerSymbol]
        println("Setting flag ...")
        compilerSymbol.setFlag(flag)
      }
      def printFlags(symbol: Symbol) {
        println("Flags: " + symbol.asInstanceOf[CompilerSymbol].flagString)
      }

      val staticField: ValDef =
        ValDef(
          mods = Modifiers(),
          name = TermName("bar"),
          tpt  = TypeTree(),
          rhs  = Literal(Constant(42))
        )
      printFlags(staticField.symbol)
      setFlag(staticField.symbol, STATIC)
      printFlags(staticField.symbol)

      val Template(parents, _, existingCode) = c.enclosingTemplate

      Template(Nil, emptyValDef, staticField :: existingCode)
    }
  }
}

During compilation, the call to setFlag seems to have an effect, because the flag string changes:

Flags: 
Setting flag ...
Flags: <static>

But it seems like it has no actual effect at all at the usage site:

package statics

class Foo extends Static

object Main extends App {
  Foo.bar        // Fails to compile
  (new Foo).bar  // Compiles
}

show and showRaw don't show any sign of STATIC, too.

How can I solve this issue?

like image 429
soc Avatar asked Jan 22 '13 16:01

soc


Video Answer


1 Answers

As far as I know, you would need to generate a companion object to have a static field, and at the moment that is not possible with type macros.

like image 69
Alex DiCarlo Avatar answered Sep 17 '22 12:09

Alex DiCarlo