2016-07-01 4 views
3

이것은 직면하고있는 문제를 단순화 한 버전이지만 근본적인 문제는 남아 있습니다. 매크로를 호출 한 후 동적으로 사례 클래스를 생성하려고합니다. 매크로 호출 등에서 매개 변수를 검색 할 수 있습니다. 문제는 quasiquote 내에서 문자열 변수를 사용하려고하는 것입니다. 본질적으로 다음을 원합니다.스칼라를 사용하여 문자열 변수 리프팅

def expand_impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = { 
    import c.universe._ 

    val toGen = "case class Foo()" 

    val toReturn = c.Expr[Any](
     q"$toGen" 
    ) 
    toReturn 
} 

그러나 사례 클래스는 생성되지 않습니다. 이제 내가 GENE으로 변경하면 "case class Foo()"가 작동하지만 toGen은 문자열을 반환하는 다른 처리 후에 생성 할 문자열이므로이를 수행 할 수 없다는 것을 알고 있습니다.

Expr[Any]("case class Foo()") 

toGen 단순히 케이스 클래스가 생성되지 않습니다 의미 따옴표 함께에 붙여 문자열 : 이런 식으로 컴파일 수동 toReturn의 값을보고 난 다음 얻을.

비슷한 문제를 찾았지만 어디에서나이 예제를 찾을 수 없습니다. quasiquote 내에서 문자열 변수의 큰 따옴표를 인용 부호로 묶지 않으려면 어떻게해야합니까?

+0

quasiquote를 사용하려면 모든 중첩 된 표현식에 대해이를 사용해야합니다. 그렇지 않으면 문자열 표현식 만 들어 올립니다. 왜 case 클래스 선언을 만들 때 quasiquote를 사용할 수 없습니까? – devkat

+0

아이디어는 다음과 같은 것입니다 :'val toGen = someMethod()'. 'someMethod()'에 의해 리턴 된 문자열은 "case class Foo()"와 같을 것이다. 올바르게 이해한다면 케이스 클래스를 반환 할 때 쿼지 캡션을 사용해야한다고 제안하는 것입니까? 그러나 이것은 someMethod()가 항상 같은 case 클래스를 리턴하지는 않을 것이고, 입력 등을 기반으로 동적으로 생성하고 문자열을 반환하기 때문에 내 문제가있는 곳입니다. – brioche

+0

문제는 quasiquotes가 문자열을 구문 분석하지 않으므로 들어 올릴식이 문자열로 표현 될 때마다 사용할 수 없습니다. 이 경우에는 Régis Jean-Gilles가 대답 할 때처럼 문자열을 파싱해야합니다. – devkat

답변

3

Context에 정의 된 parse 방법이 있습니다. 그것은 Tree을 반환하고 나무가 쿼시 퀘스트로 보간 될 수 있기 때문에 파싱을 quasiquoting과 매우 쉽게 섞고 일치시킬 수 있습니다. 예를함으로써 :

scala> :paste 
// Entering paste mode (ctrl-D to finish) 

import scala.reflect.macros.whitebox.Context 
import scala.language.experimental.macros 

def test_impl(c: Context)(): c.Tree = { 
    import c.universe._ 
    val tree = c.parse("""println(2)""") 
    q"println(1); $tree; println(3)" 
} 
def test(): Unit = macro test_impl 

// Exiting paste mode, now interpreting. 

import scala.reflect.macros.whitebox.Context 
import scala.language.experimental.macros 
test_impl: (c: scala.reflect.macros.whitebox.Context)()c.Tree 
defined term macro test:()Unit 

scala> test() 
1 
2 
3 

이 예에서이 나는 데프 매크로를 정의하지만, (귀하의 경우와 같은) 단지뿐만 아니라 매크로 주석과 함께 작동합니다.

+0

매력처럼 작동합니다. 정말 고마워요! – brioche