summaryrefslogtreecommitdiff
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
parent52696417c6c84889d903144d70b9fb5c25fd1f4c (diff)
downloadscala-aa77b6d1ec06bcec09d360b9032b90a023d10c4e.tar.gz
scala-aa77b6d1ec06bcec09d360b9032b90a023d10c4e.tar.bz2
scala-aa77b6d1ec06bcec09d360b9032b90a023d10c4e.zip
*** empty log message ***
-rw-r--r--sources/scala/tools/nsc/CompilationUnits.scala2
-rwxr-xr-xsources/scala/tools/nsc/Global.scala61
-rwxr-xr-xsources/scala/tools/nsc/Main.scala2
-rwxr-xr-xsources/scala/tools/nsc/ast/TreeGen.scala4
-rw-r--r--sources/scala/tools/nsc/ast/TreeInfo.scala23
-rw-r--r--sources/scala/tools/nsc/ast/TreePrinters.scala15
-rw-r--r--sources/scala/tools/nsc/ast/Trees.scala100
-rw-r--r--sources/scala/tools/nsc/ast/parser/ParserPhase.scala1
-rwxr-xr-xsources/scala/tools/nsc/ast/parser/Syntactic.scala26
-rwxr-xr-xsources/scala/tools/nsc/symtab/Definitions.scala10
-rw-r--r--sources/scala/tools/nsc/symtab/Flags.scala1
-rwxr-xr-xsources/scala/tools/nsc/symtab/Names.scala25
-rwxr-xr-xsources/scala/tools/nsc/symtab/Scopes.scala9
-rwxr-xr-xsources/scala/tools/nsc/symtab/StdNames.scala1
-rwxr-xr-xsources/scala/tools/nsc/symtab/SymbolLoaders.scala27
-rwxr-xr-xsources/scala/tools/nsc/symtab/Symbols.scala7
-rwxr-xr-xsources/scala/tools/nsc/symtab/Types.scala44
-rwxr-xr-xsources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala9
-rw-r--r--sources/scala/tools/nsc/typechecker/Analyzer.scala3
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Contexts.scala90
-rwxr-xr-xsources/scala/tools/nsc/typechecker/DeSugarizePhase.scala219
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Namers.scala34
-rwxr-xr-xsources/scala/tools/nsc/typechecker/TypeCheckers.scala343
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Typers.scala31
-rwxr-xr-xsources/scala/tools/scalac/typechecker/RefCheck.scala14
25 files changed, 493 insertions, 608 deletions
diff --git a/sources/scala/tools/nsc/CompilationUnits.scala b/sources/scala/tools/nsc/CompilationUnits.scala
index dd81fff836..568856ae7f 100644
--- a/sources/scala/tools/nsc/CompilationUnits.scala
+++ b/sources/scala/tools/nsc/CompilationUnits.scala
@@ -19,7 +19,7 @@ class CompilationUnits: Global {
val fresh = new FreshNameCreator;
/** the content of the compilation unit in tree form */
- var body: List[Tree] = List();
+ var body: Tree = EmptyTree;
def position(pos: int) = new Position(source, pos);
diff --git a/sources/scala/tools/nsc/Global.scala b/sources/scala/tools/nsc/Global.scala
index 061373b189..7ec16edf65 100755
--- a/sources/scala/tools/nsc/Global.scala
+++ b/sources/scala/tools/nsc/Global.scala
@@ -11,7 +11,7 @@ import scala.tools.util._;
import scala.collection.mutable.{HashSet,HashMap,ListBuffer}
import symtab._;
-import symtab.classfile.Pickle;
+import symtab.pickles.{PickleBuffer, Pickles};
import util._;
import ast._;
import ast.parser._;
@@ -38,6 +38,10 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
val global: Global.this.type = Global.this
}
+ object pickles extends Pickles {
+ val global: Global.this.type = Global.this
+ }
+
val copy = new LazyTreeCopier();
type AttrInfo = Pair[Type, List[Any]];
@@ -45,15 +49,16 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
// reporting -------------------------------------------------------
- def informTime(msg: String, start: long) = {
- val end = System.currentTimeMillis();
- reporter.info(null, "[" + msg + " in " + (end - start) + "ms]", false);
- }
def error(msg: String) = reporter.error(null, msg);
def warning(msg: String) = reporter.warning(null, msg);
- def inform(msg: String) = reporter.info(null, msg, true);
+ private def inform(msg: String) = reporter.info(null, msg, true);
+ def informProgress(msg: String) =
+ if (settings.verbose.value) inform("[" + msg + "]");
+
+ def informTime(msg: String, start: long) =
+ informProgress(msg + " in " + (System.currentTimeMillis() - start) + "ms");
def log(msg: String) =
if (settings.log contains phase.name) inform("[log " + phase + "] " + msg);
@@ -127,6 +132,7 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
}
val namerPhase = new analyzer.NamerPhase(parserPhase);
val typeCheckPhase = new analyzer.TypeCheckPhase(namerPhase);
+ val picklePhase = new pickles.PicklePhase(typeCheckPhase);
val terminalPhase = new StdPhase(typeCheckPhase) {
def name = "terminal";
@@ -150,7 +156,7 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
val symSource = new HashMap[Symbol, AbstractFile];
/** A map from compiled top-level symbols to their picklers */
- val symData = new HashMap[Symbol, Pickle];
+ val symData = new HashMap[Symbol, PickleBuffer];
def compileSources(sources: List[SourceFile]): unit = {
val startTime = System.currentTimeMillis();
@@ -164,19 +170,25 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
phase = NoPhase.next;
while (phase != terminalPhase && reporter.errors() == 0) {
- val startTime = System.currentTimeMillis();
- if (!(settings.skip contains phase.name)) phase.run;
- if (settings.print contains phase.name) treePrinter.printAll();
- if (settings.check contains phase.name) checkTrees;
- informTime(phase.description, startTime);
+ if (!(settings.skip contains phase.name)) {
+ val startTime = System.currentTimeMillis();
+ phase.run;
+ if (settings.print contains phase.name) treePrinter.printAll();
+ if (settings.check contains phase.name) checkTrees;
+ informTime(phase.description, startTime);
+ }
phase = if (settings.stop contains phase.name) terminalPhase else phase.next;
}
if (settings.Xshowcls.value != "") showDef(newTermName(settings.Xshowcls.value), false);
if (settings.Xshowobj.value != "") showDef(newTermName(settings.Xshowobj.value), true);
- if (reporter.errors() != 0)
+ if (reporter.errors() == 0) {
+ for (val Pair(sym, pickled) <- symData.elements)
+ writeSymblFile(sym, pickled)
+ } else {
for (val Pair(sym, file) <- symSource.elements)
sym.reset(loaders.sourcefileLoader(file));
+ }
informTime("total", startTime);
}
@@ -204,8 +216,7 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
}
def checkTrees: unit =
- for (val unit <- units; val tree <- unit.body)
- treeChecker.traverse(tree);
+ for (val unit <- units) treeChecker.traverse(unit.body);
def showDef(name: Name, module: boolean): unit = {
def getSym(name: Name, module: boolean): Symbol = {
@@ -224,4 +235,24 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
System.err.println("" + sym.name + ":" +
(if (module) sym.tpe.symbol.info else sym.info))
}
+
+ /** Returns the file with the given suffix for the given class. */
+ private def getFile(clazz: Symbol, suffix: String) =
+ new File(
+ settings.outdir.value + File.separatorChar +
+ clazz.fullNameString(File.separatorChar) + suffix);
+
+ private def writeSymblFile(clazz: Symbol, pickled: PickleBuffer) = {
+ val file = getFile(clazz, ".symbl");
+ try {
+ val stream = new FileOutputStream(file);
+ stream.write(pickled.bytes, 0, pickled.writeIndex);
+ stream.close();
+ informProgress("wrote " + file);
+ } catch {
+ case ex: IOException =>
+ if (settings.debug.value) ex.printStackTrace();
+ error("could not write file " + file);
+ }
+ }
}
diff --git a/sources/scala/tools/nsc/Main.scala b/sources/scala/tools/nsc/Main.scala
index 04b8ee3437..12fcc666d6 100755
--- a/sources/scala/tools/nsc/Main.scala
+++ b/sources/scala/tools/nsc/Main.scala
@@ -42,7 +42,7 @@ object Main {
ex.printStackTrace();
System.out.println("fatal error: " + msg);
}
- reporter.printSummary
+ reporter.printSummary()
}
}
diff --git a/sources/scala/tools/nsc/ast/TreeGen.scala b/sources/scala/tools/nsc/ast/TreeGen.scala
index 52848b1b5a..523bf74b78 100755
--- a/sources/scala/tools/nsc/ast/TreeGen.scala
+++ b/sources/scala/tools/nsc/ast/TreeGen.scala
@@ -13,7 +13,7 @@ abstract class TreeGen {
import global._;
- def mkGlobalRef(sym: Symbol): Tree = EmptyTree;
+ def mkGlobalRef(sym: Symbol): Tree = Ident(sym.name) setSymbol sym setType sym.tpe;
- def This(pos: int, sym: Symbol): Tree = EmptyTree;
+ def This(sym: Symbol): Tree = global.This(sym.name) setSymbol sym setType sym.thisType;
}
diff --git a/sources/scala/tools/nsc/ast/TreeInfo.scala b/sources/scala/tools/nsc/ast/TreeInfo.scala
index 03cb490d28..8167ef00d7 100644
--- a/sources/scala/tools/nsc/ast/TreeInfo.scala
+++ b/sources/scala/tools/nsc/ast/TreeInfo.scala
@@ -156,27 +156,4 @@ abstract class TreeInfo {
case AppliedTypeTree(fn, _) => methPart(fn)
case _ => tree
}
-
- /** Is name imported explicitly, not via wildcard? */
- def isExplicitImport(tree: Import, name: Name): boolean =
- tree.selectors exists (._2.==(name.toTermName));
-
- /** The symbol with name `name' imported from import clause `tree'.
- */
- def importedSymbol(tree: Import, 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.tpe.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.tpe.member(name);
- selectors = selectors.tail
- }
- result
- }
}
diff --git a/sources/scala/tools/nsc/ast/TreePrinters.scala b/sources/scala/tools/nsc/ast/TreePrinters.scala
index 64ff2f66f2..4f82d4a742 100644
--- a/sources/scala/tools/nsc/ast/TreePrinters.scala
+++ b/sources/scala/tools/nsc/ast/TreePrinters.scala
@@ -119,7 +119,7 @@ abstract class TreePrinters {
case DefDef(mods, name, tparams, vparams, tp, rhs) =>
printModifiers(mods);
- print("def " + (if (name == nme.CONSTRUCTOR) "this" else symName(tree, name)));
+ print("def " + symName(tree, name));
printTypeParams(tparams); vparams foreach printValueParams;
printOpt(": ", tp); printOpt(" = ", rhs);
@@ -147,7 +147,8 @@ abstract class TreePrinters {
print(comment); println; print(definition);
case Template(parents, body) =>
- printRow(parents, " with "); printColumn(body, " {", ";", "}");
+ printRow(parents, " with ");
+ if (!body.isEmpty) printColumn(body, "{", ";", "}")
case Block(stats, expr) =>
printColumn(stats ::: List(expr), "{", ";", "}")
@@ -231,7 +232,8 @@ abstract class TreePrinters {
})
case TypeTree() =>
- print(tree.tpe.toString());
+ if (tree.tpe == null) print("<type ?>")
+ else print(tree.tpe.toString());
case SingletonTypeTree(ref) =>
print(ref); print(".type")
@@ -239,9 +241,8 @@ abstract class TreePrinters {
case SelectFromTypeTree(qualifier, selector) =>
print(qualifier); print("#"); print(symName(tree, selector))
- case CompoundTypeTree(parents, decls) =>
- printRow(parents, " with ");
- if (!decls.isEmpty) printColumn(decls, "{", ";", "}")
+ case CompoundTypeTree(templ) =>
+ print(templ)
case AppliedTypeTree(tp, args) =>
print(tp); printRow(args, "[", ", ", "]")
@@ -254,7 +255,7 @@ abstract class TreePrinters {
def print(unit: CompilationUnit): unit = {
print("// Scala source: " + unit.source + "\n");
if (unit.body != null) {
- unit.body foreach { tree => print(tree); print(";"); println }
+ print(unit.body); println
} else {
print("<null>")
}
diff --git a/sources/scala/tools/nsc/ast/Trees.scala b/sources/scala/tools/nsc/ast/Trees.scala
index 16be82347e..b9a86b9bc8 100644
--- a/sources/scala/tools/nsc/ast/Trees.scala
+++ b/sources/scala/tools/nsc/ast/Trees.scala
@@ -225,7 +225,7 @@ class Trees: Global {
extends TypTree with SymTree;
/** Intersection type, eliminated by RefCheck */
- case class CompoundTypeTree(parents: List[Tree], decls: List[Tree])
+ case class CompoundTypeTree(templ: Template)
extends TypTree;
/** Applied type, eliminated by RefCheck */
@@ -270,7 +270,7 @@ class Trees: Global {
case TypeTree() =>
case SingletonTypeTree(ref) => (eliminated by typecheck)
case SelectFromTypeTree(qualifier, selector) => (eliminated by typecheck)
- case CompoundTypeTree(parents, decls) => (eliminated by typecheck)
+ case CompoundTypeTree(templ: Template) => (eliminated by typecheck)
case AppliedTypeTree(tpt, args) => (eliminated by typecheck)
*/
@@ -311,87 +311,87 @@ class Trees: Global {
def TypeTree(tree: Tree): TypeTree;
def SingletonTypeTree(tree: Tree, ref: Tree): SingletonTypeTree;
def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name): SelectFromTypeTree;
- def CompoundTypeTree(tree: Tree, parents: List[Tree], decls: List[Tree]): CompoundTypeTree;
+ def CompoundTypeTree(tree: Tree, templ: Template): CompoundTypeTree;
def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]): AppliedTypeTree;
}
class StrictTreeCopier extends TreeCopier {
def ClassDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], tpt: Tree, impl: Template) =
- { new ClassDef(mods, name, tparams, tpt, impl).setPos(tree.pos) }
+ new ClassDef(mods, name, tparams, tpt, impl).setPos(tree.pos);
def PackageDef(tree: Tree, name: Name, stats: List[Tree]) =
- { val t = new PackageDef(name, stats); t.setPos(tree.pos); t }
+ new PackageDef(name, stats).setPos(tree.pos);
def ModuleDef(tree: Tree, mods: int, name: Name, impl: Template) =
- { val t = new ModuleDef(mods, name, impl); t.setPos(tree.pos); t }
+ new ModuleDef(mods, name, impl).setPos(tree.pos);
def ValDef(tree: Tree, mods: int, name: Name, tpt: Tree, rhs: Tree) =
- { val t = new ValDef(mods, name, tpt, rhs); t.setPos(tree.pos); t }
+ new ValDef(mods, name, tpt, rhs).setPos(tree.pos);
def DefDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) =
- { val t = new DefDef(mods, name, tparams, vparamss, tpt, rhs); t.setPos(tree.pos); t }
+ new DefDef(mods, name, tparams, vparamss, tpt, rhs).setPos(tree.pos);
def AbsTypeDef(tree: Tree, mods: int, name: Name, lo: Tree, hi: Tree) =
- { val t = new AbsTypeDef(mods, name, lo, hi); t.setPos(tree.pos); t }
+ new AbsTypeDef(mods, name, lo, hi).setPos(tree.pos);
def AliasTypeDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], rhs: Tree) =
- { val t = new AliasTypeDef(mods, name, tparams, rhs); t.setPos(tree.pos); t }
+ new AliasTypeDef(mods, name, tparams, rhs).setPos(tree.pos);
def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree) =
- { val t = new LabelDef(name, params, rhs); t.setPos(tree.pos); t }
+ new LabelDef(name, params, rhs).setPos(tree.pos);
def Import(tree: Tree, expr: Tree, selectors: List[Pair[Name, Name]]) =
- { val t = new Import(expr, selectors); t.setPos(tree.pos); t }
+ new Import(expr, selectors).setPos(tree.pos);
def Attributed(tree: Tree, attribute: Tree, definition: Tree) =
- { val t = new Attributed(attribute, definition); t.setPos(tree.pos); t }
+ new Attributed(attribute, definition).setPos(tree.pos);
def DocDef(tree: Tree, comment: String, definition: Tree) =
- { val t = new DocDef(comment, definition); t.setPos(tree.pos); t }
+ new DocDef(comment, definition).setPos(tree.pos);
def Template(tree: Tree, parents: List[Tree], body: List[Tree]) =
- { val t = new Template(parents, body); t.setPos(tree.pos); t }
+ new Template(parents, body).setPos(tree.pos);
def Block(tree: Tree, stats: List[Tree], expr: Tree) =
- { val t = new Block(stats, expr); t.setPos(tree.pos); t }
+ new Block(stats, expr).setPos(tree.pos);
def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree) =
- { val t = new CaseDef(pat, guard, body); t.setPos(tree.pos); t }
+ new CaseDef(pat, guard, body).setPos(tree.pos);
def Sequence(tree: Tree, trees: List[Tree]) =
- { val t = new Sequence(trees); t.setPos(tree.pos); t }
+ new Sequence(trees).setPos(tree.pos);
def Alternative(tree: Tree, trees: List[Tree]) =
- { val t = new Alternative(trees); t.setPos(tree.pos); t }
+ new Alternative(trees).setPos(tree.pos);
def Bind(tree: Tree, name: Name, body: Tree) =
- { val t = new Bind(name, body); t.setPos(tree.pos); t }
+ new Bind(name, body).setPos(tree.pos);
def Function(tree: Tree, vparams: List[ValDef], body: Tree) =
- { val t = new Function(vparams, body); t.setPos(tree.pos); t }
+ new Function(vparams, body).setPos(tree.pos);
def Assign(tree: Tree, lhs: Tree, rhs: Tree) =
- { val t = new Assign(lhs, rhs); t.setPos(tree.pos); t }
+ new Assign(lhs, rhs).setPos(tree.pos);
def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree) =
- { val t = new If(cond, thenp, elsep); t.setPos(tree.pos); t }
+ new If(cond, thenp, elsep).setPos(tree.pos);
def Match(tree: Tree, selector: Tree, cases: List[CaseDef]) =
- { val t = new Match(selector, cases); t.setPos(tree.pos); t }
+ new Match(selector, cases).setPos(tree.pos);
def Return(tree: Tree, expr: Tree) =
- { val t = new Return(expr); t.setPos(tree.pos); t }
+ new Return(expr).setPos(tree.pos);
def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree) =
- { val t = new Try(block, catches, finalizer); t.setPos(tree.pos); t }
+ new Try(block, catches, finalizer).setPos(tree.pos);
def Throw(tree: Tree, expr: Tree) =
- { val t = new Throw(expr); t.setPos(tree.pos); t }
+ new Throw(expr).setPos(tree.pos);
def New(tree: Tree, tpt: Tree) =
- { val t = new New(tpt); t.setPos(tree.pos); t }
+ new New(tpt).setPos(tree.pos);
def Typed(tree: Tree, expr: Tree, tpt: Tree) =
- { val t = new Typed(expr, tpt); t.setPos(tree.pos); t }
+ new Typed(expr, tpt).setPos(tree.pos);
def TypeApply(tree: Tree, fun: Tree, args: List[Tree]) =
- { val t = new TypeApply(fun, args); t.setPos(tree.pos); t }
+ new TypeApply(fun, args).setPos(tree.pos);
def Apply(tree: Tree, fun: Tree, args: List[Tree]) =
- { val t = new Apply(fun, args); t.setPos(tree.pos); t }
+ new Apply(fun, args).setPos(tree.pos);
def Super(tree: Tree, qual: Name, mixin: Name) =
- { val t = new Super(qual, mixin); t.setPos(tree.pos); t }
+ new Super(qual, mixin).setPos(tree.pos);
def This(tree: Tree, qual: Name) =
- { val t = new This(qual); t.setPos(tree.pos); t }
+ new This(qual).setPos(tree.pos);
def Select(tree: Tree, qualifier: Tree, selector: Name) =
- { val t = new Select(qualifier, selector); t.setPos(tree.pos); t }
+ new Select(qualifier, selector).setPos(tree.pos);
def Ident(tree: Tree, name: Name) =
- { val t = new Ident(name); t.setPos(tree.pos); t }
+ new Ident(name).setPos(tree.pos);
def Literal(tree: Tree, value: Any) =
- { val t = new Literal(value); t.setPos(tree.pos); t }
+ new Literal(value).setPos(tree.pos);
def TypeTree(tree: Tree) =
- { val t = new TypeTree(); t.setPos(tree.pos); t }
+ new TypeTree().setPos(tree.pos);
def SingletonTypeTree(tree: Tree, ref: Tree) =
- { val t = new SingletonTypeTree(ref); t.setPos(tree.pos); t }
+ new SingletonTypeTree(ref).setPos(tree.pos);
def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name) =
- { val t = new SelectFromTypeTree(qualifier, selector); t.setPos(tree.pos); t }
- def CompoundTypeTree(tree: Tree, parents: List[Tree], decls: List[Tree]) =
- { val t = new CompoundTypeTree(parents, decls); t.setPos(tree.pos); t }
+ new SelectFromTypeTree(qualifier, selector).setPos(tree.pos);
+ def CompoundTypeTree(tree: Tree, templ: Template) =
+ new CompoundTypeTree(templ).setPos(tree.pos);
def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]) =
- { val t = new AppliedTypeTree(tpt, args); t.setPos(tree.pos); t }
+ new AppliedTypeTree(tpt, args).setPos(tree.pos)
}
class LazyTreeCopier(copy: TreeCopier) extends TreeCopier {
@@ -575,10 +575,10 @@ class Trees: Global {
if ((qualifier0 == qualifier) && (selector0 == selector)) => t
case _ => copy.SelectFromTypeTree(tree, qualifier, selector)
}
- def CompoundTypeTree(tree: Tree, parents: List[Tree], decls: List[Tree]) = tree match {
- case t @ CompoundTypeTree(parents0, decls0)
- if ((parents0 == parents) && (decls0 == decls)) => t
- case _ => copy.CompoundTypeTree(tree, parents, decls)
+ def CompoundTypeTree(tree: Tree, templ: Template) = tree match {
+ case t @ CompoundTypeTree(templ0)
+ if (templ0 == templ) => t
+ case _ => copy.CompoundTypeTree(tree, templ)
}
def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]) = tree match {
case t @ AppliedTypeTree(tpt0, args0)
@@ -664,8 +664,8 @@ class Trees: Global {
copy.SingletonTypeTree(tree, transform(ref))
case SelectFromTypeTree(qualifier, selector) =>
copy.SelectFromTypeTree(tree, transform(qualifier), selector)
- case CompoundTypeTree(parents, decls) =>
- copy.CompoundTypeTree(tree, transformTrees(parents), transformTrees(decls))
+ case CompoundTypeTree(templ) =>
+ copy.CompoundTypeTree(tree, transformTemplate(templ))
case AppliedTypeTree(tpt, args) =>
copy.AppliedTypeTree(tree, transform(tpt), transformTrees(args))
}
@@ -750,8 +750,8 @@ class Trees: Global {
traverse(ref)
case SelectFromTypeTree(qualifier, selector) =>
traverse(qualifier)
- case CompoundTypeTree(parents, decls) =>
- traverseTrees(parents); traverseTrees(decls)
+ case CompoundTypeTree(templ) =>
+ traverse(templ)
case AppliedTypeTree(tpt, args) =>
traverse(tpt); traverseTrees(args)
case EmptyTree | Super(_, _) | This(_) | Ident(_) | Literal(_) | TypeTree() =>
diff --git a/sources/scala/tools/nsc/ast/parser/ParserPhase.scala b/sources/scala/tools/nsc/ast/parser/ParserPhase.scala
index f4cac5680f..0e4e9643a1 100644
--- a/sources/scala/tools/nsc/ast/parser/ParserPhase.scala
+++ b/sources/scala/tools/nsc/ast/parser/ParserPhase.scala
@@ -11,6 +11,7 @@ abstract class ParserPhase(prev: Phase)
with Syntactic {
def name = "parser";
def apply(unit: global.CompilationUnit): unit = {
+ global.informProgress("parsing " + unit);
unit.body = new Parser(unit).parse();
}
}
diff --git a/sources/scala/tools/nsc/ast/parser/Syntactic.scala b/sources/scala/tools/nsc/ast/parser/Syntactic.scala
index 9f9e34d48e..1384ae1ed7 100755
--- a/sources/scala/tools/nsc/ast/parser/Syntactic.scala
+++ b/sources/scala/tools/nsc/ast/parser/Syntactic.scala
@@ -61,14 +61,12 @@ abstract class Syntactic: ParserPhase {
}
import treeBuilder._;
-
-
/** this is the general parse method
*/
- def parse(): List[Tree] = {
- val ts = compilationUnit();
+ def parse(): Tree = {
+ val t = compilationUnit();
accept(EOF);
- ts
+ t
}
/////// ERROR HANDLING //////////////////////////////////////////////////////
@@ -498,7 +496,7 @@ abstract class Syntactic: ParserPhase {
in.nextToken(); ts += simpleType()
}
atPos(pos) {
- if (in.token == LBRACE) CompoundTypeTree(ts.toList, refinement())
+ if (in.token == LBRACE) CompoundTypeTree(Template(ts.toList, refinement()))
else makeIntersectionTypeTree(ts.toList)
}
}
@@ -1710,25 +1708,25 @@ abstract class Syntactic: ParserPhase {
stats.toList
}
- /** CompilationUnit ::= [ package QualId ( `;' | `{' TopStatSeq `}' ) ] TopStatSeq .
+ /** CompilationUnit ::= package QualId `;' TopStatSeq
+ * | package QualId `{' TopStatSeq `}'
+ * | TopStatSeq
*/
- def compilationUnit(): List[Tree] = {
+ def compilationUnit(): Tree = {
if (in.token == PACKAGE) {
val pos = in.skipToken();
val pkg = qualId();
if (in.token == SEMI) {
in.nextToken();
- List(makePackaging(pkg, topStatSeq()) setPos pos);
+ makePackaging(pkg, topStatSeq()) setPos pos;
} else {
- val stats = new ListBuffer[Tree];
accept(LBRACE);
- stats += atPos(pos) { makePackaging(pkg, topStatSeq()) }
+ val t = makePackaging(pkg, topStatSeq());
accept(RBRACE);
- stats ++= topStatSeq();
- stats.toList
+ t
}
} else {
- topStatSeq()
+ makePackaging(Ident(nme.EMPTY_PACKAGE_NAME), topStatSeq())
}
}
}
diff --git a/sources/scala/tools/nsc/symtab/Definitions.scala b/sources/scala/tools/nsc/symtab/Definitions.scala
index ae927fd6c1..33f4075b48 100755
--- a/sources/scala/tools/nsc/symtab/Definitions.scala
+++ b/sources/scala/tools/nsc/symtab/Definitions.scala
@@ -13,6 +13,8 @@ abstract class Definitions: SymbolTable {
// root packages and classes
var RootClass: Symbol = _;
+ var EmptyPackage: Symbol = _;
+ var EmptyPackageClass: Symbol = _;
var JavaPackage: Symbol = _;
var JavaLangPackage: Symbol = _;
@@ -144,6 +146,13 @@ abstract class Definitions: SymbolTable {
NoSymbol.newClass(Position.NOPOS, nme.ROOT.toTypeName)
.setFlag(FINAL | PACKAGE | JAVA).setInfo(rootLoader);
+ EmptyPackage =
+ RootClass.newPackage(Position.NOPOS, nme.EMPTY_PACKAGE_NAME).setFlag(FINAL);
+ EmptyPackageClass = EmptyPackage.moduleClass;
+ EmptyPackageClass.setInfo(ClassInfoType(List(), new Scope(), EmptyPackageClass));
+ EmptyPackage.setInfo(EmptyPackageClass.typeConstructor);
+ RootClass.info.decls.enter(EmptyPackage);
+
JavaPackage = getModule("java");
JavaLangPackage = getModule("java.lang");
ScalaPackage = getModule("scala");
@@ -182,6 +191,7 @@ abstract class Definitions: SymbolTable {
SeqClass = getClass("scala.Seq");
ListClass = getClass("scala.List");
ArrayClass = getClass("scala.Array");
+ System.out.println("array class: " + ArrayClass.tpe);//debug
TypeClass = getClass("scala.Type");
PredefModule = getModule("scala.Predef");
ConsoleModule = getModule("scala.Console");
diff --git a/sources/scala/tools/nsc/symtab/Flags.scala b/sources/scala/tools/nsc/symtab/Flags.scala
index 1df4f985f3..de46342a5d 100644
--- a/sources/scala/tools/nsc/symtab/Flags.scala
+++ b/sources/scala/tools/nsc/symtab/Flags.scala
@@ -69,6 +69,7 @@ object Flags {
val ACCESSFLAGS = PRIVATE | PROTECTED;
val VARIANCES = COVARIANT | CONTRAVARIANT;
val CONSTRFLAGS = JAVA;
+ val PICKLEDFLAGS = 0x77777777 & ~LOCKED & ~INITIALIZED;
/** Flags already set by object creation and never set afterwards */
val CREATIONFLAGS = ACCESSFLAGS | METHOD | MODULE | MUTABLE | PARAM | PACKAGE |
diff --git a/sources/scala/tools/nsc/symtab/Names.scala b/sources/scala/tools/nsc/symtab/Names.scala
index 190bacc12b..d5a51fc66d 100755
--- a/sources/scala/tools/nsc/symtab/Names.scala
+++ b/sources/scala/tools/nsc/symtab/Names.scala
@@ -5,6 +5,7 @@
// $Id$
package scala.tools.nsc.symtab;
+import scala.tools.util.UTF8Codec;
import scala.tools.nsc.util.NameTransformer;
class Names {
@@ -84,6 +85,14 @@ class Names {
def newTermName(s: String): Name =
newTermName(s.toCharArray(), 0, s.length());
+ /** create a term name from the UTF8 encoded bytes in bs[offset..offset+len-1].
+ */
+ def newTermName(bs: Array[byte], offset: int, len: int): Name = {
+ val cs = new Array[char](bs.length);
+ val nchrs = UTF8Codec.decode(bs, offset, cs, 0, len);
+ newTermName(cs, 0, nchrs)
+ }
+
/** create a type name from the characters in cs[offset..offset+len-1].
*/
def newTypeName(cs: Array[char], offset: int, len: int): Name = {
@@ -103,6 +112,14 @@ class Names {
def newTypeName(s: String): Name =
newTypeName(s.toCharArray(), 0, s.length());
+ /** create a type name from the UTF8 encoded bytes in bs[offset..offset+len-1].
+ */
+ def newTypeName(bs: Array[byte], offset: int, len: int): Name = {
+ val cs = new Array[char](bs.length);
+ val nchrs = UTF8Codec.decode(bs, offset, cs, 0, len);
+ newTypeName(cs, 0, nchrs)
+ }
+
def nameChars: Array[char] = chrs;
def view(s: String): Name = newTermName(s);
@@ -146,6 +163,14 @@ class Names {
*/
final override def toString(): String = new String(chrs, index, len);
+ /** Write to UTF8 representation of this name to given character array.
+ * Start copying to index `to'. Return index of next free byte in array.
+ * Array must have enough remaining space for all bytes
+ * (i.e. maximally 3*length bytes).
+ */
+ final def copyUTF8(bs: Array[byte], offset: int): int =
+ UTF8Codec.encode(chrs, index, bs, offset, len);
+
/** return the hash value of this name
*/
final override def hashCode(): int = index;
diff --git a/sources/scala/tools/nsc/symtab/Scopes.scala b/sources/scala/tools/nsc/symtab/Scopes.scala
index b3663d01e6..d1628d7814 100755
--- a/sources/scala/tools/nsc/symtab/Scopes.scala
+++ b/sources/scala/tools/nsc/symtab/Scopes.scala
@@ -32,6 +32,10 @@ abstract class Scopes: SymbolTable {
var elems: ScopeEntry = initElems;
+ /** The number of times this scope is neted in another
+ */
+ private var nestinglevel = 0;
+
/** the hash table
*/
private var hashtable: Array[ScopeEntry] = null;
@@ -60,6 +64,7 @@ abstract class Scopes: SymbolTable {
this.hashtable = new Array[ScopeEntry](HASHSIZE);
System.arraycopy(base.hashtable, 0, this.hashtable, 0, HASHSIZE);
}
+ nestinglevel = base.nestinglevel + 1
}
def this(decls: List[Symbol]) = {
@@ -204,6 +209,10 @@ abstract class Scopes: SymbolTable {
override def toString(): String =
toList.map(.defString).mkString("{\n ", ";\n ", "\n}");
+
+ /** Return the nesting level of this scope, i.e. the number of times this scope
+ * was nested in another */
+ def nestingLevel = nestinglevel;
}
/** The empty scope (immutable).
diff --git a/sources/scala/tools/nsc/symtab/StdNames.scala b/sources/scala/tools/nsc/symtab/StdNames.scala
index 1da9ebc888..52f09275fc 100755
--- a/sources/scala/tools/nsc/symtab/StdNames.scala
+++ b/sources/scala/tools/nsc/symtab/StdNames.scala
@@ -36,6 +36,7 @@ abstract class StdNames: SymbolTable {
val COMPOUND_NAME = newTermName("<ct>");
val ANON_CLASS_NAME = newTermName("$anon");
val REFINE_CLASS_NAME = newTermName("<refinement>");
+ val EMPTY_PACKAGE_NAME = newTermName("<empty>");
val IMPORT = newTermName("<import>");
val ZERO = newTermName("<zero>");
val STAR = newTermName("*");
diff --git a/sources/scala/tools/nsc/symtab/SymbolLoaders.scala b/sources/scala/tools/nsc/symtab/SymbolLoaders.scala
index c47c464b24..c8952f641b 100755
--- a/sources/scala/tools/nsc/symtab/SymbolLoaders.scala
+++ b/sources/scala/tools/nsc/symtab/SymbolLoaders.scala
@@ -62,30 +62,31 @@ abstract class SymbolLoaders {
new SymbolLoader(root => {
System.out.println("loading " + root);//debug
assert(root.isPackageClass, root);
- val members = new Scope();
- root.setInfo(new PackageClassInfoType(members, root));
+ root.setInfo(new PackageClassInfoType(new Scope(), root));
def enterPackage(str: String, completer: SymbolLoader): unit = {
val pkg = root.newPackage(Position.NOPOS, newTermName(str));
pkg.moduleClass.setInfo(completer);
pkg.setInfo(pkg.moduleClass.tpe);
- members.enter(pkg)
+ root.info.decls.enter(pkg)
}
def enterClassAndModule(str: String, completer: SymbolLoader): unit = {
+ val owner = if (root.isRoot) definitions.EmptyPackageClass else root;
val name = newTermName(str);
- val clazz = root.newClass(Position.NOPOS, name.toTypeName);
- val module = root.newModule(Position.NOPOS, name);
+ val clazz = owner.newClass(Position.NOPOS, name.toTypeName);
+ val module = owner.newModule(Position.NOPOS, name);
clazz.setInfo(completer);
module.setInfo(completer);
module.moduleClass.setInfo(errorLoader);
- members.enter(clazz);
- members.enter(module);
+ owner.info.decls.enter(clazz);
+ owner.info.decls.enter(module);
assert(clazz.linkedModule == module);
assert(module.linkedClass == clazz);
}
val sources = new HashMap[String, AbstractFile];
+ val symbols = new HashMap[String, AbstractFile];
val classes = new HashMap[String, AbstractFile];
val packages = new HashMap[String, AbstractFile];
val it = directory.list();
@@ -93,13 +94,15 @@ abstract class SymbolLoaders {
val file = it.next().asInstanceOf[AbstractFile];
val filename = file.getName();
if (file.isDirectory()) {
- if (filename != "META_INF") {
- if (!packages.isDefinedAt(filename)) packages(filename) = file;
- }
- } else if (!root.isRoot && filename.endsWith(".class")) {
+ if (filename != "META_INF" && !packages.isDefinedAt(filename)) packages(filename) = file;
+ } else if (filename.endsWith(".symbl")) {
+ val name = filename.substring(0, filename.length() - 6);
+ if (!symbols.isDefinedAt(name) ||
+ symbols(name).getName().endsWith(".class")) symbols(name) = file;
+ } else if (filename.endsWith(".class")) {
val name = filename.substring(0, filename.length() - 6);
if (!classes.isDefinedAt(name)) classes(name) = file;
- } else if (!root.isRoot && filename.endsWith(".scala")) {
+ } else if (filename.endsWith(".scala")) {
val name = filename.substring(0, filename.length() - 6);
if (!sources.isDefinedAt(name)) sources(name) = file;
}
diff --git a/sources/scala/tools/nsc/symtab/Symbols.scala b/sources/scala/tools/nsc/symtab/Symbols.scala
index 80137e3f91..1fa0ac8865 100755
--- a/sources/scala/tools/nsc/symtab/Symbols.scala
+++ b/sources/scala/tools/nsc/symtab/Symbols.scala
@@ -109,6 +109,7 @@ abstract class Symbols: SymbolTable {
final def isModuleClass = isClass && (rawflags & MODULE) != 0;
final def isPackageClass = isClass && (rawflags & PACKAGE) != 0;
final def isRoot = isPackageClass && name == nme.ROOT.toTypeName;
+ final def isEmptyPackage = isPackageClass && name == nme.EMPTY_PACKAGE_NAME.toTypeName;
/** Does this symbol denote a stable value? */
final def isStable =
@@ -188,7 +189,7 @@ abstract class Symbols: SymbolTable {
final def info: Type = {
var cnt = 0;
while ((rawflags & INITIALIZED) == 0) {
- assert(infos != null, "infos null for " + this.name);//debug
+ assert(infos != null, "infos null for " + this.name + " " + (this == definitions.EmptyPackageClass));//debug
val tp = infos.info;
if ((rawflags & LOCKED) != 0) {
setInfo(ErrorType);
@@ -588,7 +589,9 @@ abstract class Symbols: SymbolTable {
override def tpe: Type = {
if (valid != phase) {
valid = phase;
- tpeCache = typeRef(owner.thisType, this, typeParams map (.tpe))
+ val tparams = typeParams;
+ tpeCache = typeRef(owner.thisType, this, tparams map (.tpe));
+ if (!tparams.isEmpty) tpeCache = PolyType(tparams, tpeCache);
}
tpeCache
}
diff --git a/sources/scala/tools/nsc/symtab/Types.scala b/sources/scala/tools/nsc/symtab/Types.scala
index 9d8c8f90f0..2f677c99d7 100755
--- a/sources/scala/tools/nsc/symtab/Types.scala
+++ b/sources/scala/tools/nsc/symtab/Types.scala
@@ -270,7 +270,7 @@ abstract class Types: SymbolTable {
def cloneInfo(owner: Symbol) = this;
/** The string representation of this type used as a prefix */
- def prefixString = toString() + ".";
+ def prefixString = toString() + "#";
/** The string representation of this type, with singletypes explained */
def toLongString = {
@@ -375,6 +375,7 @@ abstract class Types: SymbolTable {
override def isStable: boolean = true;
override def widen: Type = singleDeref.widen;
override def closure: Array[Type] = addClosure(this, supertype.closure);
+ override def toString(): String = prefixString + "type";
}
/** An object representing an erroneous type */
@@ -409,10 +410,12 @@ abstract class Types: SymbolTable {
case class ThisType(sym: Symbol) extends SingletonType {
override def symbol = sym;
override def singleDeref: Type = sym.typeOfThis;
- override def toString(): String =
- if (!settings.debug.value &&
- (sym.isAnonymousClass || sym.isRefinementClass)) "this.type"
- else sym.nameString + ".this.type";
+ override def prefixString =
+ if (settings.debug.value) sym.nameString + ".this.";
+ else if (sym.isRoot) ""
+ else if (sym.isAnonymousClass || sym.isRefinementClass) "this."
+ else if (sym.isPackageClass) sym.fullNameString('.') + "."
+ else sym.nameString + ".this.";
override def narrow: Type = this;
}
@@ -432,8 +435,7 @@ abstract class Types: SymbolTable {
}
override def symbol = sym;
override def prefix: Type = pre;
- override def toString(): String =
- pre.prefixString + sym.nameString + ".type";
+ override def prefixString: String = pre.prefixString + sym.nameString + ".";
}
/** A class for the bounds of abstract types and type parameters
@@ -469,6 +471,7 @@ abstract class Types: SymbolTable {
validClosure = phase;
closureCache = null;
closureCache = computeClosure;
+ System.out.println("closure(" + symbol + ") = " + List.fromArray(closureCache));//debug
}
if (closureCache == null)
throw new TypeError("illegal cyclic reference involving " + symbol);
@@ -541,10 +544,12 @@ abstract class Types: SymbolTable {
override def toString(): String = base.toString() + "(" + value + ")";
}
+ class ExtTypeRef(pre: Type, sym: Symbol, args: List[Type]) extends TypeRef(pre, sym, args);
+
/** A class for named types of the form <prefix>.<sym.name>[args]
* Cannot be created directly; one should always use `typeRef' for creation.
*/
- abstract case class TypeRef(pre: Type, sym: Symbol, args: List[Type]) extends Type {
+ case class TypeRef(pre: Type, sym: Symbol, args: List[Type]) extends Type {
assert(!sym.isAbstractType || pre.isStable || pre.isError);
def transform(tp: Type): Type =
@@ -707,7 +712,7 @@ abstract class Types: SymbolTable {
sym1.resetFlag(LOCKED);
result
} else {
- new TypeRef(pre, sym1, args) {}
+ new ExtTypeRef(pre, sym1, args) {}
}
}
@@ -734,8 +739,8 @@ abstract class Types: SymbolTable {
/** A creator for type applications */
def appliedType(tycon: Type, args: List[Type]): Type = tycon match {
- case TypeRef(pre, sym, args1) =>
- if (args eq args1) tycon else typeRef(pre, sym, args)
+ case TypeRef(pre, sym, _) => typeRef(pre, sym, args)
+ case PolyType(tparams, restpe) => restpe.subst(tparams, args)
case ErrorType => tycon
}
@@ -841,11 +846,11 @@ abstract class Types: SymbolTable {
/** A map to compute the asSeenFrom method */
class AsSeenFromMap(pre: Type, clazz: Symbol) extends TypeMap {
def apply(tp: Type): Type =
- if (pre == NoType || !clazz.isClass) tp
+ if (pre == NoType || pre == NoPrefix || !clazz.isClass) tp
else tp match {
case ThisType(sym) =>
def toPrefix(pre: Type, clazz: Symbol): Type =
- if (pre == NoType || !clazz.isClass) tp
+ if (pre == NoType || pre == NoPrefix || !clazz.isClass) tp
else if ((sym isSubClass clazz) && (pre.widen.symbol isSubClass sym)) pre
else toPrefix(pre.baseType(clazz).prefix, clazz.owner);
toPrefix(pre, clazz)
@@ -857,7 +862,7 @@ abstract class Types: SymbolTable {
}
case TypeRef(prefix, sym, args) if (sym.isTypeParameter) =>
def toInstance(pre: Type, clazz: Symbol): Type =
- if (pre == NoType || !clazz.isClass) tp
+ if (pre == NoType || pre == NoPrefix || !clazz.isClass) tp
else {
val symclazz = sym.owner;
def throwError =
@@ -1093,7 +1098,7 @@ abstract class Types: SymbolTable {
sym2.isAbstractType && (tp1 <:< tp2.bounds.lo)
||
sym2.isClass &&
- ({ val base = tp1 baseType sym2; !(base eq tp1) && (base <:< tp2) })
+ ({ val base = tp1 baseType sym2; !(base eq tp1) && (base <:< tp2) })//debug
||
sym1 == AllClass
||
@@ -1118,10 +1123,15 @@ abstract class Types: SymbolTable {
(parents2 forall tp1.<:<) && (ref2.toList forall tp1.specializes)
case Pair(RefinedType(parents1, ref1), _) =>
parents1 exists (.<:<(tp2))
+ /* todo: replace following with
case Pair(ThisType(_), _)
| Pair(SingleType(_, _), _)
| Pair(ConstantType(_, _), _) =>
- tp1.singleDeref <:< tp2
+ once patern matching bug is fixed */
+ case Pair(ThisType(_), _) => tp1.singleDeref <:< tp2
+ case Pair(SingleType(_, _), _) => tp1.singleDeref <:< tp2
+ case Pair(ConstantType(_, _), _) => tp1.singleDeref <:< tp2
+
case Pair(TypeRef(pre1, sym1, args1), _) =>
sym1 == AllClass && tp2 <:< AnyClass.tpe
||
@@ -1176,7 +1186,7 @@ abstract class Types: SymbolTable {
val cl1 = new Array[Type](cl.length + 1);
cl1(0) = tp;
System.arraycopy(cl, 0, cl1, 1, cl.length);
- cl
+ cl1
}
// Lubs and Glbs ---------------------------------------------------------
diff --git a/sources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/sources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 2379d09400..38cebbe26c 100755
--- a/sources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/sources/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -30,10 +30,6 @@ abstract class ClassfileParser {
val global: ClassfileParser.this.global.type = ClassfileParser.this.global
}
- private object unpickle extends UnPickle {
- val global: ClassfileParser.this.global.type = ClassfileParser.this.global
- }
-
def parse(file: AbstractFile, root: Symbol): unit = {
assert(!busy);
busy = true;
@@ -111,10 +107,7 @@ abstract class ClassfileParser {
if (name == null) {
val start = starts(index);
if (in.buf(start) != CONSTANT_UTF8) errorBadTag(start);
- val len = in.getChar(start + 1);
- val cs = new Array[char](len);
- val defined = UTF8Codec.decode(in.buf, start + 3, cs, 0, len);
- name = newTermName(cs, 0, defined);
+ name = newTermName(in.buf, start + 3, in.getChar(start + 1));
values(index) = name;
}
name
diff --git a/sources/scala/tools/nsc/typechecker/Analyzer.scala b/sources/scala/tools/nsc/typechecker/Analyzer.scala
index 1e5e2c17c8..58f3aee4ba 100644
--- a/sources/scala/tools/nsc/typechecker/Analyzer.scala
+++ b/sources/scala/tools/nsc/typechecker/Analyzer.scala
@@ -18,7 +18,4 @@ abstract class Analyzer
with Variances
with EtaExpansion {
val global: Global;
- import global._;
-
- case class ImportType(tree: Import) extends Type;
}
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();
}
}
diff --git a/sources/scala/tools/nsc/typechecker/DeSugarizePhase.scala b/sources/scala/tools/nsc/typechecker/DeSugarizePhase.scala
deleted file mode 100755
index 01c1789435..0000000000
--- a/sources/scala/tools/nsc/typechecker/DeSugarizePhase.scala
+++ /dev/null
@@ -1,219 +0,0 @@
-/* NSC -- new scala compiler
- * Copyright 2005 LAMP/EPFL
- * @author Martin Odersky
- */
-// $Id$
-package scala.tools.nsc.typechecker;
-
-import symtab.Flags._;
-import scala.collection.mutable.ListBuffer;
-
-/** Performs the following context-free rewritings:
- * (1) Places all pattern variables in Bind nodes. In a pattern, for identifiers `x':
- * x => x @ _
- * x:T => x @ (_ : T)
- *
- * (2) Removes pattern definitions (PatDef's) as follows:
- * If pattern is a simple (typed) identifier:
- * val x = e ==> val x = e
- * val x: T = e ==> val x: T = e
- *
- * if there are no variables in pattern
- * val p = e ==> e.match (case p => ())
- *
- * if there is exactly one variable in pattern
- * val x_1 = e.match (case p => (x_1))
- *
- * if there is more than one variable in pattern
- * val p = e ==> private synthetic val t$ = e.match (case p => (x_1, ..., x_N))
- * val x_1 = t$._1
- * ...
- * val x_N = t$._N
- *
- * (3) Removes function types as follows:
- * (argtpes) => restpe ==> scala.Function_n[argtpes, restpe]
- *
- * (4) Wraps naked case definitions in a match as follows:
- * { cases } ==> (x => x.match {cases}), except when already argument to match
- */
-abstract class DeSugarizePhase(prev: Phase) extends StdPhase(prev) {
- import global._;
- import posAssigner.atPos;
-
- def name = "desugarize";
- def apply(unit: CompilationUnit): unit =
- unit.body = new DeSugarizer(unit).transformTrees(unit.body);
-
- class DeSugarizer(unit: CompilationUnit) extends Transformer {
-
- /** introduce fresh variable of the form "ds$56"
- */
- private def getvar: Name = unit.fresh.newName("ds$");
-
- /** in patterns x => x @ _
- * x:T => x @ (_ : T)
- */
- object patvarTransformer extends Transformer {
- override def transform(tree: Tree): Tree = tree match {
- case Ident(name) if (treeInfo.isVariableName(name) && name != nme.WILDCARD) =>
- atPos(tree.pos)(Bind(name, Ident(nme.WILDCARD)))
- case Typed(id @ Ident(name), tpt) =>
- Bind(name, atPos(tree.pos)(Typed(Ident(nme.WILDCARD), tpt))) setPos id.pos
- case Apply(fn @ Apply(_, _), args) =>
- copy.Apply(tree, transform(fn), transformTrees(args))
- case Apply(fn, args) =>
- copy.Apply(tree, fn, transformTrees(args))
- case Sequence(_) | Alternative(_) | Bind(_, _) | Typed(_, _) =>
- super.transform(tree)
- case _ =>
- tree
- }
- }
-
- /** Traverse pattern and collect all variable names in buffer */
- object getvarTraverser extends Traverser {
- val buf = new ListBuffer[Name];
- def init: Traverser = { buf.clear; this }
- override def traverse(tree: Tree): unit = tree match {
- case Bind(name, tpe) =>
- if (buf.elements forall (name !=)) buf += name;
- traverse(tpe)
- case _ => super.traverse(tree)
- }
- }
-
- /** Returns list of all pattern variables without duplicates */
- private def getVariables(tree: Tree): List[Name] = {
- getvarTraverser.init.traverse(tree);
- getvarTraverser.buf.toList
- }
-
- /** Expand patdefs */
- private def transformStat(tree: Tree): List[Tree] = {
- def rebox(defs: List[Tree], boxf: Tree => Tree): List[Tree] = defs match {
- case List(stat) => List(if (stat.isDef) boxf(stat) else stat);
- case stat :: stats => stat :: (stats map boxf)
- }
- def mkTuple(trees: List[Tree]): Tree = trees match {
- case List() => Literal(())
- case List(tree) => tree
- case _ => Apply(Select(Ident(nme.scala), newTermName("Tuple" + trees.length)), trees)
- }
- tree match {
- // pattern definitions:
- // val x = e ==> val x = e
- case PatDef(mods, Ident(name), rhs) =>
- List(atPos(tree.pos)(ValDef(mods, name, EmptyTypeTree(), rhs)))
-
- // val (x @ _) = e ==> val x = e
- case PatDef(mods, Bind(name, Ident(nme.WILDCARD)), rhs) =>
- List(atPos(tree.pos)(ValDef(mods, name, EmptyTypeTree(), rhs)))
-
- // val x: T = e ==> val x: T = e
- case PatDef(mods, Typed(Ident(name), tpt), rhs) =>
- List(atPos(tree.pos)(ValDef(mods, name, tpt, rhs)))
-
- // val x @ (_: T) = e ==> val x: T = e
- case PatDef(mods, Bind(name, Typed(Ident(nme.WILDCARD), tpt)), rhs) =>
- List(atPos(tree.pos)(ValDef(mods, name, tpt, rhs)))
-
- // in case there are no variables in pattern
- // val p = e ==> e.match (case p => ())
- //
- // in case there is exactly one variable in pattern
- // val x_1 = e.match (case p => (x_1))
- //
- // in case there are more variables in pattern
- // val p = e ==> private synthetic val t$ = e.match (case p => (x_1, ..., x_N))
- // val x_1 = t$._1
- // ...
- // val x_N = t$._N
- case PatDef(mods, pat, rhs) =>
- val vars = getVariables(pat);
- val matchExpr = atPos(pat.pos) {
- Apply(
- Select(rhs, nme._match),
- List(Visitor(List(CaseDef(pat, EmptyTree, mkTuple(vars map Ident))))))
- }
- vars match {
- case List() =>
- List(matchExpr)
- case List(vname) =>
- List(ValDef(mods, vname, EmptyTypeTree(), matchExpr))
- case _ =>
- val tmp = getvar;
- val firstDef = ValDef(PRIVATE | LOCAL | SYNTHETIC,
- tmp, EmptyTypeTree(), matchExpr);
- var cnt = 0;
- val restDefs = for (val v <- vars) yield {
- cnt = cnt + 1;
- val selector = newTermName("_" + cnt);
- ValDef(mods, v, EmptyTypeTree(), Select(Ident(tmp), selector))
- }
- firstDef :: restDefs
- } map atPos(tree.pos)
-
- case DocDef(comment, defn) =>
- rebox(transformStat(defn), t => DocDef(comment, t))
-
- case Attributed(attribute, defn) =>
- rebox(transformStat(defn), t => Attributed(attribute, t))
-
- case _ =>
- List(tree)
- }
- }
-
- /** Expand patdefs in list of statements */
- private def transformStats(trees: List[Tree]): List[Tree] = {
- def isPatDef(tree: Tree): boolean = tree match {
- case PatDef(_, _, _) => true
- case DocDef(_, defn) => isPatDef(defn)
- case Attributed(_, defn) => isPatDef(defn)
- case _ => false
- }
- if (trees exists isPatDef) trees flatMap transformStat else trees
- }
-
- /** desugarize tree */
- override def transform(tree: Tree): Tree = tree match {
- // (argtpes) => restpe ==> scala.Function_n[argtpes, restpe]
- case FunctionTypeTree(argtpes, restpe) =>
- atPos(tree.pos) (
- AppliedTypeTree(
- Select(Ident(nme.scala), newTypeName("Function" + argtpes.length)),
- transformTrees(argtpes) ::: List(transform(restpe))))
-
- // { cases } ==> (x => x.match {cases}), except when already argument to match
- case Apply(s @ Select(x, nme._match), List(v @ Visitor(cases))) =>
- copy.Apply(tree,
- copy.Select(s, transform(x), nme._match),
- List(copy.Visitor(v, transformCaseDefs(cases))))
-
- case Apply(Ident(nme._match), List(v @ Visitor(cases))) =>
- copy.Apply(tree,
- Select(This(nme.EMPTY.toTypeName), nme._match),
- List(copy.Visitor(v, transformCaseDefs(cases))))
-
- case Visitor(cases) =>
- val x = getvar;
- atPos(tree.pos)(
- Function(
- List(ValDef(PARAM, x, EmptyTypeTree(), EmptyTree)),
- Apply(Select(Ident(x), nme._match), List(super.transform(tree)))))
-
- case CaseDef(pat, guard, body) =>
- copy.CaseDef(tree, transform(patvarTransformer.transform(pat)),
- transform(guard), transform(body))
-
- case PatDef(mods, pat, rhs) =>
- copy.PatDef(tree, mods, transform(patvarTransformer.transform(pat)), transform(rhs))
-
- case Template(parents, body) =>
- copy.Template(tree, transformTrees(parents), transformStats(transformTrees(body)))
-
- case Block(stats, expr) =>
- copy.Block(tree, transformStats(transformTrees(stats)), transform(expr))
- }
- }
-}
diff --git a/sources/scala/tools/nsc/typechecker/Namers.scala b/sources/scala/tools/nsc/typechecker/Namers.scala
index 1ed2f26947..3096d85017 100755
--- a/sources/scala/tools/nsc/typechecker/Namers.scala
+++ b/sources/scala/tools/nsc/typechecker/Namers.scala
@@ -16,7 +16,7 @@ trait Namers: Analyzer {
def name = "namer";
val global: Namers.this.global.type = Namers.this.global;
def apply(unit: CompilationUnit): unit =
- new Namer(startContext.make(unit)).enterSyms(unit.body);
+ new Namer(startContext.make(unit)).enterSym(unit.body);
}
class Namer(context: Context) {
@@ -29,15 +29,13 @@ trait Namers: Analyzer {
(if ((sym.rawflags & CASE) != 0) "case class " + sym.name else sym.toString()));
private def updatePosFlags(sym: Symbol, pos: int, mods: int): Symbol = {
- val sym1 = if (sym.isExternal && !sym.isPackage) sym
- else { doubleDefError(pos, sym); sym.cloneSymbol }
- sym1.pos = pos;
- val oldflags = sym1.rawflags & (INITIALIZED | LOCKED);
+ sym.pos = pos;
+ val oldflags = sym.rawflags & (INITIALIZED | LOCKED);
val newflags = mods & ~(INITIALIZED | LOCKED);
- sym1.rawflags = oldflags | newflags;
- if (sym1.isModule)
- updatePosFlags(sym1.moduleClass, pos, (mods & MODULE2CLASSFLAGS) | MODULE | FINAL);
- sym1
+ sym.rawflags = oldflags | newflags;
+ if (sym.isModule)
+ updatePosFlags(sym.moduleClass, pos, (mods & MODULE2CLASSFLAGS) | MODULE | FINAL);
+ sym
}
def enterInScope(sym: Symbol): Symbol = {
@@ -61,7 +59,7 @@ trait Namers: Analyzer {
private def enterClassSymbol(pos: int, mods: int, name: Name): Symbol = {
val c: Symbol = context.scope.lookup(name);
- if (c.isType && context.scope == c.owner.info.decls) {
+ if (c.isType && c.isExternal && context.scope == c.owner.info.decls) {
updatePosFlags(c, pos, mods)
} else {
enterInScope(context.owner.newClass(pos, name).setFlag(mods))
@@ -70,7 +68,7 @@ trait Namers: Analyzer {
private def enterModuleSymbol(pos: int, mods: int, name: Name): Symbol = {
val m: Symbol = context.scope.lookup(name);
- if (m.isModule && context.scope == m.owner.info.decls) {
+ if (m.isModule && !m.isPackage && m.isExternal && context.scope == m.owner.info.decls) {
updatePosFlags(m, pos, mods)
} else {
val newm = context.owner.newModule(pos, name);
@@ -82,7 +80,7 @@ trait Namers: Analyzer {
private def enterCaseFactorySymbol(pos: int, mods: int, name: Name): Symbol = {
val m: Symbol = context.scope.lookup(name);
- if (m.isModule && context.scope == m.owner.info.decls) {
+ if (m.isModule && !m.isPackage && m.isExternal && context.scope == m.owner.info.decls) {
updatePosFlags(m, pos, mods)
} else {
enterInScope(context.owner.newMethod(pos, name).setFlag(mods))
@@ -95,6 +93,7 @@ trait Namers: Analyzer {
def enterSym(tree: Tree): Symbol = {
def finishWith(tparams: List[AbsTypeDef]) = {
+ if (settings.debug.value) log("entered " + tree.symbol);
val ltype = typer.typeCompleter(tree);
def makeParam(tparam: AbsTypeDef): Symbol =
tree.symbol.newTypeParameter(tparam.pos, tparam.name);
@@ -104,7 +103,7 @@ trait Namers: Analyzer {
}
def finish = finishWith(List());
- if (tree.symbol != null) tree.symbol
+ if (tree.symbol != null && tree.symbol != NoSymbol) tree.symbol
else {
val owner = context.owner;
tree match {
@@ -121,10 +120,6 @@ trait Namers: Analyzer {
finishWith(tparams);
}
tree.symbol = enterClassSymbol(tree.pos, mods, name);
- val constr = tree.symbol.newConstructor(tree.pos)
- .setFlag(tree.symbol.rawflags & CONSTRFLAGS)
- .setInfo(typer.typeCompleter(tree));
- tree.symbol.info.decls enter constr;
finishWith(tparams)
case ModuleDef(mods, name, _) =>
tree.symbol = enterModuleSymbol(tree.pos, mods, name);
@@ -154,9 +149,6 @@ trait Namers: Analyzer {
finish
}
case DefDef(mods, nme.CONSTRUCTOR, tparams, vparams, tp, rhs) =>
- if (!(owner.isClass && context.scope == owner.info.decls) ||
- owner.isModuleClass || owner.isAnonymousClass || owner.isRefinementClass)
- context.unit.error(tree.pos, "constructor definition not allowed here");
tree.symbol = enterInScope(owner.newConstructor(tree.pos))
.setFlag(mods | owner.rawflags & CONSTRFLAGS);
finishWith(tparams)
@@ -173,7 +165,7 @@ trait Namers: Analyzer {
enterSym(defn)
case DocDef(_, defn) =>
enterSym(defn)
- case Import(expr, selectors) =>
+ case Import(_, _) =>
tree.symbol = NoSymbol.newImport(tree.pos);
finish
case _ =>
diff --git a/sources/scala/tools/nsc/typechecker/TypeCheckers.scala b/sources/scala/tools/nsc/typechecker/TypeCheckers.scala
index 6a31477d2b..48f265a4e9 100755
--- a/sources/scala/tools/nsc/typechecker/TypeCheckers.scala
+++ b/sources/scala/tools/nsc/typechecker/TypeCheckers.scala
@@ -19,7 +19,7 @@ trait TypeCheckers: Analyzer {
def name = "typechecker";
val global: TypeCheckers.this.global.type = TypeCheckers.this.global;
def apply(unit: CompilationUnit): unit =
- new TypeChecker(startContext.make(unit)).transformStats(unit.body, NoSymbol)
+ new TypeChecker(startContext.make(unit)).transformExpr(unit.body)
}
class TypeChecker(context: Context) {
@@ -99,7 +99,7 @@ trait TypeCheckers: Analyzer {
override def apply(t: Type): Type = {
def checkNoEscape(sym: Symbol): unit = {
val e = context.scope.lookupEntry(sym.name);
- if (e.sym == sym && e.owner == context.scope && !e.sym.isTypeParameter) {
+ if (e != null && e.sym == sym && e.owner == context.scope && !e.sym.isTypeParameter) {
badSymbol = e.sym
} else if (sym.hasFlag(PRIVATE)) {
var o = owner;
@@ -181,7 +181,7 @@ trait TypeCheckers: Analyzer {
val tparams1 = tparams map (.cloneSymbol);
val tree1 = if (tree.isType) tree
else TypeApply(tree, tparams1 map (tparam =>
- TypeTree() setPos tparam.pos setType tparam.tpe)
+ TypeTree() setPos tparam.pos setType tparam.tpe));
context.undetparams = context.undetparams ::: tparams1;
adapt(tree1 setType restpe.substSym(tparams, tparams1), mode, pt)
case MethodType(_, _) if ((mode & (EXPRmode | FUNmode)) == EXPRmode &&
@@ -198,7 +198,7 @@ trait TypeCheckers: Analyzer {
context.undetparams = List();
inferConstructorInstance(
TypeTree() setPos tree.pos
- setType1 tree.tpe.prefix.memberType(clazz.primaryConstructor),
+ setType tree.tpe.prefix.memberType(clazz.primaryConstructor),
tparams, pt);
tree
} else if (clazz.isSubClass(SeqClass)) { // (5.2)
@@ -230,23 +230,18 @@ trait TypeCheckers: Analyzer {
} else if (tree.tpe <:< pt) {
tree
} else {
- def adaptError: Tree = {
- typeError(tree.pos, tree.tpe, pt);
- explainTypes(tree.tpe, pt);
- setError(tree)
- }
val tree1 = constfold(tree, pt); // (10) (11)
- if (tree1 != tree)) transform(tree1, mode, pt)
+ if (tree1 != tree) transform(tree1, mode, pt);
else if ((mode & EXPRmode) != 0)
- if (pt.symbol == UnitClass) // (12)
+ if (pt.symbol == UnitClass && tree1.tpe <:< AnyClass.tpe) // (12)
transform(Block(List(tree), Literal(())), mode, pt)
else { // (13)
val vmeth = bestView(tree.tpe, pt);
if (vmeth != NoSymbol)
transform(Apply(Ident(vmeth.name), List(tree)), mode, pt)
- else adaptError
+ else typeErrorTree(tree, tree.tpe, pt)
}
- else adaptError
+ else typeErrorTree(tree, tree.tpe, pt)
}
}
@@ -278,7 +273,7 @@ trait TypeCheckers: Analyzer {
/** Check that
* - all parents are class types,
* - first parent cluss is not a trait; following classes are traits,
- * - fnal classes are not inherited,
+ * - final classes are not inherited,
* - sealed classes are only inherited by classes which are
* nested within definition of base class, or that occur within same
* statement sequence,
@@ -287,7 +282,7 @@ trait TypeCheckers: Analyzer {
*/
def validateParentClasses(parents: List[Tree], selfType: Type): unit = {
var c = context;
- do { c = c.outer } while (c.tree.owner == context.owner);
+ do { c = c.outer } while (c.owner == context.owner);
val defscope = c.scope;
def validateParentClass(parent: Tree, isFirst: boolean): unit = {
@@ -312,7 +307,8 @@ trait TypeCheckers: Analyzer {
if (!(selfType <:< parent.tpe.typeOfThis)) {
error(parent.pos, "illegal inheritance;\n self-type " +
selfType + " does not conform to " + parent +
- "'s selftype " + parent.tpe.typeOfThis)
+ "'s selftype " + parent.tpe.typeOfThis);
+ if (settings.explaintypes.value) explainTypes(selfType, parent.tpe.typeOfThis);
}
if (parents exists (p => p != parent && p.tpe.symbol == psym && !psym.isError))
error(parent.pos, "" + psym + " is inherited twice")
@@ -367,6 +363,12 @@ trait TypeCheckers: Analyzer {
val tpt1 = transformType(ddef.tpt, meth);
val rhs1 =
if (ddef.name == nme.CONSTRUCTOR) {
+ if (!meth.hasFlag(SYNTHETIC) &&
+ !(meth.owner.isClass ||
+ meth.owner.isModuleClass ||
+ meth.owner.isAnonymousClass ||
+ meth.owner.isRefinementClass))
+ error(ddef.pos, "constructor definition not allowed here " + meth.owner);//debug
context.enclClass.owner.setFlag(INCONSTRUCTOR);
val result = transform(ddef.rhs, EXPRmode | INCONSTRmode, UnitClass.tpe);
context.enclClass.owner.resetFlag(INCONSTRUCTOR);
@@ -423,7 +425,7 @@ trait TypeCheckers: Analyzer {
val Triple(clazz, argpts, respt) = pt match {
case TypeRef(_, sym, argtps)
if (sym == FunctionClass(fun.vparams.length) ||
- sym == PartialFunctionClass && fun.body.isInstanceOf[Match]) =>
+ sym == PartialFunctionClass && fun.vparams.length == 1 && fun.body.isInstanceOf[Match]) =>
Triple(sym, argtps.init, argtps.last)
case _ =>
Triple(FunctionClass(fun.vparams.length), fun.vparams map (x => NoType), WildcardType)
@@ -433,10 +435,8 @@ trait TypeCheckers: Analyzer {
case ValDef(_, _, tpt, _) =>
if (tpt.isEmpty)
tpt.tpe =
- if (argpt == NoType) {
- error(vparam.pos, "missing parameter type");
- ErrorType
- } else argpt
+ if (argpt == NoType) { error(vparam.pos, "missing parameter type"); ErrorType }
+ else argpt
}
namer.enterSym(vparam)
}
@@ -466,31 +466,50 @@ trait TypeCheckers: Analyzer {
cases mapConserve (cdef => tc1.transformCase(cdef, pattp, pt))
}
- def transformApply(fn: Tree, args: List[Tree]): Tree = {
+ def transformTypeApply(fun: Tree, args: List[Tree]): Tree = {
+ inferPolyAlternative(fun, args.length);
+ val args1 = args mapConserve (arg => transform(arg, TYPEmode, WildcardType));
+ val targs = args1 map (.tpe);
+ if (fun.tpe.isError || (targs exists (.isError)))
+ setError(tree)
+ else fun.tpe match {
+ case PolyType(tparams, restpe) =>
+ checkBounds(tree.pos, tparams, targs, "");
+ copy.TypeApply(tree, fun, args1) setType restpe.subst(tparams, targs)
+ }
+ }
+
+ def transformApply(fun: Tree, args: List[Tree]): Tree = {
// if function is overloaded, filter all alternatives that match
// number of arguments and expected result type.
- if (fn.hasSymbol && fn.symbol.hasFlag(OVERLOADED)) {
+ if (fun.hasSymbol && fun.symbol.hasFlag(OVERLOADED)) {
val argtypes = args map (arg => AllClass.tpe);
- val pre = fn.symbol.info.prefix;
- val sym = fn.symbol filter (alt =>
+ val pre = fun.symbol.info.prefix;
+ fun.symbol = fun.symbol filter (alt =>
isApplicable(context.undetparams, pre.memberType(alt), argtypes, pt));
- fn.symbol = sym;
- fn.tpe = pre.memberType(sym)
+ fun.tpe = pre.memberType(fun.symbol)
}
- fn.tpe match {
+ fun.tpe match {
case OverloadedType(pre, alts) =>
val args1 = args mapConserve (arg =>
transform(arg, mode & stickyModes, WildcardType));
- inferMethodAlternative(fn, context.undetparams, args1 map (.tpe.deconst), pt);
- transformApply(fn, args1);
+ inferMethodAlternative(fun, context.undetparams, args1 map (.tpe.deconst), pt);
+ transformApply(fun, args1);
case MethodType(formals0, restpe) =>
val formals = formalTypes(formals0, args.length);
if (formals.length != args.length) {
- errorTree(tree, "wrong number of arguments for " + treeSymTypeMsg(fn))
+ errorTree(tree, "wrong number of arguments for " + treeSymTypeMsg(fun))
} else {
val tparams = context.undetparams;
context.undetparams = List();
- if (!tparams.isEmpty) { // note: this case cannot arise for patterns
+ if (tparams.isEmpty) {
+ val args1 = List.map2(args, formals) ((arg, formal) =>
+ transform(arg, mode & stickyModes, formal));
+ val tree1 = copy.Apply(tree, fun, args1).setType(restpe);
+ val tree2 = constfold(tree1);
+ if (tree1 == tree2) tree2 else transform(tree2, mode, pt)
+ } else {
+ assert((mode & PATTERNmode) == 0); // this case cannot arise for patterns
val lenientTargs = protoTypeArgs(tparams, formals, restpe, pt);
val strictTargs = List.map2(lenientTargs, tparams)((targ, tparam) =>
if (targ == WildcardType) tparam.tpe else targ);
@@ -508,17 +527,11 @@ trait TypeCheckers: Analyzer {
val args1 = List.map2(args, formals)(transformArg);
if (args1 exists (.tpe.isError)) setError(tree)
else {
- val undetparams = inferMethodInstance(fn, tparams, args1, pt);
- val result = transformApply(fn, args1);
+ val undetparams = inferMethodInstance(fun, tparams, args1, pt);
+ val result = transformApply(fun, args1);
context.undetparams = undetparams;
result
}
- } else {
- val args1 = List.map2(args, formals) ((arg, formal) =>
- transform(arg, mode & stickyModes, formal));
- val tree1 = copy.Apply(tree, fn, args1).setType(restpe);
- val tree2 = constfold(tree1);
- if (tree1 == tree2) tree2 else transform(tree2, mode, pt)
}
}
case ErrorType =>
@@ -536,9 +549,8 @@ trait TypeCheckers: Analyzer {
NoSymbol
}
} else {
- var c = context;
- while (c != NoContext && !(c.owner.isClass && c.owner.name == qual))
- c = c.outer.enclClass;
+ var c = context.enclClass;
+ while (c != NoContext && c.owner.name != qual) c = c.outer.enclClass;
if (c != NoContext) c.owner
else {
error(tree.pos, "" + qual + " is not an enclosing class");
@@ -553,15 +565,11 @@ trait TypeCheckers: Analyzer {
def transformSelect(qual: Tree, name: Name): Tree = {
val sym = qual.tpe.member(name);
if (sym == NoSymbol && qual.isTerm) {
- val vmeth = bestView(tree.tpe, name);
+ val vmeth = bestView(qual.tpe, name);
if (vmeth != NoSymbol)
return transform(Select(Apply(Ident(vmeth.name), List(qual)), name), mode, pt)
}
- val pre = qual match {
- case Super(_, _) => context.enclClass.owner.thisType
- case _ => qual.tpe
- }
- stabilize(checkAccessible(tree, sym, pre, qual), pre);
+ stabilize(checkAccessible(tree, sym, qual.tpe, qual), qual.tpe)
}
/** Attribute an identifier consisting of a simple name or an outer reference.
@@ -572,97 +580,71 @@ trait TypeCheckers: Analyzer {
*/
def transformIdent(name: Name): Tree = {
def ambiguousError(msg: String) =
- unit.error(tree.pos, "reference to " + name + " is ambiguous;\n" + msg);
- def importTree(imp: Symbol) =
- imp.info.asInstanceOf[ImportType].tree;
- def importedSymbol(imp: Symbol) =
- treeInfo.importedSymbol(importTree(imp), name);
- def isExplicitImport(imp: Symbol) =
- treeInfo.isExplicitImport(importTree(imp), name);
- //System.out.println("transforming " + name);//DEBUG
-
- // Compute values of the following 4 variables,
- // except that `pre' is only set for directly inherited symbols.
- // Also detect double imports.
- var sym: Symbol = NoSymbol; // the directly found symbol
- var sym1: Symbol = NoSymbol; // the imported symbol
- var pre: Type = null; // if symbols are class members, their prefix type
- var impSym = NoSymbol; // if symbols are imported, the import symbol from
- // which they were imported.
- var cx: Context = context;
- while (sym == NoSymbol && cx != NoContext) {
- val symEntry = cx.scope.lookupEntry(name);
- var impEntry = cx.scope.lookupEntry(nme.IMPORT);
- while (impEntry != null) {
- var impSym1 = impEntry.sym;
- impEntry = cx.scope.lookupNextEntry(impEntry);
- sym1 = importedSymbol(impSym1);
- if (sym1 != NoSymbol) { // check whether shadowed by sym, reset to NoSymbol if yes.
- if (symEntry != null) {
- var impEntry1 = symEntry.owner.lookupEntry(nme.IMPORT);
- while (impEntry1 != null && sym1 != NoSymbol) {
- if (impEntry1.sym == impSym1) sym1 = NoSymbol;
- // directly found takes precedence
- impEntry1 = symEntry.owner.lookupNextEntry(impEntry1);
- }
- }
- }
- if (sym1 != NoSymbol) { // check for ambiguous imports
- var impSym2: Symbol = NoSymbol; // alternative import symbol
- var sym2: Symbol = NoSymbol; // alternative imported symbol
- def ambiguousImportError = ambiguousError(
- "it is imported twice in the same scope by\n" +
- importTree(impSym1) + "\nand " + importTree(impSym2));
- while (impEntry != null) {
- impSym2 = impEntry.sym;
- impEntry = cx.scope.lookupNextEntry(impEntry);
- if (impSym2.owner == impSym1.owner) {
- sym2 = importedSymbol(impSym2);
- if (sym2 != NoSymbol) {
- if (isExplicitImport(impSym2)) {
- if (isExplicitImport(impSym1)) ambiguousImportError;
- sym1 = sym2;
- impSym1 = impSym2;
- }
- if (isExplicitImport(impSym1)) sym2 = NoSymbol;
- }
- }
- }
- if (sym2 != NoSymbol) ambiguousImportError
- }
- }
- if (symEntry != null) sym = symEntry.sym;
- cx = cx.enclClass;
- if (cx != NoContext) {
- pre = cx.owner.thisType;
- if (sym == NoSymbol) sym = pre.member(name);
- cx = cx.outer;
+ error(tree.pos, "reference to " + name + " is ambiguous;\n" + msg);
+
+ var defSym: Symbol = NoSymbol; // the directly found symbol
+ var defEntry: ScopeEntry = null; // the scope entry of defSym, if defined in a local scope
+ var pre: Type = NoPrefix; // the prefix type of defSym, if a class member
+
+ var cx = context;
+ while (defSym == NoSymbol && cx != NoContext) {
+ defEntry = cx.scope.lookupEntry(name);
+ pre = cx.enclClass.owner.thisType;
+ if (defEntry != null) defSym = defEntry.sym
+ else {
+ cx = cx.enclClass;
+ defSym = pre.member(name);
+ if (defSym == NoSymbol) cx = cx.outer;
}
}
+ val symDepth = if (defEntry == null) cx.depth
+ else cx.depth - (cx.scope.nestingLevel - defEntry.owner.nestingLevel);
+ var impSym: Symbol = NoSymbol; // the imported symbol
+ var imports = context.imports; // impSym != NoSymbol => it is imported from imports.head
+ while (impSym == NoSymbol && !imports.isEmpty && imports.head.depth > symDepth) {
+ impSym = imports.head.importedSymbol(name);
+ if (impSym == NoSymbol) imports = imports.tail;
+ }
// detect ambiguous definition/import,
- // update `sym' to be the final resolved symbol,
- // update `pre' to be `sym's prefix type in case it is a class member,
+ // update `defSym' to be the final resolved symbol,
+ // update `pre' to be `sym's prefix type in case it is an imported member,
// and compute value of:
var qual: Tree = EmptyTree; // the qualififier tree if transformed tree is a select
- if (sym != NoSymbol) {
- if (sym1 != NoSymbol)
+ if (defSym != NoSymbol) {
+ if (impSym != NoSymbol)
ambiguousError(
- "it is both defined in " + sym.owner +
- " and imported subsequently by \n" + importTree(impSym));
- else if (sym.owner.isClass && !sym.owner.isPackageClass)
- qual = gen.This(tree.pos, pre.symbol);
+ "it is both defined in " + defSym.owner +
+ " and imported subsequently by \n" + imports.head);
+ else if (defSym.owner.isClass && !defSym.owner.isPackageClass)
+ qual = gen.This(pre.symbol) setPos tree.pos;
} else {
- if (sym1 != NoSymbol) {
- sym = sym1;
- qual = importTree(impSym).expr.duplicate;
+ if (impSym != NoSymbol) {
+ var impSym1 = NoSymbol;
+ var imports1 = imports.tail;
+ def ambiguousImportError = ambiguousError(
+ "it is imported twice in the same scope by\n" + impSym + "\nand " + impSym1);
+ while (!imports1.isEmpty && imports1.head.depth == imports.head.depth) {
+ var impSym1 = imports1.head.importedSymbol(name);
+ if (impSym1 != NoSymbol) {
+ if (imports1.head.isExplicitImport(name)) {
+ if (imports.head.isExplicitImport(name)) ambiguousImportError;
+ impSym = impSym1;
+ imports = imports1;
+ }
+ if (imports.head.isExplicitImport(name)) impSym1 = NoSymbol;
+ }
+ }
+ if (impSym1 != NoSymbol) ambiguousImportError;
+ defSym = impSym;
+ qual = imports.head.tree.expr;
pre = qual.tpe;
} else {
error(tree.pos, "not found: " + decode(name));
- sym = context.owner.newErrorSymbol(name);
+ defSym = context.owner.newErrorSymbol(name);
}
}
- stabilize(checkAccessible(tree, sym, pre, qual), pre);
+ stabilize(checkAccessible(tree, defSym, pre, qual), pre);
}
/** Post-process an identifier or selection node, performing the following:
@@ -690,6 +672,7 @@ trait TypeCheckers: Analyzer {
}
// begin transform1
+ System.out.println("transforming " + tree);//debug
val sym: Symbol = tree.symbol;
if (sym != null) sym.initialize;
if (settings.debug.value && tree.isDef) global.log("transforming definition of " + sym);
@@ -741,10 +724,12 @@ trait TypeCheckers: Analyzer {
.transformBlock(block, mode, pt)
case Sequence(elems) =>
- copy.Sequence(tree, elems mapConserve (elem => transform(elem, mode, pt))) setType pt
+ val elems1 = elems mapConserve (elem => transform(elem, mode, pt));
+ copy.Sequence(tree, elems1) setType pt
case Alternative(alts) =>
- copy.Alternative(tree, alts mapConserve (alt => transform(alt, mode, pt))) setType pt
+ val alts1 = alts mapConserve (alt => transform(alt, mode, pt));
+ copy.Alternative(tree, alts1) setType pt
case Bind(name, body) =>
val body1 = transform(body, mode, pt);
@@ -759,7 +744,7 @@ trait TypeCheckers: Analyzer {
case Assign(lhs, rhs) =>
def isGetter(sym: Symbol) = sym.info match {
- case PolyType(List(), _) => !sym.isStable
+ case PolyType(List(), _) => sym.owner.isClass && !sym.isStable
case _ => false
}
val lhs1 = transformExpr(lhs);
@@ -794,16 +779,14 @@ trait TypeCheckers: Analyzer {
copy.Match(tree, selector1, cases1) setType lub(cases1 map (.tpe))
case Return(expr) =>
- if ((context.owner.rawflags & INITIALIZED) == 0) {
+ val enclFun = context.owner.enclMethod;
+ if (!enclFun.isMethod || enclFun.isConstructor)
+ errorTree(tree, "return outside method definition")
+ else if ((context.owner.rawflags & INITIALIZED) == 0)
errorTree(tree, "method with return needs result type")
- } else {
- val enclFun = context.owner.enclMethod;
- if (!enclFun.isMethod || enclFun.isConstructor) {
- errorTree(tree, "return outside method definition")
- } else {
- val expr1: Tree = transform(expr, EXPRmode, enclFun.tpe.resultType);
- copy.Return(tree, expr1) setSymbol enclFun setType AllClass.tpe;
- }
+ else {
+ val expr1: Tree = transform(expr, EXPRmode, enclFun.tpe.resultType);
+ copy.Return(tree, expr1) setSymbol enclFun setType AllClass.tpe;
}
case Try(block, catches, finalizer) =>
@@ -819,7 +802,7 @@ trait TypeCheckers: Analyzer {
copy.Throw(tree, expr1) setType AllClass.tpe
case New(tpt: Tree) =>
- val tpt1 = transform(tpt, TYPEmode, WildcardType);
+ val tpt1 = transform(tpt, TYPEmode | FUNmode, WildcardType);
copy.New(tree, tpt1).setType(tpt.tpe)
case Typed(expr, tpt @ Ident(nme.WILDCARD_STAR)) =>
@@ -836,59 +819,47 @@ trait TypeCheckers: Analyzer {
copy.Typed(tree, expr1, tpt1)
case TypeApply(fun, args) =>
- val fun1 = transform(fun, mode & stickyModes | FUNmode, WildcardType);
- inferPolyAlternative(fun1, args.length);
- val args1 = args mapConserve (arg => transform(arg, TYPEmode, WildcardType));
- val targs = args1 map (.tpe);
- if (fun1.tpe.isError || (targs exists (.isError)))
- setError(tree)
- else fun1.tpe match {
- case PolyType(tparams, restpe) =>
- checkBounds(tree.pos, tparams, targs, "");
- copy.TypeApply(tree, fun1, args1) setType restpe.subst(tparams, targs)
- }
+ transformTypeApply(transform(fun, mode & stickyModes | FUNmode, WildcardType), args);
- case Apply(fn, args) =>
- val fnpt = if ((mode & PATTERNmode) != 0) pt else WildcardType;
- transformApply(transform(fn, mode | FUNmode | POLYmode, fnpt), args)
+ case Apply(fun, args) =>
+ val funpt = if ((mode & PATTERNmode) != 0) pt else WildcardType;
+ transformApply(transform(fun, mode & stickyModes | FUNmode | POLYmode, funpt), args)
case Super(qual, mix) =>
val clazz = qualifyingClass(qual);
- if (clazz == NoSymbol)
- setError(tree)
- else
- tree setSymbol clazz
- setType (
- if (mix == nme.EMPTY.toTypeName) {
- intersectionType(clazz.info.parents)
- } else {
- val ps = clazz.info.parents dropWhile (p => p.symbol.name != mix);
- if (ps.isEmpty) {
- error(tree.pos, "" + mix + " does not name a mixin base class of " + clazz);
- ErrorType
- } else ps.head
- })
+ if (clazz == NoSymbol) setError(tree)
+ else {
+ val owntype =
+ if (mix == nme.EMPTY.toTypeName) intersectionType(clazz.info.parents)
+ else {
+ val ps = clazz.info.parents dropWhile (p => p.symbol.name != mix);
+ if (ps.isEmpty) {
+ error(tree.pos, "" + mix + " does not name a mixin base class of " + clazz);
+ ErrorType
+ } else ps.head
+ }
+ tree setSymbol clazz setType owntype
+ }
case This(qual) =>
val clazz = qualifyingClass(qual);
if (clazz == NoSymbol) setError(tree)
else {
- tree.setSymbol(clazz);
- tree.setType(
- if (pt.isStable || (mode & QUALmode) != 0) clazz.thisType
- else clazz.typeOfThis)
- }
+ val owntype = if (pt.isStable || (mode & QUALmode) != 0) clazz.thisType
+ else clazz.typeOfThis;
+ tree setSymbol clazz setType owntype
+ }
case Select(qual, name) =>
- val qual1 = transform(qual, EXPRmode | QUALmode | POLYmode, WildcardType);
- if (name.isTypeName) checkStable(qual1);
+ var qual1 = transform(qual, EXPRmode | QUALmode | POLYmode, WildcardType);
+ if (name.isTypeName) qual1 = checkStable(qual1);
transformSelect(qual1, name);
case Ident(name) =>
transformIdent(name)
case Literal(value) =>
- tree.setType(literalType(value))
+ tree setType literalType(value)
case SingletonTypeTree(ref) =>
val ref1 = checkStable(transform(ref, EXPRmode | QUALmode, AnyRefClass.tpe));
@@ -897,24 +868,24 @@ trait TypeCheckers: Analyzer {
case SelectFromTypeTree(qual, selector) =>
tree setType transformSelect(transform(qual, TYPEmode, WildcardType), selector).tpe
- case CompoundTypeTree(parents, refinements) =>
+ case CompoundTypeTree(templ: Template) =>
tree setType {
- val parents1 = parents mapConserve (parent => transform(parent, TYPEmode, WildcardType));
+ val parents1 = templ.parents mapConserve (parent =>
+ transform(parent, TYPEmode, WildcardType));
if (parents1 exists (.tpe.isError)) ErrorType
else {
val decls = new Scope();
val self = refinedType(parents1 map (.tpe), context.enclClass.owner, decls);
- new TypeChecker(context.make(tree, self.symbol, decls))
- .transformRefinement(refinements);
+ new TypeChecker(context.make(tree, self.symbol, decls)).transformRefinement(templ.body);
self
}
}
case AppliedTypeTree(tpt, args) =>
val tpt1 = transform(tpt, mode | FUNmode, WildcardType);
- val args1 = args mapConserve (arg => transform(arg, TYPEmode, WildcardType));
val tparams = context.undetparams;
context.undetparams = List();
+ val args1 = args mapConserve (arg => transform(arg, TYPEmode, WildcardType));
if (tpt1.tpe.isError)
setError(tree)
else if (tparams.length == args1.length)
@@ -928,7 +899,12 @@ trait TypeCheckers: Analyzer {
def transform(tree: Tree, mode: int, pt: Type): Tree =
try {
- if (tree.tpe != null) tree else adapt(transform1(tree, mode, pt), mode, pt)
+ if (tree.tpe != null) tree
+ else {
+ val tree1 = transform1(tree, mode, pt);
+ System.out.println("transformed " + tree1 + ":" + tree1.tpe);//debug
+ adapt(tree1, mode, pt)
+ }
} catch {
case ex: TypeError =>
reportTypeError(tree.pos, ex);
@@ -938,6 +914,9 @@ trait TypeCheckers: Analyzer {
def transformExpr(tree: Tree): Tree =
transform(tree, EXPRmode, WildcardType);
+ def transformQualExpr(tree: Tree): Tree =
+ transform(tree, EXPRmode | QUALmode, WildcardType);
+
def transformType(tree: Tree, owner: Symbol) =
checkNoEscape(owner, transform(tree, TYPEmode, WildcardType));
}
diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala
index 12cfb8a66a..57162d4092 100755
--- a/sources/scala/tools/nsc/typechecker/Typers.scala
+++ b/sources/scala/tools/nsc/typechecker/Typers.scala
@@ -54,7 +54,7 @@ trait Typers: Analyzer {
}
private def deconstIfNotFinal(sym: Symbol, tpe: Type): Type =
- if (sym.isVariable || !sym.hasFlag(FINAL)) tpe.deconst else tpe;
+ if (sym.isVariable || (sym.rawflags & FINAL) == 0) tpe.deconst else tpe;
private def enterTypeParams(owner: Symbol, tparams: List[AbsTypeDef]): List[Symbol] = {
@@ -102,9 +102,11 @@ trait Typers: Analyzer {
val tparamSyms = enterTypeParams(meth, tparams);
val vparamSymss = enterValueParams(meth, vparamss);
val restype = deconstIfNotFinal(meth,
- if (meth.name == nme.CONSTRUCTOR) context.enclClass.owner.tpe
- else if (tpt.isEmpty) { tpt.tpe = typechecker.transformExpr(rhs).tpe; tpt.tpe }
- else typechecker.transformType(tpt, meth).tpe);
+ if (tpt.isEmpty) {
+ tpt.tpe = if (meth.name == nme.CONSTRUCTOR) context.enclClass.owner.tpe
+ else typechecker.transformExpr(rhs).tpe;
+ tpt.tpe
+ } else typechecker.transformType(tpt, meth).tpe);
def mkMethodType(vparams: List[Symbol], restpe: Type) =
MethodType(vparams map (.tpe), restpe);
makePolyType(
@@ -151,18 +153,21 @@ trait Typers: Analyzer {
TypeBounds(typechecker.transformType(lo, sym).tpe,
typechecker.transformType(hi, sym).tpe);
- case imptree @ Import(expr, selectors) =>
- val expr1 = typechecker.transformExpr(expr);
+ case Import(expr, selectors) =>
+ val expr1 = typechecker.transformQualExpr(expr);
val base = expr1.tpe;
typechecker.checkStable(expr1);
- for (val Pair(from, to) <- selectors) {
- if (from != nme.WILDCARD && base != ErrorType &&
- base.member(from) == NoSymbol && base.member(from.toTypeName) == NoSymbol)
- unit.error(tree.pos, from.decode + " is not a member of " + expr);
- if (to != null && to != nme.WILDCARD && (selectors exists (p => p._2 == to)))
- unit.error(tree.pos, to.decode + " appears twice as a target of a renaming");
+ def checkSelectors(selectors: List[Pair[Name, Name]]): unit = selectors match {
+ case Pair(from, to) :: rest =>
+ if (from != nme.WILDCARD && base != ErrorType &&
+ base.member(from) == NoSymbol && base.member(from.toTypeName) == NoSymbol)
+ unit.error(tree.pos, from.decode + " is not a member of " + expr);
+ if (to != null && to != nme.WILDCARD && (rest exists (sel => sel._2 == to)))
+ unit.error(tree.pos, to.decode + " appears twice as a target of a renaming");
+ checkSelectors(rest)
+ case Nil =>
}
- ImportType(imptree)
+ expr1.tpe
}
} catch {
case ex: TypeError =>
diff --git a/sources/scala/tools/scalac/typechecker/RefCheck.scala b/sources/scala/tools/scalac/typechecker/RefCheck.scala
index 1b3ce2e0a2..9b94cf99fb 100755
--- a/sources/scala/tools/scalac/typechecker/RefCheck.scala
+++ b/sources/scala/tools/scalac/typechecker/RefCheck.scala
@@ -863,6 +863,15 @@ class RefCheck(globl: scalac.Global) extends Transformer(globl) {
gen.DefDef(hashCodeSym, body)
}
+ private def isTrueSubClassOfCaseClass(clazz: Symbol): boolean = {
+ val cl = clazz.closure();
+ var i = 1; while (i < cl.length) {
+ if (cl(i).symbol().isCaseClass()) return true;
+ i = i + 1
+ }
+ false
+ }
+
private def addSyntheticMethods(templ: Template, clazz: ClassSymbol): Template = {
val ts = new TreeList();
if (clazz.isCaseClass()) {
@@ -883,7 +892,10 @@ class RefCheck(globl: scalac.Global) extends Transformer(globl) {
if (global.target != Global.TARGET_MSIL)
ts.append(getTypeMethod(clazz));
} else if ((clazz.flags & ABSTRACT) == 0) {
- ts.append(gen.mkTagMethod(clazz));
+ if (!isTrueSubClassOfCaseClass(clazz)) {
+ System.out.println("" + clazz + " gets tag method");
+ ts.append(gen.mkTagMethod(clazz));
+ }
if (global.target != Global.TARGET_MSIL)
ts.append(getTypeMethod(clazz));
}