2014-06-19 9 views
4

자바 타입에 대한 스칼라 타입의 인 코드 생성기로 사용할 다음 코드 스 니펫을 생성했습니다.scala macro 자바 빈 클래스 생성시 알려지지 않은 타입 오류

object Macros { 
    def encode[A <: Product, B](value:A):B = macro MacrosImpl.encode_impl[A, B] 
} 

class MacrosImpl(val c:Context) { 
    import c.universe._ 
    def encode_impl[ScalaType: c.WeakTypeTag, JavaType: c.WeakTypeTag](value:c.Expr[ScalaType]) = { 

    val scalaType: WeakTypeTag[ScalaType] = implicitly[WeakTypeTag[ScalaType]] 

    val fields = scalaType.tpe.typeSymbol.companion.typeSignature.members.collectFirst { 
     case method if method.name.toString == "apply" => method 
    }.toList.flatMap(_.asMethod.paramLists.flatten). 
     map{ 
     case s if s.name.toString == "id" => q"underlying.setId($value.$s.orNull)" 
     case s => q"underlying.${c.universe.newTermName("set" + s.name.toString.capitalize) }($value.$s)" 
    } 

    val javaType: WeakTypeTag[JavaType] = implicitly[WeakTypeTag[JavaType]] 

    q""" 
     val underlying = new ${javaType.tpe}() 
     ..$fields 
     underlying 
     """ 
    } 
} 

이 매크로 프로젝트를 컴파일 할 때 잘 컴파일 할 때 사용하려고합니다. 라이브러리 프로젝트 컴파일을 사용할 때 예외가 발생합니다.

private val x: IpDataEntry = IpDataEntry(None, "a", "a") 
println(Macros.encode[IpDataEntry, Underlying](x)) //not comp 


[error] Unknown type: <error>, <error> [class scala.reflect.internal.Types$ErrorType$, class scala.reflect.internal.Types$ErrorType$] TypeRef? false 
[trace] Stack trace suppressed: run 'last web/compile:compile' for the full output. 
[error] (web/compile:compile) scala.reflect.internal.FatalError: Unknown type: <error>, <error> [class scala.reflect.internal.Types$ErrorType$, class scala.reflect.internal.Types$ErrorType$] TypeRef? false 
[error] Total time: 12 s, completed Jun 19, 2014 11:53:42 AM 

여기에 붙어있어서 코드에서 아무 것도 잘못 찾을 수 없습니다.

스칼라 버전은 2.11.1입니다.

+0

전체 프로젝트를 공개 할 수 있습니까? 기둥에? –

+0

U는 내 목숨을 구했는데, 고마워. :) – jdevelop

답변

1

해결책을 직접 찾았습니다. 코드 블록

q"underlying.setId($value.$s.orNull)" 

$s은 TermName이 아닙니다. 그래서 수정했습니다.

q"underlying.setId($value.${c.universe.newTermName(s.name.toString)}.orNull)" 

어쨌든 오류가 구문 트리의 올바른 문제로 전달되는 경우 정말 유용합니다. 나는이 문제를 알아 내기 위해 약 2 일을 낭비한다.