summaryrefslogblamecommitdiff
path: root/sources/scala/tools/nsc/typechecker/Contexts.scala
blob: bbc965c4684c6746d97d1adbca269a0077eb57d9 (plain) (tree)



















                                                                                 
                                                                                              












                                    








                                                                                    









                                                                                         
                                                                












































                                                                          
/* NSC -- new scala compiler
 * Copyright 2005 LAMP/EPFL
 * @author  Martin Odersky
 */
// $Id$
package scala.tools.nsc.typechecker;

import scala.tools.util.Position;

class Contexts: Analyzer {
  import global._;

  val NoContext = new Context();

  val startContext = {
    import definitions._;
    var sc = NoContext.make(EmptyTree, RootClass, RootClass.info.decls);
    def addImport(pkg: Symbol): unit = {
      sc = sc.make(sc.tree, sc.owner, new Scope(sc.scope));
      val impTree = Import(gen.mkGlobalRef(pkg), List(Pair(nme.WILDCARD, null)));
      impTree.setSymbol(NoSymbol.newImport(Position.NOPOS)).setType(this.ImportType(impTree));
      sc.scope.enter(impTree.symbol)
    }
    if (!settings.noimports.value) {
      addImport(JavaLangPackage);
      addImport(ScalaPackage);
      if (!settings.nopredefs.value)
	addImport(PredefModule);
    }
    sc
  }

  class Context {
    var unit: CompilationUnit = _;
    var tree: Tree = _;                     // Tree associated with this context
    var owner: Symbol = _;                  // The current owner
    var scope: Scope = _;                   // The current scope
    var outer: Context = _;                 // The next outer context
    var enclClass: Context = this;          // The next outer context whose tree
					    // is a class template
    var variance: int = _;                  // Variance relative to enclosing class.
    var undetparams: List[Symbol] = List(); // Undetermined type parameters
    var constructorClass: Symbol = _;       // Class for auxiliary constructor
    var depth: int = 0;
    val imports: List[Tree] = List();

    def make(unit: CompilationUnit, tree: Tree, owner: Symbol, scope: Scope): Context = {
      val c = new Context();
      c.unit = unit;
      c.tree = tree;
      c.owner = owner;
      c.scope = scope;
      c.enclClass = if ((tree.isInstanceOf[Template] ||
			 tree.isInstanceOf[CompoundTypeTree]) &&
			tree != this.tree) c
		    else this.enclClass;
      c.variance = this.variance;
      c.constructorClass = this.constructorClass;
      c.depth = this.depth + 1;
      c.outer = this;
      c
    }

    def make(unit: CompilationUnit): Context =
      make(unit, EmptyTree, this.owner, new Scope(this.owner.info.decls));

    def make(tree: Tree, owner: Symbol, scope: Scope): Context =
      make(this.unit, tree, owner, scope);

    def makeNewScope(tree: Tree, owner: Symbol): Context =
      make(tree, owner, new Scope(this.scope));

    def make(tree: Tree, owner: Symbol): Context =
      make(tree, owner, this.scope);

    def make(tree: Tree): Context =
      make(tree, this.owner);

    def outerContext(clazz: Symbol): Context = {
      var c = this;
      while (c != NoContext && c.owner != clazz) c = c.outer.enclClass;
      c
    }

    def isLocal(): boolean = tree match {
      case Block(_,_) => true
      case PackageDef(_, _) => false
      case EmptyTree => false
      case _ => outer.isLocal()
    }

    override def toString(): String = {
      if (this == NoContext) "NoContext";
      else tree.toString() + "\n:: " + outer.toString()
    }
  }
}