java bean类创建的scala宏未知类型错误

标签 scala macros scala-quasiquotes

我创建了以下代码片段,用作 scala 类型到 java 类型的编码生成器。

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

我被困在这里,在我的代码中找不到任何错误。

Scala 版本是 2.11.1。

最佳答案

我自己找到了解决方案。在代码块中

q"underlying.setId($value.$s.orNull)"
$s不是 TermName。所以我把它修改为
q"underlying.setId($value.${c.universe.newTermName(s.name.toString)}.orNull)"

无论如何,如果该错误指向语法树中的正确问题,它真的很有用。我浪费了大约 2 天的时间来找出问题所在。

关于java bean类创建的scala宏未知类型错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24313942/

相关文章:

string - 将字符串表达式转换为实际工作实例表达式

Scala:为案例类动态生成匹配子句

scala - 使用 Scala quasiquotes 提升字符串变量

list - 有没有像流这样的数据结构,但很弱?

scala - Scala 案例类的重载构造函数?

使用函数调用作为参数的 C 错误检查宏定义不会在 MSVC 上编译

c - 可变大小数组

scala - 确定 Scala 类中 Option 字段的类型

scala - 动态加载 Scala 编译器插件

objective-c - 如何将函数的结果作为宏变量传递?