Scala typeprovider宏扩展期间的堆栈溢出

Scala typeprovider宏扩展期间的堆栈溢出,scala,scala-macros,type-providers,Scala,Scala Macros,Type Providers,我在玩一些宏,我认为编写一个json类型的提供程序是一个很好的开始,可以更深入地了解所有这些是如何工作的,但是我遇到了一个奇怪的错误,我自己似乎无法理解。如果您想查看全部内容,可以在GitHub上找到代码: 有问题的部分是,我试图使它尽可能的类型安全,这意味着我希望以这样一种方式实现json数组,即对它们进行索引将返回正确的类型(作为后续的宏调用)。守则的有关方法: json到树方法: def jsonToTpe(value: JValue): Option[Tree] = value matc

我在玩一些宏,我认为编写一个json类型的提供程序是一个很好的开始,可以更深入地了解所有这些是如何工作的,但是我遇到了一个奇怪的错误,我自己似乎无法理解。如果您想查看全部内容,可以在GitHub上找到代码:

有问题的部分是,我试图使它尽可能的类型安全,这意味着我希望以这样一种方式实现json数组,即对它们进行索引将返回正确的类型(作为后续的宏调用)。守则的有关方法:

json到树方法:

def jsonToTpe(value: JValue): Option[Tree] = value match {
  case JNothing => None
  case JNull => None
  case JString(s) => Some(q"$s")
  case JDouble(d) => Some(q"$d")
  case JDecimal(d) => Some(q"scala.BigDecimal(${d.toString})")
  case JInt(i) => Some(q"scala.BigInt(${i.toByteArray})")
  case JLong(l) => Some(q"$l")
  case JBool(b) => Some(q"$b")
  case JArray(arr) =>
    val arrTree = arr.flatMap(jsonToTpe)

    val clsName = c.freshName[TypeName](TypeName("harraycls"))
    val hArray =
      q"""
         class $clsName {
           @_root_.com.example.json.provider.body(scala.Array[Any](..$arrTree))
           def apply(i: Int): Any = macro _root_.com.example.json.provider.DelegatedMacros.arrApply_impl

           @_root_.com.example.json.provider.body(scala.Array[Any](..$arrTree))
           def toArray: scala.Array[Any] = macro _root_.com.example.json.provider.DelegatedMacros.selectField_impl
         }
         new $clsName {}
       """

    Some(hArray)
  case JSet(set) => Some(q"scala.Set(..${set.flatMap(jsonToTpe)})")
  case JObject(fields) =>
    val fs = fields.flatMap { case (k, v) =>
      jsonToTpe(v).map(v => q"""
        @_root_.com.example.json.provider.body($v) def ${TermName(k)}: Any =
          macro _root_.com.example.json.provider.DelegatedMacros.selectField_impl""")
    }

    val clsName = c.freshName[TypeName](TypeName("jsoncls"))
    Some(q"""
       class $clsName {
        ..$fs
       }
       new $clsName {}
     """)
}
阅读注释:

class body(tree: Any) extends StaticAnnotation

def arrApply_impl(c: whitebox.Context)(i: c.Expr[Int]): c.Tree = {
  import c.universe._

  def bail(msg: String): Nothing = {
    c.abort(c.enclosingPosition, msg)
  }

  def error(msg: String): Unit = {
    c.error(c.enclosingPosition, msg)
  }

  val arrValue = selectField_impl(c)
  val arrElems = arrValue match {
    case q"scala.Array.apply[$tpe](..$elems)($cls)" => elems
    case _ => bail("arr needs to be an array of constants")
  }
  val idx = i.tree match {
    case Literal(Constant(ix: Int)) => ix
    case _ => bail(s"i needs to be a constant Int, got ${showRaw(i.tree)}")
  }

  arrElems(idx)
}

def selectField_impl(c: whitebox.Context) : c.Tree = {
  c.macroApplication.symbol.annotations.filter(
    _.tree.tpe <:< c.typeOf[body]
  ).head.tree.children.tail.head
}
这就是我调用它的方式:

val tpe3 = TypeProvider("arrayofobj.json")
println(tpe3.toArray.mkString(", "))
读取INT数组或基元字段对象的工作方式与预期相同,但对象数组在编译期间引发堆栈溢出:

[error] /home/isti/projects/json-typeprovider/core/src/main/scala/com/example/Hello.scala:7:14: Internal error: unable to find the outer accessor symbol of object Hello
[error] object Hello extends App {
[error]              ^
[error] ## Exception when compiling 1 sources to /home/isti/projects/json-typeprovider/core/target/scala-2.12/classes
[error] null
[error] java.lang.String.valueOf(String.java:2994)
[error] scala.collection.mutable.StringBuilder.append(StringBuilder.scala:200)
[error] scala.collection.TraversableOnce.$anonfun$addString$1(TraversableOnce.scala:359)
[error] scala.collection.immutable.List.foreach(List.scala:389)
[error] scala.collection.TraversableOnce.addString(TraversableOnce.scala:357)
[error] scala.collection.TraversableOnce.addString$(TraversableOnce.scala:353)
[error] scala.collection.AbstractTraversable.addString(Traversable.scala:104)
[error] scala.collection.TraversableOnce.mkString(TraversableOnce.scala:323)
[error] scala.collection.TraversableOnce.mkString$(TraversableOnce.scala:322)
[error] scala.collection.AbstractTraversable.mkString(Traversable.scala:104)
[error] scala.collection.TraversableOnce.mkString(TraversableOnce.scala:325)
[error] scala.collection.TraversableOnce.mkString$(TraversableOnce.scala:325)
[error] scala.collection.AbstractTraversable.mkString(Traversable.scala:104)
[error] scala.collection.TraversableOnce.mkString(TraversableOnce.scala:327)
[error] scala.collection.TraversableOnce.mkString$(TraversableOnce.scala:327)
[error] scala.collection.AbstractTraversable.mkString(Traversable.scala:104)
[error] xsbt.DelegatingReporter$.makePosition$1(DelegatingReporter.scala:89)
[error] xsbt.DelegatingReporter$.convert(DelegatingReporter.scala:94)
[error] xsbt.DelegatingReporter.info0(DelegatingReporter.scala:125)
[error] xsbt.DelegatingReporter.info0(DelegatingReporter.scala:102)
[error] scala.reflect.internal.Reporter.error(Reporting.scala:84)
[error] scala.reflect.internal.Reporting.globalError(Reporting.scala:69)
[error] scala.reflect.internal.Reporting.globalError$(Reporting.scala:69)
[error] scala.reflect.internal.SymbolTable.globalError(SymbolTable.scala:16)
[error] scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerSelect(ExplicitOuter.scala:235)
[error] scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerPath(ExplicitOuter.scala:267)
[error] scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerPath(ExplicitOuter.scala:267)
[error] scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerPath(ExplicitOuter.scala:267)
[error] scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerPath(ExplicitOuter.scala:267)
[error] scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerPath(ExplicitOuter.scala:267)
[error] scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerPath(ExplicitOuter.scala:267)
[error] scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerPath(ExplicitOuter.scala:267)
[error] scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerPath(ExplicitOuter.scala:267)

编辑:这只是堆栈跟踪的顶部,还有更多的
scala.tools.nsc.transform.explicitoter$OuterPathTransformer.outerPath(explicitoter.scala:267)

你知道吗?我遇到了一个类似的问题。不,我放弃了,因为当我在这里问的时候,我已经束手无策了。斯卡拉是个弱智,巴基,你知道吗?我遇到了一个类似的问题。不,我放弃了,因为当我在这里问起这个问题的时候,我已经束手无策了。斯卡拉是个弱智和有车的人
[error] /home/isti/projects/json-typeprovider/core/src/main/scala/com/example/Hello.scala:7:14: Internal error: unable to find the outer accessor symbol of object Hello
[error] object Hello extends App {
[error]              ^
[error] ## Exception when compiling 1 sources to /home/isti/projects/json-typeprovider/core/target/scala-2.12/classes
[error] null
[error] java.lang.String.valueOf(String.java:2994)
[error] scala.collection.mutable.StringBuilder.append(StringBuilder.scala:200)
[error] scala.collection.TraversableOnce.$anonfun$addString$1(TraversableOnce.scala:359)
[error] scala.collection.immutable.List.foreach(List.scala:389)
[error] scala.collection.TraversableOnce.addString(TraversableOnce.scala:357)
[error] scala.collection.TraversableOnce.addString$(TraversableOnce.scala:353)
[error] scala.collection.AbstractTraversable.addString(Traversable.scala:104)
[error] scala.collection.TraversableOnce.mkString(TraversableOnce.scala:323)
[error] scala.collection.TraversableOnce.mkString$(TraversableOnce.scala:322)
[error] scala.collection.AbstractTraversable.mkString(Traversable.scala:104)
[error] scala.collection.TraversableOnce.mkString(TraversableOnce.scala:325)
[error] scala.collection.TraversableOnce.mkString$(TraversableOnce.scala:325)
[error] scala.collection.AbstractTraversable.mkString(Traversable.scala:104)
[error] scala.collection.TraversableOnce.mkString(TraversableOnce.scala:327)
[error] scala.collection.TraversableOnce.mkString$(TraversableOnce.scala:327)
[error] scala.collection.AbstractTraversable.mkString(Traversable.scala:104)
[error] xsbt.DelegatingReporter$.makePosition$1(DelegatingReporter.scala:89)
[error] xsbt.DelegatingReporter$.convert(DelegatingReporter.scala:94)
[error] xsbt.DelegatingReporter.info0(DelegatingReporter.scala:125)
[error] xsbt.DelegatingReporter.info0(DelegatingReporter.scala:102)
[error] scala.reflect.internal.Reporter.error(Reporting.scala:84)
[error] scala.reflect.internal.Reporting.globalError(Reporting.scala:69)
[error] scala.reflect.internal.Reporting.globalError$(Reporting.scala:69)
[error] scala.reflect.internal.SymbolTable.globalError(SymbolTable.scala:16)
[error] scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerSelect(ExplicitOuter.scala:235)
[error] scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerPath(ExplicitOuter.scala:267)
[error] scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerPath(ExplicitOuter.scala:267)
[error] scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerPath(ExplicitOuter.scala:267)
[error] scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerPath(ExplicitOuter.scala:267)
[error] scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerPath(ExplicitOuter.scala:267)
[error] scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerPath(ExplicitOuter.scala:267)
[error] scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerPath(ExplicitOuter.scala:267)
[error] scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerPath(ExplicitOuter.scala:267)