Могу ли я получить пакет/владельца из ClassDef в реализации аннотации макроса Scala?

Учитывая (Скала 2.10.3),

package models
@MyAnnotation
case class MyClass() 

Как получить имя пакета в реализации макроса?

Я пробовал:

1) Было предложено typeCheck как здесь, но это приводит к переполнению стека (хотя я вижу, что он выдает правильное полное имя).

val result = {
  annottees.map(_.tree).toList match {

    case classDef @ q"$mods class $name[..$tparams](..$first)(...$rest) extends ..$parents { $self => ..$body }" :: Nil => {

    val full = c.typeCheck(q"??? : $name").tpe.typeSymbol.fullName
...

2) Сбор ClassDef и вызов .symbol показывает, что его нет.

Я бы хотел избежать:

3) Передача значения в качестве аргумента аннотации.

4) Аннотирование пакета и сохранение имени для использования при расширении класса.

5) Разбор .enclosingPosition контекста в надежде, что структура пакета и каталога соответствует.

Я испортил typeCheck? Должен ли я согласиться на № 3 или № 4? Любые предложения, как достичь моей цели?

Большое спасибо за любой вклад,

- Джулиан


person Julian Peeters    schedule 10.04.2014    source источник


Ответы (1)


Я бы проверил фиктивное определение, например. c.typeCheck(q"class Dummy${newTypeName(c.fresh())}"), а затем посмотрите на его символ. Проходя по цепочке Symbol.owner этого символа, вы обнаружите прилагаемый пакет.

person Eugene Burmako    schedule 10.04.2014
comment
Спасибо за предложение, это было бы здорово, но компилятор пожаловался: [error] Error occurred in an application involving default arguments. Итак, я добавил Modifiers() вот так: c.typeCheck(q"class Dummy ${newTypeName(c.fresh()); Modifiers() }") , но это привело к ошибке ввода: [error] last tree to typer: type Dummy [error] symbol: <none> (flags: ) [error] symbol definition: <none> [error] symbol owners: [error] context owners: -- Есть идеи? - person Julian Peeters; 11.04.2014
comment
Ах, вот на правильном пути: val freshName = c.fresh(newTypeName("Probe$")) val probe = c.typeCheck(q""" {class $freshName; ()} """) val owner = probe match { case Block(List(t), r) => t.symbol.owner } Премного обязан. - person Julian Peeters; 11.04.2014