2013-01-22 10 views
6

Vorrei aggiungere un campo statico (denominato bar in questo esempio) a una classe (denominata Foo) con una macro di tipo (denominata Static).Come generare un membro statico e aggiungerlo a una classe all'interno di una macro di tipo?

Questo è il modo Attualmente sto cercando di farlo:

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) 
    } 
    } 
} 

Durante la compilazione, la chiamata a setFlag sembra avere un effetto, perché i cambiamenti stringa bandiera:

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

Ma sembra che non abbia alcun effetto reale sul sito di utilizzo:

package statics 

class Foo extends Static 

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

show e showRaw non mostrano alcun segno di STATIC, anche.

Come posso risolvere questo problema?

+0

Ciao Simon! Mi dispiace, sono stato davvero sommerso in questi giorni. Cercherò di ottenere questo e altri problemi che hai segnalato al più presto. –

risposta

1

Per quanto ne so, è necessario generare un oggetto companion per avere un campo statico e al momento non è possibile con macro di tipo.

+0

Direi che questa risposta è corretta. Da quello che so, STATIC dovrebbe essere solo messo su membri di oggetti: http://groups.google.com/group/scala-internals/browse_thread/thread/d385bcd60b08faf6 –

+1

Per quanto ne so, 'scalac' sta aggiungendo forwarder statici a classi di oggetti companion, quindi la funzionalità esiste da qualche parte. Spero che ci sia un modo per dire al compilatore di farlo per elementi personalizzati. – soc

Problemi correlati