2012-12-04 55 views
1

我想改变一个编译器插件一些其他人写了哪些typer后直接运行,我想生成引发异常的代码。斯卡拉编译器生成抛出代码

Exception类看起来像这样:

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 
... 

我想我无论如何都必须用“新”的方式不同,没有人知道这是如何正确地完成?

回答

2

有人斯卡拉邮件列表告诉我的解决方案:

我应该得到的符号不同,我需要的类的符号,而不是模块,后者使用,如果它是一个对象调用它等方法,但我们需要这里的类,所以不是

val symbol = rootMirror.getModuleByName(newTermName(exceptionName)) 

我写

val symbol = rootMirror.getClassByName(newTermName(exceptionName))