treecheckers.scala

来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 154 行

SCALA
154
字号
/* NSC -- new Scala compiler * Copyright 2005-2007 LAMP/EPFL * @author  Martin Odersky */// $Id: TreeCheckers.scala 13819 2008-01-28 18:43:24Z odersky $package scala.tools.nsc.typecheckerimport scala.tools.nsc.symtab.Flags._import scala.tools.nsc.util.{Position, NoPosition}abstract class TreeCheckers extends Analyzer {  import global._  val tpeOfTree = new scala.collection.mutable.HashMap[Tree, Type]  def checkTrees {    Console.println("[consistency check at start of phase " + phase + "]")    for (unit <- currentRun.units) check(unit)  }  def check(unit: CompilationUnit) {    informProgress("checking "+unit)    val context = rootContext(unit)    context.checking = true    tpeOfTree.clear    val checker = new TreeChecker(context)    val unit0 = currentRun.currentUnit    currentRun.currentUnit = unit    checker.precheck.traverse(unit.body)    checker.typed(unit.body)    checker.postcheck.traverse(unit.body)    currentRun.advanceUnit    assert(currentRun.currentUnit == unit)    currentRun.currentUnit = unit0  }  override def newTyper(context: Context): Typer = new TreeChecker(context)  class TreeChecker(context0: Context) extends Typer(context0) {    import infer._    override def typed(tree: Tree, mode: Int, pt: Type): Tree = {      tree match {        case EmptyTree | TypeTree() =>          ;        case _ =>          try {            if (!tpeOfTree.contains(tree)) {              tpeOfTree.update(tree, tree.tpe)              tree.tpe = null            }            val newtree = super.typed(tree, mode, pt);            if ((newtree ne tree) && !newtree.isInstanceOf[Literal])              error(tree.pos, "trees differ\n old: " + tree + " [" + tree.getClass() +                    "]\n new: " + newtree + " [" + newtree.getClass() + "]")          } catch {            case ex: Throwable =>              Console.println("exception while typing "+tree)              throw ex          }      }      tree    }    object precheck extends Traverser {      override def traverse(tree: Tree) {        try {          tree match {            case DefDef(_, _, _, _, _, _) =>              if (tree.symbol.hasFlag(ACCESSOR) &&                   !tree.symbol.isDeferred &&                  !tree.symbol.tpe.resultType.isInstanceOf[ConstantType]) {                assert(tree.symbol.accessed != NoSymbol, tree.symbol)                assert(tree.symbol.accessed.getter(tree.symbol.owner) == tree.symbol ||                       tree.symbol.accessed.setter(tree.symbol.owner) == tree.symbol)              }            case ValDef(_, _, _, _) =>              if (tree.symbol.hasGetter) {                assert(tree.symbol.getter(tree.symbol.owner) != NoSymbol, tree.symbol)              }            case Apply(_, args) =>              assert(args forall (EmptyTree !=))            case Select(_, _) =>              assert(tree.symbol != NoSymbol, tree)            case This(_) =>              if (!(tree.symbol.isStatic && (tree.symbol hasFlag MODULE))) {                var o = currentOwner                while (o != tree.symbol) {                  o = o.owner                  if (o == NoSymbol) {                    error(tree.pos, "tree symbol "+tree.symbol+" does not point to enclosing class; tree = "+tree)                    return                  }                }              }            case _ =>          }          if (tree.pos == NoPosition && tree != EmptyTree) {            error(tree.pos, "tree without position: " + tree)          } else if ((tree.tpe eq null) && phase.id >= currentRun.typerPhase.id) {            error(tree.pos, "tree without type: " + tree)          } else if (tree.isDef && tree.symbol.owner != currentOwner) {            var owner = currentOwner            while (owner.isTerm && !owner.isMethod && tree.symbol.owner != owner)              owner = owner.owner;            if (tree.symbol.owner != owner) {              error(tree.pos, "" + tree.symbol + " has wrong owner: " + tree.symbol.owner +                    tree.symbol.owner.locationString + ", should be: " +                    currentOwner + currentOwner.locationString)            }          } else {            super.traverse(tree)          }        } catch {          case ex: Throwable =>            if (settings.debug.value)              Console.println("exception when traversing " + tree);            throw(ex)        }      }    }    object postcheck extends Traverser {      override def traverse(tree: Tree) {        try {          tree match {            case EmptyTree | TypeTree() =>              ;            case _ =>              tpeOfTree.get(tree) match {                case Some(oldtpe) =>                  if (!(oldtpe =:= tree.tpe))                    error(tree.pos, "types differ\n old: " + oldtpe +                          "\n new: " + tree.tpe + "\n tree: " + tree)                  tree.tpe = oldtpe                  super.traverse(tree)                case None =>              }          }        } catch {          case ex: Throwable =>            if (settings.debug.value)              Console.println("exception when traversing " + tree);            throw(ex)        }      }    }  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?