summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2005-06-02 18:32:58 +0000
committerMartin Odersky <odersky@gmail.com>2005-06-02 18:32:58 +0000
commit2b80c3e689522c4c8adcee49d85836005b6ea187 (patch)
tree95df01204f6727d23312b0d99f804c099f1a3b72
parent364559e23368475e9bfad26fd28f229842b3e97b (diff)
downloadscala-2b80c3e689522c4c8adcee49d85836005b6ea187.tar.gz
scala-2b80c3e689522c4c8adcee49d85836005b6ea187.tar.bz2
scala-2b80c3e689522c4c8adcee49d85836005b6ea187.zip
*** empty log message ***
-rw-r--r--config/list/nsc.lst5
-rw-r--r--sources/scala/CaseClass.scala1
-rwxr-xr-xsources/scala/tools/nsc/Global.scala55
-rw-r--r--sources/scala/tools/nsc/Phase.scala5
-rw-r--r--sources/scala/tools/nsc/StdPhase.scala18
-rw-r--r--sources/scala/tools/nsc/SubComponent.scala23
-rwxr-xr-xsources/scala/tools/nsc/ast/TreeGen.scala9
-rw-r--r--sources/scala/tools/nsc/ast/Trees.scala101
-rwxr-xr-xsources/scala/tools/nsc/ast/parser/Parsers.scala41
-rwxr-xr-xsources/scala/tools/nsc/ast/parser/Scanners.scala2
-rw-r--r--sources/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala (renamed from sources/scala/tools/nsc/ast/parser/ParserPhase.scala)16
-rw-r--r--sources/scala/tools/nsc/ast/parser/Tokens.scala140
-rw-r--r--sources/scala/tools/nsc/ast/parser/TreeBuilder.scala36
-rw-r--r--sources/scala/tools/nsc/matching/PatternUtil.scala4
-rwxr-xr-xsources/scala/tools/nsc/symtab/Definitions.scala41
-rw-r--r--sources/scala/tools/nsc/symtab/Flags.scala102
-rwxr-xr-xsources/scala/tools/nsc/symtab/Names.scala4
-rwxr-xr-xsources/scala/tools/nsc/symtab/Scopes.scala4
-rwxr-xr-xsources/scala/tools/nsc/symtab/StdNames.scala18
-rwxr-xr-xsources/scala/tools/nsc/symtab/SymbolTable.scala1
-rwxr-xr-xsources/scala/tools/nsc/symtab/Symbols.scala33
-rwxr-xr-xsources/scala/tools/nsc/symtab/Types.scala86
-rw-r--r--sources/scala/tools/nsc/symtab/classfile/ClassfileConstants.scala60
-rwxr-xr-xsources/scala/tools/nsc/symtab/classfile/PickleFormat.scala76
-rwxr-xr-xsources/scala/tools/nsc/symtab/classfile/Pickler.scala42
-rw-r--r--sources/scala/tools/nsc/transform/SampleTransform.scala6
-rw-r--r--sources/scala/tools/nsc/transform/Transform.scala12
-rw-r--r--sources/scala/tools/nsc/transform/TypesAsValues.scala26
-rw-r--r--sources/scala/tools/nsc/typechecker/Analyzer.scala15
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Contexts.scala8
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Infer.scala17
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Namers.scala37
-rwxr-xr-xsources/scala/tools/nsc/typechecker/RefChecks.scala684
-rw-r--r--sources/scala/tools/nsc/typechecker/TreeCheckers.scala2
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Typers.scala71
-rw-r--r--sources/scala/xml/parsing/MarkupHandler.scala5
-rw-r--r--sources/scala/xml/parsing/MarkupParser.scala4
37 files changed, 1287 insertions, 523 deletions
diff --git a/config/list/nsc.lst b/config/list/nsc.lst
index 85d70bc768..506e2d750c 100644
--- a/config/list/nsc.lst
+++ b/config/list/nsc.lst
@@ -11,15 +11,15 @@ Main.scala
NoPhase.scala
Phase.scala
Settings.scala
-StdPhase.scala
+SubComponent.scala
ast/TreeGen.scala
ast/TreeInfo.scala
ast/TreePrinters.scala
ast/Trees.scala
-ast/parser/ParserPhase.scala
ast/parser/Parsers.scala
ast/parser/Scanners.scala
+ast/parser/SyntaxAnalyzer.scala
ast/parser/Tokens.scala
ast/parser/TreeBuilder.scala
@@ -53,7 +53,6 @@ symtab/classfile/UnPickler.scala
transform/SampleTransform.scala
transform/Transform.scala
-transform/TypesAsValues.scala
typechecker/Analyzer.scala
typechecker/ConstantFolder.scala
diff --git a/sources/scala/CaseClass.scala b/sources/scala/CaseClass.scala
index ef0864c97f..9b31387599 100644
--- a/sources/scala/CaseClass.scala
+++ b/sources/scala/CaseClass.scala
@@ -24,4 +24,5 @@ trait CaseClass extends AnyRef {
*/
def caseArity: Int ;
+ def caseName: String = ""; // for now
}
diff --git a/sources/scala/tools/nsc/Global.scala b/sources/scala/tools/nsc/Global.scala
index 86358d2ab9..317bc06ecd 100755
--- a/sources/scala/tools/nsc/Global.scala
+++ b/sources/scala/tools/nsc/Global.scala
@@ -40,22 +40,12 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
val global: Global.this.type = Global.this
}
- object pickler extends Pickler {
- val global: Global.this.type = Global.this
- }
-
- object typer extends analyzer.Typer(analyzer.NoContext);
-
object checker extends TreeCheckers {
val global: Global.this.type = Global.this
}
val copy = new LazyTreeCopier();
- object variance extends Variances {
- val global: Global.this.type = Global.this
- }
-
type AttrInfo = Pair[Type, List[Any]];
val attributes = new HashMap[Symbol, List[AttrInfo]];
@@ -71,7 +61,7 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
def informTime(msg: String, start: long) =
informProgress(msg + " in " + (System.currentTimeMillis() - start) + "ms");
- def log(msg: String) =
+ def log(msg: Object): unit =
if (settings.log contains phase.name) inform("[log " + phase + "] " + msg);
// file interface -------------------------------------------------------
@@ -131,10 +121,11 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
// Phases ------------------------------------------------------------
- object parserPhase extends ParserPhase(NoPhase) {
+ object syntaxAnalyzer extends SyntaxAnalyzer {
val global: Global.this.type = Global.this
}
+ val parserPhase = new syntaxAnalyzer.ParserPhase(NoPhase);
val firstPhase = parserPhase;
definitions.init; // needs firstPhase to be defined, that's why it is placed here.
@@ -142,7 +133,28 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
object analyzer extends Analyzer {
val global: Global.this.type = Global.this;
}
- val infer = new analyzer.Inferencer(analyzer.NoContext);
+ val typer = new analyzer.Typer(analyzer.NoContext.make(EmptyTree, definitions.RootClass, new Scope())) {
+ override def typed(tree: Tree, mode: int, pt: Type): Tree = {
+ if (settings.debug.value) log("typing [[" + tree + "]]");
+ val result = super.typed(tree, mode, pt);
+ if (settings.debug.value) log(" ==> " + result + ":" + result.tpe);
+ result
+ }
+ }
+ val infer = typer.infer;
+
+ val namerPhase = new analyzer.NamerPhase(parserPhase);
+ val typerPhase = new analyzer.TyperPhase(namerPhase);
+
+ object pickler extends Pickler {
+ val global: Global.this.type = Global.this
+ }
+ val picklePhase = new pickler.PicklePhase(typerPhase);
+
+ object refchecks extends RefChecks {
+ val global: Global.this.type = Global.this;
+ }
+ val refchecksPhase = new refchecks.Phase(picklePhase);
//object transmatcher extends TransMatcher {
// val global: Global.this.type = Global.this;
@@ -155,14 +167,9 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
object sampleTransform extends SampleTransform {
val global: Global.this.type = Global.this;
}
+ val samplePhase = new sampleTransform.Phase(refchecksPhase);
- val namerPhase = new analyzer.NamerPhase(parserPhase);
- val typeCheckPhase = new analyzer.TypeCheckPhase(namerPhase);
- val picklePhase = new pickler.PicklePhase(typeCheckPhase);
//val transMatchPhase = new transmatcher.TransMatchPhase(picklePhase);
- //val samplePhase = new sampleTransform.Phase(transMatchPhase);
- val typesAsValuesPhase: Phase = null; //new typesAsValues.Phase(transMatchPhase);
- val samplePhase = new sampleTransform.Phase(typeCheckPhase);
/*
object icode extends ICode {
val symtab: Global.this.type = Global.this
@@ -175,14 +182,12 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
}
*/
- val terminalPhase = new StdPhase(samplePhase) {
- val global: Global.this.type = Global.this;
+ val terminalPhase = new Phase(samplePhase) {
def name = "terminal";
- def apply(unit: CompilationUnit): unit = {}
+ def run: unit = {}
}
-
// Units and how to compile them -------------------------------------
private var unitbuf = new ListBuffer[CompilationUnit];
@@ -235,8 +240,10 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
}
}
} else {
- for (val Pair(sym, file) <- symSource.elements)
+ for (val Pair(sym, file) <- symSource.elements) {
sym.reset(new loaders.SourcefileLoader(file));
+ if (sym.isTerm) sym.moduleClass.reset(loaders.errorLoader);
+ }
}
informTime("total", startTime);
informStatistics;
diff --git a/sources/scala/tools/nsc/Phase.scala b/sources/scala/tools/nsc/Phase.scala
index a20779ee8c..d344e8486a 100644
--- a/sources/scala/tools/nsc/Phase.scala
+++ b/sources/scala/tools/nsc/Phase.scala
@@ -15,15 +15,18 @@ abstract class Phase(val prev: Phase) {
def name: String;
def description: String = name;
- def exactMatch: boolean = false;
+ def erasedTypes: boolean = false;
def run: unit;
override def toString() = name;
+ //commented out, just use `id' to compare.
+ /*
def >= (other: Phase): Boolean = {
this == other || prev >= other
}
+ */
// def check(units: List[CompilationUnit]): unit =
// for (val unit <- units; val checker <- checkers) checker.traverse(unit); // def checkers: List[Checker] = List();
diff --git a/sources/scala/tools/nsc/StdPhase.scala b/sources/scala/tools/nsc/StdPhase.scala
deleted file mode 100644
index 1a663a6a45..0000000000
--- a/sources/scala/tools/nsc/StdPhase.scala
+++ /dev/null
@@ -1,18 +0,0 @@
-/* NSC -- new scala compiler
- * Copyright 2005 LAMP/EPFL
- * @author Martin Odersky
- */
-// $Id$
-package scala.tools.nsc;
-
-abstract class StdPhase(prev: Phase) extends Phase(prev) {
- val global: Global;
- def run: unit =
- for (val unit <- global.units) {
- if (global.settings.debug.value) System.out.println("[running phase " + name + " on " + unit + "]");//debug
- apply(unit);
- }
- def apply(unit: global.CompilationUnit): unit;
-}
-
-
diff --git a/sources/scala/tools/nsc/SubComponent.scala b/sources/scala/tools/nsc/SubComponent.scala
new file mode 100644
index 0000000000..dbec8b8f93
--- /dev/null
+++ b/sources/scala/tools/nsc/SubComponent.scala
@@ -0,0 +1,23 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
+package scala.tools.nsc;
+
+/** An nsc sub-component.
+ */
+abstract class SubComponent {
+
+ val global: Global;
+
+ abstract class StdPhase(prev: Phase) extends Phase(prev) {
+ def run: unit =
+ for (val unit <- global.units) {
+ if (global.settings.debug.value) System.out.println("[running phase " + name + " on " + unit + "]");//debug
+ apply(unit);
+ }
+ def apply(unit: global.CompilationUnit): unit;
+ }
+}
+
diff --git a/sources/scala/tools/nsc/ast/TreeGen.scala b/sources/scala/tools/nsc/ast/TreeGen.scala
index 39c504f626..fc31aeff4c 100755
--- a/sources/scala/tools/nsc/ast/TreeGen.scala
+++ b/sources/scala/tools/nsc/ast/TreeGen.scala
@@ -40,7 +40,8 @@ abstract class TreeGen {
}
/** Builds a reference to given symbol. */
- def mkRef(sym: Symbol): Tree = mkRef(sym.owner.thisType, sym);
+ def mkRef(sym: Symbol): Tree =
+ if (sym.owner.isClass) mkRef(sym.owner.thisType, sym) else Ident(sym);
/** Replaces tree type with a stable type if possible */
def stabilize(tree: Tree): Tree = tree match {
@@ -92,8 +93,7 @@ abstract class TreeGen {
}
def mkIsInstanceOf(value: Tree, tpe: Type): Tree = {
- val afterTAV = global.phase >= global.typesAsValuesPhase;
- mkIsInstanceOf(value, tpe, afterTAV);
+ mkIsInstanceOf(value, tpe, global.phase.erasedTypes);
}
/** Builds a cast with given value and type. */
@@ -112,8 +112,7 @@ abstract class TreeGen {
}
def mkAsInstanceOf(value: Tree, tpe: Type): Tree = {
- val afterTAV = global.phase >= global.typesAsValuesPhase;
- mkAsInstanceOf(value, tpe, afterTAV);
+ mkAsInstanceOf(value, tpe, global.phase.erasedTypes);
}
}
diff --git a/sources/scala/tools/nsc/ast/Trees.scala b/sources/scala/tools/nsc/ast/Trees.scala
index 6e2fa1e14c..e3230fe19e 100644
--- a/sources/scala/tools/nsc/ast/Trees.scala
+++ b/sources/scala/tools/nsc/ast/Trees.scala
@@ -78,8 +78,9 @@ abstract class Trees: Global {
private def syntheticParams(owner: Symbol, formals: List[Type]): List[Symbol] = {
var cnt = 0;
- def freshName = { cnt = cnt + 1; newTermName("x$" + cnt) }
- formals map owner.newValueParameter(owner.pos, freshName).setInfo
+ def freshName() = { cnt = cnt + 1; newTermName("x$" + cnt) }
+ for (val formal <- formals) yield
+ owner.newValueParameter(owner.pos, freshName()).setInfo(formal);
}
// ----- tree node alternatives --------------------------------------
@@ -109,17 +110,29 @@ abstract class Trees: Global {
sym.name,
sym.typeParams map AbsTypeDef,
TypeTree(sym.typeOfThis),
- impl)
+ impl) setSymbol sym
}
}
+ /** Construct class definition with given class symbol, value parameters, supercall arguments
+ * and template body.
+ * @param sym the class symbol
+ * @param vparamss the value parameters -- if they have symbols they should be owned by `sym'
+ * @param argss the supercall arguments
+ * @param body the template statements without primary constructor and value parameter fields.
+ */
+ def ClassDef(sym: Symbol, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree]): ClassDef =
+ ClassDef(sym, Template(sym.info.parents map TypeTree, vparamss, argss, body));
+
/** Singleton object definition */
case class ModuleDef(mods: int, name: Name, impl: Template)
extends DefTree;
/** Value definition */
case class ValDef(mods: int, name: Name, tpt: Tree, rhs: Tree)
- extends DefTree;
+ extends DefTree {
+ assert(tpt.isType); assert(rhs.isTerm)
+ }
def ValDef(sym: Symbol, rhs: Tree): ValDef =
posAssigner.atPos(sym.pos) {
@@ -133,7 +146,9 @@ abstract class Trees: Global {
/** Method definition */
case class DefDef(mods: int, name: Name, tparams: List[AbsTypeDef],
vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree)
- extends DefTree;
+ extends DefTree {
+ assert(tpt.isType); assert(rhs.isTerm);
+ }
def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef =
posAssigner.atPos(sym.pos) {
@@ -181,17 +196,13 @@ abstract class Trees: Global {
/** Labelled expression - the symbols in the array (must be Idents!)
* are those the label takes as argument */
- case class LabelDef(name: Name, params: List[ValDef], rhs: Tree)
+ case class LabelDef(name: Name, params: List[Ident], rhs: Tree)
extends DefTree with TermTree;
- def LabelDef(sym: Symbol, rhs: List[Symbol] => Tree): LabelDef =
+ def LabelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef =
posAssigner.atPos(sym.pos) {
atPhase(phase.next) {
- sym.tpe match {
- case MethodType(formals, _) =>
- val params = syntheticParams(sym, formals);
- LabelDef(sym.name, params map ValDef, rhs(params)) setSymbol sym
- }
+ LabelDef(sym.name, params map Ident, rhs) setSymbol sym
}
}
@@ -217,6 +228,20 @@ abstract class Trees: Global {
case class Template(parents: List[Tree], body: List[Tree])
extends SymTree;
+ def Template(parents: List[Tree], vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree]): Template = {
+ /** Add constructor to template */
+ var vparamss1 =
+ vparamss map (.map (vd =>
+ ValDef(PARAM | (vd.mods & IMPLICIT), vd.name, vd.tpt.duplicate, EmptyTree)));
+ if (vparamss1.isEmpty ||
+ !vparamss1.head.isEmpty && (vparamss1.head.head.mods & IMPLICIT) != 0)
+ vparamss1 = List() :: vparamss1;
+ val superRef: Tree = Select(Super(nme.EMPTY.toTypeName, nme.EMPTY.toTypeName), nme.CONSTRUCTOR);
+ val superCall = (superRef /: argss) (Apply);
+ val constr: Tree = DefDef(0, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), superCall);
+ Template(parents, List.flatten(vparamss) ::: constr :: body)
+ }
+
/** Block of expressions (semicolon separated expressions) */
case class Block(stats: List[Tree], expr: Tree)
extends TermTree;
@@ -276,11 +301,19 @@ abstract class Trees: Global {
extends TermTree;
/** Object instantiation
- * @param init either a constructor or a template
+ * @param tpt a class type
+ * one should always use factory method below to build a user level new.
*/
- case class New(typeOrTempl: Tree)
+ case class New(tpt: Tree)
extends TermTree;
+ /** Factory method for object creation <new tpt(args_1)...(args_n)> */
+ def New(tpt: Tree, argss: List[List[Tree]]): Tree = {
+ assert(!argss.isEmpty);
+ val superRef: Tree = Select(New(tpt), nme.CONSTRUCTOR);
+ (superRef /: argss) (Apply);
+ }
+
/** Type annotation, eliminated by explicit outer */
case class Typed(expr: Tree, tpt: Tree)
extends TermTree;
@@ -421,7 +454,7 @@ abstract class Trees: Global {
def DefDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef;
def AbsTypeDef(tree: Tree, mods: int, name: Name, lo: Tree, hi: Tree): AbsTypeDef;
def AliasTypeDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], rhs: Tree): AliasTypeDef;
- def LabelDef(tree: Tree, name: Name, params: List[ValDef], rhs: Tree): LabelDef;
+ def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree): LabelDef;
def Import(tree: Tree, expr: Tree, selectors: List[Pair[Name, Name]]): Import;
def Attributed(tree: Tree, attribute: Tree, definition: Tree): Attributed;
def DocDef(tree: Tree, comment: String, definition: Tree): DocDef;
@@ -470,7 +503,7 @@ abstract class Trees: Global {
new AbsTypeDef(mods, name, lo, hi).copyAttrs(tree);
def AliasTypeDef(tree: Tree, mods: int, name: Name, tparams: List[AbsTypeDef], rhs: Tree) =
new AliasTypeDef(mods, name, tparams, rhs).copyAttrs(tree);
- def LabelDef(tree: Tree, name: Name, params: List[ValDef], rhs: Tree) =
+ def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree) =
new LabelDef(name, params, rhs).copyAttrs(tree);
def Import(tree: Tree, expr: Tree, selectors: List[Pair[Name, Name]]) =
new Import(expr, selectors).copyAttrs(tree);
@@ -573,7 +606,7 @@ abstract class Trees: Global {
if (mods0 == mods && (name0 == name) && (tparams0 == tparams) && (rhs0 == rhs)) => t
case _ => copy.AliasTypeDef(tree, mods, name, tparams, rhs)
}
- def LabelDef(tree: Tree, name: Name, params: List[ValDef], rhs: Tree) = tree match {
+ def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree) = tree match {
case t @ LabelDef(name0, params0, rhs0)
if ((name0 == name) && (params0 == params) && (rhs0 == rhs)) => t
case _ => copy.LabelDef(tree, name, params, rhs)
@@ -770,7 +803,7 @@ abstract class Trees: Global {
copy.AliasTypeDef(tree, mods, name, transformAbsTypeDefs(tparams), transform(rhs))
}
case LabelDef(name, params, rhs) =>
- copy.LabelDef(tree, name, transformValDefs(params), transform(rhs))
+ copy.LabelDef(tree, name, transformIdents(params), transform(rhs))
case Import(expr, selectors) =>
copy.Import(tree, transform(expr), selectors)
case Attributed(attribute, definition) =>
@@ -780,7 +813,7 @@ abstract class Trees: Global {
case Template(parents, body) =>
copy.Template(tree, transformTrees(parents), transformStats(body, tree.symbol))
case Block(stats, expr) =>
- copy.Block(tree, transformTrees(stats), transform(expr))
+ copy.Block(tree, transformStats(stats, currentOwner), transform(expr))
case CaseDef(pat, guard, body) =>
copy.CaseDef(tree, transform(pat), transform(guard), transform(body))
case Sequence(trees) =>
@@ -855,7 +888,7 @@ abstract class Trees: Global {
atOwner(exprOwner)(transform(stat))
else transform(stat));
- def atOwner[A](owner: Symbol)(trans: A): A = {
+ def atOwner[A](owner: Symbol)(trans: => A): A = {
val prevOwner = currentOwner;
currentOwner = owner;
val result = trans;
@@ -963,7 +996,7 @@ abstract class Trees: Global {
atOwner(exprOwner)(traverse(stat))
else traverse(stat));
- def atOwner(owner: Symbol)(traverse: unit): unit = {
+ def atOwner(owner: Symbol)(traverse: => unit): unit = {
val prevOwner = currentOwner;
currentOwner = owner;
traverse;
@@ -971,6 +1004,30 @@ abstract class Trees: Global {
}
}
+ class TreeTypeSubstituter(from: List[Symbol], to: List[Type]) extends Traverser {
+ val typeSubst = new SubstTypeMap(from, to);
+ override def traverse(tree: Tree): unit = {
+ if (tree.tpe != null) tree.tpe = typeSubst(tree.tpe);
+ super.traverse(tree)
+ }
+ def apply(tree: Tree): Tree = { val tree1 = tree.duplicate; traverse(tree1); tree1 }
+ }
+
+ class TreeSymSubstituter(from: List[Symbol], to: List[Symbol]) extends Traverser {
+ val symSubst = new SubstSymMap(from, to);
+ override def traverse(tree: Tree): unit = {
+ def subst(from: List[Symbol], to: List[Symbol]): unit = {
+ if (!from.isEmpty)
+ if (tree.symbol == from.head) tree setSymbol to.head
+ else subst(from.tail, to.tail)
+ }
+ if (tree.tpe != null) tree.tpe = symSubst(tree.tpe);
+ if (tree.hasSymbol) subst(from, to);
+ super.traverse(tree)
+ }
+ def apply(tree: Tree): Tree = { val tree1 = tree.duplicate; traverse(tree1); tree1 }
+ }
+
final class TreeList {
private var trees = List[Tree]();
def append(t: Tree): TreeList = { trees = t :: trees; this }
@@ -991,5 +1048,7 @@ abstract class Trees: Global {
tree
}
}
+
+
}
diff --git a/sources/scala/tools/nsc/ast/parser/Parsers.scala b/sources/scala/tools/nsc/ast/parser/Parsers.scala
index e62c204b72..6802f83930 100755
--- a/sources/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/sources/scala/tools/nsc/ast/parser/Parsers.scala
@@ -38,7 +38,7 @@ import Tokens._;
* (4) Wraps naked case definitions in a match as follows:
* { cases } ==> (x => x.match {cases}), except when already argument to match
*/
-abstract class Parsers: ParserPhase {
+abstract class Parsers: SyntaxAnalyzer {
import global._;
import posAssigner.atPos;
@@ -741,7 +741,7 @@ abstract class Parsers: ParserPhase {
simpleExpr()
}
- /* SimpleExpr ::= new SimpleType [`(' [Exprs] `)'] {`with' SimpleType} [TemplateBody]
+ /* SimpleExpr ::= new SimpleType {`(' [Exprs] `)'} {`with' SimpleType} [TemplateBody]
* | SimpleExpr1
* SimpleExpr1 ::= literal
* | xLiteral
@@ -788,14 +788,16 @@ abstract class Parsers: ParserPhase {
case NEW =>
t = atPos(in.skipToken()) {
val parents = new ListBuffer[Tree] + simpleType();
- var args: List[Tree] = List();
- if (in.token == LPAREN) args = argumentExprs();
+ val argss = new ListBuffer[List[Tree]];
+ if (in.token == LPAREN)
+ do { argss += argumentExprs() } while (in.token == LPAREN)
+ else argss += List();
while (in.token == WITH) {
in.nextToken();
parents += simpleType()
}
val stats = if (in.token == LBRACE) templateBody() else List();
- makeNew(parents.toList, stats, args)
+ makeNew(parents.toList, stats, argss.toList)
}
isNew = true
case _ =>
@@ -1488,7 +1490,7 @@ abstract class Parsers: ParserPhase {
}
/** ClassDef ::= ClassSig [`:' SimpleType] ClassTemplate
- * ClassSig ::= Id [TypeParamClause] [ClassParamClause]
+ * ClassSig ::= Id [TypeParamClause] {ClassParamClause}
*/
def classDef(mods: int): Tree =
atPos(in.skipToken()) {
@@ -1501,7 +1503,7 @@ abstract class Parsers: ParserPhase {
val mods1 = if (vparamss.isEmpty && (mods & Flags.ABSTRACT) != 0) {
mods | Flags.TRAIT
} else mods;
- val template = classTemplate(mods1, vparamss);
+ val template = classTemplate(mods1, name, vparamss);
ClassDef(mods1, name, tparams, thistpe, template)
}
@@ -1510,27 +1512,31 @@ abstract class Parsers: ParserPhase {
def objectDef(mods: int): Tree =
atPos(in.skipToken()) {
val name = ident();
- val template = classTemplate(mods, List());
+ val template = classTemplate(mods, name, List());
ModuleDef(mods, name, template)
}
/** ClassTemplate ::= [`extends' TemplateParents] [TemplateBody]
+ * TemplateParents ::= SimpleType {`(' [Exprs] `)'} {`with' SimpleType}
*/
- def classTemplate(mods: int, vparamss: List[List[ValDef]]): Template =
+ def classTemplate(mods: int, name: Name, vparamss: List[List[ValDef]]): Template =
atPos(in.pos) {
val parents = new ListBuffer[Tree];
- var args: List[Tree] = List();
+ val argss = new ListBuffer[List[Tree]];
if (in.token == EXTENDS) {
in.nextToken();
parents += simpleType();
- if (in.token == LPAREN) args = argumentExprs();
+ if (in.token == LPAREN)
+ do { argss += argumentExprs() } while (in.token == LPAREN)
+ else argss += List();
while (in.token == WITH) {
in.nextToken();
parents += simpleType()
}
- }
- parents += scalaScalaObjectConstr;
- if ((mods & Flags.CASE)!= 0) parents += caseClassConstr;
+ } else argss += List();
+ if (name != nme.ScalaObject.toTypeName)
+ parents += scalaScalaObjectConstr;
+ if (name.isTypeName && (mods & Flags.CASE) != 0) parents += caseClassConstr;
val ps = parents.toList;
var body =
if (in.token == LBRACE) {
@@ -1540,9 +1546,8 @@ abstract class Parsers: ParserPhase {
syntaxError("`extends' or `{' expected", true);
List()
}
- if ((mods & Flags.TRAIT) == 0)
- body = makeConstructorPart(mods, vparamss, args) ::: body;
- Template(ps, body)
+ if ((mods & Flags.TRAIT) == 0) Template(ps, vparamss, argss.toList, body)
+ else Template(ps, body)
}
////////// TEMPLATES ////////////////////////////////////////////////////////////
@@ -1660,7 +1665,7 @@ abstract class Parsers: ParserPhase {
if (in.token == LBRACKET)
t = atPos(in.pos)(AppliedTypeTree(t, typeArgs()));
val args = if (in.token == LPAREN) argumentExprs() else List();
- atPos(pos) { makeNew(List(t), List(), args) }
+ atPos(pos) { New(t, List(args)) }
}
def joinAttributes(attrs: List[Tree], defs: List[Tree]): List[Tree] =
diff --git a/sources/scala/tools/nsc/ast/parser/Scanners.scala b/sources/scala/tools/nsc/ast/parser/Scanners.scala
index c9669488d9..6a015a4d64 100755
--- a/sources/scala/tools/nsc/ast/parser/Scanners.scala
+++ b/sources/scala/tools/nsc/ast/parser/Scanners.scala
@@ -10,7 +10,7 @@ import scala.tools.util.{Position, SourceFile}
import SourceFile.{LF, FF, CR, SU}
import scala.tools.nsc.util.CharArrayReader;
-abstract class Scanners: ParserPhase {
+abstract class Scanners: SyntaxAnalyzer {
import global._;
diff --git a/sources/scala/tools/nsc/ast/parser/ParserPhase.scala b/sources/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala
index 07ca77e2cc..9d6395b48c 100644
--- a/sources/scala/tools/nsc/ast/parser/ParserPhase.scala
+++ b/sources/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala
@@ -1,21 +1,19 @@
/* NSC -- new scala compiler
* Copyright 2005 LAMP/EPFL
- * @author Martin Odersky
+ * @author Martin Odersky
*/
// $Id$
package scala.tools.nsc.ast.parser;
-abstract class ParserPhase(prev: Phase)
- extends StdPhase(prev)
- with Scanners
- with Parsers {
+/** An nsc sub-component.
+ */
+abstract class SyntaxAnalyzer extends SubComponent with Parsers with Scanners {
+ class ParserPhase(prev: scala.tools.nsc.Phase) extends StdPhase(prev) {
def name = "parser";
def apply(unit: global.CompilationUnit): unit = {
global.informProgress("parsing " + unit);
unit.body = new Parser(unit).parse();
}
-
- /** this is the first phase */
- override def >= (other: Phase) = this == other;
-
+ }
}
+
diff --git a/sources/scala/tools/nsc/ast/parser/Tokens.scala b/sources/scala/tools/nsc/ast/parser/Tokens.scala
index 90d1b7ad7b..853e97e2e3 100644
--- a/sources/scala/tools/nsc/ast/parser/Tokens.scala
+++ b/sources/scala/tools/nsc/ast/parser/Tokens.scala
@@ -8,85 +8,85 @@ package scala.tools.nsc.ast.parser;
object Tokens {
/** special tokens */
- val EMPTY = -3;
- val UNDEF = -2;
- val ERROR = -1;
- val EOF = 0;
+ final val EMPTY = -3;
+ final val UNDEF = -2;
+ final val ERROR = -1;
+ final val EOF = 0;
/** literals */
- val CHARLIT = 1;
- val INTLIT = 2;
- val LONGLIT = 3;
- val FLOATLIT = 4;
- val DOUBLELIT = 5;
- val STRINGLIT = 6;
- val SYMBOLLIT = 7;
+ final val CHARLIT = 1;
+ final val INTLIT = 2;
+ final val LONGLIT = 3;
+ final val FLOATLIT = 4;
+ final val DOUBLELIT = 5;
+ final val STRINGLIT = 6;
+ final val SYMBOLLIT = 7;
/** identifier */
- val IDENTIFIER = 10;
+ final val IDENTIFIER = 10;
/** keywords */
- val IF = 20;
- val FOR = 21;
- val ELSE = 22;
- val THIS = 23;
- val NULL = 24;
- val NEW = 25;
- val WITH = 26;
- val SUPER = 27;
- val CASE = 28;
- val CASECLASS = 29;
- val CASEOBJECT = 30;
- val VAL = 31;
- val ABSTRACT = 32;
- val FINAL = 33;
- val PRIVATE = 34;
- val PROTECTED = 35;
- val OVERRIDE = 36;
- val IMPLICIT = 37;
- val VAR = 38;
- val DEF = 39;
- val TYPE = 40;
- val EXTENDS = 41;
- val TRUE = 42;
- val FALSE = 43;
- val OBJECT = 44;
- val CLASS = 45;
+ final val IF = 20;
+ final val FOR = 21;
+ final val ELSE = 22;
+ final val THIS = 23;
+ final val NULL = 24;
+ final val NEW = 25;
+ final val WITH = 26;
+ final val SUPER = 27;
+ final val CASE = 28;
+ final val CASECLASS = 29;
+ final val CASEOBJECT = 30;
+ final val VAL = 31;
+ final val ABSTRACT = 32;
+ final val FINAL = 33;
+ final val PRIVATE = 34;
+ final val PROTECTED = 35;
+ final val OVERRIDE = 36;
+ final val IMPLICIT = 37;
+ final val VAR = 38;
+ final val DEF = 39;
+ final val TYPE = 40;
+ final val EXTENDS = 41;
+ final val TRUE = 42;
+ final val FALSE = 43;
+ final val OBJECT = 44;
+ final val CLASS = 45;
- val IMPORT = 46;
- val PACKAGE = 47;
- val YIELD = 48;
- val DO = 49;
- val TRAIT = 50;
- val SEALED = 51;
- val THROW = 52;
- val TRY = 53;
- val CATCH = 54;
- val FINALLY = 55;
- val WHILE = 56;
- val RETURN = 57;
- val MATCH = 58;
+ final val IMPORT = 46;
+ final val PACKAGE = 47;
+ final val YIELD = 48;
+ final val DO = 49;
+ final val TRAIT = 50;
+ final val SEALED = 51;
+ final val THROW = 52;
+ final val TRY = 53;
+ final val CATCH = 54;
+ final val FINALLY = 55;
+ final val WHILE = 56;
+ final val RETURN = 57;
+ final val MATCH = 58;
/** special symbols */
- val COMMA = 61;
- val SEMI = 62;
- val DOT = 63;
- val USCORE = 64;
- val COLON = 65;
- val EQUALS = 66;
- val LARROW = 67;
- val ARROW = 68;
- val SUBTYPE = 70;
- val SUPERTYPE = 71;
- val HASH = 72;
- val AT = 73;
- val VIEWBOUND = 74; //todo: elim
+ final val COMMA = 61;
+ final val SEMI = 62;
+ final val DOT = 63;
+ final val USCORE = 64;
+ final val COLON = 65;
+ final val EQUALS = 66;
+ final val LARROW = 67;
+ final val ARROW = 68;
+ final val SUBTYPE = 70;
+ final val SUPERTYPE = 71;
+ final val HASH = 72;
+ final val AT = 73;
+ final val VIEWBOUND = 74; //todo: elim
/** parenthesis */
- val LPAREN = 90;
- val RPAREN = 91;
- val LBRACKET = 92;
- val RBRACKET = 93;
- val LBRACE = 94;
- val RBRACE = 95;
+ final val LPAREN = 90;
+ final val RPAREN = 91;
+ final val LBRACKET = 92;
+ final val RBRACKET = 93;
+ final val LBRACE = 94;
+ final val RBRACE = 95;
}
diff --git a/sources/scala/tools/nsc/ast/parser/TreeBuilder.scala b/sources/scala/tools/nsc/ast/parser/TreeBuilder.scala
index 70b31cd2f6..751bf04060 100644
--- a/sources/scala/tools/nsc/ast/parser/TreeBuilder.scala
+++ b/sources/scala/tools/nsc/ast/parser/TreeBuilder.scala
@@ -20,9 +20,9 @@ abstract class TreeBuilder {
private object patvarTransformer extends Transformer {
override def transform(tree: Tree): Tree = tree match {
- case Ident(name) if (treeInfo.isVariableName(name)) =>
+ case Ident(name) if (treeInfo.isVariableName(name) && name != nme.WILDCARD) =>
atPos(tree.pos)(Bind(name, Ident(nme.WILDCARD)))
- case Typed(id @ Ident(name), tpt) =>
+ case Typed(id @ Ident(name), tpt) if (treeInfo.isVariableName(name) && name != nme.WILDCARD) =>
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))
@@ -90,16 +90,16 @@ abstract class TreeBuilder {
}
/** Create tree representing an object creation <new parents { stats }> */
- def makeNew(parents: List[Tree], stats: List[Tree], args: List[Tree]): Tree =
+ def makeNew(parents: List[Tree], stats: List[Tree], argss: List[List[Tree]]): Tree =
if (parents.tail.isEmpty && stats.isEmpty)
- Apply(Select(New(parents.head), nme.CONSTRUCTOR), args)
+ New(parents.head, argss)
else {
val x = freshName(nme.ANON_CLASS_NAME.toString());
Block(
List(ClassDef(
FINAL | SYNTHETIC, x, List(), TypeTree(),
- Template(parents, makeConstructorPart(0, List(List()), args) ::: stats))),
- New(Apply(Select(Ident(x), nme.CONSTRUCTOR), List())))
+ Template(parents, List(List()), argss, stats))),
+ New(Ident(x), List(List())))
}
/** Create a tree represeting an assignment <lhs = rhs> */
@@ -265,28 +265,6 @@ abstract class TreeBuilder {
}
}
- /** Add constructor to template */
- def makeConstructorPart(mods: int, vparamss: List[List[ValDef]], args: List[Tree]): List[Tree] = {
- var vparamss1 =
- vparamss map (.map (vd =>
- ValDef(PARAM | (vd.mods & IMPLICIT), vd.name, vd.tpt.duplicate, EmptyTree)));
- if (vparamss1.isEmpty ||
- !vparamss1.head.isEmpty && (vparamss1.head.head.mods & IMPLICIT) != 0)
- vparamss1 = List() :: vparamss1;
- val constr: Tree = DefDef(
- mods & ConstrFlags | SYNTHETIC, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(),
- makeSuperCall(args));
- val vparams: List[Tree] =
- for (val vparams <- vparamss; val vparam <- vparams) yield vparam;
- vparams ::: List(constr)
- }
-
- /** Create supercall */
- def makeSuperCall(args: List[Tree]): Tree =
- Apply(
- Select(Super(nme.EMPTY.toTypeName, nme.EMPTY.toTypeName), nme.CONSTRUCTOR),
- args);
-
/** Create a tree representing a function type */
def makeFunctionTypeTree(argtpes: List[Tree], restpe: Tree): Tree =
AppliedTypeTree(
@@ -295,7 +273,7 @@ abstract class TreeBuilder {
/** Append implicit view section if for `implicitViews' if nonempty */
def addImplicitViews(vparamss: List[List[ValDef]], implicitViews: List[Tree]): List[List[ValDef]] = {
- def makeViewParam(tpt: Tree) = ValDef(PARAM | IMPLICIT, freshName("view$"), tpt, EmptyTree);
+ def makeViewParam(tpt: Tree) = ValDef(PARAM | IMPLICIT | LOCAL | PRIVATE, freshName("view$"), tpt, EmptyTree);
if (implicitViews.isEmpty) vparamss
else vparamss ::: List(implicitViews map makeViewParam)
}
diff --git a/sources/scala/tools/nsc/matching/PatternUtil.scala b/sources/scala/tools/nsc/matching/PatternUtil.scala
index 1607c44856..475446eb56 100644
--- a/sources/scala/tools/nsc/matching/PatternUtil.scala
+++ b/sources/scala/tools/nsc/matching/PatternUtil.scala
@@ -14,7 +14,7 @@ import scala.tools.util.Position;
/** utility functions
*/
abstract class PatternUtil {
-
+/*
val global: Global;
import global._;
@@ -74,5 +74,5 @@ abstract class PatternUtil {
traverse(pat);
generatedVars;
}
-
+*/
} // class PatternUtil
diff --git a/sources/scala/tools/nsc/symtab/Definitions.scala b/sources/scala/tools/nsc/symtab/Definitions.scala
index c3b325addb..27ae5b4d93 100755
--- a/sources/scala/tools/nsc/symtab/Definitions.scala
+++ b/sources/scala/tools/nsc/symtab/Definitions.scala
@@ -37,9 +37,9 @@ abstract class Definitions: SymbolTable {
// the scala value classes
var UnitClass: Symbol = _;
var BooleanClass: Symbol = _;
- def Boolean_not = IterableClass.info.decl(nme.ZNOT);
- def Boolean_and = IterableClass.info.decl(nme.ZAND);
- def Boolean_or = IterableClass.info.decl(nme.ZOR);
+ def Boolean_not = getMember(IterableClass, nme.ZNOT);
+ def Boolean_and = getMember(IterableClass, nme.ZAND);
+ def Boolean_or = getMember(IterableClass, nme.ZOR);
var ByteClass: Symbol = _;
var ShortClass: Symbol = _;
var CharClass: Symbol = _;
@@ -50,34 +50,38 @@ abstract class Definitions: SymbolTable {
// the scala reference classes
var ScalaObjectClass: Symbol = _;
- def ScalaObjectClass_tag = ScalaObjectClass.info.decl( nme.tag );
+ def ScalaObjectClass_tag = getMember(ScalaObjectClass, nme.tag );
var AttributeClass: Symbol = _;
var RefClass: Symbol = _;
var PartialFunctionClass: Symbol = _;
var IterableClass: Symbol = _;
- def Iterable_next = IterableClass.info.decl("next");
- def Iterable_hasNext = IterableClass.info.decl("hasNext");
+ def Iterable_next = getMember(IterableClass, "next");
+ def Iterable_hasNext = getMember(IterableClass, "hasNext");
var IteratorClass: Symbol = _;
var SeqClass: Symbol = _;
- def Seq_length = SeqClass.info.decl("length");
+ def Seq_length = getMember(SeqClass, "length");
var ListClass: Symbol = _;
- def List_isEmpty = ListClass.info.decl("isEmpty");
- def List_head = ListClass.info.decl("head");
- def List_tail = ListClass.info.decl("tail");
+ def List_isEmpty = getMember(ListClass, "isEmpty");
+ def List_head = getMember(ListClass, "head");
+ def List_tail = getMember(ListClass, "tail");
var ArrayClass: Symbol = _;
var TypeClass: Symbol = _;
+ var SerializableClass: Symbol = _;
var PredefModule: Symbol = _;
var ConsoleModule: Symbol = _;
var MatchErrorModule: Symbol = _;
- def MatchError_fail = MatchErrorModule.info.decl("fail");
- def MatchError_report = MatchErrorModule.info.decl("report");
+ def MatchError_fail = getMember(MatchErrorModule, "fail");
+ def MatchError_report = getMember(MatchErrorModule, "report");
+ var CaseOpsModule: Symbol = _;
var RepeatedParamClass: Symbol = _;
var ByNameParamClass: Symbol = _;
val MaxTupleArity = 9;
val MaxFunctionArity = 9;
def TupleClass(i: int): Symbol = getClass("scala.Tuple" + i);
+ def tupleField(n:int, j:int) = getMember(TupleClass(n), "_" + j);
def FunctionClass(i: int): Symbol = getClass("scala.Function" + i);
+ def functionApply(n:int) = getMember(FunctionClass(n), "apply");
def tupleType(elems: List[Type]) =
if (elems.length <= MaxTupleArity) {
@@ -85,8 +89,6 @@ abstract class Definitions: SymbolTable {
typeRef(sym.typeConstructor.prefix, sym, elems)
} else NoType;
- def tupleField(n:int, j:int) =
- TupleClass(n).info.decl("_"+j.toString());
def functionType(formals: List[Type], restpe: Type) =
if (formals.length <= MaxFunctionArity) {
@@ -94,7 +96,6 @@ abstract class Definitions: SymbolTable {
typeRef(sym.typeConstructor.prefix, sym, formals ::: List(restpe))
} else NoType;
- def functionApply(n:int) = FunctionClass(n).info.decl("apply");
def isTupleType(tp: Type): boolean = tp match {
case TypeRef(_, sym, elems) =>
@@ -143,9 +144,17 @@ abstract class Definitions: SymbolTable {
def getModule(fullname: Name): Symbol =
getModuleOrClass(fullname, true);
+
def getClass(fullname: Name): Symbol =
getModuleOrClass(fullname, false);
+ def getMember(owner: Symbol, name: Name) = {
+ val result = owner.info.nonPrivateMember(name);
+ if (result == NoSymbol)
+ throw new FatalError(owner.toString() + " does not have a member " + name);
+ result
+ }
+
private def getModuleOrClass(fullname: Name, module: boolean): Symbol = {
var sym = RootClass;
var i = 0;
@@ -258,9 +267,11 @@ abstract class Definitions: SymbolTable {
ListClass = getClass("scala.List");
ArrayClass = getClass("scala.Array");
TypeClass = getClass("scala.Type");
+ SerializableClass = getClass("java.io.Serializable");
PredefModule = getModule("scala.Predef");
ConsoleModule = getModule("scala.Console");
MatchErrorModule = getModule("scala.MatchError");
+ CaseOpsModule = getModule("scala.runtime.CaseOps");
RepeatedParamClass = newCovariantPolyClass(
ScalaPackageClass, nme.REPEATED_PARAM_CLASS_NAME,
tparam => typeRef(SeqClass.typeConstructor.prefix, SeqClass, List(tparam.typeConstructor)));
diff --git a/sources/scala/tools/nsc/symtab/Flags.scala b/sources/scala/tools/nsc/symtab/Flags.scala
index 19f5681913..8823f3d49f 100644
--- a/sources/scala/tools/nsc/symtab/Flags.scala
+++ b/sources/scala/tools/nsc/symtab/Flags.scala
@@ -8,83 +8,83 @@ package scala.tools.nsc.symtab;
object Flags {
// modifiers
- val IMPLICIT = 0x00000001;
- val FINAL = 0x00000002;
- val PRIVATE = 0x00000004;
- val PROTECTED = 0x00000008;
-
- val SEALED = 0x00000010;
- val OVERRIDE = 0x00000020;
- val CASE = 0x00000040;
- val ABSTRACT = 0x00000080; // abstract class, or used in conjunction
+ final val IMPLICIT = 0x00000001;
+ final val FINAL = 0x00000002;
+ final val PRIVATE = 0x00000004;
+ final val PROTECTED = 0x00000008;
+
+ final val SEALED = 0x00000010;
+ final val OVERRIDE = 0x00000020;
+ final val CASE = 0x00000040;
+ final val ABSTRACT = 0x00000080; // abstract class, or used in conjunction
// with abstract override.
// Note difference to DEFERRED!
- val DEFERRED = 0x00000100; // was `abstract' for members
- val METHOD = 0x00000200; // a def parameter
- val TRAIT = 0x00000400; // a trait
- val MODULE = 0x00000800; // symbol is module or class implementing a module
+ final val DEFERRED = 0x00000100; // was `abstract' for members
+ final val METHOD = 0x00000200; // a def parameter
+ final val TRAIT = 0x00000400; // a trait
+ final val MODULE = 0x00000800; // symbol is module or class implementing a module
- val MUTABLE = 0x00001000; // symbol is a mutable variable.
- val PARAM = 0x00002000; // symbol is a (value or type) parameter to a method
- val PACKAGE = 0x00004000; // symbol is a java package
- val DEPRECATED = 0x00008000; // symbol is deprecated.
+ final val MUTABLE = 0x00001000; // symbol is a mutable variable.
+ final val PARAM = 0x00002000; // symbol is a (value or type) parameter to a method
+ final val PACKAGE = 0x00004000; // symbol is a java package
+ final val DEPRECATED = 0x00008000; // symbol is deprecated.
- val COVARIANT = 0x00010000; // symbol is a covariant type variable
- val CONTRAVARIANT = 0x00020000; // symbol is a contravariant type variable
- val ABSOVERRIDE = 0x00040000; // combination of abstract & override
- val LOCAL = 0x00080000; // symbol is local to current class.
+ final val COVARIANT = 0x00010000; // symbol is a covariant type variable
+ final val CONTRAVARIANT = 0x00020000; // symbol is a contravariant type variable
+ final val ABSOVERRIDE = 0x00040000; // combination of abstract & override
+ final val LOCAL = 0x00080000; // symbol is local to current class.
// pre: PRIVATE is also set
- val JAVA = 0x00100000; // symbol was defined by a Java class
- val SYNTHETIC = 0x00200000; // symbol is compiler-generated
- val STABLE = 0x00400000; // functions that are assumed to be stable
+ final val JAVA = 0x00100000; // symbol was defined by a Java class
+ final val SYNTHETIC = 0x00200000; // symbol is compiler-generated
+ final val STABLE = 0x00400000; // functions that are assumed to be stable
// (typically, access methods for valdefs)
- val STATIC = 0x00800000; // static field, method or class
+ final val STATIC = 0x00800000; // static field, method or class
- val ACCESSED = 0x01000000; // symbol was accessed at least once
- val SELECTOR = 0x02000000; // symbol was used as selector in Select
+ final val ACCESSED = 0x01000000; // symbol was accessed at least once
+ final val SELECTOR = 0x02000000; // symbol was used as selector in Select
- val CAPTURED = 0x04000000; // variable is accessed from nested function. Set by LambdaLift
- val ACCESSOR = 0x08000000; // a value or variable accessor
+ final val CAPTURED = 0x04000000; // variable is accessed from nested function. Set by LambdaLift
+ final val ACCESSOR = 0x08000000; // a value or variable accessor
- val ACCESS_METHOD = 0x10000000; // function is an access function for a method in some
+ final val ACCESS_METHOD = 0x10000000; // function is an access function for a method in some
// outer class; set by ExplicitOuter
- val PARAMACCESSOR = 0x20000000; // for value definitions: is an access method for a val parameter
+ final val PARAMACCESSOR = 0x20000000; // for value definitions: is an access method for a final val parameter
// for parameters: is a val parameter
- val LABEL = 0x40000000; // symbol is a label. Set by TailCall
- val BRIDGE = 0x80000000; // function is a bridge method. Set by Erasure
+ final val LABEL = 0x40000000; // symbol is a label. Set by TailCall
+ final val BRIDGE = 0x80000000; // function is a bridge method. Set by Erasure
- val INTERFACE = 0x100000000l; // symbol is an interface
- val IS_ERROR = 0x200000000l; // symbol is an error symbol
- val OVERLOADED = 0x400000000l; // symbol is overloaded
+ final val INTERFACE = 0x100000000l; // symbol is an interface
+ final val IS_ERROR = 0x200000000l; // symbol is an error symbol
+ final val OVERLOADED = 0x400000000l; // symbol is overloaded
- val TRANS_FLAG = 0x800000000l; // transient flag guaranteed to be reset after each phase.
- val LIFTED = TRANS_FLAG; // transient flag for lambdalift
- val INCONSTRUCTOR = TRANS_FLAG; // transient flag for analyzer
+ final val TRANS_FLAG = 0x800000000l; // transient flag guaranteed to be reset after each phase.
+ final val LIFTED = TRANS_FLAG; // transient flag for lambdalift
+ final val INCONSTRUCTOR = TRANS_FLAG; // transient flag for analyzer
- val INITIALIZED = 0x1000000000l; // symbol's definition is complete
- val LOCKED = 0x2000000000l; // temporary flag to catch cyclic dependencies
+ final val INITIALIZED = 0x1000000000l; // symbol's definition is complete
+ final val LOCKED = 0x2000000000l; // temporary flag to catch cyclic dependencies
// masks
- val SourceFlags = 0x001FFFFF; // these modifiers can be set in source programs.
- val ExplicitFlags = // these modifiers can be set explicitly in source programs.
+ final val SourceFlags = 0x001FFFFF; // these modifiers can be set in source programs.
+ final val ExplicitFlags = // these modifiers can be set explicitly in source programs.
PRIVATE | PROTECTED | ABSTRACT | FINAL | SEALED | OVERRIDE | CASE | IMPLICIT | ABSOVERRIDE;
- val PrintableFlags = // these modifiers appear in TreePrinter output.
+ final val PrintableFlags = // these modifiers appear in TreePrinter output.
ExplicitFlags | LOCAL | SYNTHETIC | STABLE | ACCESSOR |
ACCESS_METHOD | PARAMACCESSOR | LABEL | BRIDGE | STATIC;
- val GenFlags = // these modifiers can be in generated trees
+ final val GenFlags = // these modifiers can be in generated trees
SourceFlags | PrintableFlags;
- val FieldFlags = MUTABLE | ACCESSED | PARAMACCESSOR | STATIC;
+ final val FieldFlags = MUTABLE | ACCESSED | PARAMACCESSOR | STATIC | FINAL;
- val AccessFlags = PRIVATE | PROTECTED;
- val VARIANCES = COVARIANT | CONTRAVARIANT;
- val ConstrFlags = JAVA;
- val PickledFlags = 0xFFFFFFFF & ~LOCKED & ~INITIALIZED;
+ final val AccessFlags = PRIVATE | PROTECTED;
+ final val VARIANCES = COVARIANT | CONTRAVARIANT;
+ final val ConstrFlags = JAVA;
+ final val PickledFlags = 0xFFFFFFFF & ~LOCKED & ~INITIALIZED;
/** Module flags inherited by their module-class */
- val ModuleToClassFlags = AccessFlags | PACKAGE;
+ final val ModuleToClassFlags = AccessFlags | PACKAGE;
def flags2mods(flags: long): int = flags.asInstanceOf[int] & GenFlags;
diff --git a/sources/scala/tools/nsc/symtab/Names.scala b/sources/scala/tools/nsc/symtab/Names.scala
index ce7d66aed1..db919b182a 100755
--- a/sources/scala/tools/nsc/symtab/Names.scala
+++ b/sources/scala/tools/nsc/symtab/Names.scala
@@ -16,6 +16,8 @@ class Names {
private val HASH_MASK = 0x7FFF;
private val NAME_SIZE = 0x20000;
+ final val nameDebug = true;
+
/** memory to store all names sequentially
*/
var chrs: Array[char] = new Array[char](NAME_SIZE);
@@ -250,7 +252,7 @@ class Names {
/** Replace $op_name by corresponding operator symbol */
def decode: String =
NameTransformer.decode(toString()) +
- (if (isTypeName) "!" else "");//debug
+ (if (nameDebug && isTypeName) "!" else "");//debug
}
private class TermName(index: int, len: int, hash: int) extends Name(index, len) {
diff --git a/sources/scala/tools/nsc/symtab/Scopes.scala b/sources/scala/tools/nsc/symtab/Scopes.scala
index 4ce45d88d0..e606d5370b 100755
--- a/sources/scala/tools/nsc/symtab/Scopes.scala
+++ b/sources/scala/tools/nsc/symtab/Scopes.scala
@@ -109,9 +109,7 @@ abstract class Scopes: SymbolTable {
/** enter a symbol
*/
- def enter(sym: Symbol): unit = {
- enter(newScopeEntry(sym, this));
- }
+ def enter(sym: Symbol): unit = enter(newScopeEntry(sym, this));
private def createHash: unit = {
hashtable = new Array[ScopeEntry](HASHSIZE);
diff --git a/sources/scala/tools/nsc/symtab/StdNames.scala b/sources/scala/tools/nsc/symtab/StdNames.scala
index 45e6ac28dc..154a0584f3 100755
--- a/sources/scala/tools/nsc/symtab/StdNames.scala
+++ b/sources/scala/tools/nsc/symtab/StdNames.scala
@@ -88,6 +88,7 @@ abstract class StdNames: SymbolTable {
val WILDCARD_STAR = newTermName("_*");
val COMPOUND_NAME = newTermName("<ct>");
val ANON_CLASS_NAME = newTermName("$anon");
+ val ANONFUN_CLASS_NAME = newTermName("$anonfun");
val REFINE_CLASS_NAME = newTermName("<refinement>");
val EMPTY_PACKAGE_NAME = newTermName("<empty>");
val IMPORT = newTermName("<import>");
@@ -160,16 +161,22 @@ abstract class StdNames: SymbolTable {
val asInstanceOf = newTermName("asInstanceOf");
val asInstanceOfErased = newTermName("asInstanceOf$erased");
val box = newTermName("box");
+ val caseArity = newTermName("caseArity");
+ val caseElement = newTermName("caseElement");
+ val caseName = newTermName("caseName");
val checkCastability = newTermName("checkCastability");
val coerce = newTermName("coerce");
val defaultValue = newTermName("defaultValue");
val dummy = newTermName("$dummy");
val elem = newTermName("elem");
val elements = newTermName("elements");
+ val eq = newTermName("eq");
+ val equals_ = newTermName("equals");
val fail = newTermName("fail");
val report = newTermName("report");
val false_ = newTermName("false");
val filter = newTermName("filter");
+ val finalize_ = newTermName("finalize");
val flatMap = newTermName("flatMap");
val foreach = newTermName("foreach");
val getClass_ = newTermName("getClass");
@@ -189,17 +196,16 @@ abstract class StdNames: SymbolTable {
val nobinding = newTermName("nobinding");
val next = newTermName("next");
val newArray = newTermName("newArray");
+ val notify_ = newTermName("notify");
+ val notifyAll_ = newTermName("notifyAll");
val null_ = newTermName("null");
val predef = newTermName("predef");
val print = newTermName("print");
val runtime = newTermName("runtime");
+ val readResolve = newTermName("readResolve");
val scala = newTermName("scala");
val xml = newTermName("xml");
val synchronized_ = newTermName("synchronized");
- val caseArity = newTermName("caseArity");
- val caseElement = newTermName("caseElement");
- val eq = newTermName("eq");
- val equals = newTermName("equals");
val tail = newTermName("tail");
val toString_ = newTermName("toString");
val that = newTermName("that");
@@ -210,11 +216,7 @@ abstract class StdNames: SymbolTable {
val update = newTermName("update");
val view_ = newTermName("view");
val tag = newTermName("$tag");
- val finalize_ = newTermName("finalize");
val wait = newTermName("wait");
- val notify_ = newTermName("notify");
- val notifyAll_ = newTermName("notifyAll");
- val GetType = newTermName("GetType");
val ZNOT = encode("!");
val ZAND = encode("&&");
diff --git a/sources/scala/tools/nsc/symtab/SymbolTable.scala b/sources/scala/tools/nsc/symtab/SymbolTable.scala
index de57388c29..81de817b43 100755
--- a/sources/scala/tools/nsc/symtab/SymbolTable.scala
+++ b/sources/scala/tools/nsc/symtab/SymbolTable.scala
@@ -16,6 +16,7 @@ abstract class SymbolTable extends Names
with StdNames {
def settings: Settings;
def rootLoader: LazyType;
+ def log(msg: Object): unit;
private var CNT = 0;
private var ph: Phase = NoPhase;
diff --git a/sources/scala/tools/nsc/symtab/Symbols.scala b/sources/scala/tools/nsc/symtab/Symbols.scala
index e4793071ab..f31e572a7c 100755
--- a/sources/scala/tools/nsc/symtab/Symbols.scala
+++ b/sources/scala/tools/nsc/symtab/Symbols.scala
@@ -73,6 +73,8 @@ abstract class Symbols: SymbolTable {
new ClassSymbol(this, pos, name);
final def newAnonymousClass(pos: int) =
newClass(pos, nme.ANON_CLASS_NAME.toTypeName);
+ final def newAnonymousFunctionClass(pos: int) =
+ newClass(pos, nme.ANONFUN_CLASS_NAME.toTypeName);
final def newRefinementClass(pos: int) =
newClass(pos, nme.REFINE_CLASS_NAME.toTypeName);
final def newErrorClass(name: Name) = {
@@ -106,7 +108,7 @@ abstract class Symbols: SymbolTable {
final def isAliasType = isType && !isClass && !hasFlag(DEFERRED);
final def isAbstractType = isType && !isClass && hasFlag(DEFERRED);
final def isTypeParameter = isType && hasFlag(PARAM);
- final def isAnonymousClass = isClass && (name startsWith nme.ANON_CLASS_NAME); // startsWith necessary because name may grow when lifted
+ final def isAnonymousClass = isClass && (name startsWith nme.ANON_CLASS_NAME); // startsWith necessary because name may grow when lifted and also because of anonymous function classes
final def isRefinementClass = isClass && name == nme.REFINE_CLASS_NAME.toTypeName; // no lifting for refinement classes
final def isModuleClass = isClass && hasFlag(MODULE);
final def isPackageClass = isClass && hasFlag(PACKAGE);
@@ -139,8 +141,8 @@ abstract class Symbols: SymbolTable {
final def isSealed: boolean =
isClass && (hasFlag(SEALED) || isSubClass(AnyValClass) || isSubClass(ArrayClass));
- /** Is this symbol locally defined? I.e. not a member of a class or module */
- final def isLocal: boolean = owner.isTerm || hasFlag(LOCAL);
+ /** Is this symbol locally defined? I.e. not accessed from outside `this' instance */
+ final def isLocal: boolean = owner.isTerm;
/** Is this class locally defined?
* A class is local, if
@@ -159,7 +161,7 @@ abstract class Symbols: SymbolTable {
* (2) it is abstract override and its super symbol in `base' is nonexistent or inclomplete.
*/
final def isIncompleteIn(base: Symbol): boolean =
- (this == NoSymbol) ||
+ (base == NoSymbol) ||
(this hasFlag DEFERRED) ||
(this hasFlag ABSOVERRIDE) && isIncompleteIn(superSymbol(base));
@@ -308,13 +310,17 @@ abstract class Symbols: SymbolTable {
* inheritance graph (i.e. subclass.isLess(superclass) always holds).
* the ordering is given by: (isType, -|closure| for type symbols, id)
*/
- final def isLess(that: Symbol): boolean =
+ final def isLess(that: Symbol): boolean = {
+ def closureLength(sym: Symbol) =
+ if (sym.isAbstractType) 1 + sym.info.bounds.hi.closure.length
+ else sym.info.closure.length;
if (this.isType)
that.isType &&
- {val diff = this.info.closure.length - that.info.closure.length;
+ {val diff = closureLength(this) - closureLength(that);
diff > 0 || diff == 0 && this.id < that.id}
else
that.isType || this.id < that.id;
+ }
/** A partial ordering between symbols.
* (this isNestedIn that) holds iff this symbol is defined within
@@ -351,7 +357,7 @@ abstract class Symbols: SymbolTable {
def suchThat(cond: Symbol => boolean): Symbol = {
val result = filter(cond);
- assert(!result.hasFlag(OVERLOADED)/*, result.alternatives*/);
+ assert(!(result hasFlag OVERLOADED), result.alternatives);
result
}
@@ -396,7 +402,7 @@ abstract class Symbols: SymbolTable {
/** Return every accessor of a primary constructor parameter in this case class */
final def caseFieldAccessors: List[Symbol] = {
assert(isClass && hasFlag(CASE));
- info.decls.toList.filter(sym => !sym.hasFlag(PARAM) && sym.hasFlag(PARAMACCESSOR))
+ info.decls.toList filter (sym => !(sym hasFlag PRIVATE) && sym.hasFlag(PARAMACCESSOR))
}
/** The symbol accessed by this accessor function.
@@ -449,18 +455,18 @@ abstract class Symbols: SymbolTable {
/** The symbol overridden by this symbol in given base class */
final def overriddenSymbol(base: Symbol): Symbol =
base.info.nonPrivateDecl(name).suchThat(sym =>
- sym.isType || (owner.thisType.memberType(sym) matches tpe));
+ !sym.isTerm || (owner.thisType.memberType(sym) matches tpe));
/** The symbol overriding this symbol in given subclass */
final def overridingSymbol(base: Symbol): Symbol =
base.info.nonPrivateDecl(name).suchThat(sym =>
- sym.isType || (base.thisType.memberType(sym) matches base.thisType.memberType(this)));
+ !sym.isTerm || (base.thisType.memberType(sym) matches base.thisType.memberType(this)));
/** The symbol accessed by a super in the definition of `this' when seen from
* class `base'. This symbol is always concrete.
* pre: `this.owner' is in the base class sequence of `base'.
*/
- final def superSymbol(base: Symbol): Symbol = {
+ final def superSymbol(base: Symbol): Symbol = {
var bcs = base.info.baseClasses.dropWhile(.!=(owner)).tail;
var sym: Symbol = NoSymbol;
while (!bcs.isEmpty && sym == NoSymbol) {
@@ -473,7 +479,7 @@ abstract class Symbols: SymbolTable {
// ToString -------------------------------------------------------------------
/** A tag which (in the ideal case) uniquely identifies class symbols */
- final def tag: int = name.toString().hashCode();
+ final def tag: int = fullNameString.hashCode();
/** The simple name of this Symbol (this is always a term name) */
final def simpleName: Name =
@@ -589,8 +595,7 @@ abstract class Symbols: SymbolTable {
final def defString: String =
compose(List(flagsToString(flags & ExplicitFlags),
keyString,
- varianceString + nameString,
- infoString(rawInfo)));
+ varianceString + nameString + infoString(rawInfo)));
/** Concatenate strings separated by spaces */
private def compose(ss: List[String]): String =
diff --git a/sources/scala/tools/nsc/symtab/Types.scala b/sources/scala/tools/nsc/symtab/Types.scala
index 614f054c13..7dd9f40b0b 100755
--- a/sources/scala/tools/nsc/symtab/Types.scala
+++ b/sources/scala/tools/nsc/symtab/Types.scala
@@ -212,7 +212,7 @@ abstract class Types: SymbolTable {
* - Or both types are method types with equivalent type parameter types
* and matching result types
* - Or both types are equivalent
- * - Or phase.exactMatch is false and both types are neither method nor
+ * - Or phase.erasedTypes is false and both types are neither method nor
* poly types.
*/
def matches(that: Type): boolean =
@@ -313,6 +313,7 @@ abstract class Types: SymbolTable {
else baseClasses.head.newOverloaded(this, alts)
}
+ //todo: use narrow.memberType?
def findMember(name: Name, excludedFlags: int, requiredFlags: int): Symbol = {
//System.out.println("find member " + name.decode + " in " + this + ":" + this.baseClasses);//DEBUG
var members: Scope = null;
@@ -403,7 +404,14 @@ abstract class Types: SymbolTable {
// todo see whether we can do without
override def isError: boolean = true;
override def decls: Scope = new ErrorScope(NoSymbol);
- override def findMember(name: Name, excludedFlags: int, requiredFlags: int): Symbol = decls lookup name;
+ override def findMember(name: Name, excludedFlags: int, requiredFlags: int): Symbol = {
+ var sym = decls lookup name;
+ if (sym == NoSymbol) {
+ sym = NoSymbol.newErrorSymbol(name);
+ decls enter sym
+ }
+ sym
+ }
override def baseType(clazz: Symbol): Type = this;
override def toString(): String = "<error>";
override def narrow: Type = this;
@@ -477,10 +485,8 @@ abstract class Types: SymbolTable {
case class TypeBounds(lo: Type, hi: Type) extends SubType {
protected def supertype: Type = hi;
override def bounds: TypeBounds = this;
- def containsType(that: Type) = lo <:< that && that <:< hi;
- override def toString() =
- (if (lo.symbol != AllClass) " >: " + lo else "") +
- (if (hi.symbol != AnyClass) " <: " + hi else "");
+ def containsType(that: Type) = that <:< this || lo <:< that && that <:< hi;
+ override def toString() = ">: " + lo + " <: " + hi;
}
/** A common base class for intersection types and class types
@@ -489,6 +495,8 @@ abstract class Types: SymbolTable {
override val parents: List[Type];
override val decls: Scope;
+ assert(!parents.exists (.isInstanceOf[TypeBounds]), this);//debug
+
private var closureCache: Array[Type] = _;
private var baseClassCache: List[Symbol] = _;
private var validClosure: Phase = null;
@@ -565,7 +573,8 @@ abstract class Types: SymbolTable {
override def toString(): String =
parents.mkString("", " with ", "") +
- (if (settings.debug.value || decls.elems != null) decls.mkString("{", "; ", "}") else "")
+ (if (settings.debug.value || parents.isEmpty || decls.elems != null)
+ decls.mkString("{", "; ", "}") else "")
}
/** A class representing intersection types with refinements of the form
@@ -600,6 +609,7 @@ abstract class Types: SymbolTable {
*/
case class TypeRef(pre: Type, sym: Symbol, args: List[Type]) extends Type {
assert(!sym.isAbstractType || pre.isStable || pre.isError);
+ assert(!pre.isInstanceOf[ClassInfoType], this);
def transform(tp: Type): Type =
tp.asSeenFrom(pre, sym.owner).subst(sym.typeParams, args);
@@ -711,7 +721,8 @@ abstract class Types: SymbolTable {
override def erasure = resultType.erasure;
override def toString(): String =
- (if (typeParams.isEmpty) "=>! " else typeParams.mkString("[", ",", "]")) + resultType;//!!!
+ (if (typeParams.isEmpty) "=>! "
+ else (typeParams map (.defString)).mkString("[", ",", "]")) + resultType;
override def cloneInfo(owner: Symbol) = {
val tparams = cloneSymbols(typeParams, owner);
@@ -774,10 +785,8 @@ abstract class Types: SymbolTable {
/** The canonical creator for single-types */
def singleType(pre: Type, sym: Symbol): SingleType = {
- if (checkMalformedSwitch && !pre.isStable && !pre.isError) {
- System.out.println("malformed: " + pre + "." + sym.name + checkMalformedSwitch);//debug
+ if (checkMalformedSwitch && !pre.isStable && !pre.isError)
throw new MalformedType(pre, sym.name.toString());
- }
new SingleType(pre, rebind(pre, sym)) {}
}
@@ -967,14 +976,6 @@ abstract class Types: SymbolTable {
else if ((sym isSubClass clazz) && (pre.widen.symbol isSubClass sym)) pre
else toPrefix(pre.baseType(clazz).prefix, clazz.owner);
toPrefix(pre, clazz)
- case SingleType(pre, sym) =>
- if (sym.isPackageClass) tp // fast path // todo remove this case; it is redundant
- else
-// try {
- mapOver(tp)
-// } catch {
-// case ex: MalformedType => apply(tp.singleDeref) // todo: try needed?
-// }
case TypeRef(prefix, sym, args) if (sym.isTypeParameter) =>
def toInstance(pre: Type, clazz: Symbol): Type =
if (pre == NoType || pre == NoPrefix || !clazz.isClass) tp
@@ -1309,7 +1310,7 @@ abstract class Types: SymbolTable {
case Pair(_, MethodType(_, _)) => false
case Pair(_, PolyType(_, _)) => false
case _ =>
- !phase.exactMatch || tp1 =:= tp2
+ !phase.erasedTypes || tp1 =:= tp2
}
/** Prepend type `tp' to closure `cl' */
@@ -1458,16 +1459,18 @@ abstract class Types: SymbolTable {
case List() => AllClass.tpe
case List(t) => t
case ts @ PolyType(tparams, _) :: _ =>
- assert(false);//debug
PolyType(
List.map2(tparams, List.transpose(matchingBounds(ts, tparams)))
- ((tparam, bounds) => tparam.cloneSymbol.setInfo(glb(bounds))),
- lub0(ts map (.resultType)))
+ ((tparam, bounds) => tparam.cloneSymbol.setInfo(glb(bounds))),
+ lub0(matchingInstTypes(ts, tparams)))
case ts @ MethodType(pts, _) :: rest =>
MethodType(pts, lub0(matchingRestypes(ts, pts)))
+ case ts @ TypeBounds(_, _) :: rest =>
+ TypeBounds(glb(ts map (.bounds.lo)), lub(ts map (.bounds.hi)))
case ts =>
val closures: List[Array[Type]] = ts map (.closure);
val lubBaseTypes: Array[Type] = lubArray(closures);
+ //log("closures = " + (closures map (cl => List.fromArray(cl))) + ", lubbases = " + List.fromArray(lubBaseTypes));//DEBUG
val lubParents = spanningTypes(List.fromArray(lubBaseTypes));
val lubOwner = commonOwner(ts);
val lubBase = intersectionType(lubParents, lubOwner);
@@ -1483,7 +1486,7 @@ abstract class Types: SymbolTable {
else {
val symtypes = List.map2(narrowts, syms)
((t, sym) => t.memberInfo(sym).substThis(t.symbol, lubThisType));
- System.out.println("common symbols: " + syms + ":" + symtypes);//debug
+ if (settings.debug.value) log("common symbols: " + syms + ":" + symtypes);//debug
if (proto.isTerm)
proto.cloneSymbol.setInfo(lub(symtypes))
else if (symtypes.tail forall (symtypes.head =:=))
@@ -1506,18 +1509,18 @@ abstract class Types: SymbolTable {
for (val sym <- lubBase.nonPrivateMembers)
// add a refinement symbol for all non-class members of lubBase
// which are refined by every type in ts.
- if (!sym.isClass && (narrowts forall (t => refines(t, sym))))
+ if (!sym.isClass && !sym.isConstructor && (narrowts forall (t => refines(t, sym))))
addMember(lubThisType, lubType, lubsym(sym));
if (lubType.decls.isEmpty) lubBase else lubType;
}
if (settings.debug.value) {
- System.out.println(indent + "lub of " + ts);//debug
+ log(indent + "lub of " + ts);//debug
indent = indent + " ";
}
val res = limitRecursion(ts, "least upper", lub0);
if (settings.debug.value) {
indent = indent.substring(0, indent.length() - 2);
- System.out.println(indent + "lub of " + ts + " is " + res);//debug
+ log(indent + "lub of " + ts + " is " + res);//debug
}
res
}
@@ -1531,9 +1534,11 @@ abstract class Types: SymbolTable {
PolyType(
List.map2(tparams, List.transpose(matchingBounds(ts, tparams)))
((tparam, bounds) => tparam.cloneSymbol.setInfo(lub(bounds))),
- glb0(ts map (.resultType)))
+ glb0(matchingInstTypes(ts, tparams)))
case ts @ MethodType(pts, _) :: rest =>
MethodType(pts, glb0(matchingRestypes(ts, pts)))
+ case ts @ TypeBounds(_, _) :: rest =>
+ TypeBounds(lub(ts map (.bounds.lo)), glb(ts map (.bounds.hi)))
case ts =>
try {
val glbOwner = commonOwner(ts);
@@ -1573,7 +1578,7 @@ abstract class Types: SymbolTable {
})
}
for (val t <- ts; val sym <- t.nonPrivateMembers)
- if (!(sym.isClass || (glbThisType specializes sym)))
+ if (!sym.isClass && !sym.isConstructor && !(glbThisType specializes sym))
addMember(glbThisType, glbType, glbsym(sym));
if (glbType.decls.isEmpty) glbBase else glbType;
} catch {
@@ -1583,13 +1588,13 @@ abstract class Types: SymbolTable {
}
}
if (settings.debug.value) {
- System.out.println(indent + "glb of " + ts);//debug
+ log(indent + "glb of " + ts);//debug
indent = indent + " ";
}
val res = limitRecursion(ts, "greatest lower", glb0);
if (settings.debug.value) {
indent = indent.substring(0, indent.length() - 2);
- System.out.println(indent + "glb of " + ts + " is " + res);//debug
+ log(indent + "glb of " + ts + " is " + res);//debug
}
res
}
@@ -1605,7 +1610,7 @@ abstract class Types: SymbolTable {
/** The most deeply nested owner that contains all the symbols
* of thistype or prefixless typerefs/singletype occurrences in given list of types */
private def commonOwner(tps: List[Type]): Symbol = {
- if (settings.debug.value) System.out.println("computing common owner of types " + tps);//debug
+ if (settings.debug.value) log("computing common owner of types " + tps);//debug
commonOwnerMap.init;
tps foreach { tp => commonOwnerMap.apply(tp); () }
commonOwnerMap.result
@@ -1648,7 +1653,7 @@ abstract class Types: SymbolTable {
/** Make symbol `sym' a member of scope `tp.decls' where `thistp' is the narrowed
* owner type of the scope */
private def addMember(thistp: Type, tp: Type, sym: Symbol): unit = {
- System.out.println("add member " + sym);//debug
+ if (settings.debug.value) log("add member " + sym);//debug
if (!(thistp specializes sym)) {
if (sym.isTerm)
for (val alt <- tp.nonPrivateDecl(sym.name).alternatives)
@@ -1671,6 +1676,19 @@ abstract class Types: SymbolTable {
throw new Error("lub/glb of incompatible types: " + tps.mkString("", " and ", ""))
}
+ /** All types in list must be polytypes with type parameter lists of
+ * same length as tparams.
+ * Returns list of instance types, where corresponding type
+ * parameters are renamed to tparams.
+ */
+ private def matchingInstTypes(tps: List[Type], tparams: List[Symbol]): List[Type] =
+ tps map {
+ case PolyType(tparams1, restpe) if (tparams1.length == tparams.length) =>
+ restpe.substSym(tparams1, tparams)
+ case _ =>
+ throw new Error("lub/glb of incompatible types: " + tps.mkString("", " and ", ""))
+ }
+
/** All types in list must be method types with equal parameter types.
* Returns list of their result types.
*/
@@ -1685,7 +1703,7 @@ abstract class Types: SymbolTable {
// Errors and Diagnostics ---------------------------------------------------------
/** An exception signalling a type error */
- class TypeError(msg: String) extends java.lang.Error(msg);
+ class TypeError(val msg: String) extends java.lang.Error(msg);
/** An exception signalling a malformed type */
class MalformedType(msg: String) extends TypeError(msg) {
diff --git a/sources/scala/tools/nsc/symtab/classfile/ClassfileConstants.scala b/sources/scala/tools/nsc/symtab/classfile/ClassfileConstants.scala
index dbda7bcc20..f023552443 100644
--- a/sources/scala/tools/nsc/symtab/classfile/ClassfileConstants.scala
+++ b/sources/scala/tools/nsc/symtab/classfile/ClassfileConstants.scala
@@ -7,36 +7,36 @@ package scala.tools.nsc.symtab.classfile;
object ClassfileConstants {
- val JAVA_MAGIC = 0xCAFEBABE;
- val JAVA_MAJOR_VERSION = 45;
- val JAVA_MINOR_VERSION = 3;
+ final val JAVA_MAGIC = 0xCAFEBABE;
+ final val JAVA_MAJOR_VERSION = 45;
+ final val JAVA_MINOR_VERSION = 3;
- val JAVA_ACC_PUBLIC = 0x0001;
- val JAVA_ACC_PRIVATE = 0x0002;
- val JAVA_ACC_PROTECTED = 0x0004;
- val JAVA_ACC_STATIC = 0x0008;
- val JAVA_ACC_FINAL = 0x0010;
- val JAVA_ACC_SUPER = 0x0020;
- val JAVA_ACC_SYNCHRONIZED = 0x0020;
- val JAVA_ACC_VOLATILE = 0x0040;
- val JAVA_ACC_BRIDGE = 0x0040;
- val JAVA_ACC_TRANSIENT = 0x0080;
- val JAVA_ACC_NATIVE = 0x0100;
- val JAVA_ACC_INTERFACE = 0x0200;
- val JAVA_ACC_ABSTRACT = 0x0400;
- val JAVA_ACC_STRICT = 0x0800;
- val JAVA_ACC_SYNTHETIC = 0x1000;
+ final val JAVA_ACC_PUBLIC = 0x0001;
+ final val JAVA_ACC_PRIVATE = 0x0002;
+ final val JAVA_ACC_PROTECTED = 0x0004;
+ final val JAVA_ACC_STATIC = 0x0008;
+ final val JAVA_ACC_FINAL = 0x0010;
+ final val JAVA_ACC_SUPER = 0x0020;
+ final val JAVA_ACC_SYNCHRONIZED = 0x0020;
+ final val JAVA_ACC_VOLATILE = 0x0040;
+ final val JAVA_ACC_BRIDGE = 0x0040;
+ final val JAVA_ACC_TRANSIENT = 0x0080;
+ final val JAVA_ACC_NATIVE = 0x0100;
+ final val JAVA_ACC_INTERFACE = 0x0200;
+ final val JAVA_ACC_ABSTRACT = 0x0400;
+ final val JAVA_ACC_STRICT = 0x0800;
+ final val JAVA_ACC_SYNTHETIC = 0x1000;
- val CONSTANT_UTF8 = 1;
- val CONSTANT_UNICODE = 2;
- val CONSTANT_INTEGER = 3;
- val CONSTANT_FLOAT = 4;
- val CONSTANT_LONG = 5;
- val CONSTANT_DOUBLE = 6;
- val CONSTANT_CLASS = 7;
- val CONSTANT_STRING = 8;
- val CONSTANT_FIELDREF = 9;
- val CONSTANT_METHODREF = 10;
- val CONSTANT_INTFMETHODREF = 11;
- val CONSTANT_NAMEANDTYPE = 12;
+ final val CONSTANT_UTF8 = 1;
+ final val CONSTANT_UNICODE = 2;
+ final val CONSTANT_INTEGER = 3;
+ final val CONSTANT_FLOAT = 4;
+ final val CONSTANT_LONG = 5;
+ final val CONSTANT_DOUBLE = 6;
+ final val CONSTANT_CLASS = 7;
+ final val CONSTANT_STRING = 8;
+ final val CONSTANT_FIELDREF = 9;
+ final val CONSTANT_METHODREF = 10;
+ final val CONSTANT_INTFMETHODREF = 11;
+ final val CONSTANT_NAMEANDTYPE = 12;
}
diff --git a/sources/scala/tools/nsc/symtab/classfile/PickleFormat.scala b/sources/scala/tools/nsc/symtab/classfile/PickleFormat.scala
index 1f05cf1234..4b763baa10 100755
--- a/sources/scala/tools/nsc/symtab/classfile/PickleFormat.scala
+++ b/sources/scala/tools/nsc/symtab/classfile/PickleFormat.scala
@@ -51,43 +51,43 @@ object PickleFormat {
*
* len is remaining length after `len'.
*/
- val TERMname = 1;
- val TYPEname = 2;
- val NONEsym = 3;
- val TYPEsym = 4;
- val ALIASsym = 5;
- val CLASSsym = 6;
- val MODULEsym = 7;
- val VALsym = 8;
- val EXTref = 9;
- val EXTMODCLASSref = 10;
- val NOtpe = 11;
- val NOPREFIXtpe = 12;
- val THIStpe = 13;
- val SINGLEtpe = 14;
- val CONSTANTtpe = 15;
- val TYPEREFtpe = 16;
- val TYPEBOUNDStpe = 17;
- val REFINEDtpe = 18;
- val CLASSINFOtpe = 19;
- val METHODtpe = 20;
- val POLYtpe = 21;
- val IMPLICITMETHODtpe = 22;
- val LITERALunit = 24;
- val LITERALboolean = 25;
- val LITERALbyte = 26;
- val LITERALshort = 27;
- val LITERALchar = 28;
- val LITERALint = 29;
- val LITERALlong = 30;
- val LITERALfloat = 31;
- val LITERALdouble = 32;
- val LITERALstring = 33;
- val LITERALnull = 34;
- val LITERALzero = 35;
+ final val TERMname = 1;
+ final val TYPEname = 2;
+ final val NONEsym = 3;
+ final val TYPEsym = 4;
+ final val ALIASsym = 5;
+ final val CLASSsym = 6;
+ final val MODULEsym = 7;
+ final val VALsym = 8;
+ final val EXTref = 9;
+ final val EXTMODCLASSref = 10;
+ final val NOtpe = 11;
+ final val NOPREFIXtpe = 12;
+ final val THIStpe = 13;
+ final val SINGLEtpe = 14;
+ final val CONSTANTtpe = 15;
+ final val TYPEREFtpe = 16;
+ final val TYPEBOUNDStpe = 17;
+ final val REFINEDtpe = 18;
+ final val CLASSINFOtpe = 19;
+ final val METHODtpe = 20;
+ final val POLYtpe = 21;
+ final val IMPLICITMETHODtpe = 22;
+ final val LITERALunit = 24;
+ final val LITERALboolean = 25;
+ final val LITERALbyte = 26;
+ final val LITERALshort = 27;
+ final val LITERALchar = 28;
+ final val LITERALint = 29;
+ final val LITERALlong = 30;
+ final val LITERALfloat = 31;
+ final val LITERALdouble = 32;
+ final val LITERALstring = 33;
+ final val LITERALnull = 34;
+ final val LITERALzero = 35;
- val firstSymTag = NONEsym;
- val lastSymTag = VALsym;
- val firstTypeTag = NOtpe;
- val lastTypeTag = POLYtpe;
+ final val firstSymTag = NONEsym;
+ final val lastSymTag = VALsym;
+ final val firstTypeTag = NOtpe;
+ final val lastTypeTag = POLYtpe;
}
diff --git a/sources/scala/tools/nsc/symtab/classfile/Pickler.scala b/sources/scala/tools/nsc/symtab/classfile/Pickler.scala
index f8dbada928..5c1c7dbe53 100755
--- a/sources/scala/tools/nsc/symtab/classfile/Pickler.scala
+++ b/sources/scala/tools/nsc/symtab/classfile/Pickler.scala
@@ -15,33 +15,31 @@ import PickleFormat._;
* Serialize a top-level module and/or class;
* @see EntryTags.scala for symbol table attribute format.
*/
-abstract class Pickler {
- val global: Global;
+abstract class Pickler extends SubComponent {
import global._;
class PicklePhase(prev: Phase) extends StdPhase(prev) {
def name = "pickler";
- val global: Pickler.this.global.type = Pickler.this.global;
- def apply(unit: CompilationUnit): unit = pickle(unit.body);
-
- private def pickle(tree: Tree): unit = tree match {
- case PackageDef(_, stats) => stats foreach pickle;
- case ClassDef(_, _, _, _, _) | ModuleDef(_, _, _) =>
- val sym = tree.symbol;
- if (settings.debug.value) System.out.println("pickling " + tree + " " + sym);//debug
- val pickle = new Pickle(sym.name.toTermName, sym.owner);
- def add(sym: Symbol) = {
- if (!sym.isExternal && !symData.contains(sym)) {
- if (settings.debug.value) log("pickling " + sym);
- pickle.putSymbol(sym);
- symData(sym) = pickle;
+ def apply(unit: CompilationUnit): unit = {
+ def pickle(tree: Tree): unit = tree match {
+ case PackageDef(_, stats) => stats foreach pickle;
+ case ClassDef(_, _, _, _, _) | ModuleDef(_, _, _) =>
+ val sym = tree.symbol;
+ val pickle = new Pickle(sym.name.toTermName, sym.owner);
+ def add(sym: Symbol) = {
+ if (!sym.isExternal && !symData.contains(sym)) {
+ if (settings.debug.value) log("pickling " + sym);
+ pickle.putSymbol(sym);
+ symData(sym) = pickle;
+ }
}
- }
- add(sym);
- add(sym.linkedSym);
- pickle.finish
- case _ =>
+ add(sym);
+ add(sym.linkedSym);
+ pickle.finish
+ case _ =>
}
+ pickle(unit.body);
+ }
}
class Pickle(rootName: Name, rootOwner: Symbol) extends PickleBuffer(new Array[byte](4096), -1, 0) {
@@ -231,7 +229,7 @@ abstract class Pickler {
def finish = {
assert(writeIndex == 0);
writeNat(ep);
- if (settings.debug.value) System.out.println("" + ep + " entries");//debug
+ if (settings.debug.value) log("" + ep + " entries");//debug
for (val i <- Iterator.range(0, ep)) writeEntry(entries(i))
}
}
diff --git a/sources/scala/tools/nsc/transform/SampleTransform.scala b/sources/scala/tools/nsc/transform/SampleTransform.scala
index 75595ebaca..7a525022c9 100644
--- a/sources/scala/tools/nsc/transform/SampleTransform.scala
+++ b/sources/scala/tools/nsc/transform/SampleTransform.scala
@@ -12,14 +12,14 @@ abstract class SampleTransform extends Transform {
import global._; // the global environment
import definitions._; // standard classes and methods
- import typer.typed; // methods to type trees
+ import typer.{typed, atOwner}; // methods to type trees
import posAssigner.atPos; // for filling in tree positions
/** the following two members override abstract members in Transform */
protected val phaseName: String = "sample-phase";
- protected def newTransformer: Transformer = new SampleTransformer;
+ protected def newTransformer(unit: CompilationUnit): Transformer = new SampleTransformer(unit);
- class SampleTransformer extends Transformer {
+ class SampleTransformer(unit: CompilationUnit) extends Transformer {
override def transform(tree: Tree): Tree = {
val tree1 = super.transform(tree); // transformers always maintain `currentOwner'.
diff --git a/sources/scala/tools/nsc/transform/Transform.scala b/sources/scala/tools/nsc/transform/Transform.scala
index 49b46d92f5..886ccf931f 100644
--- a/sources/scala/tools/nsc/transform/Transform.scala
+++ b/sources/scala/tools/nsc/transform/Transform.scala
@@ -5,20 +5,18 @@
// $Id$
package scala.tools.nsc.transform;
-/** A sample transform.
+/** A base class for transforms.
+ * A transform contains a compiler phase which applies a tree transformer.
*/
-abstract class Transform {
-
- val global: Global;
+abstract class Transform extends SubComponent {
protected val phaseName: String;
- protected def newTransformer: global.Transformer;
+ protected def newTransformer(unit: global.CompilationUnit): global.Transformer;
class Phase(prev: scala.tools.nsc.Phase) extends StdPhase(prev) {
- val global: Transform.this.global.type = Transform.this.global;
def name: String = phaseName;
def apply(unit: global.CompilationUnit): unit =
- unit.body = newTransformer.transform(unit.body);
+ unit.body = newTransformer(unit).transform(unit.body);
}
}
diff --git a/sources/scala/tools/nsc/transform/TypesAsValues.scala b/sources/scala/tools/nsc/transform/TypesAsValues.scala
deleted file mode 100644
index f9f85fd288..0000000000
--- a/sources/scala/tools/nsc/transform/TypesAsValues.scala
+++ /dev/null
@@ -1,26 +0,0 @@
-/* NSC -- new scala compiler
- * Copyright 2005 LAMP/EPFL
- * @author
- */
-// $Id$
-package scala.tools.nsc.transform;
-
-abstract class TypesAsValues extends Transform {
-
- // inherits abstract value `global' and class `Phase' from Transform
-
- import global._; // the global environment
- import definitions._; // standard classes and methods
- import typer.typed; // methods to type trees
- import posAssigner.atPos; // for filling in tree positions
-
- protected val phaseName: String = "typesAsValues-phase";
- protected def newTransformer: Transformer = new TypesAsValuesTransformer;
-
- class TypesAsValuesTransformer extends Transformer {
-
- override def transform(tree: Tree): Tree = tree; //@todo
-
- }
-
-}
diff --git a/sources/scala/tools/nsc/typechecker/Analyzer.scala b/sources/scala/tools/nsc/typechecker/Analyzer.scala
index 18de3855b8..108781e275 100644
--- a/sources/scala/tools/nsc/typechecker/Analyzer.scala
+++ b/sources/scala/tools/nsc/typechecker/Analyzer.scala
@@ -5,17 +5,16 @@
// $Id$
package scala.tools.nsc.typechecker;
-import scala.tools.util.Position;
-
/** The main attribution phase.
*/
abstract class Analyzer
- extends Contexts
- with Namers
- with Typers
- with Infer
- with EtaExpansion
- {
+ extends SubComponent
+ with Contexts
+ with Namers
+ with Typers
+ with Infer
+ with Variances
+ with EtaExpansion {
val global: Global;
}
diff --git a/sources/scala/tools/nsc/typechecker/Contexts.scala b/sources/scala/tools/nsc/typechecker/Contexts.scala
index 85bc6e9d74..807283bffc 100755
--- a/sources/scala/tools/nsc/typechecker/Contexts.scala
+++ b/sources/scala/tools/nsc/typechecker/Contexts.scala
@@ -8,7 +8,7 @@ package scala.tools.nsc.typechecker;
import symtab.Flags._;
import scala.tools.util.Position;
-class Contexts: Analyzer {
+abstract class Contexts: Analyzer {
import global._;
val NoContext = new Context {
@@ -197,7 +197,7 @@ class Contexts: Analyzer {
}
impls
}
- if (settings.debug.value) System.out.println("collect implicit imports " + imp + "=" + collect(imp.tree.selectors));//debug
+ if (settings.debug.value) log("collect implicit imports " + imp + "=" + collect(imp.tree.selectors));//debug
collect(imp.tree.selectors)
}
@@ -206,10 +206,10 @@ class Contexts: Analyzer {
val newImplicits: List[ImplicitInfo] =
if (owner != outer.owner && owner.isClass && !owner.isPackageClass) {
if (!owner.hasFlag(INITIALIZED)) return outer.implicitss;
- if (settings.debug.value) System.out.println("collect member implicits " + owner + ", implicit members = " + owner.thisType.implicitMembers);//debug
+ if (settings.debug.value) log("collect member implicits " + owner + ", implicit members = " + owner.thisType.implicitMembers);//debug
collectImplicits(owner.thisType.implicitMembers, owner.thisType)
} else if (scope != outer.scope && !owner.isPackageClass) {
- if (settings.debug.value) System.out.println("collect local implicits " + scope.toList);//debug
+ if (settings.debug.value) log("collect local implicits " + scope.toList);//debug
collectImplicits(scope.toList, NoPrefix)
} else if (imports != outer.imports) {
assert(imports.tail == outer.imports);
diff --git a/sources/scala/tools/nsc/typechecker/Infer.scala b/sources/scala/tools/nsc/typechecker/Infer.scala
index 96e4909557..b50da84cb8 100755
--- a/sources/scala/tools/nsc/typechecker/Infer.scala
+++ b/sources/scala/tools/nsc/typechecker/Infer.scala
@@ -9,7 +9,6 @@ abstract class Infer: Analyzer {
import symtab.Flags._;
import global._;
import definitions._;
- import variance.{varianceInType, varianceInTypes};
import posAssigner.atPos;
import util.ListBuffer;
@@ -138,14 +137,6 @@ abstract class Infer: Analyzer {
case tp1 => tp1
}
- class TreeSubstituter(tparams: List[Symbol], targs: List[Type]) extends Traverser {
- val typeSubst = new SubstTypeMap(tparams, targs);
- override def traverse(tree: Tree): unit = {
- if (tree.tpe != null) tree.tpe = typeSubst(tree.tpe);
- super.traverse(tree)
- }
- }
-
/** The context-dependent inferencer part */
class Inferencer(context: Context) {
@@ -426,7 +417,7 @@ abstract class Infer: Analyzer {
foundReqMsg(PolyType(undetparams, skipImplicit(tree.tpe)), pt));
} else {
checkBounds(tree.pos, undetparams, targs, "inferred ");
- new TreeSubstituter(undetparams, targs).traverse(tree);
+ new TreeTypeSubstituter(undetparams, targs).traverse(tree);
}
/** Substitite free type variables `undetparams' of application `fn(args)', given prototype `pt'.
@@ -439,7 +430,7 @@ abstract class Infer: Analyzer {
val targs = methTypeArgs(
undetparams, formalTypes(formals, argtpes.length), restpe, argtpes, pt, uninstantiated);
checkBounds(fn.pos, undetparams, targs, "inferred ");
- val treeSubst = new TreeSubstituter(undetparams, targs);
+ val treeSubst = new TreeTypeSubstituter(undetparams, targs);
treeSubst.traverse(fn);
treeSubst.traverseTrees(args);
uninstantiated.toList;
@@ -465,7 +456,7 @@ abstract class Infer: Analyzer {
try {
val targs = solve(tvars, undetparams, undetparams map varianceInType(restpe), true);
checkBounds(tree.pos, undetparams, targs, "inferred ");
- new TreeSubstituter(undetparams, targs).traverse(tree)
+ new TreeTypeSubstituter(undetparams, targs).traverse(tree)
} catch {
case ex: NoInstance =>
errorTree(tree, "constructor of type " + restpe +
@@ -528,7 +519,7 @@ abstract class Infer: Analyzer {
*/
def inferMethodAlternative(tree: Tree, undetparams: List[Symbol], argtpes: List[Type], pt: Type): unit = tree.tpe match {
case OverloadedType(pre, alts) => tryTwice {
- if (settings.debug.value) System.out.println("infer method alt " + tree.symbol + " with alternatives " + (alts map pre.memberType) + ", argtpes = " + argtpes + ", pt = " + pt);//debug
+ if (settings.debug.value) log("infer method alt " + tree.symbol + " with alternatives " + (alts map pre.memberType) + ", argtpes = " + argtpes + ", pt = " + pt);//debug
val alts1 = alts filter (alt => isApplicable(undetparams, pre.memberType(alt), argtpes, pt));
def improves(sym1: Symbol, sym2: Symbol) = {
sym2 == NoSymbol || sym2.isError ||
diff --git a/sources/scala/tools/nsc/typechecker/Namers.scala b/sources/scala/tools/nsc/typechecker/Namers.scala
index ce348ed796..3c553ad48c 100755
--- a/sources/scala/tools/nsc/typechecker/Namers.scala
+++ b/sources/scala/tools/nsc/typechecker/Namers.scala
@@ -15,7 +15,6 @@ trait Namers: Analyzer {
import definitions._;
class NamerPhase(prev: Phase) extends StdPhase(prev) {
- val global: Namers.this.global.type = Namers.this.global;
def name = "namer";
def apply(unit: CompilationUnit): unit =
new Namer(startContext.make(unit)).enterSym(unit.body);
@@ -43,7 +42,7 @@ trait Namers: Analyzer {
(if (sym.hasFlag(CASE)) "case class " + sym.name else sym.toString()));
private def updatePosFlags(sym: Symbol, pos: int, mods: int): Symbol = {
- if (settings.debug.value) System.out.println("overwriting " + sym);
+ if (settings.debug.value) log("overwriting " + sym);
sym.pos = pos;
val oldflags = sym.flags & (INITIALIZED | LOCKED);
val newflags = mods & ~(INITIALIZED | LOCKED);
@@ -81,6 +80,7 @@ trait Namers: Analyzer {
private def enterClassSymbol(pos: int, mods: int, name: Name): Symbol = {
val c: Symbol = context.scope.lookup(name);
if (c.isType && c.isExternal && context.scope == c.owner.info.decls) {
+ symSource(c) = context.unit.source.getFile();
updatePosFlags(c, pos, mods);
} else {
enterInScope(context.owner.newClass(pos, name).setFlag(mods))
@@ -90,6 +90,7 @@ trait Namers: Analyzer {
private def enterModuleSymbol(pos: int, mods: int, name: Name): Symbol = {
val m: Symbol = context.scope.lookup(name);
if (m.isTerm && !m.isPackage && m.isExternal && (context.scope == m.owner.info.decls)) {
+ symSource(m) = context.unit.source.getFile();
updatePosFlags(m, pos, mods)
} else {
val newm = context.owner.newModule(pos, name);
@@ -102,6 +103,7 @@ trait Namers: Analyzer {
private def enterCaseFactorySymbol(pos: int, mods: int, name: Name): Symbol = {
val m: Symbol = context.scope.lookup(name);
if (m.isTerm && !m.isPackage && m.isExternal && context.scope == m.owner.info.decls) {
+ symSource(m) = context.unit.source.getFile();
updatePosFlags(m, pos, mods)
} else {
enterInScope(context.owner.newMethod(pos, name).setFlag(mods))
@@ -114,7 +116,7 @@ trait Namers: Analyzer {
def enterSym(tree: Tree): Namer = {
def finishWith(tparams: List[AbsTypeDef]): unit = {
- if (settings.debug.value) log("entered " + tree.symbol);
+ if (settings.debug.value) log("entered " + tree.symbol + " in " + context.owner);
var ltype: LazyType = innerNamer.typeCompleter(tree);
if (!tparams.isEmpty) {
new Namer(context.makeNewScope(tree, tree.symbol)).enterSyms(tparams);
@@ -139,7 +141,6 @@ trait Namers: Analyzer {
setInfo innerNamer.caseFactoryCompleter(tree)
}
tree.symbol = enterClassSymbol(tree.pos, mods, name);
- if (settings.debug.value) System.out.println("entered: " + tree.symbol + flagsToString(tree.symbol.flags));//debug
finishWith(tparams)
case ModuleDef(mods, name, _) =>
tree.symbol = enterModuleSymbol(tree.pos, mods | MODULE | FINAL, name);
@@ -243,7 +244,7 @@ trait Namers: Analyzer {
}
private def deconstIfNotFinal(sym: Symbol, tpe: Type): Type =
- if (sym.isVariable || !sym.isFinal) tpe.deconst else tpe;
+ if (sym.isVariable || !(sym hasFlag FINAL)) tpe.deconst else tpe;
def enterValueParams(owner: Symbol, vparamss: List[List[ValDef]]): List[List[Symbol]] = {
def enterValueParam(param: ValDef): Symbol = {
@@ -284,12 +285,12 @@ trait Namers: Analyzer {
val meth = context.owner;
val tparamSyms = typer.reenterTypeParams(tparams);
val vparamSymss = enterValueParams(meth, vparamss);
- val restype = deconstIfNotFinal(meth,
+ val restype =
if (tpt.isEmpty) {
tpt.tpe = if (meth.name == nme.CONSTRUCTOR) context.enclClass.owner.tpe
- else typer.typed(rhs).tpe;
+ else deconstIfNotFinal(meth, typer.typed(rhs).tpe);
tpt.tpe
- } else typer.typedType(tpt).tpe);
+ } else typer.typedType(tpt).tpe;
def mkMethodType(vparams: List[Symbol], restpe: Type) = {
val formals = vparams map (.tpe);
if (!vparams.isEmpty && vparams.head.hasFlag(IMPLICIT))
@@ -358,16 +359,15 @@ trait Namers: Analyzer {
new Namer(context.makeNewScope(tree, sym)).methodSig(tparams, vparamss, tpt, rhs))
case ValDef(_, _, tpt, rhs) =>
- deconstIfNotFinal(sym,
- if (tpt.isEmpty)
- if (rhs.isEmpty) {
- context.error(tpt.pos, "missing parameter type");
- ErrorType
- } else {
- tpt.tpe = newTyper(context.make(tree, sym)).typed(rhs).tpe;
- tpt.tpe
- }
- else typer.typedType(tpt).tpe)
+ if (tpt.isEmpty)
+ if (rhs.isEmpty) {
+ context.error(tpt.pos, "missing parameter type");
+ ErrorType
+ } else {
+ tpt.tpe = deconstIfNotFinal(sym, newTyper(context.make(tree, sym)).typed(rhs).tpe);
+ tpt.tpe
+ }
+ else typer.typedType(tpt).tpe
case AliasTypeDef(_, _, tparams, rhs) =>
new Namer(context.makeNewScope(tree, sym)).aliasTypeSig(sym, tparams, rhs)
@@ -437,7 +437,6 @@ trait Namers: Analyzer {
}
checkNoConflict(DEFERRED, PRIVATE);
checkNoConflict(FINAL, SEALED);
- if (!sym.hasFlag(MODULE)) checkNoConflict(FINAL, PRIVATE);
checkNoConflict(PRIVATE, PROTECTED);
checkNoConflict(PRIVATE, OVERRIDE);
checkNoConflict(DEFERRED, FINAL);
diff --git a/sources/scala/tools/nsc/typechecker/RefChecks.scala b/sources/scala/tools/nsc/typechecker/RefChecks.scala
new file mode 100755
index 0000000000..f7e5b3e32d
--- /dev/null
+++ b/sources/scala/tools/nsc/typechecker/RefChecks.scala
@@ -0,0 +1,684 @@
+/* NSC -- new scala compiler
+ * Copyright 2005 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
+package scala.tools.nsc.typechecker;
+
+import symtab.Flags._;
+import collection.mutable.HashMap;
+import util.ListBuffer;
+import transform.Transform;
+
+/** Post-attribution checking and transformation.
+ * //todo: check whether we always check type parameter bounds.
+ *
+ * This phase performs the following checks.
+ *
+ * - All overrides conform to rules.
+ * - All type arguments conform to bounds.
+ * - All type variable uses conform to variance annotations.
+ * - No forward reference to a term symbol extends beyond a value definition.
+ *
+ * It performs the following transformations.
+ *
+ * - Local modules are replaced by variables and classes
+ * - caseArity, caseElement implementations added to case classes
+ * - equals, and hashCode and toString methods are added to case classes,
+ * unless they are defined in the class or a baseclass
+ * different from java.lang.Object
+ * - toString method is added to case objects,
+ * unless they are defined in the class or a baseclass
+ * different from java.lang.Object
+ * - Calls to case factory methods are replaced by new's.
+ * - Function nodes are eliminated.
+ */
+abstract class RefChecks extends Transform {
+
+ import global._;
+ import definitions._;
+ import typer.{typed, typedOperator, atOwner};
+ import posAssigner.atPos;
+
+ /** the following two members override abstract members in Transform */
+ protected val phaseName: String = "refchecks";
+ protected def newTransformer(unit: CompilationUnit): Transformer = new RefCheckTransformer(unit);
+
+ class RefCheckTransformer(unit: CompilationUnit) extends Transformer {
+
+// Override checking ------------------------------------------------------------
+
+ /** 1. Check all members of class `clazz' for overriding conditions.
+ * That is for overriding member M and overridden member O:
+ *
+ * 1.1. M must have the same or stronger access privileges as O.
+ * 1.2. O must not be final.
+ * 1.3. O is deferred, or M has `override' modifier.
+ * 1.4. If O is an immutable value, then so is M.
+ * 1.5. Neither M nor O are a parameterized type alias
+ * 1.6. If O is a type alias, then M is an alias of O.
+ * 1.7. If O is an abstract type then
+ * either M is an abstract type, and M's bounds are sharper than O's bounds.
+ * or M is an unparameterized type alias or class which conforms to O's bounds.
+ * 1.8. If O and M are values, then M's type is a subtype of O's type.
+ * 2. Check that only abstract classes have deferred members
+ * 3. Check that every member with an `override' modifier
+ * overrides some other member.
+ */
+ private def checkAllOverrides(clazz: Symbol): unit = {
+
+ val self = clazz.thisType;
+
+ def infoString(sym: Symbol) =
+ sym.toString() +
+ (if (sym.owner == clazz) ""
+ else (sym.locationString +
+ (if (sym.isAliasType) ", which equals " + self.memberInfo(sym)
+ else if (sym.isAbstractType) " with bounds " + self.memberInfo(sym)
+ else if (sym.isTerm) " of type " + self.memberInfo(sym)
+ else "")));
+
+ /* Check that all conditions for overriding `other' by `member' are met. */
+ def checkOverride(clazz: Symbol, member: Symbol, other: Symbol): unit = {
+ val pos = if (member.owner == clazz) member.pos else clazz.pos;
+
+ def overrideError(msg: String): unit =
+ if (other.tpe != ErrorType && member.tpe != ErrorType)
+ unit.error(pos, "error overriding " + infoString(other) +
+ ";\n " + infoString(member) + " " + msg);
+
+ def overrideTypeError(): unit = {
+ if (other.tpe != ErrorType && member.tpe != ErrorType) {
+ overrideError("has incompatible type");
+ explainTypes(member.tpe, other.tpe);
+ }
+ }
+
+ //System.out.println(infoString(member) + " overrides " + infoString(other) + " in " + clazz);//DEBUG
+
+ // return if we already checked this combination elsewhere
+ if (member.owner != clazz) {
+ if ((member.owner isSubClass other.owner) &&
+ ((member hasFlag DEFERRED) || !(other hasFlag DEFERRED))) {
+ //System.out.println(infoString(member) + " shadows1 " + infoString(other) " in " + clazz);//DEBUG
+ return;
+ }
+ if (clazz.info.parents exists (parent =>
+ (parent.symbol isSubClass other.owner) && (parent.symbol isSubClass member.owner) &&
+ ((member hasFlag DEFERRED) || !(other hasFlag DEFERRED)))) {
+ //System.out.println(infoString(member) + " shadows2 " + infoString(other) + " in " + clazz);//DEBUG
+ return;
+ }
+ if (clazz.info.parents forall (parent =>
+ (parent.symbol isSubClass other.owner) == (parent.symbol isSubClass member.owner))) {
+ //System.out.println(infoString(member) + " shadows " + infoString(other) + " in " + clazz);//DEBUG
+ return;
+ }
+ }
+
+ if (member hasFlag PRIVATE) { // (1.1)
+ overrideError("has weaker access privileges; it should not be private");
+ } else if ((member hasFlag PROTECTED) && !(other hasFlag PROTECTED)) { // 1
+ overrideError("has weaker access privileges; it should not be protected");
+ } else if (other hasFlag FINAL) { // (1.2)
+ overrideError("cannot override final member");
+ } else if (!(other hasFlag DEFERRED) && !(member hasFlag (OVERRIDE | ABSOVERRIDE))) { // (1.3)
+ overrideError("needs `override' modifier");
+ } else if (other.isStable && !member.isStable) { // (1.4)
+ overrideError("needs to be an immutable value");
+ } else {
+ if (other.isAliasType) {
+ if (!member.typeParams.isEmpty) // (1.5)
+ overrideError("may not be parameterized");
+ if (!other.typeParams.isEmpty) // (1.5)
+ overrideError("may not override parameterized type");
+ if (!(self.memberType(member) =:= self.memberType(other))) // (1.6)
+ overrideTypeError();
+ } else if (other.isAbstractType) {
+ if (!member.typeParams.isEmpty) // (1.7)
+ overrideError("may not be parameterized");
+ if (!(self.memberInfo(other).bounds containsType self.memberInfo(member))) // (1.7)
+ overrideTypeError();
+ } else if (other.isTerm) {
+ if (!(self.memberInfo(member) <:< (self.memberInfo(other)))) // 8
+ overrideTypeError();
+ }
+ }
+ }
+
+ // 1. Check all members for overriding conditions.
+ for (val bc <- clazz.info.baseClasses.tail; val other <- bc.info.decls.toList)
+ if (!other.isClass && !(other hasFlag PRIVATE) && !other.isConstructor) {
+ val member = clazz.tpe.member(other.name) filter
+ (sym => sym.isType || (self.memberType(sym) matches self.memberType(other)));
+ if (member hasFlag OVERLOADED) {
+ val alt1 = member.alternatives.head;
+ val alt2 = member.alternatives.tail.head;
+ val pos = if (alt1.owner == clazz) alt1.pos
+ else if (alt2.owner == clazz) alt2.pos
+ else clazz.pos;
+ unit.error(pos,
+ "ambiguous override: both " + infoString(alt1) +
+ "\n and " + infoString(alt2) +
+ "\n override " + infoString(other));
+ } else if (member != other && !(member hasFlag LOCAL)) {
+ member.flags = member.flags | ACCESSED;
+ checkOverride(clazz, member, other);
+ }
+ }
+
+ // 2. Check that only abstract classes have deferred members
+ if (clazz.isClass && !(clazz hasFlag ABSTRACT)) {
+ def abstractClassError(msg: String): unit = {
+ unit.error(clazz.pos,
+ (if (clazz.isAnonymousClass || clazz.isModuleClass) "object creation impossible"
+ else clazz.toString() + " needs to be abstract") + ", since " + msg);
+ clazz.setFlag(ABSTRACT);
+ }
+ for (val member <- clazz.tpe.members)
+ if (member hasFlag DEFERRED) {
+ abstractClassError(
+ infoString(member) + " is not defined" +
+ (if (member hasFlag MUTABLE)
+ "\n(Note that variables need to be initialized to be defined)" else ""))
+ } else if (member.isIncompleteIn(clazz)) {
+ val other = member.superSymbol(clazz);
+ abstractClassError(
+ infoString(member) + " is marked `abstract' and `override'" +
+ (if (other != NoSymbol)
+ " and overrides incomplete superclass member " + infoString(other)
+ else ""))
+ }
+ }
+
+ // 3. Check that every defined member with an `override' modifier overrides some other member.
+ for (val member <- clazz.info.decls.toList)
+ if ((member hasFlag (OVERRIDE | ABSOVERRIDE)) &&
+ (clazz.info.baseClasses.tail forall (bc => member.overriddenSymbol(bc) == NoSymbol))) {
+ System.out.println(clazz.info.baseClasses.tail);//debug
+ unit.error(member.pos, member.toString() + " overrides nothing");
+ member resetFlag OVERRIDE
+ }
+ }
+
+ // Basetype Checking --------------------------------------------------------
+
+ /** 1. Check that later type instances in the base-type sequence
+ * are subtypes of earlier type instances of the same trait.
+ * 2. Check that case classes do not inherit from case classes.
+ * 3. Check that at most one base type is a case-class.
+ */
+ private def validateBaseTypes(clazz: Symbol): unit = {
+ val seenTypes = new Array[Type](clazz.info.closure.length);
+ var seenCaseClass = if (clazz hasFlag CASE) clazz else NoSymbol;
+
+ def validateTypes(tps: List[Type], includeSuper: boolean): unit = {
+ if (!tps.isEmpty) {
+ for (val tp <- tps.tail.reverse) validateType(tp, false);
+ if (includeSuper) validateType(tps.head, true);
+ }
+ }
+
+ def validateType(tp: Type, includeSuper: boolean): unit = {
+ val baseClass = tp.symbol;
+ if (baseClass.isClass) {
+ val index = clazz.info.closurePos(baseClass);
+ if (index >= 0) {
+ if (seenTypes(index) != null && !(seenTypes(index) <:< tp))
+ unit.error(clazz.pos, "illegal inheritance;\n " + clazz +
+ " inherits different type instances of " + baseClass +
+ ":\n" + tp + " and " + seenTypes(index));
+ seenTypes(index) = tp;
+ // check that case classes do not inherit from case classes
+ if (baseClass hasFlag CASE) {
+ if (seenCaseClass != NoSymbol && seenCaseClass != baseClass)
+ unit.error(clazz.pos, "illegal combination of case " +
+ seenCaseClass + " and case " + baseClass + " in one object");
+ seenCaseClass = baseClass
+ }
+ }
+ validateTypes(tp.parents, includeSuper);
+ }
+ }
+
+ validateTypes(clazz.info.parents, true);
+ }
+
+ // Variance Checking --------------------------------------------------------
+
+ private val ContraVariance = -1;
+ private val NoVariance = 0;
+ private val CoVariance = 1;
+ private val AnyVariance = 2;
+
+ /** Check variance of type variables in this type
+ */
+ private def validateVariance(base: Symbol, all: Type, variance: int): unit = {
+
+ def varianceString(variance: int): String =
+ if (variance == 1) "covariant"
+ else if (variance == -1) "contravariant"
+ else "invariant";
+
+ def relativeVariance(tvar: Symbol): int = {
+ val clazz = tvar.owner;
+ var sym = base;
+ var state = CoVariance;
+ while (sym != clazz && state != AnyVariance) {
+ //System.out.println("flip: " + sym + " " + sym.isParameter());//DEBUG
+ if ((sym hasFlag PARAM) && !sym.owner.isConstructor) state = -state;
+ else if (!sym.owner.isClass) state = AnyVariance;
+ else if (sym.isAliasType) state = NoVariance;
+ sym = sym.owner;
+ }
+ state
+ }
+
+ def validateVariance(tp: Type, variance: int): unit = tp match {
+ case ErrorType => ;
+ case WildcardType => ;
+ case NoType => ;
+ case NoPrefix => ;
+ case ThisType(_) => ;
+ case ConstantType(_, _) => ;
+ case SingleType(pre, sym) =>
+ validateVariance(pre, variance)
+ case TypeRef(pre, sym, args) =>
+ if (sym.variance != NoVariance) {
+ val v = relativeVariance(sym);
+ if (v != AnyVariance && sym.variance != v * variance) {
+ //System.out.println("relativeVariance(" + base + "," + sym + ") = " + v);//DEBUG
+ unit.error(base.pos,
+ varianceString(sym.variance) + " " + sym +
+ " occurs in " + varianceString(v * variance) +
+ " position in type " + all + " of " + base);
+ }
+ }
+ validateVariance(pre, variance);
+ validateVarianceArgs(args, variance, sym.typeParams);
+ case ClassInfoType(parents, decls, symbol) =>
+ validateVariances(parents, variance);
+ case RefinedType(parents, decls) =>
+ validateVariances(parents, variance);
+ case TypeBounds(lo, hi) =>
+ validateVariance(lo, -variance);
+ validateVariance(hi, variance);
+ case MethodType(formals, result) =>
+ validateVariance(result, variance);
+ case PolyType(tparams, result) =>
+ validateVariance(result, variance);
+ }
+
+ def validateVariances(tps: List[Type], variance: int): unit =
+ tps foreach (tp => validateVariance(tp, variance));
+
+ def validateVarianceArgs(tps: List[Type], variance: int, tparams: List[Symbol]): unit =
+ (tps zip tparams) foreach {
+ case Pair(tp, tparam) => validateVariance(tp, variance * tparam.variance)
+ }
+
+ validateVariance(all, variance)
+ }
+
+// Forward reference checking ---------------------------------------------------
+
+ class LevelInfo(val outer: LevelInfo) {
+ val scope: Scope = if (outer == null) new Scope() else new Scope(outer.scope);
+ var maxindex: int = Integer.MIN_VALUE;
+ var refpos: int = _;
+ var refsym: Symbol = _;
+ }
+
+ private var currentLevel: LevelInfo = null;
+ private val symIndex = new HashMap[Symbol, int];
+
+ private def pushLevel(): unit =
+ currentLevel = new LevelInfo(currentLevel);
+
+ private def popLevel(): unit =
+ currentLevel = currentLevel.outer;
+
+ private def enterSyms(stats: List[Tree]): unit = {
+ var index = -1;
+ for (val stat <- stats) {
+ index = index + 1;
+ stat match {
+ case ClassDef(_, _, _, _, _) | DefDef(_, _, _, _, _, _) if (stat.symbol.isLocal) =>
+ currentLevel.scope.enter(newScopeEntry(stat.symbol, currentLevel.scope));
+ symIndex(stat.symbol) = index;
+ case _ =>
+ }
+ }
+ }
+
+ private def enterReference(pos: int, sym: Symbol): unit =
+ if (sym.isLocal && sym.isTerm) {
+ val e = currentLevel.scope.lookupEntry(sym.name);
+ if (e != null && sym == e.sym) {
+ var l = currentLevel;
+ while (l.scope != e.owner) l = l.outer;
+ val symindex = symIndex(sym);
+ if (l.maxindex < symindex) {
+ l.refpos = pos;
+ l.refsym = sym;
+ l.maxindex = symindex;
+ }
+ }
+ }
+
+// Adding synthetic methods --------------------------------------------------------------
+
+ private def addSyntheticMethods(templ: Template, clazz: Symbol): Template = {
+
+ def hasImplementation(name: Name): boolean = {
+ val sym = clazz.info.nonPrivateMember(name);
+ sym.isTerm &&
+ (sym.owner == clazz ||
+ !(ObjectClass isSubClass sym.owner) && !(sym hasFlag DEFERRED));
+ }
+
+ def syntheticMethod(name: Name, flags: int, tpe: Type) = {
+ val method = clazz.newMethod(clazz.pos, name) setFlag (flags | OVERRIDE) setInfo tpe;
+ clazz.info.decls.enter(method);
+ method
+ }
+
+ def caseElementMethod: Tree = {
+ val method = syntheticMethod(
+ nme.caseElement, FINAL, MethodType(List(IntClass.tpe), AnyClass.tpe));
+ val caseFields = clazz.caseFieldAccessors map gen.mkRef;
+ typed(
+ DefDef(method, vparamss =>
+ if (caseFields.isEmpty) Literal(null)
+ else {
+ var i = caseFields.length;
+ var cases = List(CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(null)));
+ for (val field <- caseFields.reverse) {
+ i = i - 1; cases = CaseDef(Literal(i), EmptyTree, field) :: cases
+ }
+ Match(Ident(vparamss.head.head), cases)
+ }))
+ }
+
+ def caseArityMethod: Tree = {
+ val method = syntheticMethod(nme.caseArity, FINAL, PolyType(List(), IntClass.tpe));
+ typed(DefDef(method, vparamss => Literal(clazz.caseFieldAccessors.length)))
+ }
+
+ def caseNameMethod: Tree = {
+ val method = syntheticMethod(nme.caseName, FINAL, PolyType(List(), StringClass.tpe));
+ typed(DefDef(method, vparamss => Literal(clazz.name.decode)))
+ }
+
+ def moduleToStringMethod: Tree = {
+ val method = syntheticMethod(nme.toString_, FINAL, MethodType(List(), StringClass.tpe));
+ typed(DefDef(method, vparamss => Literal(clazz.name.decode)))
+ }
+
+ def tagMethod: Tree = {
+ val method = syntheticMethod(nme.tag, FINAL, MethodType(List(), IntClass.tpe));
+ typed(DefDef(method, vparamss => Literal(clazz.tag)))
+ }
+
+ def forwardingMethod(name: Name): Tree = {
+ val target = getMember(CaseOpsModule, "_" + name);
+ val method = syntheticMethod(
+ name, 0, MethodType(target.tpe.paramTypes.tail, target.tpe.resultType));
+ typed(DefDef(method, vparamss =>
+ Apply(gen.mkRef(target), This(clazz) :: (vparamss.head map Ident))));
+ }
+
+ def readResolveMethod: Tree = {
+ // !!! the synthetic method "readResolve" should be private,
+ // but then it is renamed !!!
+ val method = syntheticMethod(nme.readResolve, PROTECTED, MethodType(List(), ObjectClass.tpe));
+ typed(DefDef(method, vparamss => gen.mkRef(clazz.sourceModule)))
+ }
+
+ val ts = new ListBuffer[Tree];
+ if (clazz hasFlag CASE) {
+ ts += tagMethod;
+ if (clazz.isModuleClass) {
+ ts += moduleToStringMethod;
+ if (clazz.isSubClass(SerializableClass)) {
+ // If you serialize a singleton and then deserialize it twice,
+ // you will have two instances of your singleton, unless you implement
+ // the readResolve() method (see http://www.javaworld.com/javaworld/
+ // jw-04-2003/jw-0425-designpatterns_p.html)
+ ts += readResolveMethod;
+ }
+ } else {
+ ts += caseElementMethod;
+ ts += caseArityMethod;
+ ts += caseNameMethod;
+ if (!hasImplementation(nme.equals_)) ts += forwardingMethod(nme.equals_);
+ if (!hasImplementation(nme.hashCode_)) ts += forwardingMethod(nme.hashCode_);
+ if (!hasImplementation(nme.toString_)) ts += forwardingMethod(nme.toString_);
+ }
+ }
+ val synthetics = ts.toList;
+ copy.Template(
+ templ, templ.parents, if (synthetics.isEmpty) templ.body else templ.body ::: synthetics)
+ }
+
+// Transformation ------------------------------------------------------------
+
+ override def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = {
+ pushLevel();
+ enterSyms(stats);
+ var index = -1;
+ val stats1 = stats flatMap { stat => index = index + 1; transformStat(stat, index) }
+ popLevel();
+ stats1
+ }
+
+ def transformStat(tree: Tree, index: int): List[Tree] = tree match {
+ case ModuleDef(_, name, impl) =>
+ val sym = tree.symbol;
+ //val localTyper = typer.atOwner(currentOwner);
+ val cdef = typed(ClassDef(sym.moduleClass, impl));
+ if (sym.isStatic) List(transform(cdef))
+ else {
+ val moduleType = sym.tpe;
+
+ // var m$: T = null; or, if class member: local var m$: T = _;
+ val mvar = currentOwner.newVariable(sym.pos, name.toString() + "$") setInfo moduleType;
+ if (currentOwner.isClass) {
+ mvar setFlag (PRIVATE | LOCAL | SYNTHETIC);
+ sym.owner.info.decls.enter(mvar);
+ }
+ val vdef = typed(ValDef(mvar, if (sym.isLocal) Literal(null) else EmptyTree));
+
+ // def m: T = { if (m$ == null) m$ = new m$class; m$ }
+ sym.setFlag(METHOD | STABLE);
+ sym.setInfo(PolyType(List(), moduleType));
+ val ddef = typed(
+ DefDef(sym, vparamss =>
+ Block(
+ List(
+ If(
+ Apply(Select(Ident(mvar), nme.EQ), List(Literal(null))),
+ Assign(Ident(mvar), New(TypeTree(moduleType), List(List()))),
+ EmptyTree)),
+ Ident(mvar))));
+ transformTrees(List(cdef, vdef, ddef))
+ }
+
+ case ValDef(_, _, _, _) =>
+ val tree1 = transform(tree); // important to do before forward reference check
+ //todo: handle variables
+ if (tree.symbol.isLocal && index <= currentLevel.maxindex) {
+ if (settings.debug.value) System.out.println(currentLevel.refsym);
+ unit.error(currentLevel.refpos, "forward reference extends over definition of " + tree.symbol);
+ }
+ List(tree1)
+
+ case _ =>
+ List(transform(tree))
+ }
+
+ override def transform(tree: Tree): Tree = try {
+
+ /* Convert a reference of a case factory to a new of the class it produces. */
+ def toConstructor: Tree = {
+ var tpe = tree.tpe;
+ while (!tpe.symbol.isClass) tpe = tpe.resultType;
+ assert(tpe.symbol hasFlag CASE);
+ typedOperator(atPos(tree.pos)(Select(New(TypeTree(tpe)), tpe.symbol.primaryConstructor)))
+ }
+
+ /* Check whether argument types conform to bounds of type parameters */
+ def checkBounds(tparams: List[Symbol], argtps: List[Type]): unit = try {
+ infer.checkBounds(tree.pos, tparams, argtps, "");
+ } catch {
+ case ex: TypeError => unit.error(tree.pos, ex.getMessage());
+ }
+
+ val sym = tree.symbol;
+ var result = tree;
+ tree match {
+ case ClassDef(mods, name, tparams, tpe, impl) =>
+ validateVariance(sym, sym.info, CoVariance);
+ validateVariance(sym, sym.typeOfThis, CoVariance);
+ result = copy.ClassDef(
+ tree, mods, name, tparams, tpe, addSyntheticMethods(impl, tree.symbol))
+
+ case DefDef(_, _, _, _, _, _) =>
+ validateVariance(sym, sym.tpe, CoVariance);
+
+ case ValDef(_, _, _, _) =>
+ validateVariance(sym, sym.tpe, if ((sym.flags & MUTABLE) != 0) NoVariance else CoVariance);
+
+ case AbsTypeDef(_, _, _, _) =>
+ validateVariance(sym, sym.info, CoVariance);
+
+ case AliasTypeDef(_, _, _, _) =>
+ validateVariance(sym, sym.info, CoVariance);
+
+ case Template(_, _) =>
+ validateBaseTypes(currentOwner);
+ checkAllOverrides(currentOwner);
+
+ case TypeTree() =>
+ new TypeTraverser {
+ def traverse(tp: Type) = tp match {
+ case TypeRef(pre, sym, args) => checkBounds(sym.typeParams, args); this
+ case _ => this
+ }
+ } traverse tree.tpe
+
+ case TypeApply(fn, args) =>
+ checkBounds(fn.tpe.typeParams, args map (.tpe));
+
+ case Function(vparams, body) =>
+ /* Transform a function node (x_1,...,x_n) => body of type FunctionN[T_1, .., T_N, R] to
+ *
+ * class $anon() extends Object() with FunctionN[T_1, .., T_N, R] with ScalaObject {
+ * def apply(x_1: T_1, ..., x_N: T_n): R = body
+ * }
+ * new $anon()
+ *
+ * transform a function node (x => body) of type PartialFunction[T, R] where
+ * body = x match { case P_i if G_i => E_i }_i=1..n
+ * to:
+ *
+ * class $anon() extends Object() with PartialFunction[T, R] with ScalaObject {
+ * def apply(x: T): R = body;
+ * def isDefinedAt(x: T): boolean = x match {
+ * case P_1 if G_1 => true
+ * ...
+ * case P_n if G_n => true
+ * case _ => false
+ * }
+ * }
+ * new $anon()
+ *
+ * However, if one of the patterns P_i if G_i is a default pattern, generate instead
+ *
+ * def isDefinedAt(x: T): boolean = true
+ */
+ result = {
+ val anonClass =
+ currentOwner.newAnonymousFunctionClass(tree.pos) setFlag (FINAL | SYNTHETIC);
+ anonClass setInfo ClassInfoType(
+ List(ObjectClass.tpe, tree.tpe, ScalaObjectClass.tpe), new Scope(), anonClass);
+ val targs = tree.tpe.typeArgs;
+ val applyMethod = anonClass.newMethod(tree.pos, nme.apply)
+ setFlag FINAL setInfo MethodType(targs.init, targs.last);
+ anonClass.info.decls enter applyMethod;
+ for (val vparam <- vparams)
+ vparam.symbol.owner = applyMethod;
+ var members = List(
+ DefDef(FINAL, nme.apply, List(), List(vparams), TypeTree(targs.last), body)
+ setSymbol applyMethod);
+ if (tree.tpe.symbol == PartialFunctionClass) {
+ val isDefinedAtMethod = anonClass.newMethod(tree.pos, nme.isDefinedAt)
+ setFlag FINAL setInfo MethodType(targs.init, BooleanClass.tpe);
+ anonClass.info.decls enter isDefinedAtMethod;
+ def idbody(idparam: Symbol) = body match {
+ case Match(_, cases) =>
+ val substParam = new TreeSymSubstituter(List(vparams.head.symbol), List(idparam));
+ def transformCase(cdef: CaseDef): CaseDef =
+ CaseDef(substParam(cdef.pat), substParam(cdef.guard), Literal(true));
+ def isDefaultCase(cdef: CaseDef) = cdef match {
+ case CaseDef(Ident(nme.WILDCARD), EmptyTree, _) => true
+ case CaseDef(Bind(_, Ident(nme.WILDCARD)), EmptyTree, _) => true
+ case _ => false
+ }
+ if (cases exists isDefaultCase) Literal(true)
+ else Match(
+ Ident(idparam),
+ (cases map transformCase) :::
+ List(CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(false))))
+ }
+ members = DefDef(isDefinedAtMethod, vparamss => idbody(vparamss.head.head)) :: members;
+ }
+ typed(
+ atPos(tree.pos)(
+ Block(
+ List(ClassDef(anonClass, List(List()), List(List()), members)),
+ New(TypeTree(anonClass.tpe), List(List())))))
+ }
+
+ case New(tpt) =>
+ enterReference(tree.pos, tpt.tpe.symbol);
+
+ case Ident(name) =>
+ if (sym.isMethod && sym.hasFlag(CASE))
+ result = toConstructor
+ else if (name != nme.WILDCARD && name != nme.WILDCARD_STAR.toTypeName) {
+ sym setFlag ACCESSED;
+ assert(sym != NoSymbol, tree);//debug
+ enterReference(tree.pos, sym);
+ }
+
+ case Select(qual, name) =>
+ if (sym.isMethod && sym.hasFlag(CASE))
+ result = toConstructor
+ else {
+ sym setFlag ACCESSED;
+ if (!treeInfo.isSelf(qual, currentOwner.enclClass)) sym.flags = sym.flags | SELECTOR;
+ if (sym hasFlag DEFERRED) {
+ qual match {
+ case Super(qualifier, mixin) =>
+ val base = currentOwner.enclClass;
+ val member = sym.overridingSymbol(base);
+ if (mixin != nme.EMPTY.toTypeName || member == NoSymbol ||
+ !((member hasFlag ABSOVERRIDE) && member.isIncompleteIn(base)))
+ unit.error(tree.pos, "symbol accessed from super may not be abstract");
+ case _ =>
+ }
+ }
+ }
+
+ case _ =>
+ }
+ super.transform(result)
+ } catch {
+ case ex: TypeError =>
+ if (settings.debug.value) ex.printStackTrace();
+ unit.error(tree.pos, ex.getMessage());
+ tree
+ }
+ }
+}
diff --git a/sources/scala/tools/nsc/typechecker/TreeCheckers.scala b/sources/scala/tools/nsc/typechecker/TreeCheckers.scala
index 741cfa4ca1..791f865f24 100644
--- a/sources/scala/tools/nsc/typechecker/TreeCheckers.scala
+++ b/sources/scala/tools/nsc/typechecker/TreeCheckers.scala
@@ -60,7 +60,7 @@ abstract class TreeCheckers extends Analyzer {
override def traverse(tree: Tree): unit = {
if (tree.pos == Position.NOPOS)
error(tree.pos, "tree without position: " + tree)
- else if (tree.tpe == null && phase.id >= typeCheckPhase.id)
+ else if (tree.tpe == null && phase.id >= typerPhase.id)
error(tree.pos, "tree without type: " + tree)
}
}
diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala
index 61f5272e7d..075eeb7e60 100755
--- a/sources/scala/tools/nsc/typechecker/Typers.scala
+++ b/sources/scala/tools/nsc/typechecker/Typers.scala
@@ -20,7 +20,7 @@ abstract class Typers: Analyzer {
var selcnt = 0;
var implcnt = 0;
- class TypeCheckPhase(prev: Phase) extends StdPhase(prev) {
+ class TyperPhase(prev: Phase) extends StdPhase(prev) {
def name = "typer";
val global: Typers.this.global.type = Typers.this.global;
def apply(unit: CompilationUnit): unit =
@@ -39,7 +39,7 @@ abstract class Typers: Analyzer {
}
private def inferView(pos: int, from: Type, to: Type, reportAmbiguous: boolean): Tree = {
- if (settings.debug.value) System.out.println("infer view from " + from + " to " + to);//debug
+ if (settings.debug.value) log("infer view from " + from + " to " + to);//debug
val res = inferImplicit(pos, functionType(List(from), to), true, reportAmbiguous);
res
}
@@ -234,7 +234,7 @@ abstract class Typers: Analyzer {
*/
// def adapt(tree: Tree, mode: int, pt: Type): Tree = {
private def adapt(tree: Tree, mode: int, pt: Type): Tree = tree.tpe match {
- case ct @ ConstantType(base, value) if (ct <:< pt) => // (0)
+ case ct @ ConstantType(base, value) if ((mode & TYPEmode) == 0 && (ct <:< pt)) => // (0)
copy.Literal(tree, value)
case OverloadedType(pre, alts) if ((mode & FUNmode) == 0) => // (1)
inferExprAlternative(tree, pt);
@@ -245,7 +245,7 @@ abstract class Typers: Analyzer {
if ((mode & EXPRmode) != 0 && sym == ByNameParamClass) => // (2)
adapt(tree setType arg, mode, pt);
case PolyType(tparams, restpe) if ((mode & TAPPmode) == 0) => // (3)
- if (settings.debug.value && tree.symbol != null) System.out.println("adapting " + tree + " " + tree.symbol.tpe + " " + tree.symbol.getClass() + " " + tree.symbol.hasFlag(CASE));//debug
+ if (settings.debug.value && tree.symbol != null) log("adapting " + tree + " " + tree.symbol.tpe + " " + tree.symbol.getClass() + " " + tree.symbol.hasFlag(CASE));//debug
val tparams1 = cloneSymbols(tparams);
val tree1 = if (tree.isType) tree
else TypeApply(tree, tparams1 map (tparam =>
@@ -324,7 +324,7 @@ abstract class Typers: Analyzer {
return typed(Apply(coercion, List(tree)) setPos tree.pos, mode, pt);
}
}
- System.out.println(tree);
+ if (settings.debug.value) log("error tree = " + tree);
typeErrorTree(tree, tree.tpe, pt)
}
}
@@ -339,7 +339,7 @@ abstract class Typers: Analyzer {
val newTree = New(supertpt) setType
PolyType(tparams, appliedType(supertpt.tpe, tparams map (.tpe)));
val tree = typed(atPos(supertpt.pos)(Apply(Select(newTree, nme.CONSTRUCTOR), superargs)));
- if (settings.debug.value) System.out.println("superconstr " + tree + " co = " + context.owner);//debug
+ if (settings.debug.value) log("superconstr " + tree + " co = " + context.owner);//debug
tree.tpe
}
@@ -366,6 +366,7 @@ abstract class Typers: Analyzer {
superargs map (.duplicate))) setPos supertpt.pos;
}
}
+ //System.out.println("parents(" + context.owner + ") = " + supertpt :: mixins);//DEBUG
List.mapConserve(supertpt :: mixins)(tpt => checkNoEscaping.privates(context.owner, tpt))
}
@@ -477,6 +478,9 @@ abstract class Typers: Analyzer {
if (context.owner.isAnonymousClass)
intersectionType(context.owner.info.parents, context.owner.owner)
else context.owner.typeOfThis;
+ // the following is necessary for templates generated later
+ new Namer(context.outer.make(templ, context.owner, context.owner.info.decls))
+ .enterSyms(templ.body);
validateParentClasses(parents1, selfType);
val body1 = templ.body flatMap addGetterSetter;
val body2 = typedStats(body1, templ.symbol);
@@ -616,6 +620,8 @@ abstract class Typers: Analyzer {
def funmode = mode & stickyModes | FUNmode | POLYmode;
+ def ptOrLub(tps: List[Type]) = if (isFullyDefined(pt)) pt else lub(tps);
+
def typedCases(cases: List[CaseDef], pattp: Type): List[CaseDef] = {
List.mapConserve(cases)(cdef =>
newTyper(context.makeNewScope(tree, context.owner)).typedCase(cdef, pattp, pt))
@@ -629,7 +635,7 @@ abstract class Typers: Analyzer {
if (tparams.length == args.length) {
val targs = args map (.tpe);
checkBounds(tree.pos, tparams, targs, "");
- if (settings.debug.value) System.out.println("type app " + tparams + " => " + targs + " = " + restpe.subst(tparams, targs));//debug
+ if (settings.debug.value) log("type app " + tparams + " => " + targs + " = " + restpe.subst(tparams, targs));//debug
copy.TypeApply(tree, fun, args) setType restpe.subst(tparams, targs);
} else {
errorTree(tree, "wrong number of type parameters for " + treeSymTypeMsg(fun))
@@ -682,7 +688,7 @@ abstract class Typers: Analyzer {
val args1 = List.map2(args, formals)(typedArg);
if (args1 exists (.tpe.isError)) setError(tree)
else {
- if (settings.debug.value) System.out.println("infer method inst " + fun + ", tparams = " + tparams + ", args = " + args1.map(.tpe) + ", pt = " + pt + ", lobounds = " + tparams.map(.tpe.bounds.lo));//debug
+ if (settings.debug.value) log("infer method inst " + fun + ", tparams = " + tparams + ", args = " + args1.map(.tpe) + ", pt = " + pt + ", lobounds = " + tparams.map(.tpe.bounds.lo));//debug
val undetparams = inferMethodInstance(fun, tparams, args1, pt);
val result = typedApply(fun, args1);
context.undetparams = undetparams;
@@ -734,7 +740,7 @@ abstract class Typers: Analyzer {
copy.Select(tree, Apply(coercion, List(qual)) setPos qual.pos, name), mode, pt)
}
if (sym.info == NoType) {
- if (settings.debug.value) System.out.println("qual = " + qual + "\nmembers = " + qual.tpe.members);
+ if (settings.debug.value) log("qual = " + qual + ":" + qual.tpe + "\nmembers = " + qual.tpe.members + "\nfound = " + sym);
errorTree(tree,
decode(name) + " is not a member of " + qual.tpe.widen +
(if (Position.line(tree.pos) > Position.line(qual.pos))
@@ -826,8 +832,8 @@ abstract class Typers: Analyzer {
pre = qual.tpe;
} else {
if (settings.debug.value) {
- System.out.println(context);//debug
- System.out.println(context.imports);//debug
+ log(context);//debug
+ log(context.imports);//debug
}
error(tree.pos, "not found: " + decode(name));
defSym = context.owner.newErrorSymbol(name);
@@ -844,7 +850,7 @@ abstract class Typers: Analyzer {
// begin typed1
val sym: Symbol = tree.symbol;
if (sym != null) sym.initialize;
- //if (settings.debug.value && tree.isDef) global.log("typing definition of " + sym);//DEBUG
+ //if (settings.debug.value && tree.isDef) log("typing definition of " + sym);//DEBUG
tree match {
case PackageDef(name, stats) =>
val stats1 = newTyper(context.make(tree, sym.moduleClass, sym.info.decls))
@@ -945,13 +951,13 @@ abstract class Typers: Analyzer {
} else {
val thenp1 = typed(thenp, pt);
val elsep1 = typed(elsep, pt);
- copy.If(tree, cond1, thenp1, elsep1) setType lub(List(thenp1.tpe, elsep1.tpe));
+ copy.If(tree, cond1, thenp1, elsep1) setType ptOrLub(List(thenp1.tpe, elsep1.tpe));
}
case Match(selector, cases) =>
val selector1 = typed(selector);
val cases1 = typedCases(cases, selector1.tpe);
- copy.Match(tree, selector1, cases1) setType lub(cases1 map (.tpe))
+ copy.Match(tree, selector1, cases1) setType ptOrLub(cases1 map (.tpe))
case Return(expr) =>
val enclFun = if (tree.symbol != NoSymbol) tree.symbol else context.owner.enclMethod;
@@ -970,7 +976,7 @@ abstract class Typers: Analyzer {
val finalizer1 = if (finalizer.isEmpty) finalizer
else typed(finalizer, UnitClass.tpe);
copy.Try(tree, block1, catches1, finalizer1)
- setType lub(block1.tpe :: (catches1 map (.tpe)))
+ setType ptOrLub(block1.tpe :: (catches1 map (.tpe)))
case Throw(expr) =>
val expr1 = typed(expr, ThrowableClass.tpe);
@@ -1009,7 +1015,7 @@ abstract class Typers: Analyzer {
var fun1 = typed(fun, funmode, funpt);
// if function is overloaded, filter all alternatives that match
// number of arguments and expected result type.
- // if (settings.debug.value) System.out.println("trans app " + fun1 + ":" + fun1.symbol + ":" + fun1.tpe + " " + args);//DEBUG
+ // if (settings.debug.value) log("trans app " + fun1 + ":" + fun1.symbol + ":" + fun1.tpe + " " + args);//DEBUG
if (fun1.hasSymbol && fun1.symbol.hasFlag(OVERLOADED)) {
val argtypes = args map (arg => AllClass.tpe);
val pre = fun1.symbol.tpe.prefix;
@@ -1110,7 +1116,7 @@ abstract class Typers: Analyzer {
try {
if (settings.debug.value) {
assert(pt != null, tree);//debug
- //System.out.println("typing " + tree);//DEBUG
+ //System.out.println("typing " + tree);//debug
}
val tree1 = if (tree.tpe != null) tree else typed1(tree, mode, pt);
if (tree1.isEmpty) tree1 else adapt(tree1, mode, pt)
@@ -1119,21 +1125,42 @@ abstract class Typers: Analyzer {
reportTypeError(tree.pos, ex);
setError(tree)
case ex: Throwable =>
- if (true || settings.debug.value)//!!!
+ if (settings.debug.value)
System.out.println("exception when typing " + tree + ", pt = " + pt);
throw(ex)
}
+ def atOwner(owner: Symbol): Typer =
+ new Typer(context.make(context.tree, owner));
+
+ def atOwner(tree: Tree, owner: Symbol): Typer =
+ new Typer(context.make(tree, owner));
+
+ /** Types expression or definition `tree' */
def typed(tree: Tree): Tree =
typed(tree, EXPRmode, WildcardType);
+
+ /** Types expression `tree' with given prototype `pt' */
def typed(tree: Tree, pt: Type): Tree =
typed(tree, EXPRmode, pt);
+
+ /** Types qualifier `tree' of a select node. E.g. is tree occurs in acontext like `tree.m'. */
def typedQualifier(tree: Tree): Tree =
typed(tree, EXPRmode | QUALmode | POLYmode, WildcardType);
+
+ /** Types function part of an application */
+ def typedOperator(tree: Tree): Tree =
+ typed(tree, EXPRmode | FUNmode | POLYmode | TAPPmode, WildcardType);
+
+ /** Types a pattern with prototype `pt' */
def typedPattern(tree: Tree, pt: Type): Tree =
typed(tree, PATTERNmode, pt);
+
+ /** Types a (fully parameterized) type tree */
def typedType(tree: Tree): Tree =
typed(tree, TYPEmode, WildcardType);
+
+ /** Types a type or type constructor tree */
def typedTypeConstructor(tree: Tree): Tree =
typed(tree, TYPEmode | FUNmode, WildcardType);
@@ -1150,16 +1177,16 @@ abstract class Typers: Analyzer {
var tree: Tree = EmptyTree;
def fail(reason: String): Tree = {
if (settings.debug.value)
- System.out.println(tree.toString() + " is not a valid implicit value because:\n" + reason);
+ log(tree.toString() + " is not a valid implicit value because:\n" + reason);
EmptyTree
}
try {
tree = Ident(info.name) setPos pos;
if (!local) tree setSymbol info.sym;
tree = typed1(tree, EXPRmode, pt);
- if (settings.debug.value) System.out.println("typed implicit " + tree + ":" + tree.tpe + ", pt = " + pt);//debug
+ if (settings.debug.value) log("typed implicit " + tree + ":" + tree.tpe + ", pt = " + pt);//debug
val tree1 = adapt(tree, EXPRmode, pt);
- if (settings.debug.value) System.out.println("adapted implicit " + tree.symbol + ":" + info.sym);//debug
+ if (settings.debug.value) log("adapted implicit " + tree.symbol + ":" + info.sym);//debug
if (info.sym == tree.symbol) tree1
else fail("syms differ: " + tree.symbol + " " + info.sym)
} catch {
@@ -1183,7 +1210,7 @@ abstract class Typers: Analyzer {
iss = iss.tail;
while (!is.isEmpty) {
tree = tc.typedImplicit(pos, is.head, pt, local);
- if (settings.debug.value) System.out.println("tested " + is.head.sym + is.head.sym.locationString + ":" + is.head.tpe + "=" + tree);//debug
+ if (settings.debug.value) log("tested " + is.head.sym + is.head.sym.locationString + ":" + is.head.tpe + "=" + tree);//debug
val is0 = is;
is = is.tail;
if (tree != EmptyTree) {
diff --git a/sources/scala/xml/parsing/MarkupHandler.scala b/sources/scala/xml/parsing/MarkupHandler.scala
index 4f54c77f1e..74ced1b666 100644
--- a/sources/scala/xml/parsing/MarkupHandler.scala
+++ b/sources/scala/xml/parsing/MarkupHandler.scala
@@ -21,7 +21,10 @@ import scala.util.logging._;
* @todo can we ignore more entity declarations (i.e. those with extIDs)?
* @todo expanding entity references
*/
-abstract class MarkupHandler with Logged {
+abstract class MarkupHandler extends AnyRef with Logged with ConsoleLogger {
+
+ // impl. of Logged
+ //def log(msg:String) = {}
/** returns true is this markup handler is validing */
val isValidating: Boolean = false;
diff --git a/sources/scala/xml/parsing/MarkupParser.scala b/sources/scala/xml/parsing/MarkupParser.scala
index 3d845035c4..a9bd9d34f1 100644
--- a/sources/scala/xml/parsing/MarkupParser.scala
+++ b/sources/scala/xml/parsing/MarkupParser.scala
@@ -883,7 +883,7 @@ abstract class MarkupParser: (MarkupParser with MarkupHandler) extends AnyRef wi
//Console.println("hello, popped");
- stmt.match {
+ stmt match {
// parameter entity
case "INCLUDE" =>
doInclude();
@@ -892,7 +892,7 @@ abstract class MarkupParser: (MarkupParser with MarkupHandler) extends AnyRef wi
}
case 'I' =>
nextch;
- ch.match {
+ ch match {
case 'G' =>
nextch;
xToken("NORE");