0

I have a macros plugin that checks if an entity is a case class and then returns all fields in a dot notation.

Eg.

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

So the main method would return

Seq("language.name")

This has been working fine with scala 2.11.6 and 2.11.8, however, I've just updated my project to 2.11.12 and I started having a GC overhead error.

My previous method used to be implemented as:

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

As I mentioned it worked on 2.11.6 and 2.11.8, but fails with a casting error in 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

Then I updated the code to match the typeSymbol as follows:

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

However this is resulting in the following error:

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

I've increased my memory to 3/4gb but I get the same error. using on my zsh config:

alias sbt="sbt -mem 3092"

I've added a spec by almost copying all dependency types for the entity I was interested in pulling all field names on my plugin project including the @Lenses dependency and the test passes. but no luck so far.

Any hints if the match is expensive

However, on a real project which is a multi module in a large codebase it GCs.

UPDATE: I've changed the implementation of the match with:

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

This solves the issue with 2.11.12, however, I'm trying back to 2.11.8 with an entity with parameter with deep nested types and the GC throws the error. It looks like this macro expansion is causing some overhead or infinite loop, because I see the memory of the java compiler going up even though I've increased the memory to 12GB

raul782
  • 479
  • 1
  • 5
  • 15
  • Can't reproduce. In 2.11.12 both implementations of `isCClass` work: https://gist.github.com/DmytroMitin/e0f03a6b48997be46b544611a742786a Or even `def isCClass(tpe: Type): Boolean = tpe.widen.dealias.typeSymbol.asClass.isCaseClass` – Dmytro Mitin Jul 08 '18 at 10:34
  • Did I mention that a trait called PageHelper calls this in a macro and within this, I loop over all the fields of the class and if a if it’s a type I add it to recursively extract the full path of each field. I’ll update my question in a few. – raul782 Jul 08 '18 at 21:52

0 Answers0