有沒有辦法使用宏而不是從內部類的實例獲取父類,而不是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類,對象,甚至嵌套的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'類型),所以我可能能夠以這種方式獲得。 –