2017-11-03 11 views
1

저는 scalameta를 가지고 놀고 있는데, 메소드 실행이 얼마나 오래 걸렸는 지에 대한 측정을 보내는 일반적인 측정 주석을 원합니다.Future를 반환하고 여러 개의 인수 또는 여러 개의 인수가있는 메서드 (예 : 카레)를 일치시키는 방법은 무엇입니까?

Qing Wei의 캐시 주석 데모를 사용했습니다. https://www.cakesolutions.net/teamblogs/scalameta-tut-cache

비동기 메서드는 작동하지만 내 속성은 ExecutionContext 인수 목록으로 인해 Future를 반환하는 메서드와 일치하지 않습니다.

내 주석은 다음과 같습니다

@measure("C") 
def testAsync(x: String)(implicit ec: ExecutionContext) : Future[String] = { 
Future(test(x)) 
} 

:

@measure("A") 
def test(x: String): String = x 

@measure("B") 
def testMultipleArg(x: Int, y: Int): Int = x + y 

나는 같은 비동기 방법과 그것을 사용하고 싶습니다 :

package measurements 

import scala.concurrent.Future 
import scala.meta._ 

class measure(name: String) extends scala.annotation.StaticAnnotation { 
    inline def apply(defn: Any): Any = meta { 
    defn match { 
     case defn: Defn.Def => { 
     this match { 
      case q"new $_($backendParam)" => 
      val body: Term = MeasureMacroImpl.expand(backendParam, defn) 
      defn.copy(body = body) 
      case x => 
      abort(s"Unrecognized pattern $x") 
     } 
     } 
     case _ => 
     abort("This annotation only works on `def`") 
    } 
    } 
} 

object MeasureMacroImpl { 

    def expand(nameExpr: Term.Arg, annotatedDef: Defn.Def): Term = { 
    val name: Term.Name = Term.Name(nameExpr.syntax) 
    annotatedDef match { 
     case q"..$_ def $methodName[..$tps](..$nonCurriedParams): $rtType = $expr" => { 
     rtType match { 
      case f: Future[Any] => q""" 
      val name = $name 
      println("before " + name) 
      val future: ${rtType} = ${expr} 
      future.map(result => { 
       println("after " + name) 
       result 
      }) 
      """ 
      case _ => q""" 
      val name = $name 
      println("before " + name) 
      val result: ${rtType} = ${expr} 
      println("after " + name) 
      result 
      """ 
     } 
     } 
     case _ => abort("This annotation only works on `def`") 
    } 
    } 
} 

나는이 같은 주석을 사용 하지만 다음 오류가 발생합니다 :

exception during macro expansion: 
scala.meta.internal.inline.AbortException: This annotation only works on `def` 

문제는 MeasureMacroImpl과 일치한다고 가정하지만 여러 인수 그룹과 일치시키는 방법을 모르겠습니다. 너희들이 날 도와 줄 수 있니? 어떤 아이디어 나 샘플 코드도 크게 감사 할 것입니다. 나는 스칼라와 스칼라 메타에 대해 매우 익숙하지 않아서 사소한 질문을하면 사과한다.

답변

2

MeasureMacroImpl이 카레 매개 변수와 일치하지 않으므로 오류가 발생합니다.

그것은 카레 PARAMS 일치 상당히 사소한, 단순히 ..$nonCurriedParams

+0

이 근무 ...$nonCurriedParams 대신

scala case q"..$_ def $methodName[..$tps](...$nonCurriedParams): $rtType = $expr"

주의를 사용! 고맙습니다. 튜토리얼을 계속 작성하십시오. :) –