我正在开发一个 Scala 编译器插件,试图转换每个函数调用,比如
myfuncall(1)
进入
val newvalue = myfuncall(1)
newvalue
但是,当函数调用是另一个函数的返回值时,我会遇到麻烦。这是我要转换的代码
class A[C]
class B[C] extends A[C]
trait MyTrait[C] {
def func1: A[C]
}
object MyObject extends MyTrait[Int] {
def func1 = new B
}
在上面的示例中,编译器可以成功推断出 的结果new B应该转换为A[Int],因为func1in应该具有与inMyObject相同的返回类型。func1MyTrait[Int]
但是,当我使用编译器插件进行转换时会出现问题。
class A[C]
class B[C] extends A[C]
trait MyTrait[C] {
def func1: A[C]
}
object MyObject extends MyTrait[Int] {
def func1 = {
val newvalue = new B
newvalue
}
}
现在,newvalue不提供任何额外的类型信息,而是编译器必须推断它。结果类型newvalue是B[Nothing],这是编译器可以推断的最具体的类型。
然后当我尝试newvalue作为func1. func1requires A[Int], whilenewvalue是 type B[Nothing],无法匹配。
如果我能提前知道所需的返回类型,问题就可以解决func1,因为我可以newvalue用这个返回类型指定,如下所示
class A[C]
class B[C] extends A[C]
trait MyTrait[C] {
def func1: A[C]
}
object MyObject extends MyTrait[Int] {
def func1 = {
val newvalue: A[Int] = new B
newvalue
}
}
上面的代码可以编译成功。
我的问题是,在编写 Scala 编译器插件时,我怎么知道func1in的返回类型,因为 的签名并没有告诉它的返回类型。MyObjectA[Int]func1
我认为找出编译器如何从in的签名中获取inA[Int]的返回类型也很有帮助。 func1MyObjectfunc1MyTrait[Int]
当MyTrait和MyObject被定义在两个不同的源文件中时,这个问题就变得更加困难了。