2017-03-04 245 views
0

我正在創建一些從封裝方法的註釋中讀取一些信息的宏庫。如何防止StaticAnnotation中的類型檢查?

@info(foo(bar, baz)) 
def enclosing() = { 
    myMacro() 
} 

這些信息在StaticAnnotation@info被編碼爲foo(bar, baz)

foo(bar, baz)包含的信息myMacro需要,然而,foo(bar, baz)不能在該位置@info型檢查,並導致編譯器錯誤時類型檢查foo(bar, baz)

我在想我是否可以創建一個宏dontTypecheck,以防止foo(bar, baz)類型選中。所以,我可以創造這樣的:

@info(dontTypecheck { 
    foo(bar, baz) 
}) 
def enclosing() = { 
    myMacro() 
} 

dontTypecheck宏應生成含有Tree untype覈對foo(bar, baz)

如何創建dontTypecheck宏?

回答

1

一個想法是使用另一種註釋保存信息

class Info[T](t: T) extends scala.annotation.StaticAnnotation { 
} 

class AnnInfo extends StaticAnnotation { 
    def macroTransform(annottees: Any*): Any = macro AnnInfImpl.impl 
} 

trait AnnotationUtils { 
    val c: scala.reflect.macros.blackbox.Context 

    import c.universe._ 

    final def getAnnotation(x: MemberDef) = x.mods.annotations 


} 

class AnnInfImpl(val c: blackbox.Context) extends AnnotationUtils { 

    import c.universe._ 
    // edit 1 
    def impl(annottees: Tree*): Tree = { 
    annottees.head match { 
     case x: DefDef => 
     // collect value from `@Info(value)` 
     val info: List[Tree] = getAnnotation(x).collect { case q"new $name ($value)" => value } 
     val newBody = 
      q""" 
       { 
       val info = ${info.map(e => show(e))} 
       println(info)// just print it 
       ${x.rhs} 
       }""" 
     DefDef(
      mods = Modifiers(), //dropMods 
      name = x.name, 
      tparams = x.tparams, 
      vparamss = x.vparamss, 
      tpt = x.tpt, 
      rhs = newBody 
     ) 
    } 
    } 
} 

//測試

class AnnInfoTest { 
    val a = 1 
    val b = 2 

    def f(a: Int, b: Int) = a + b 


    @Info(f(a, b)) 
    @AnnInfo 
    def e = ??? 
} 

如果你打電話e將打印List(f(a, b))

+0

請問,如果你刪除'高清F IT工作(一:Int,b:Int)= a + b'? –

+0

是的,這是工作:) –

+0

它編譯是因爲宏註釋'@ AnnInfo'刪除了@Info(f(a,b))'。在'@ Info'被刪除後,我怎樣才能在'e'的宏內回想'@ Info'? –

相關問題