inferImplicitValue
을 사용하여 매크로 내부의 암시 적 변수를 나타내는 트리를 가져오고 해당 구문 트리를 평가하려는 스칼라 매크로 (스칼라 2.11)를 작성하고 있습니다. 값. 나는 실제로이 일을했지만 모든 상황에서 효과가있는 것 같지 않습니다. [1]. 나는 실패한 간단한 예제를 만들었다.inferImplicitValue에서 반환 된 스칼라 구문 트리가 평가하지 못했습니다.
// a class for implicit evidence
class DemoEvidence(val value: Int)
// define 'foo' method for invoking the macro
object demoModule {
def foo: Int = macro DemoMacros.fooImpl
}
class DemoMacros(val c: whitebox.Context) {
import c.universe._
def fooImpl: Tree = {
val vInt = try {
// get the tree representing the implicit value
val impl = c.inferImplicitValue(typeOf[DemoEvidence], silent = false)
// print it out
println(s"impl= $impl")
// try to evaluate the tree (this is failing)
val eval = c.eval(c.Expr[DemoEvidence](c.untypecheck(impl.duplicate)))
eval.value
} catch {
case e: Throwable => {
// on failure print out the failure message
println(s"Eval failed with: $e\nStack trace:\n${e.printStackTrace}")
0
}
}
q"$vInt" // return tree representing the integer value
}
}
나는 위의 컴파일하고 다음을 호출하면 :
나는 컴파일을 참조object demo {
implicit val demoEvidence: DemoEvidence = new DemoEvidence(42)
val i: Int = demoModule.foo
}
는 다음과 같은 방법으로 실패 :
impl= demo.this.demoEvidence
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at scala.tools.reflect.ToolBoxFactory$ToolBoxImpl$ToolBoxGlobal$$anonfun$compile$1.apply(ToolBoxFactory.scala:275)
...
전체 출력에서 : https://gist.github.com/erikerlandson/df48f64329be6ab9de9caef5f5be4a83
그래서, 선언을위한 트리를 찾는 중임을 알 수 있습니다. d 암시 적 값 demo.this.demoEvidence
이지만 해당 트리의 평가가 실패했습니다. 이 기본 접근 방식이 내 프로젝트의 다른 곳에서 작동하는 것을 보았습니다. 그 차이점이 무엇인지, 왜 여기서 실패하는지는 확실하지 않습니다.
[1] 업데이트 : 암시 적 값이 (하위) 프로젝트에서 정의되고 컴파일 된 다음 해당 프로젝트의 외부를 사용하면 예상대로 작동합니다. 이 접근법이 저에게 효과가있는 경우였습니다.
그래서 문제는 그것이 살아야만하는 근본적인 제한인지, 아니면 현명한 해결 방법이 있는지, 아니면 수정 될 수있는 매크로 내에서 암시 적 값을 추론하는 "버그"인지 여부입니다.
UPDATE : 나는 이것에 대한 스칼라 문제를 제기 :의 eval
주어진 의미가 실행을위한 클래스 파일 형태로 존재하는 object demo
을 기대하고있다 스택 트레이스의 모습에서 https://github.com/scala/scala-dev/issues/353
최소한 스택 트레이스와 예외의'toString'을 포함 할 수 있습니다. –
나는 어떤 흔적도 얻지 못했습니다. 하지만 try/catch를 제거하고 내가 얻은 것을 보도록하겠습니다. – eje
아니면 그냥'catch'에서'e.printStackTrace'를 사용하십시오. –