MethodSymbol
을 스칼라 2.10의 메서드 정의 트리 (즉, DefDef
)의 왼쪽으로 편리하게 전환 할 수 있습니까?메서드 기호와 본문에서 메서드 정의 트리 만들기
예를 들어, 특성의 인스턴스를 취해 모든 특성의 메소드를 일부 디버깅 기능으로 포장하는 매크로를 작성한다고 가정합니다. 내가 쓸 수있는 다음과 같은 : 나는 특성을 구현하는 새로운 익명 클래스에서이 방법을 고집하고 해당 클래스 - 당신이 경우 전체 작업 예를 here을 찾을 수 있습니다 인스턴스의 지루한 사업을 생략 한
import scala.language.experimental.macros
import scala.reflect.macros.Context
object WrapperExample {
def wrap[A](a: A): A = macro wrap_impl[A]
def wrap_impl[A: c.WeakTypeTag](c: Context)(a: c.Expr[A]) = {
import c.universe._
val wrapped = weakTypeOf[A]
val f = Select(reify(Predef).tree, "println")
val methods = wrapped.declarations.collect {
case m: MethodSymbol if !m.isConstructor => DefDef(
Modifiers(Flag.OVERRIDE),
m.name,
Nil, Nil,
TypeTree(),
Block(
Apply(f, c.literal("Calling: " + m.name.decoded).tree :: Nil),
Select(a.tree, m.name)
)
)
}.toList
//...
}
' 관심이 다시.
이 지금은 예를 들어,이를 작성할 수 있습니다
scala> trait X { def foo = 1; def bar = 'a }
defined trait X
scala> val x = new X {}
x: X = [email protected]
scala> val w: X = WrapperExample.wrap[X](x)
w: X = [email protected]
scala> w.foo
Calling: foo
res0: Int = 1
scala> w.bar
Calling: bar
res1: Symbol = 'a
그래서 작동하지만, 매우 간단한의 경우 - 그것은하지 않습니다 형질 액세스 수정, 주석 매개 변수 목록과 방법을 경우,
정말 원하는 것은 새로운 바디에 대한 메소드 심볼과 트리를 가져와 DefDef
을 반환하는 함수입니다. 나는 손으로 하나 쓰기 시작했지만, 그것은 다음과 같이 가로장 설치 등등 물건을 많이 포함됩니다, 성가신 자세한 정보 및 오류가 발생하기 쉬운입니다
List(if (method.isImplicit) Some(Flag.IMPLICIT) else None, ...)
. 새 Reflection API에서이 작업을 수행하는 데 더 좋은 방법이 없습니까?
감사합니다. (+1)하지만 랩핑하려는 특성이 라이브러리에 있다면 어떻게 될까요? 그 경우 나는 위의 접근법에 갇혀있다. –
아, 무슨 뜻인지 알 겠어. 이 API는 https://github.com/scalamacros/kepler/blob/0acb8a30c379f268e8a3e1340504530493a1a1dc/src/reflect/scala/reflect/api/Trees.scala#L2480에서 사용할 수 있습니다. 2.10.1에서 더 이상 사용되지 않지만 구현 방법을 살펴 보시기 바랍니다. https://github.com/scalamacros/kepler/blob/0acb8a30c379f268e8a3e1340504530493a1a1dc/src/reflect/scala/reflect/internal/Trees.scala#L975 . –