2014-01-10 3 views
4

매크로 주석 ("현재") 유형을 얻으려면 어떻게해야합니까?매크로 주석 유형

import scala.annotation.StaticAnnotation 
import scala.reflect.macros._ 
import language.experimental.macros 

class myself extends StaticAnnotation { 
    def macroTransform(annottees: Any*) = macro myselfMacro.impl 
} 
object myselfMacro { 
    def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = { 
    import c.universe._ 
    val a = annottees.head 
    println(s"static type = ${a.staticType}") 
    println(s"actual type = ${a.actualType}") 
    c.Expr[Any](Literal(Constant())) 
    } 
} 

시험 :

@myself class Foo 

출력 :

static type = Nothing 
actual type = null 
I 그 종류를 원하는 이유는 I는 예를 들어, 입력 파라미터로 사용하려는 것이다

Bar[Foo]


편집 :

좋아, 그래서 올바른 접근 방식은 다음과 같이 생각 :

def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = { 
    import c.universe._ 
    val v = annottees.head.asInstanceOf[ClassDef] 
    val tpe = v.tpe // <- tpe is null as the annotated type is not yet type checked! 
    val tpe2 = if (tpe == null) 
    c.typeCheck(v).tpe // <- fails with a compiler error (assertion failure) 
    else 
    tpe 
    println(s"Type of annottee: $tpe2") 
    ??? 
} 

그러나 given this post by Eugene Burmako, 그것은 본다 ... it is currently not possible 같은

+0

매크로 주석이 2.11.x에서 발생하지 않는다고 생각했습니다. 그게 바뀌 었습니까? – wheaties

+1

매크로 파라다이스 플러그인을 통해 2.10과 2.11에서 이미 발생했습니다. 우리가 표준 배포판에 포함되는 것에 대해 이야기하고 있다면, 바닐라 2.10도 바닐라 2.11도 그럴 것입니다. –

+0

유스 케이스에 대해 자세히 설명해 주시겠습니까? 매크로 주석이 확장 될 때 annottee는 아직 생성되지 않은 기호 (때로는 표시되지만 지정되지는 않음)가 없습니다. 따라서 심볼/유형으로는 트리별로 만 참조 할 수 없습니다. 물론, c.typecheck의 결과는 당신에게 어떤 기호/유형을 줄 것이다. 그러나 참조 목적이 아닌 내성을 위해서만 사용될 수있을 것이다. –

답변

4

매크로 주석이 확장되고 있습니다. 주석은 심볼이 생성되지 않습니다. 그것은 아직 (때로는 그렇지만 주어진 것이 아닙니다). 결과적으로 심볼/유형으로 트리를 참조 할 수 없습니다 (예 : Ident(TypeName("Foo")). 물론, c.typecheck의 결과는 당신에게 어떤 기호/유형을 줄 것이다. 그러나 참조 목적이 아닌 내성을 위해서만 사용될 수있을 것이다.

이 방법은 위생 문제에서 벗어나면 잘 작동합니다. 컴패니언 개체가 Foo이라는 클래스/형식 멤버를 정의한 경우 인 Serializer[Foo]은 원래 클래스가 아닌 동반자의 멤버에 바인딩됩니다. 현재이 문제를 해결할 좋은 방법이 없습니다 (사례 클래스에 적용/적용되지 않은 메소드를 생성 할 때 scalac 자체가이 문제를 해결해야하지만 어떻게 완료되었는지는 알 필요가 없습니다). 우리는이 문제에 대한 해결책을 제시 할 계획이지만, 다음 달에 작업을 시작하기 때문에 트렁크 또는 천국에 도착할 때까지 잠시 기다려야합니다.

+0

"하지만 어떻게 완료되었는지 알고 싶지는 않습니다."...하지만 우리는 않습니다. 여전히 매크로 주석에 전달 된 moduleDef 또는 classDef를 유형 검사 할 수있는 방법을 찾을 수 없습니다. –