Как создать подстановочный знак в макросе Scala?

Я не могу понять, как программно создавать экзистенциальные типы в макросах Scala.

Например, предположим, что у меня есть ClassSymbol, представляющий класс C[T] с одним параметром типа.

Теперь, как мне программно создать тип C[_ <: java.lang.Number]?

В частности, я понятия не имею, как использовать объект-конструктор ExistentialType. Глядя на его подпись:

def apply(quantified: List[Symbol], underlying: Type): ExistentialType

Что я передаю как quantified?


person ghik    schedule 05.12.2013    source источник


Ответы (1)


Насколько я понимаю, вам нужно создавать квантифицированные символы самостоятельно, задавая их подписи вручную. Вот сокращенная и адаптированная версия того, что -Ymacro-debug-lite напечатал, когда я компилировал typeOf[C[_ <: Number]]. Возможно, Джейсон или Пол знают ярлык, который позволяет избежать создания символов вручную, но я не уверен, что он существует в общедоступном API.

class C[T]

object Test extends App {
  import scala.reflect.runtime.universe._
  val c = typeOf[C[_]].typeSymbol
  val targ = build.newNestedSymbol(NoSymbol, newTypeName("_$1"), NoPosition, build.flagsFromBits(34359738384L), false)
  build.setTypeSignature(targ, TypeBounds(typeOf[Nothing], typeOf[Number]))
  println(ExistentialType(List(targ), TypeRef(c.owner.asClass.thisPrefix, c, List(TypeRef(NoPrefix, targ, Nil)))))
}
person Eugene Burmako    schedule 06.12.2013
comment
Большое спасибо. Хотя я не уверен, что это будет работать с владельцем NoSymbol. Я помню, как пытался что-то подобное и получил несколько сбоев. - person ghik; 06.12.2013
comment
И чтобы сделать этот фрагмент кода немного более понятным, флаги на самом деле DEFERRED | EXISTENTIAL. Последний, к сожалению, недоступен в общедоступном API. - person ghik; 06.12.2013
comment
Джейсон предлагает typer.packSymbols(sym.typeParams, sym.tpe) (для этого потребуется приведение к c.callsiteTyper), and then if you need to modify the type bounds of the underscore, use setTypeSignature` квантификаторов экзистенциального типа. - person Eugene Burmako; 07.12.2013