Есть ли способ получить родительский класс из экземпляра внутреннего класса с использованием макросов, а не run-time reflection?Найти внешний класс, если предоставлен экземпляр внутреннего класса
У меня есть набор классов, как это:
trait IdProvider {
type IdObject = Id.type
case class Id(underlying: Int)
}
case class SomeEntity(id: SomeEntity.Id)
object SomeEntity extends IdProvider
И некоторый код, который работает с произвольными IdProvider#Id
с:
val lookup = Map[IdProvider#IdObject, Set[Operation]]
def can(operation: Operation, id: IdProvider#Id): Boolean = {
val idObject = findIdTypeFromInstance(id) // This is what I don't have
lookup.get(idObject).exists(s => s(operation))
}
Изъятие лист из this gist by Paul P. теперь у меня есть этот макрос:
def findIdTypeFromInstance[T <: AnyRef : c.WeakTypeTag](
c: blackbox.Context)(thing: c.Expr[T]): c.Expr[T] = {
import c.universe._
val companion = thing.actualType.typeSymbol.companion match {
case NoSymbol =>
c.abort(c.enclosingPosition, s"Instance of ${thing.actualType} has no companion object")
case sym => sym
}
def make[U: c.WeakTypeTag] = c.Expr[U](internal.gen.mkAttributedRef(companion))
make(c.WeakTypeTag(companion.typeSignature))
}
Это работает для более простых случаев (корпус верхнего уровня cla sses, classes и objects, и даже вложенные классы case). Однако при работе с IdProvider
установки над макро пытается генерировать это дерево:
Select(This(TypeName("IdProvider")), TermName("Id"))
Это приводит к очень длинной трассировки стека в моем тесте, который начинается с:
scala.reflect.internal.Types$TypeError: value is not a member of my.spec.MacroSpec
Я не имею был найден путь от экземпляра или компаньона (IdProvider#Id
) к родительскому классу (в данном случае SomeEntity
). Есть ли способ добраться до SomeEntity
или мне нужно использовать run-time reflection?
Это хорошая идея. Я уже разоблачаю внешний экземпляр (с помощью типа 'self'), чтобы я мог получить таким образом. –