Search code examples
scalareflectionmetaprogrammingscala-macrosaux-pattern

Get class that is being refined from the refinement


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?


Solution

  • 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