가장 아래에 설명 된 펑키 시나리오의 비트 내부 객체 회원의 루트 형의 형태 인수를 가져옵니다.스칼라 매크로 : 클래스 정의
sealed trait Painting[T]
이 있고 그 다음에 trait ImpressionistPainting[T] extends Painting[T]
등과 같이 더 특수화 된 유사 콘텐츠가 있다고 가정하면 간단한 밀폐 유형 제품군을 구축 할 수 있습니다.
class Gallery[T <: Gallery[T]]()(implicit helper: GalleryHelper[T])
그리고 :
trait GalleryHelper[T <: Gallery[T]] {
def paintings: Set[Painting[_]]
}
object GalleryHelper {
implicit def materialize[T <: Gallery[T]]: GalleyHelper[T] = {
macro MyMacro.materialize[T]
}
def apply[T <: Gallery[T]]()(
implicit ev: GalleryHelper[T]
): GalleryHelper[T] = ev
}
지금까지 아주 기본적이고 간단 foo는 바 코드
나는 다음 F와 클래스 다형성과 같은 바인딩 유형을 경계해야합니다.
매크로 같은, 내가 갤러리를 설명하거나 임의의 "사용자 콘텐츠"입력이 경우에해야 할 항목의 도우미 목록을 구체화에이 설정의 전체 목표는 :
class MyGallery extends Gallery[MyGallery] {
object `le-reve` extends CubistPainting[Picasso]
object starry_night extends PostImpressionistPainting[VanGogh]
// ..
}
을 이제와 나는 매크로 원하는 일부 매크로의 compat 재미는 문제의 도우미를 실현하고 MemberType <:< Painting[_]
을있는 사람들을 추출 T <: Gallery[T]
의 멤버를 필터링 할 수 있습니다.
모두 매우 간단합니다. 아래에 표시된 것은 상속 된 모든 멤버의 목록을 작성된 순서대로 반환해야하기 때문에 간단히 type.decls.filter(_.typeSignature <:< typeOf[Filter]
보다 복잡합니다. 주어진 갤러리는 다른 갤러리를 확장합니다.
def findMembersWithBound[T : WeakTypeTag, Filter : TypeTag](
exclusions: Symbol => Option[Symbol] = { s: Symbol => Some(s) }
): Set[Symbol] = {
val tpe = weakTypeOf[T].typeSymbol.typeSignature
(
for {
baseClass <- tpe.baseClasses.reverse.flatMap(exclusions(_))
symbol <- baseClass.typeSignature.members.sorted
if symbol.typeSignature <:< typeOf[Filter]
} yield symbol
)(collection.breakOut)
}
그래서 암시 매크로, 타입 T에 대한 모듈 멤버의 기본 탐색이 경우 Painting[_]
에, 하위 유형별로 필터링 할 필요가 다음 사용자 경우가 제공하는 어떤 특정 유형의 인수를 보면 변형 유형은 Painting
입니다. 이것은 어떤 식 으로든 관련이 경우 사용자가 직접 object
와 Painting[_]
을 Painting
의 하위 클래스를 결코 확장하지 않도록 유형 제품군은 밀봉된다.
@macrocompat.bundle
class MyMacro(val c: blackbox.Context) {
import c.universe._
def materialize[T <: Gallery[T]]: Tree = {
val galleryTpe = weakTypeOf[T]
val fields = findMembersWithBound[T, Painting[_]](exclusions)
val colMembers = sourceMembers.map { member =>
val memberType = member.typeSignatureIn(galleryTpe)
memberType.baseClasses.find(colSymbol ==) match {
case Some(root) => {
// Herein lies the problem, typeArgs is Nil.
root.typeSignatureIn(memberType).typeArgs.headOption match {
case Some(colSignature) => colSignature
case None => c.abort(
c.enclosingPosition,
s"Could not find the artist for ${member.asModule.name}"
)
}
}
case None => c.abort(c.enclosingPosition, s"Could not find root painting type for ${member.asModule.name}")
}
}
}
문제는 Painting
로 전달 원래의 형태 인수 중 어느 것도 typeSignature
가 범위 등을 평가하는 apper 것에도 불구하고, 더 이상 볼 수없고, 단순히 확인 반을 만들기 위해 노력하고 있다는 것입니다 고흐는 유명한 월도가되지 않습니다.
그러나 다른 dealias
나에 대한 올바른 API는 다시 그 typeArgs
볼 수 있도록 무엇입니까? 현재 비어있는 목록입니다.