2017-03-04 12 views
0

나는 둘러싸는 방법에 주석에서 일부 정보를 읽는 일부 매크로 라이브러리를 만들고있다.StaticAnnotation에서 유형 검사를 방지하는 방법은 무엇입니까?

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

이러한 정보는 StaticAnnotation@infofoo(bar, baz)로 인코딩된다.

foo(bar, baz)이 포함되어 정보 myMacro 필요하지만, foo(bar, baz)이 위치 @info에 입력-확인하고 foo(bar, baz)을 유형 검사 할 때 컴파일러 오류가 발생 할 수 없습니다.

foo(bar, baz) 유형을 확인하지 못하도록 매크로 dontTypecheck을 만들 수 있는지 궁금합니다. 내가 좋아하는 뭔가를 만들 수 있도록 :

@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 = ??? 
} 

당신이`데프 F를 삭제하면

+0

List(f(a, b)) 그것이 작동합니까 인쇄됩니다 e를 호출하는 경우 (A 저장 사용입니다 : Int, b : Int) = a + b'? –

+0

네, 작동합니다 :) –

+0

매크로 주석'@ AnnInfo'가'@Info (f (a, b))'를 삭제했기 때문에 컴파일됩니다. '@ Info'가 삭제 된 후에'e' 내부의 매크로에서'@ Info'를 어떻게 불러 낼 수 있습니까? –