我想将我的scalac
插件拆分成多个文件。这听起来很容易,但由于源自import global._
行的路径依赖类型问题,我无法将其拉下来。
这是Lex Spoon的示例插件:
package localhost
import scala.tools.nsc
import nsc.Global
import nsc.Phase
import nsc.plugins.Plugin
import nsc.plugins.PluginComponent
class DivByZero(val global: Global) extends Plugin {
import global._
val name = "divbyzero"
val description = "checks for division by zero"
val components = List[PluginComponent](Component)
private object Component extends PluginComponent {
val global: DivByZero.this.global.type = DivByZero.this.global
val runsAfter = "refchecks"
// Using the Scala Compiler 2.8.x the runsAfter should be written as below
// val runsAfter = List[String]("refchecks");
val phaseName = DivByZero.this.name
def newPhase(_prev: Phase) = new DivByZeroPhase(_prev)
class DivByZeroPhase(prev: Phase) extends StdPhase(prev) {
override def name = DivByZero.this.name
def apply(unit: CompilationUnit) {
for ( tree @ Apply(Select(rcvr, nme.DIV), List(Literal(Constant(0)))) <- unit.body;
if rcvr.tpe <:< definitions.IntClass.tpe)
{
unit.error(tree.pos, "definitely division by zero")
}
}
}
}
}
如何在Component
的范围内放置DivByZeroPhase
和import global._
在自己的文件中?
答案 0 :(得分:4)
这是一个非常古老的项目,我做了同样的事情:
如果您不需要从全局传递路径相关类型,请不要担心尝试保持其“this.global”部分相关。
答案 1 :(得分:3)
在Scala Refactoring库中,我通过使用特征CompilerAccess来解决它:
trait CompilerAccess {
val global: tools.nsc.Global
}
现在需要访问global
的所有其他特征只是将CompilerAccess
声明为依赖:
trait TreeTraverser {
this: CompilerAccess =>
import global._
...
}
然后有一个类混合了所有这些特征并提供了一个全局实例:
trait SomeRefactoring extends TreeTraverser with OtherTrait with MoreTraits {
val global = //wherever you get your global from
}
这个方案对我来说效果很好。
答案 2 :(得分:2)
您可以为组件创建单独的类并传递全局:
class TemplateComponent(val global: Global) extends PluginComponent {
import global._
val runsAfter = List[String]("refchecks")
val phaseName = "plugintemplate"
def newPhase(prev: Phase) = new StdPhase(prev) {
override def name = phaseName
def apply(unit:CompilationUnit) = {
}
}
}