У меня есть некоторые проблемы с макросами scala и идентификацией реализованного типа конструктора. Не уверен, что я делаю что-то неправильно здесь или что будет правильным вызовом. Из документации, похоже, typeSignatureIn
должен возвращать правильную информацию, например. ClassTag [Int], но когда я запускаю макрос, я фактически получаю ClassTag [U], который не может скомпилироваться, поскольку U является параметром типа, а не реализованным типом.Получение реализованного типа для класса Scala с использованием макросов
import scala.language.experimental.macros
import scala.reflect.ClassTag
import scala.reflect.macros.Context
def macroImpl[T: c.WeakTypeTag](c: Context) = {
import c.universe._
val typeToMock = weakTypeOf[T]
val primaryConstructorOpt = typeToMock.members.collectFirst {
case method: MethodSymbolApi if method.isPrimaryConstructor => method
}
val constructorArgumentsTypes = primaryConstructorOpt.map {
constructor =>
val constructorTypeContext = constructor.typeSignatureIn(typeToMock)
val constructorArguments = constructor.paramss
constructorArguments.map { symbols =>
symbols.map(_.typeSignatureIn(constructorTypeContext))
}
}
println(typeToMock)
println(constructorArgumentsTypes)
c.literalUnit
}
def foo[T] = macro macroImpl[T]
class Foo[U: ClassTag]
foo[Foo[Int]]
запустить его:
scala> foo[Foo[Int]]
Foo[Int]
Some(List(List(), List(scala.reflect.ClassTag[U]))
Мне нужно, чтобы получить ClassTag [Int] каким-то образом, чтобы иметь возможность генерировать правильный дерево позже, какие-то идеи?
большое спасибо. Все еще изо всех сил пытаюсь интегрировать это в более широкую кодовую базу, но это дало мне хорошее руководство для того, –