summaryrefslogtreecommitdiff
path: root/sources/scala/tools/nsc/typechecker/Contexts.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2005-03-07 21:16:40 +0000
committerMartin Odersky <odersky@gmail.com>2005-03-07 21:16:40 +0000
commitaa77b6d1ec06bcec09d360b9032b90a023d10c4e (patch)
treeb696a47022b94f0b4100f28c663c1452900975a0 /sources/scala/tools/nsc/typechecker/Contexts.scala
parent52696417c6c84889d903144d70b9fb5c25fd1f4c (diff)
downloadscala-aa77b6d1ec06bcec09d360b9032b90a023d10c4e.tar.gz
scala-aa77b6d1ec06bcec09d360b9032b90a023d10c4e.tar.bz2
scala-aa77b6d1ec06bcec09d360b9032b90a023d10c4e.zip
*** empty log message ***
Diffstat (limited to 'sources/scala/tools/nsc/typechecker/Contexts.scala')
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Contexts.scala90
1 files changed, 73 insertions, 17 deletions
diff --git a/sources/scala/tools/nsc/typechecker/Contexts.scala b/sources/scala/tools/nsc/typechecker/Contexts.scala
index bbc965c468..65e8b0925d 100755
--- a/sources/scala/tools/nsc/typechecker/Contexts.scala
+++ b/sources/scala/tools/nsc/typechecker/Contexts.scala
@@ -10,16 +10,22 @@ import scala.tools.util.Position;
class Contexts: Analyzer {
import global._;
- val NoContext = new Context();
+ val NoContext = new Context {
+ override def imports: List[ImportInfo] = List();
+ }
val startContext = {
import definitions._;
- var sc = NoContext.make(EmptyTree, RootClass, RootClass.info.decls);
+ var sc = NoContext.make(
+ Template(List(), List()) setSymbol NoSymbol setType NoType,
+ definitions.RootClass,
+ definitions.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)
+ val impTree = Import(gen.mkGlobalRef(pkg), List(Pair(nme.WILDCARD, null)))
+ setSymbol NoSymbol.newImport(Position.NOPOS).setInfo(pkg.tpe)
+ setType NoType;
+ sc = sc.make(
+ Template(List(), List(impTree)) setSymbol NoSymbol setType NoType, sc.owner, sc.scope)
}
if (!settings.noimports.value) {
addImport(JavaLangPackage);
@@ -36,13 +42,17 @@ class Contexts: Analyzer {
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 enclClass: Context = _; // The next outer context whose tree is a
+ // template or package definition
var variance: int = _; // Variance relative to enclosing class.
- var undetparams: List[Symbol] = List(); // Undetermined type parameters
- var constructorClass: Symbol = _; // Class for auxiliary constructor
+ private var _undetparams: List[Symbol] = List(); // Undetermined type parameters
var depth: int = 0;
- val imports: List[Tree] = List();
+
+ def undetparams = _undetparams;
+ def undetparams_=(ps: List[Symbol]) = {
+ System.out.println("undetparams = " + ps);
+ _undetparams = ps
+ }
def make(unit: CompilationUnit, tree: Tree, owner: Symbol, scope: Scope): Context = {
val c = new Context();
@@ -50,19 +60,18 @@ class Contexts: Analyzer {
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.enclClass = tree match {
+ case Template(_, _) | PackageDef(_, _) => c
+ case _ => 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));
+ make(unit, EmptyTree, this.owner, this.scope);
def make(tree: Tree, owner: Symbol, scope: Scope): Context =
make(this.unit, tree, owner, scope);
@@ -93,6 +102,53 @@ class Contexts: Analyzer {
if (this == NoContext) "NoContext";
else tree.toString() + "\n:: " + outer.toString()
}
+
+ private var importsCache: List[ImportInfo] = null;
+
+ def imports: List[ImportInfo] = {
+ def collectImports(stats: List[Tree]): List[ImportInfo] = stats match {
+ case Nil => outer.imports
+ case (imp @ Import(_, _)) :: rest => new ImportInfo(imp, depth) :: collectImports(rest)
+ case _ :: rest => collectImports(rest)
+ }
+ if (importsCache == null) {
+ importsCache = tree match {
+ case PackageDef(_, stats) => collectImports(stats)
+ case Template(_, stats) => collectImports(stats)
+ case Block(stats, _) => collectImports(stats)
+ case _ => outer.imports
+ }
+ }
+ importsCache
+ }
+ }
+
+ class ImportInfo(val tree: Import, val depth: int) {
+
+ /** Is name imported explicitly, not via wildcard? */
+ def isExplicitImport(name: Name): boolean =
+ tree.selectors exists (._2.==(name.toTermName));
+
+ /** The symbol with name `name' imported from import clause `tree'.
+ */
+ def importedSymbol(name: Name): Symbol = {
+ var result: Symbol = NoSymbol;
+ var renamed = false;
+ var selectors = tree.selectors;
+ while (selectors != Nil && result == NoSymbol) {
+ if (selectors.head._2 == name.toTermName)
+ result = tree.expr.symbol.info.member(
+ if (name.isTypeName) selectors.head._1.toTypeName else selectors.head._1);
+ else if (selectors.head._1 == name.toTermName)
+ renamed = true
+ else if (selectors.head._1 == nme.WILDCARD && !renamed)
+ result = tree.expr.symbol.info.member(name);
+ selectors = selectors.tail
+ }
+ result
+ }
+
+ override def toString() = tree.toString();
}
}