Я пытаюсь изменить плагин компилятора, написанный другим человеком, который запускается сразу после типизатора, и я хочу сгенерировать код, который генерирует исключение.
Класс исключения выглядит так:
case class MyException(message: String) extends Exception(message)
Однако в реальном коде это внутренний класс.
Я посмотрел, как он получил символы фиксированного класса и сделал это аналогично, не знаю, есть ли способ лучше, но вот как он это сделал:
val exceptionClass = MyException.getClass.getName
val exceptionName = if (exceptionClass.last == '$') exceptionClass.dropRight(1) else exceptionClass
val symbol = rootMirror.getModuleByName(newTermName(exceptionName))
Чтобы бросить исключение, я сделал это:
import CODE._
THROW(symbol, Literal(Constant("My message")))
Я думаю, что следующее также эквивалентно (и дает эквивалентное поведение)
Throw(symbol.tpe, Literal(Constant("My Message")))
Throw(NEW(symbol, Literal(Constant("My message"))))
Throw(New(symbol.tpe, Literal(Constant("My message"))))
Но у меня есть исключение:
== Enclosing template or block ==
Apply( // val <error>: <error> in class <error>
new MyException.type."<init>" // val <error>: <error> in class <error>, tree.tpe=<error>
Nil
)
== Expanded type of tree ==
TypeRef(TypeSymbol(class MyException extends ))
uncaught exception during compilation: scala.reflect.internal.Types$TypeError
error: scala.reflect.internal.Types$TypeError: MyException.type does not have a constructor
...
Я полагаю, мне как-то придется использовать "новое" по-другому, кто-нибудь знает, как это делается правильно?