Get class that is being refined from the refinement

97 Views Asked by At

Consider the following sealed trait:

sealed trait Type

object Type {
    case object S
}

sealed trait Test{
    type Tpe <: Type
}

object Test {
    type Aux[T <: Type] = Test{ type Tpe = T }
}

Given a ClassSymbol denoting Test.Aux[S.type] is there a way to get a ClassSymbol denoting sealed trait Test?

2

There are 2 best solutions below

0
Dmytro Mitin On BEST ANSWER

OP's solution uses symbol internals (scala.reflect.internal.Symbols#Symbol).

This is solution via types:

val symbol1: ClassSymbol = typeOf[Aux[Type.S.type]].typeSymbol.asClass
val symbol2: ClassSymbol = typeOf[Test].typeSymbol.asClass

val symbol2_ = symbol1.typeSignature match {
  case RefinedType(List(parent), decls) => parent.typeSymbol.asClass
} 

symbol2_ == symbol2 // true
0
Some Name On

After digging in the API I found the following solution:

def refinedSealedTrait(symbol: Symbols#Symbol): Symbols#Symbol = {
  if (!symbol.isRefinementClass) {
    c.abort(...)
  }
  val parents = symbol.parentSymbols
  if (parents.size != 1) {
    c.abort(...)
  }
  val parentSymbol = parents.iterator.next

  if (parentSymbol.isSealed && parentSymbol.isTrait) {
    parentSymbol
  } else {
    c.abort(...)
  }
}