0

我有一个宏插件,它检查一个实体是否是一个案例类,然后以点表示法返回所有字段。

例如。

case class Language(name: String)
@Lenses
case class Page(a: Language)

所以主方法会返回

Seq("language.name")

这在 scala 2.11.6 和 2.11.8 中运行良好,但是,我刚刚将我的项目更新到 2.11.12,并且开始出现 GC 开销错误。

我以前的方法曾经被实现为:

def isCClass(tpe: Type): Boolean = {
  tpe.widen.dealias.typeSymbol.asInstanceOf[ClassSymbol].isCaseClass
}

正如我所提到的,它适用于 2.11.6 和 2.11.8,但在 2.11.12 中因转换错误而失败

exception during macro expansion:
[error] java.lang.ClassCastException:  scala.reflect.internal.Symbols$AbstractTypeSymbol cannot be cast to scala.reflect.api.Symbols$ClassSymbolApi

然后我更新了代码以匹配 typeSymbol,如下所示:

  def isCClass(tpe: Type): Boolean = {
    tpe.widen.dealias.typeSymbol match {
      case typeSymbol: ClassSymbol => typeSymbol.asInstanceOf[ClassSymbol].isCaseClass
      case _ => false
    }
  }

但是,这会导致以下错误:

exception during macro expansion: [error] java.lang.OutOfMemoryError: GC overhead limit exceeded

我已将内存增加到 3/4gb,但我得到了同样的错误。在我的 zsh 配置上使用:

alias sbt="sbt -mem 3092"

我通过几乎复制我感兴趣的实体的所有依赖项类型添加了一个规范,我有兴趣在我的插件项目中提取所有字段名称,包括@Lenses 依赖项和测试通过。但到目前为止还没有运气。

如果比赛很昂贵,任何提示

然而,在一个真正的项目中,它是一个大型代码库中的一个多模块,它会被 GC。

更新:我已经改变了比赛的实施:

def isCClass(tpe: Type): Boolean = {
    val tpeSymbol = tpe.widen.dealias.typeSymbol 
    if (tpeSymbol.isClass) tpeSymbol.asInstanceOf[ClassSymbol].isCaseClass else false
  }

这解决了 2.11.12 的问题,但是,我尝试使用具有深度嵌套类型的参数的实体回到 2.11.8,并且 GC 抛出错误。看起来这个宏扩展会导致一些开销或无限循环,因为我看到 java 编译器的内存在增加,即使我已经将内存增加到 12GB

4

0 回答 0