2011-04-12 6 views
6

Je voudrais diviser mon plugin scalac en plusieurs fichiers. Cela semble facile, mais je n'ai pas réussi à le retirer en raison de problèmes de type dépendant du chemin provenant de la ligne import global._.Diviser le plugin scalac en plusieurs fichiers

est ici plugin exemple de 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") 
      } 
     } 
    } 
    } 
} 

Comment puis-je mettre Component et DivByZeroPhase dans leurs propres fichiers sans avoir la import global._ portée?

Répondre

2

Vous pouvez créer une catégorie distincte pour votre composant et passer global dans:

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) = { 
    }  
    } 
} 
3

Dans la bibliothèque Scala refactorisation, je l'ai résolu en ayant un trait CompilerAccess:

trait CompilerAccess { 
    val global: tools.nsc.Global 
} 

Maintenant, tous les d'autres traits qui doivent accéder global simplement déclarer CompilerAccess en tant que dépendance:

trait TreeTraverser { 
    this: CompilerAccess => 
    import global._ 

    ... 
} 

puis il y a une classe qui se mélange dans tous ces traits et fournit une instance de global:

trait SomeRefactoring extends TreeTraverser with OtherTrait with MoreTraits { 
    val global = //wherever you get your global from 
} 

Ce système fonctionnait très bien pour moi.

Questions connexes