summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2005-09-23 12:28:07 +0000
committerMartin Odersky <odersky@gmail.com>2005-09-23 12:28:07 +0000
commitfcc3a4867d2df32377b56c908c46617a92745ce8 (patch)
tree534c4deb305f19ca3c3a76b3472b87c7dadb868d
parent14c330159a76b428b4ca5aa25c112d61836bd79a (diff)
downloadscala-fcc3a4867d2df32377b56c908c46617a92745ce8.tar.gz
scala-fcc3a4867d2df32377b56c908c46617a92745ce8.tar.bz2
scala-fcc3a4867d2df32377b56c908c46617a92745ce8.zip
*** empty log message ***
-rwxr-xr-xsources/scala/tools/nsc/Global.scala12
-rw-r--r--sources/scala/tools/nsc/Phase.scala2
-rw-r--r--sources/scala/tools/nsc/ast/TreePrinters.scala2
-rw-r--r--sources/scala/tools/nsc/ast/Trees.scala2
-rwxr-xr-xsources/scala/tools/nsc/symtab/Definitions.scala11
-rw-r--r--sources/scala/tools/nsc/symtab/Flags.scala2
-rwxr-xr-xsources/scala/tools/nsc/symtab/Scopes.scala2
-rwxr-xr-xsources/scala/tools/nsc/symtab/SymbolTable.scala5
-rwxr-xr-xsources/scala/tools/nsc/symtab/Symbols.scala93
-rwxr-xr-xsources/scala/tools/nsc/symtab/Types.scala123
-rwxr-xr-xsources/scala/tools/nsc/transform/AddInterfaces.scala25
-rwxr-xr-xsources/scala/tools/nsc/transform/LambdaLift.scala2
-rwxr-xr-xsources/scala/tools/nsc/transform/Mixin.scala185
-rw-r--r--sources/scala/tools/nsc/transform/Transform.scala3
-rw-r--r--sources/scala/tools/nsc/typechecker/Analyzer.scala1
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Contexts.scala13
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Infer.scala16
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Namers.scala4
-rwxr-xr-xsources/scala/tools/nsc/typechecker/SyntheticMethods.scala2
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Typers.scala16
-rw-r--r--sources/scala/tools/nsc/util/Statistics.scala15
21 files changed, 321 insertions, 215 deletions
diff --git a/sources/scala/tools/nsc/Global.scala b/sources/scala/tools/nsc/Global.scala
index 30e05a306d..117b0271e1 100755
--- a/sources/scala/tools/nsc/Global.scala
+++ b/sources/scala/tools/nsc/Global.scala
@@ -153,11 +153,6 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
var globalPhase: Phase = NoPhase;
- override def phase_=(p: Phase): unit = {
- assert(p.id <= globalPhase.id + 1);
- super.phase_=(p)
- }
-
abstract class GlobalPhase(prev: Phase) extends Phase(prev) {
def run: unit = units foreach applyPhase;
def apply(unit: CompilationUnit): unit;
@@ -264,6 +259,7 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
val parserPhase = syntaxAnalyzer.newPhase(NoPhase);
val firstPhase = parserPhase;
+ currentRun = NoRun + 1;
phase = parserPhase;
definitions.init; // needs firstPhase and phase to be defined != NoPhase,
// that's why it is placed here.
@@ -332,10 +328,13 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
symSource.clear;
symData.clear;
reporter.resetCounters();
+ phase = firstPhase;
+ while (phase != terminalPhase) { phase.resetPhase; phase = phase.next }
+
for (val source <- sources)
addUnit(new CompilationUnit(source));
- globalPhase = NoPhase.next;
+ globalPhase = firstPhase;
while (globalPhase != terminalPhase && reporter.errors() == 0) {
val startTime = System.currentTimeMillis();
phase = globalPhase;
@@ -367,6 +366,7 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
writeSymblFile(sym, pickled)
}
}
+ currentRun = currentRun + 1;
} else {
for (val Pair(sym, file) <- symSource.elements) {
sym.reset(new loaders.SourcefileLoader(file));
diff --git a/sources/scala/tools/nsc/Phase.scala b/sources/scala/tools/nsc/Phase.scala
index 31410ce162..ce77502452 100644
--- a/sources/scala/tools/nsc/Phase.scala
+++ b/sources/scala/tools/nsc/Phase.scala
@@ -15,6 +15,8 @@ abstract class Phase(val prev: Phase) {
if (prev == null) Flags.InitialFlags else prev.flagMask | newFlags;
def flagMask: long = fmask;
+ def resetPhase: unit = {}
+
private var nx: Phase = this;
if (prev != null) prev.nx = this;
diff --git a/sources/scala/tools/nsc/ast/TreePrinters.scala b/sources/scala/tools/nsc/ast/TreePrinters.scala
index bda8158881..326b4e68f5 100644
--- a/sources/scala/tools/nsc/ast/TreePrinters.scala
+++ b/sources/scala/tools/nsc/ast/TreePrinters.scala
@@ -259,7 +259,7 @@ abstract class TreePrinters {
def print(tree: Tree): unit =
printRaw(
- if (tree.isDef && tree.symbol != NoSymbol && tree.symbol.hasFlag(INITIALIZED)) {
+ if (tree.isDef && tree.symbol != NoSymbol && tree.symbol.isInitialized) {
tree match {
case ClassDef(_, _, _, _, impl) => ClassDef(tree.symbol, impl)
case ModuleDef(_, _, impl) => ModuleDef(tree.symbol, impl)
diff --git a/sources/scala/tools/nsc/ast/Trees.scala b/sources/scala/tools/nsc/ast/Trees.scala
index 79d5d212de..80a8216c5f 100644
--- a/sources/scala/tools/nsc/ast/Trees.scala
+++ b/sources/scala/tools/nsc/ast/Trees.scala
@@ -17,7 +17,7 @@ abstract class Trees: Global {
abstract class Tree {
- nodeCount = nodeCount + 1;
+ if (util.Statistics.enabled) nodeCount = nodeCount + 1;
var pos: int = Position.NOPOS;
var tpe: Type = _;
diff --git a/sources/scala/tools/nsc/symtab/Definitions.scala b/sources/scala/tools/nsc/symtab/Definitions.scala
index 275948bdc0..4bb6f60e7d 100755
--- a/sources/scala/tools/nsc/symtab/Definitions.scala
+++ b/sources/scala/tools/nsc/symtab/Definitions.scala
@@ -10,6 +10,7 @@ import collection.mutable.HashMap;
import Flags._;
abstract class Definitions: SymbolTable {
+
object definitions {
// root packages and classes
@@ -80,9 +81,9 @@ abstract class Definitions: SymbolTable {
val MaxTupleArity = 9;
val MaxFunctionArity = 9;
- def TupleClass(i: int): Symbol = getClass("scala.Tuple" + i);
+ var TupleClass: Array[Symbol] = _;
def tupleField(n:int, j:int) = getMember(TupleClass(n), "_" + j);
- def FunctionClass(i: int): Symbol = getClass("scala.Function" + i);
+ var FunctionClass: Array[Symbol] = _;
def functionApply(n:int) = getMember(FunctionClass(n), "apply");
def tupleType(elems: List[Type]) =
@@ -327,6 +328,12 @@ abstract class Definitions: SymbolTable {
tparam => typeRef(SeqClass.typeConstructor.prefix, SeqClass, List(tparam.typeConstructor)));
ByNameParamClass = newCovariantPolyClass(
ScalaPackageClass, nme.BYNAME_PARAM_CLASS_NAME, tparam => AnyClass.typeConstructor);
+ TupleClass = new Array(MaxTupleArity + 1);
+ for (val i <- List.range(1, MaxTupleArity + 1))
+ TupleClass(i) = getClass("scala.Tuple" + i);
+ FunctionClass = new Array(MaxFunctionArity + 1);
+ for (val i <- List.range(0, MaxFunctionArity + 1))
+ FunctionClass(i) = getClass("scala.Function" + i);
// members of class scala.Any
Any_== = newMethod(
diff --git a/sources/scala/tools/nsc/symtab/Flags.scala b/sources/scala/tools/nsc/symtab/Flags.scala
index 0cadf154a9..4fc5330461 100644
--- a/sources/scala/tools/nsc/symtab/Flags.scala
+++ b/sources/scala/tools/nsc/symtab/Flags.scala
@@ -64,7 +64,6 @@ object Flags {
final val TRANS_FLAG = 0x2000000000l; // transient flag guaranteed to be reset after each phase.
final val INCONSTRUCTOR = TRANS_FLAG; // transient flag for analyzer
- final val INITIALIZED = 0x4000000000l; // symbol's definition is complete
final val LOCKED = 0x8000000000l; // temporary flag to catch cyclic dependencies
final val InitialFlags = 0x000000FFFFFFFFFFl; // flags that are enabled from phase 1.
@@ -124,7 +123,6 @@ object Flags {
else if (flag == TRANS_FLAG) "<trans-flag>"
else if (flag == MIXEDIN) "<mixedin>"
else if (flag == EXPANDEDNAME) "<expandedname>"
- else if (flag == INITIALIZED) "<initialized>"
else if (flag == LOCKED) "<locked>"
else if (flag == STATICMODULE) "<staticobject>"
else if (flag == STATICMEMBER) "<staticmember>"
diff --git a/sources/scala/tools/nsc/symtab/Scopes.scala b/sources/scala/tools/nsc/symtab/Scopes.scala
index 47c1bcb226..634fd280ed 100755
--- a/sources/scala/tools/nsc/symtab/Scopes.scala
+++ b/sources/scala/tools/nsc/symtab/Scopes.scala
@@ -114,7 +114,7 @@ abstract class Scopes: SymbolTable {
*/
def enter(sym: Symbol): unit = enter(newScopeEntry(sym, this));
- /** enter a symbol
+ /** enter a symbol, asserting that no symbol with same name exists in scope
*/
def enterUnique(sym: Symbol): unit = {
assert(lookup(sym.name) == NoSymbol);
diff --git a/sources/scala/tools/nsc/symtab/SymbolTable.scala b/sources/scala/tools/nsc/symtab/SymbolTable.scala
index ba15a14b19..32f128cdc9 100755
--- a/sources/scala/tools/nsc/symtab/SymbolTable.scala
+++ b/sources/scala/tools/nsc/symtab/SymbolTable.scala
@@ -18,6 +18,7 @@ abstract class SymbolTable extends Names
def settings: Settings;
def rootLoader: LazyType;
def log(msg: Object): unit;
+ def firstPhase: Phase;
private var ph: Phase = NoPhase;
def phase: Phase = ph;
@@ -27,6 +28,10 @@ abstract class SymbolTable extends Names
ph = p
}
+ final val NoRun = 0;
+
+ var currentRun: int = NoRun;
+
def atPhase[T](ph: Phase)(op: => T): T = {
val current = phase;
phase = ph;
diff --git a/sources/scala/tools/nsc/symtab/Symbols.scala b/sources/scala/tools/nsc/symtab/Symbols.scala
index abd68a107c..72b5a35f73 100755
--- a/sources/scala/tools/nsc/symtab/Symbols.scala
+++ b/sources/scala/tools/nsc/symtab/Symbols.scala
@@ -28,6 +28,7 @@ abstract class Symbols: SymbolTable {
private var rawflags: long = 0;
var pos = initPos;
val id = { ids = ids + 1; ids }
+ var validForRun: int = NoRun;
def setPos(pos: int): this.type = { this.pos = pos; this }
@@ -48,9 +49,9 @@ abstract class Symbols: SymbolTable {
final def newConstructor(pos: int) =
newMethod(pos, nme.CONSTRUCTOR);
final def newModule(pos: int, name: Name, clazz: ClassSymbol) =
- new TermSymbol(this, pos, name).setFlag(MODULE | FINAL).setModuleClass(clazz);
+ new ModuleSymbol(this, pos, name).setFlag(MODULE | FINAL).setModuleClass(clazz);
final def newModule(pos: int, name: Name) = {
- val m = new TermSymbol(this, pos, name).setFlag(MODULE | FINAL);
+ val m = new ModuleSymbol(this, pos, name).setFlag(MODULE | FINAL);
m.setModuleClass(new ModuleClassSymbol(m))
}
final def newPackage(pos: int, name: Name) = {
@@ -204,6 +205,9 @@ abstract class Symbols: SymbolTable {
(this hasFlag DEFERRED) ||
(this hasFlag ABSOVERRIDE) && isIncompleteIn(superSymbol(base));
+ final def isInitialized: boolean =
+ validForRun == currentRun;
+
/** The variance of this symbol as an integer */
final def variance: int =
if (hasFlag(COVARIANT)) 1
@@ -247,8 +251,8 @@ abstract class Symbols: SymbolTable {
*/
final def info: Type = {
var cnt = 0;
- while ((rawflags & INITIALIZED) == 0) {
- //if (settings.debug.value) System.out.println("completing " + this + " in " + this.owner);//DEBUG
+ while (validForRun != currentRun) {
+ //if (settings.debug.value) System.out.println("completing " + this + " in " + this.owner);//debug
assert(infos != null, this.name);
val tp = infos.info;
if ((rawflags & LOCKED) != 0) {
@@ -260,7 +264,7 @@ abstract class Symbols: SymbolTable {
try {
phase = infos.start;
tp.complete(this);
- // if (settings.debug.value && (rawflags & INITIALIZED) != 0) System.out.println("completed " + this/* + ":" + info*/);//DEBUG
+ // if (settings.debug.value && (validForRun == currentRun) System.out.println("completed " + this/* + ":" + info*/);//DEBUG
rawflags = rawflags & ~LOCKED
} finally {
phase = current
@@ -275,16 +279,16 @@ abstract class Symbols: SymbolTable {
/** Set initial info. */
def setInfo(info: Type): this.type = {
- if (limit == NoPhase) {
- assert(phase != NoPhase);
- infos = new TypeHistory(phase, info, null);
- limit = phase;
+ assert(info != null);
+ infos = new TypeHistory(firstPhase, info, null);
+ limit = phase;
+ if (info.isComplete) {
+ rawflags = rawflags & ~LOCKED;
+ validForRun = currentRun
} else {
- infos = new TypeHistory(infos.start, info, null);
+ rawflags = rawflags & ~LOCKED;
+ validForRun = NoRun
}
- assert(info != null);
- rawflags = if (info.isComplete) rawflags | INITIALIZED & ~LOCKED;
- else rawflags & ~INITIALIZED & ~LOCKED;
this
}
@@ -299,16 +303,18 @@ abstract class Symbols: SymbolTable {
/** Return info without checking for initialization or completing */
final def rawInfo: Type = {
if (limit.id < phase.id) {
- if ((rawflags & INITIALIZED) != 0) {
+ if (validForRun == currentRun) {
val current = phase;
var itr = infoTransformers.nextFrom(limit);
infoTransformers = itr; // caching optimization
while (itr.phase != NoPhase && itr.phase.id < current.id) {
phase = itr.phase;
val info1 = itr.transform(this, infos.info);
- if (!(info1 eq infos.info))
+ if (info1 ne infos.info) {
infos = new TypeHistory(phase.next, info1, infos);
- itr = itr.nextFrom(phase.next)
+ }
+ limit = phase.next;
+ itr = itr.nextFrom(limit)
}
phase = current;
limit = current;
@@ -317,14 +323,14 @@ abstract class Symbols: SymbolTable {
infos.info
} else {
var infos = this.infos;
- while (phase.id < infos.start.id && infos.prev != null) infos = infos.prev;
+ while (phase.id < infos.start.id) infos = infos.prev;
infos.info
}
}
/** Initialize the symbol */
final def initialize: this.type = {
- if ((rawflags & INITIALIZED) == 0) info;
+ if (!isInitialized) info;
this
}
@@ -723,18 +729,7 @@ abstract class Symbols: SymbolTable {
class TermSymbol(initOwner: Symbol, initPos: int, initName: Name) extends Symbol(initOwner, initPos, initName) {
override def isTerm = true;
- private var referenced: Symbol = NoSymbol;
-
- override def owner: Symbol =
- if (phase.flatClasses && hasFlag(MODULE) && !hasFlag(METHOD) &&
- rawowner != NoSymbol && !rawowner.isPackageClass) rawowner.owner
- else rawowner;
-
- override def name: Name =
- if (phase.flatClasses && hasFlag(MODULE) && !hasFlag(METHOD) &&
- rawowner != NoSymbol && !rawowner.isPackageClass)
- newTermName(rawowner.name.toString() + "$" + rawname);
- else rawname;
+ protected var referenced: Symbol = NoSymbol;
def cloneSymbolImpl(owner: Symbol): Symbol = {
val clone = new TermSymbol(owner, pos, name);
@@ -762,6 +757,33 @@ abstract class Symbols: SymbolTable {
}
}
+ /** A class for term symbols */
+ class ModuleSymbol(initOwner: Symbol, initPos: int, initName: Name) extends TermSymbol(initOwner, initPos, initName) {
+
+ private var flatname = nme.EMPTY;
+
+ override def owner: Symbol =
+ if (phase.flatClasses && !hasFlag(METHOD) &&
+ rawowner != NoSymbol && !rawowner.isPackageClass) rawowner.owner
+ else rawowner;
+
+ override def name: Name =
+ if (phase.flatClasses && !hasFlag(METHOD) &&
+ rawowner != NoSymbol && !rawowner.isPackageClass) {
+ if (flatname == nme.EMPTY) {
+ assert(rawowner.isClass);
+ flatname = newTermName(rawowner.name.toString() + "$" + rawname);
+ }
+ flatname
+ } else rawname;
+
+ override def cloneSymbolImpl(owner: Symbol): Symbol = {
+ val clone = new ModuleSymbol(owner, pos, name);
+ clone.referenced = referenced;
+ clone
+ }
+ }
+
/** A class of type symbols. Alias and abstract types are direct instances
* of this class. Classes are instances of a subclass.
*/
@@ -776,7 +798,7 @@ abstract class Symbols: SymbolTable {
if (isValid(tpePhase)) {
tpePhase = phase
} else {
- if (hasFlag(INITIALIZED)) tpePhase = phase;
+ if (isInitialized) tpePhase = phase;
tpeCache = NoType;
val targs = if (phase.erasedTypes && this != ArrayClass) List()
else unsafeTypeParams map (.tpe);
@@ -805,7 +827,7 @@ abstract class Symbols: SymbolTable {
}
def cloneSymbolImpl(owner: Symbol): Symbol =
new TypeSymbol(owner, pos, name);
- typeSymbolCount = typeSymbolCount + 1;
+ if (util.Statistics.enabled) typeSymbolCount = typeSymbolCount + 1;
}
/** A class for class symbols */
@@ -868,7 +890,7 @@ abstract class Symbols: SymbolTable {
override def sourceModule = if (isModuleClass) linkedModule else NoSymbol;
- classSymbolCount = classSymbolCount + 1;
+ if (util.Statistics.enabled) classSymbolCount = classSymbolCount + 1;
}
/** A class for module class symbols
@@ -914,5 +936,8 @@ abstract class Symbols: SymbolTable {
case class CyclicReference(sym: Symbol, info: Type) extends TypeError("illegal cyclic reference involving " + sym);
/** A class for type histories */
- private case class TypeHistory(start: Phase, info: Type, prev: TypeHistory);
+ private case class TypeHistory(start: Phase, info: Type, prev: TypeHistory) {
+ assert(prev == null || start.id > prev.start.id, this);
+ override def toString() = "TypeHistory" + info.hashCode() + "(" + start + "," + info + "," + prev + ")";
+ }
}
diff --git a/sources/scala/tools/nsc/symtab/Types.scala b/sources/scala/tools/nsc/symtab/Types.scala
index 31126f8169..23a68176ef 100755
--- a/sources/scala/tools/nsc/symtab/Types.scala
+++ b/sources/scala/tools/nsc/symtab/Types.scala
@@ -31,10 +31,16 @@ import Flags._;
abstract class Types: SymbolTable {
import definitions._;
- //staticstics
+ //statistics
var singletonClosureCount = 0;
var compoundClosureCount = 0;
var typerefClosureCount = 0;
+ var findMemberCount = 0;
+ var noMemberCount = 0;
+ var multMemberCount = 0;
+ var findMemberMillis = 0l;
+ var subtypeCount = 0;
+ var subtypeMillis = 0l;
private var explainSwitch = false;
private var checkMalformedSwitch = true;
@@ -44,6 +50,8 @@ abstract class Types: SymbolTable {
/** The base class for all types */
trait Type {
+ def isTrivial: boolean = false;
+
/** The symbol associated with the type */
def symbol: Symbol = NoSymbol;
@@ -161,15 +169,19 @@ abstract class Types: SymbolTable {
* and instantiate all parameters by arguments of `pre'.
* Proceed analogously for thistypes referring to outer classes. */
def asSeenFrom(pre: Type, clazz: Symbol): Type =
- if (!phase.erasedTypes || pre.symbol == ArrayClass) new AsSeenFromMap(pre, clazz) apply this;
- else this;
+ if (!isTrivial && (!phase.erasedTypes || pre.symbol == ArrayClass)) {
+ new AsSeenFromMap(pre, clazz) apply this;
+ } else this;
/** The info of `sym', seen as a member of this type. */
def memberInfo(sym: Symbol): Type =
sym.info.asSeenFrom(this, sym.owner);
/** The type of `sym', seen as a memeber of this type. */
- def memberType(sym: Symbol): Type = sym.tpe.asSeenFrom(this, sym.owner);
+ def memberType(sym: Symbol): Type = {
+ //System.out.println("" + this + " memberType " + sym + ":" + sym.tpe);//DEBUG
+ sym.tpe.asSeenFrom(this, sym.owner);
+ }
/** Substitute types `to' for occurrences of references to symbols `from'
* in this type. */
@@ -192,14 +204,20 @@ abstract class Types: SymbolTable {
new ContainsTraverser(sym).traverse(this).result;
/** Is this type a subtype of that type? */
- def <:<(that: Type): boolean =
- if (explainSwitch) explain("<", isSubType, this, that)
- else (this eq that) || isSubType(this, that);
+ def <:<(that: Type): boolean = {
+ if (util.Statistics.enabled) subtypeCount = subtypeCount + 1;
+ val startTime = if (util.Statistics.enabled) System.currentTimeMillis() else 0l;
+ val result =
+ (this eq that) ||
+ (if (explainSwitch) explain("<", isSubType, this, that) else isSubType(this, that));
+ if (util.Statistics.enabled) subtypeMillis = subtypeMillis + System.currentTimeMillis() - startTime;
+ result
+ }
/** Is this type equivalent to that type? */
def =:=(that: Type): boolean =
- if (explainSwitch) explain("<", isSameType, this, that)
- else (this eq that) || isSameType(this, that);
+ (this eq that) ||
+ (if (explainSwitch) explain("<", isSameType, this, that) else isSameType(this, that));
/** Does this type implement symbol `sym' with same or stronger type? */
def specializes(sym: Symbol): boolean =
@@ -301,6 +319,9 @@ abstract class Types: SymbolTable {
//todo: use narrow only for modules? (correct? efficiency gain?)
def findMember(name: Name, excludedFlags: int, requiredFlags: int): Symbol = {
+ if (util.Statistics.enabled) findMemberCount = findMemberCount + 1;
+ val startTime = if (util.Statistics.enabled) System.currentTimeMillis() else 0l;
+
//System.out.println("find member " + name.decode + " in " + this + ":" + this.baseClasses);//DEBUG
var members: Scope = null;
var member: Symbol = NoSymbol;
@@ -323,6 +344,7 @@ abstract class Types: SymbolTable {
if (excl == 0) {
if (name.isTypeName) {
checkMalformedSwitch = savedCheckMalformedSwitch;
+ if (util.Statistics.enabled) findMemberMillis = findMemberMillis + System.currentTimeMillis() - startTime;
return sym
} else if (member == NoSymbol) {
member = sym
@@ -357,8 +379,14 @@ abstract class Types: SymbolTable {
excluded = excludedFlags
} // while (continue)
checkMalformedSwitch = savedCheckMalformedSwitch;
- if (members == null) member
- else baseClasses.head.newOverloaded(this, members.toList)
+ if (util.Statistics.enabled) findMemberMillis = findMemberMillis + System.currentTimeMillis() - startTime;
+ if (members == null) {
+ if (util.Statistics.enabled) if (member == NoSymbol) noMemberCount = noMemberCount + 1;
+ member
+ } else {
+ if (util.Statistics.enabled) multMemberCount = multMemberCount + 1;
+ baseClasses.head.newOverloaded(this, members.toList)
+ }
}
}
@@ -391,7 +419,7 @@ abstract class Types: SymbolTable {
override def isStable: boolean = true;
override def widen: Type = singleDeref.widen;
override def closure: Array[Type] = {
- singletonClosureCount = singletonClosureCount + 1;
+ if (util.Statistics.enabled) singletonClosureCount = singletonClosureCount + 1;
addClosure(this, supertype.closure);
}
override def toString(): String = prefixString + "type";
@@ -422,11 +450,13 @@ abstract class Types: SymbolTable {
/** An object representing a non-existing type */
case object NoType extends Type {
+ override def isTrivial: boolean = true;
override def toString(): String = "<notype>"
}
/** An object representing a non-existing prefix */
case object NoPrefix extends Type {
+ override def isTrivial: boolean = true;
override def isStable: boolean = true;
override def prefixString = "";
override def toString(): String = "<noprefix>";
@@ -436,6 +466,7 @@ abstract class Types: SymbolTable {
*/
abstract case class ThisType(sym: Symbol) extends SingletonType {
assert(sym.isClass && !sym.isModuleClass || sym.isRoot, sym);
+ override def isTrivial: boolean = sym.isPackageClass;
override def symbol = sym;
override def singleDeref: Type = sym.typeOfThis;
override def prefixString =
@@ -452,6 +483,7 @@ abstract class Types: SymbolTable {
* `singleType' for creation.
*/
abstract case class SingleType(pre: Type, sym: Symbol) extends SingletonType {
+ override val isTrivial: boolean = pre.isTrivial;
private var singleDerefCache: Type = _;
private var singleDerefPhase: Phase = null;
override def singleDeref: Type = {
@@ -472,6 +504,7 @@ abstract class Types: SymbolTable {
}
abstract case class SuperType(thistpe: Type, supertp: Type) extends SingletonType {
+ override val isTrivial: boolean = thistpe.isTrivial && supertp.isTrivial;
override def symbol = thistpe.symbol;
override def singleDeref = supertp;
override def prefix: Type = supertp.prefix;
@@ -485,6 +518,7 @@ abstract class Types: SymbolTable {
/** A class for the bounds of abstract types and type parameters
*/
abstract case class TypeBounds(lo: Type, hi: Type) extends SubType {
+ override val isTrivial: boolean = lo.isTrivial && hi.isTrivial;
def supertype: Type = hi;
override def bounds: TypeBounds = this;
def containsType(that: Type) = that <:< this || lo <:< that && that <:< hi;
@@ -504,7 +538,7 @@ abstract class Types: SymbolTable {
override def closure: Array[Type] = {
def computeClosure: Array[Type] =
try {
- compoundClosureCount = compoundClosureCount + 1;
+ if (util.Statistics.enabled) compoundClosureCount = compoundClosureCount + 1;
//System.out.println("computing closure of " + symbol.tpe + " " + parents);//DEBUG
addClosure(symbol.tpe, glbArray(parents map (.closure)));
} catch {
@@ -598,6 +632,7 @@ abstract class Types: SymbolTable {
/** A class representing a constant type */
abstract case class ConstantType(value: Constant) extends SingletonType {
assert(value.tpe.symbol != UnitClass);
+ override def isTrivial: boolean = true;
override def symbol: Symbol = value.tpe.symbol;
override def singleDeref: Type = value.tpe;
override def deconst: Type = value.tpe;
@@ -616,6 +651,9 @@ abstract class Types: SymbolTable {
private var closureCache: Array[Type] = _;
private var closurePhase: Phase = null;
+ override val isTrivial: boolean =
+ pre.isTrivial && !sym.isTypeParameter && args.forall(.isTrivial);
+
def transform(tp: Type): Type =
tp.asSeenFrom(pre, sym.owner).subst(sym.typeParams, args);
@@ -666,7 +704,7 @@ abstract class Types: SymbolTable {
if (p != phase) {
closurePhase = phase;
if (!isValidForBaseClasses(p)) {
- typerefClosureCount = typerefClosureCount + 1;
+ if (util.Statistics.enabled) typerefClosureCount = typerefClosureCount + 1;
closureCache =
if (sym.isAbstractType) addClosure(this, transform(bounds.hi).closure)
else transform(sym.info.closure);
@@ -702,6 +740,9 @@ abstract class Types: SymbolTable {
*/
case class MethodType(override val paramTypes: List[Type],
override val resultType: Type) extends Type {
+ override val isTrivial: boolean =
+ paramTypes.forall(.isTrivial) && resultType.isTrivial;
+
assert(paramTypes forall (pt => !pt.symbol.isImplClass));//debug
override def paramSectionCount: int = resultType.paramSectionCount + 1;
@@ -898,34 +939,12 @@ abstract class Types: SymbolTable {
var accesses = 0;
var collisions = 0; //todo: use HashSet!
-/* statistics
- var uniqueThis = 0;
- var uniqueSingle = 0;
- var uniqueSuper = 0;
- var uniqueTypeRef = 0;
- var uniqueTypeBounds = 0;
- var uniqueConstant = 0;
- var uniqueMethod = 0;
- var duplicateThis = 0;
- var duplicateSingle = 0;
- var duplicateSuper = 0;
- var duplicateTypeRef = 0;
- var duplicateTypeBounds = 0;
- var duplicateConstant = 0;
- var duplicateMethod = 0;
-
- def allTypes = new Iterator[Type] {
- var i = 0;
- def hasNext: boolean = { while (i < size && table(i) == null) { i = i + 1 }; i < size }
- def next: Type = if (hasNext) { val r = table(i); i = i + 1; r } else null;
- }
-*/
private def findEntry(tp: Type): Type = {
var h = tp.hashCode() % size;
- accesses = accesses + 1;
+ if (util.Statistics.enabled) accesses = accesses + 1;
var entry = table(h);
while (entry != null && entry != tp) {
- collisions = collisions + 1;
+ if (util.Statistics.enabled) collisions = collisions + 1;
h = (h + 1) % size;
entry = table(h)
}
@@ -957,31 +976,9 @@ abstract class Types: SymbolTable {
private def unique[T <: Type](tp: T): T = {
val tp1 = findEntry(tp);
if (tp1 == null) {
-/*
- tp.asInstanceOf[Type] match {
- case ThisType(_) => uniqueThis = uniqueThis + 1
- case SingleType(_, _) => uniqueSingle = uniqueSingle + 1
- case SuperType(_, _) => uniqueSuper = uniqueSuper + 1
- case TypeRef(_, _, _) => uniqueTypeRef = uniqueTypeRef + 1
- case TypeBounds(_, _) => uniqueTypeBounds = uniqueTypeBounds + 1
- case ConstantType(_) => uniqueConstant = uniqueConstant + 1
- case MethodType(_, _) => uniqueMethod = uniqueMethod + 1
- }
-*/
- uniques = uniques + 1;
+ if (util.Statistics.enabled) uniques = uniques + 1;
addEntry(tp); tp
} else {
-/*
- tp.asInstanceOf[Type] match {
- case ThisType(_) => duplicateThis = duplicateThis + 1
- case SingleType(_, _) => duplicateSingle = duplicateSingle + 1
- case SuperType(_, _) => duplicateSuper = duplicateSuper + 1
- case TypeRef(_, _, _) => duplicateTypeRef = duplicateTypeRef + 1
- case TypeBounds(_, _) => duplicateTypeBounds = duplicateTypeBounds + 1
- case ConstantType(_) => duplicateConstant = duplicateConstant + 1
- case MethodType(_, _) => duplicateMethod = duplicateMethod + 1
- }
-*/
tp1.asInstanceOf[T]
}
}
@@ -1269,7 +1266,7 @@ abstract class Types: SymbolTable {
}
/** Do tp1 and tp2 denote equivalent types? */
- def isSameType(tp1: Type, tp2: Type): boolean = (tp1 eq tp2) || {
+ def isSameType(tp1: Type, tp2: Type): boolean = {
Pair(tp1, tp2) match {
case Pair(ErrorType, _) => true
case Pair(WildcardType, _) => true
@@ -1342,7 +1339,7 @@ abstract class Types: SymbolTable {
List.forall2(tps1, tps2)((tp1, tp2) => tp1 =:= tp2);
/** Does tp1 conform to tp2? */
- def isSubType(tp1: Type, tp2: Type): boolean = (tp1 eq tp2) || {
+ def isSubType(tp1: Type, tp2: Type): boolean = {
Pair(tp1, tp2) match {
case Pair(ErrorType, _) => true
case Pair(WildcardType, _) => true
diff --git a/sources/scala/tools/nsc/transform/AddInterfaces.scala b/sources/scala/tools/nsc/transform/AddInterfaces.scala
index bb6c6721ff..a266590f51 100755
--- a/sources/scala/tools/nsc/transform/AddInterfaces.scala
+++ b/sources/scala/tools/nsc/transform/AddInterfaces.scala
@@ -24,6 +24,11 @@ abstract class AddInterfaces extends InfoTransform {
private val implClassMap = new HashMap[Symbol, Symbol];
private val implMethodMap = new HashMap[Symbol, Symbol];
+ override def resetTransform: unit = {
+ implClassMap.clear;
+ implMethodMap.clear
+ }
+
private def needsImplMethod(sym: Symbol): boolean =
sym.isMethod && isInterfaceMember(sym) &&
(!(sym hasFlag (DEFERRED | SUPERACCESSOR)) || (sym hasFlag lateDEFERRED));
@@ -36,15 +41,17 @@ abstract class AddInterfaces extends InfoTransform {
case Some(c) => c
case None =>
atPhase(erasurePhase) {
- val impl = iface.cloneSymbolImpl(iface.owner)
- setFlag (iface.flags & ~(INTERFACE | lateINTERFACE))
- setInfo new LazyImplClassType(iface);
- impl.name = nme.implClassName(iface.name);
- //includeInTypeOfThis(iface, impl);
- //includeInTypeOfThis(impl, impl);
- //todo: use implClassMap only for local impl classes
+ val implName = nme.implClassName(iface.name);
+ var impl = if (iface.owner.isClass) iface.owner.info.decls.lookup(implName) else NoSymbol;
+ if (impl == NoSymbol) {
+ impl = iface.cloneSymbolImpl(iface.owner);
+ impl.name = implName;
+ if (iface.owner.isClass) iface.owner.info.decls enter impl
+ }
+ impl.pos = iface.pos;
+ impl.flags = iface.flags & ~(INTERFACE | lateINTERFACE);
+ impl setInfo new LazyImplClassType(iface);
implClassMap(iface) = impl;
- if (iface.owner.isClass) iface.owner.info.decls enter impl;
if (settings.debug.value) log("generating impl class " + impl);
impl
}
@@ -145,7 +152,7 @@ abstract class AddInterfaces extends InfoTransform {
new ChangeOwnerAndReturnTraverser(ifaceMethod, implMethod).traverse(tree);
tree
case None =>
- throw new Error("implMethod missing for " + ifaceMethod + " " + ifaceMethod.isExternal)
+ throw new Error("implMethod missing for " + ifaceMethod)
}
private def implMemberDef(tree: Tree): Tree =
diff --git a/sources/scala/tools/nsc/transform/LambdaLift.scala b/sources/scala/tools/nsc/transform/LambdaLift.scala
index e4647a41f2..ab03f02af2 100755
--- a/sources/scala/tools/nsc/transform/LambdaLift.scala
+++ b/sources/scala/tools/nsc/transform/LambdaLift.scala
@@ -256,7 +256,7 @@ abstract class LambdaLift extends InfoTransform {
if (sym.isClass) sym.owner = sym.owner.toInterface;
if (sym.isMethod) sym setFlag LIFTED;
liftedDefs(sym.owner) += tree;
- sym.owner.info.decls enter sym;
+ sym.owner.info.decls enterUnique sym;
if (settings.debug.value) log("lifted: " + sym + sym.locationString);
EmptyTree
}
diff --git a/sources/scala/tools/nsc/transform/Mixin.scala b/sources/scala/tools/nsc/transform/Mixin.scala
index ff56fcfd2b..587057e47a 100755
--- a/sources/scala/tools/nsc/transform/Mixin.scala
+++ b/sources/scala/tools/nsc/transform/Mixin.scala
@@ -41,99 +41,118 @@ abstract class Mixin extends InfoTransform {
private def implClass(iface: Symbol): Symbol = erasure.implClass(iface);
- override def transformInfo(sym: Symbol, tp: Type): Type = tp match {
- case ClassInfoType(parents, decls, clazz) =>
- assert(sym == clazz, "not equal: " + sym + " " + clazz);
- var parents1 = parents;
- var decls1 = decls;
- def addMember(member: Symbol): Symbol = {
- if (decls1 eq decls) decls1 = new Scope(decls.toList);
- if (settings.debug.value) log("new member of " + clazz + ":" + member.defString);//debug
- decls1 enter member;
- member
- }
- def addLateInterfaceMembers = {
- def newGetter(field: Symbol): Symbol =
- clazz.newMethod(field.pos, nme.getterName(field.name))
- setFlag (field.flags & ~(PRIVATE | LOCAL) | ACCESSOR | DEFERRED | SYNTHETIC)
- setInfo MethodType(List(), field.info);
- def newSetter(field: Symbol): Symbol =
- clazz.newMethod(field.pos, nme.getterToSetter(nme.getterName(field.name)))
- setFlag (field.flags & ~(PRIVATE | LOCAL) | ACCESSOR | DEFERRED | SYNTHETIC)
- setInfo MethodType(List(field.info), UnitClass.tpe);
- clazz.info;
- val impl = implClass(clazz);
- assert(impl != NoSymbol, "" + clazz + " " + flattenPhase.flatClasses + atPhase(flattenPhase)(clazz.owner.info.decls));
- for (val member <- impl.info.decls.toList) {
- if (!member.isMethod && !member.isModule && !member.isModuleVar) {
- assert(member.isTerm && !member.hasFlag(DEFERRED), member);
- if (member.getter(impl) hasFlag PRIVATE) member.makeNotPrivate(clazz);
- var getter = member.getter(clazz);
- if (getter == NoSymbol) getter = addMember(newGetter(member));
- else getter setFlag (member getFlag MUTABLE);
- if (!member.tpe.isInstanceOf[ConstantType]) {
- var setter = member.setter(clazz);
- if (setter == NoSymbol) setter = addMember(newSetter(member));
- }
- } else if ((member hasFlag (LIFTED | BRIDGE)) && !(member hasFlag PRIVATE)) {
- member.expandName(clazz);
- addMember(member.cloneSymbol(clazz));
- }
- }
+ def addMember(clazz: Symbol, member: Symbol): Symbol = {
+ if (settings.debug.value) log("new member of " + clazz + ":" + member.defString);//debug
+ clazz.info.decls enter member;
+ member
+ }
+
+ def addLateInterfaceMembers(clazz: Symbol) =
+ if (!(clazz hasFlag MIXEDIN)) {
+ clazz setFlag MIXEDIN;
+ def newGetter(field: Symbol): Symbol =
+ clazz.newMethod(field.pos, nme.getterName(field.name))
+ setFlag (field.flags & ~(PRIVATE | LOCAL) | ACCESSOR | DEFERRED | SYNTHETIC)
+ setInfo MethodType(List(), field.info);
+ def newSetter(field: Symbol): Symbol =
+ clazz.newMethod(field.pos, nme.getterToSetter(nme.getterName(field.name)))
+ setFlag (field.flags & ~(PRIVATE | LOCAL) | ACCESSOR | DEFERRED | SYNTHETIC)
+ setInfo MethodType(List(field.info), UnitClass.tpe);
+ clazz.info;
+ val impl = implClass(clazz);
+ assert(impl != NoSymbol);
+ for (val member <- impl.info.decls.toList) {
+ if (!member.isMethod && !member.isModule && !member.isModuleVar) {
+ assert(member.isTerm && !member.hasFlag(DEFERRED), member);
+ if (member.getter(impl) hasFlag PRIVATE) member.makeNotPrivate(clazz);
+ var getter = member.getter(clazz);
+ if (getter == NoSymbol) getter = addMember(clazz, newGetter(member));
+ else getter setFlag (member getFlag MUTABLE);
+ if (!member.tpe.isInstanceOf[ConstantType]) {
+ var setter = member.setter(clazz);
+ if (setter == NoSymbol) setter = addMember(clazz, newSetter(member));
+ }
+ } else if ((member hasFlag (LIFTED | BRIDGE)) && !(member hasFlag PRIVATE)) {
+ member.expandName(clazz);
+ addMember(clazz, member.cloneSymbol(clazz));
+ }
}
- def addMixedinMembers = {
- for (val bc <- clazz.info.baseClasses.tail.takeWhile(parents.head.symbol !=)) {
- if (bc.isImplClass) {
- for (val member <- bc.info.decls.toList) {
- if (isForwarded(member) && !isStatic(member) &&
- (clazz.info.member(member.name).alternatives contains member)) {
- val member1 = addMember(member.cloneSymbol(clazz) setFlag MIXEDIN);
- member1.asInstanceOf[TermSymbol] setAlias member;
- }
+ if (settings.debug.value) log("new defs of " + clazz + " = " + clazz.info.decls);
+ }
+
+ def addMixedinMembers(clazz: Symbol): unit =
+ if (!(clazz hasFlag MIXEDIN) && (clazz != ObjectClass)) {
+ assert(!clazz.isTrait, clazz);
+ clazz setFlag MIXEDIN;
+ assert(!clazz.info.parents.isEmpty, clazz);
+ val superclazz = clazz.info.parents.head.symbol;
+ addMixedinMembers(superclazz);
+ for (val bc <- clazz.info.baseClasses.tail.takeWhile(superclazz !=))
+ if (bc.hasFlag(lateINTERFACE))
+ addLateInterfaceMembers(bc);
+ for (val bc <- clazz.info.baseClasses.tail.takeWhile(superclazz !=)) {
+ if (bc.isImplClass) {
+ for (val member <- bc.info.decls.toList) {
+ if (isForwarded(member) && !isStatic(member) &&
+ (clazz.info.member(member.name).alternatives contains member)) {
+ val member1 = addMember(clazz, member.cloneSymbol(clazz) setFlag MIXEDIN);
+ member1.asInstanceOf[TermSymbol] setAlias member;
}
- } else if (bc.hasFlag(lateINTERFACE)) {
- for (val member <- atPhase(phase.next)(bc.info.decls.toList)) {
- if (member hasFlag ACCESSOR) {
- val member1 = addMember(
- member.cloneSymbol(clazz) setFlag (MIXEDIN | FINAL) resetFlag DEFERRED);
- if (!member.isSetter)
- member.tpe match {
- case MethodType(List(), ConstantType(_)) =>
- ;
- case _ =>
- addMember(
- clazz.newValue(member.pos, nme.getterToLocal(member.name))
- setFlag (LOCAL | PRIVATE | MIXEDIN | member.getFlag(MUTABLE))
- setInfo member.tpe.resultType)
- }
- } else if (member hasFlag SUPERACCESSOR) {
- val member1 = addMember(member.cloneSymbol(clazz)) setFlag MIXEDIN;
- assert(member1.alias != NoSymbol, member1);
- member1.asInstanceOf[TermSymbol] setAlias rebindSuper(clazz, member.alias, bc);
- } else if (member.isMethod && member.isModule && !(member hasFlag (LIFTED | BRIDGE))) {
- addMember(member.cloneSymbol(clazz) setFlag MIXEDIN)
- }
+ }
+ } else if (bc.hasFlag(lateINTERFACE)) {
+ for (val member <- bc.info.decls.toList) {
+ if (member hasFlag ACCESSOR) {
+ val member1 = addMember(clazz,
+ member.cloneSymbol(clazz) setFlag (MIXEDIN | FINAL) resetFlag DEFERRED);
+ if (!member.isSetter)
+ member.tpe match {
+ case MethodType(List(), ConstantType(_)) =>
+ ;
+ case _ =>
+ addMember(clazz,
+ clazz.newValue(member.pos, nme.getterToLocal(member.name))
+ setFlag (LOCAL | PRIVATE | MIXEDIN | member.getFlag(MUTABLE))
+ setInfo member.tpe.resultType)
+ }
+ } else if (member hasFlag SUPERACCESSOR) {
+ val member1 = addMember(clazz, member.cloneSymbol(clazz)) setFlag MIXEDIN;
+ assert(member1.alias != NoSymbol, member1);
+ member1.asInstanceOf[TermSymbol] setAlias rebindSuper(clazz, member.alias, bc);
+ } else if (member.isMethod && member.isModule && !(member hasFlag (LIFTED | BRIDGE))) {
+ addMember(clazz, member.cloneSymbol(clazz) setFlag MIXEDIN)
}
}
}
}
+ if (settings.debug.value) log("new defs of " + clazz + " = " + clazz.info.decls);
+ }
+ override def transformInfo(sym: Symbol, tp: Type): Type = tp match {
+ case ClassInfoType(parents, decls, clazz) =>
+ assert(clazz.info eq tp, tp);
+ assert(sym == clazz, tp);
+ var parents1 = parents;
+ var decls1 = decls;
if (!clazz.isPackageClass) {
atPhase(phase.next)(clazz.owner.info);
if (clazz.isImplClass) {
clazz setFlag lateMODULE;
- clazz.owner.info.decls.enter(
- clazz.owner.newModule(sym.pos, sym.name.toTermName, sym.asInstanceOf[ClassSymbol])
- setInfo sym.tpe);
+ var sourceModule = clazz.owner.info.decls.lookup(sym.name.toTermName);
+ if (sourceModule != NoSymbol) {
+ sourceModule.pos = sym.pos;
+ sourceModule.flags = MODULE | FINAL;
+ } else {
+ sourceModule = clazz.owner.newModule(
+ sym.pos, sym.name.toTermName, sym.asInstanceOf[ClassSymbol]);
+ clazz.owner.info.decls enter sourceModule
+ }
+ sourceModule setInfo sym.tpe;
assert(clazz.sourceModule != NoSymbol);//debug
parents1 = List();
- decls1 = new Scope(decls.toList filter isForwarded)
+ decls1 = new Scope(decls.toList filter isForwarded)
} else if (!parents.isEmpty) {
parents1 = parents.head :: (parents.tail map toInterface);
- if (!(clazz hasFlag INTERFACE)) addMixedinMembers
- else if (clazz hasFlag lateINTERFACE) addLateInterfaceMembers
}
- if (settings.debug.value) log("new defs of " + clazz + " = " + decls1);
}
//decls1 = atPhase(phase.next)(new Scope(decls1.toList));//debug
if ((parents1 eq parents) && (decls1 eq decls)) tp
@@ -159,6 +178,9 @@ abstract class Mixin extends InfoTransform {
tree match {
case Template(parents, body) =>
localTyper = typer.atOwner(tree, currentOwner);
+ atPhase(phase.next)(currentOwner.owner.info);//needed?
+ if (!currentOwner.isTrait) addMixedinMembers(currentOwner)
+ else if (currentOwner hasFlag lateINTERFACE) addLateInterfaceMembers(currentOwner);
tree
case DefDef(mods, name, tparams, List(vparams), tpt, rhs) if currentOwner.isImplClass =>
if (isForwarded(sym)) {
@@ -226,7 +248,7 @@ abstract class Mixin extends InfoTransform {
if ((sym hasFlag SYNTHETIC) && (sym hasFlag ACCESSOR))
addDefDef(sym, vparamss => EmptyTree)
}
- } else if (!clazz.isImplClass && !(clazz hasFlag INTERFACE)) {
+ } else if (!clazz.isTrait) {
for (val sym <- clazz.info.decls.toList) {
if (sym hasFlag MIXEDIN) {
if (sym hasFlag ACCESSOR) {
@@ -272,7 +294,7 @@ abstract class Mixin extends InfoTransform {
}
} else tree
case This(_) if tree.symbol.isImplClass =>
- assert(tree.symbol == currentOwner.enclClass, "" + tree.symbol + " " + currentOwner.enclClass);
+ assert(tree.symbol == currentOwner.enclClass, "" + tree + " " + tree.symbol + " " + currentOwner.enclClass);
selfRef(tree.pos)
case Select(qual @ Super(_, mix), name) =>
if (currentOwner.enclClass.isImplClass) {
@@ -296,11 +318,12 @@ abstract class Mixin extends InfoTransform {
if (sym.isMethod) {
assert(sym hasFlag (LIFTED | BRIDGE), sym);
val sym1 = enclInterface.info.decl(sym.name);
- assert(sym1 != NoSymbol && !(sym1 hasFlag OVERLOADED), sym);//debug
+ assert(sym1 != NoSymbol, sym);
+ assert(!(sym1 hasFlag OVERLOADED), sym);//debug
tree setSymbol sym1
} else {
val getter = sym.getter(enclInterface);
- assert(getter != NoSymbol, "" + enclInterface + " " + sym);
+ assert(getter != NoSymbol);
localTyper.typed {
atPos(tree.pos) {
Apply(Select(qual, getter), List())
diff --git a/sources/scala/tools/nsc/transform/Transform.scala b/sources/scala/tools/nsc/transform/Transform.scala
index cfdf796f27..4d7aebbc71 100644
--- a/sources/scala/tools/nsc/transform/Transform.scala
+++ b/sources/scala/tools/nsc/transform/Transform.scala
@@ -13,11 +13,14 @@ abstract class Transform extends SubComponent {
/** The transformer factory */
protected def newTransformer(unit: global.CompilationUnit): global.Transformer;
+ def resetTransform: unit = {}
+
/** Create a new phase which applies transformer */
def newPhase(prev: scala.tools.nsc.Phase): StdPhase = new Phase(prev);
/** The phase defined by this transform */
class Phase(prev: scala.tools.nsc.Phase) extends StdPhase(prev) {
+ override def resetPhase: unit = resetTransform;
def apply(unit: global.CompilationUnit): unit = {
newTransformer(unit).transformUnit(unit);
}
diff --git a/sources/scala/tools/nsc/typechecker/Analyzer.scala b/sources/scala/tools/nsc/typechecker/Analyzer.scala
index 267f5ba39c..f08cb58fda 100644
--- a/sources/scala/tools/nsc/typechecker/Analyzer.scala
+++ b/sources/scala/tools/nsc/typechecker/Analyzer.scala
@@ -33,6 +33,7 @@ abstract class Analyzer
val global: Analyzer.this.global.type = Analyzer.this.global;
val phaseName = "typer";
def newPhase(_prev: Phase): StdPhase = new StdPhase(_prev) {
+ override def resetPhase: unit = resetTyper;
def apply(unit: CompilationUnit): unit =
unit.body = newTyper(startContext.make(unit)).typed(unit.body)
}
diff --git a/sources/scala/tools/nsc/typechecker/Contexts.scala b/sources/scala/tools/nsc/typechecker/Contexts.scala
index 807283bffc..ed6450b067 100755
--- a/sources/scala/tools/nsc/typechecker/Contexts.scala
+++ b/sources/scala/tools/nsc/typechecker/Contexts.scala
@@ -39,6 +39,17 @@ abstract class Contexts: Analyzer {
sc
}
+ def resetContexts: unit = {
+ var sc = startContext;
+ while (sc != NoContext) {
+ sc.tree match {
+ case Import(qual, _) => qual.tpe = singleType(qual.symbol.owner.thisType, qual.symbol)
+ case _ =>
+ }
+ sc = sc.outer
+ }
+ }
+
class Context {
var unit: CompilationUnit = _;
var tree: Tree = _; // Tree associated with this context
@@ -205,7 +216,7 @@ abstract class Contexts: Analyzer {
if (implicitsCache == null) {
val newImplicits: List[ImplicitInfo] =
if (owner != outer.owner && owner.isClass && !owner.isPackageClass) {
- if (!owner.hasFlag(INITIALIZED)) return outer.implicitss;
+ if (!owner.isInitialized) return outer.implicitss;
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) {
diff --git a/sources/scala/tools/nsc/typechecker/Infer.scala b/sources/scala/tools/nsc/typechecker/Infer.scala
index fe7a9995f5..b6bd8a99dc 100755
--- a/sources/scala/tools/nsc/typechecker/Infer.scala
+++ b/sources/scala/tools/nsc/typechecker/Infer.scala
@@ -12,6 +12,10 @@ abstract class Infer: Analyzer {
import posAssigner.atPos;
import util.ListBuffer;
+ var normM = 0;
+ var normP = 0;
+ var normO = 0;
+
/* -- Type parameter inference utility functions -------------------------------------- */
/** The formal parameter types corresponding to `formals'.
@@ -135,9 +139,15 @@ abstract class Infer: Analyzer {
* Implicit parameters are skipped.
*/
private def normalize(tp: Type): Type = skipImplicit(tp) match {
- case MethodType(formals, restpe) => functionType(formals, normalize(restpe))
- case PolyType(List(), restpe) => normalize(restpe);
- case tp1 => tp1
+ case MethodType(formals, restpe) =>
+ if (util.Statistics.enabled) normM = normM + 1;
+ functionType(formals, normalize(restpe))
+ case PolyType(List(), restpe) =>
+ if (util.Statistics.enabled) normP = normP + 1;
+ normalize(restpe);
+ case tp1 =>
+ if (util.Statistics.enabled) normO = normO + 1;
+ tp1
}
/** The context-dependent inferencer part */
diff --git a/sources/scala/tools/nsc/typechecker/Namers.scala b/sources/scala/tools/nsc/typechecker/Namers.scala
index b547301645..06546a6341 100755
--- a/sources/scala/tools/nsc/typechecker/Namers.scala
+++ b/sources/scala/tools/nsc/typechecker/Namers.scala
@@ -17,9 +17,7 @@ trait Namers: Analyzer {
def updatePosFlags(sym: Symbol, pos: int, mods: int): Symbol = {
if (settings.debug.value) log("overwriting " + sym);
sym.pos = pos;
- val oldflags = sym.flags & (INITIALIZED | LOCKED);
- val newflags = mods & ~(INITIALIZED | LOCKED);
- sym.flags = oldflags | newflags;
+ sym.flags = mods | sym.flags & LOCKED;
if (sym.isModule)
updatePosFlags(sym.moduleClass, pos, (mods & ModuleToClassFlags) | MODULE | FINAL);
if (sym.owner.isPackageClass && sym.linkedSym.rawInfo.isInstanceOf[loaders.SymbolLoader])
diff --git a/sources/scala/tools/nsc/typechecker/SyntheticMethods.scala b/sources/scala/tools/nsc/typechecker/SyntheticMethods.scala
index dafad66d54..937c2419a9 100755
--- a/sources/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/sources/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -81,7 +81,7 @@ abstract class SyntheticMethods: Analyzer {
}
val ts = new ListBuffer[Tree];
- if (clazz hasFlag CASE) {
+ if ((clazz hasFlag CASE) && !phase.erasedTypes) {
if (!hasImplementation(nme.tag)) ts += tagMethod;
if (clazz.isModuleClass) {
if (!hasImplementation(nme.toString_)) ts += moduleToStringMethod;
diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala
index 5c2ff01376..b6b07e9ce9 100755
--- a/sources/scala/tools/nsc/typechecker/Typers.scala
+++ b/sources/scala/tools/nsc/typechecker/Typers.scala
@@ -21,12 +21,14 @@ abstract class Typers: Analyzer {
var idcnt = 0;
var selcnt = 0;
var implcnt = 0;
+ var impltime = 0l;
private val transformed = new HashMap[Tree, Tree];
private val superDefs = new HashMap[Symbol, ListBuffer[Tree]];
- def init = {
+ def resetTyper: unit = {
+ resetContexts;
transformed.clear;
superDefs.clear;
}
@@ -1032,6 +1034,7 @@ abstract class Typers: Analyzer {
val tree1 = if (qual == EmptyTree) tree
else atPos(tree.pos)(Select(qual, name));
// atPos necessary because qualifier might come from startContext
+ //System.out.println("check acc: " + defSym + " " + pre);//DEBUG
stabilize(checkAccessible(tree1, defSym, pre, qual), pre, mode, pt)
}
@@ -1163,7 +1166,7 @@ abstract class Typers: Analyzer {
val enclFun = if (tree.symbol != NoSymbol) tree.symbol else context.owner.enclMethod;
if (!enclFun.isMethod || enclFun.isConstructor)
errorTree(tree, "return outside method definition")
- else if (!context.owner.hasFlag(INITIALIZED))
+ else if (!context.owner.isInitialized)
errorTree(tree, "method " + context.owner + " has return statement; needs result type")
else {
val expr1: Tree = typed(expr, enclFun.tpe.finalResultType);
@@ -1230,7 +1233,7 @@ abstract class Typers: Analyzer {
if (sym != NoSymbol)
fun1 = adapt(fun1 setSymbol sym setType pre.memberType(sym), funmode, WildcardType)
}
- appcnt = appcnt + 1;
+ if (util.Statistics.enabled) appcnt = appcnt + 1;
typedApply(fun1, args)
}
@@ -1268,7 +1271,7 @@ abstract class Typers: Analyzer {
typedSelect(qual1, nme.CONSTRUCTOR);
case Select(qual, name) =>
- selcnt = selcnt + 1;
+ if (util.Statistics.enabled) selcnt = selcnt + 1;
var qual1 = typedQualifier(qual);
if (name.isTypeName) qual1 = checkStable(qual1);
typedSelect(qual1, name);
@@ -1401,7 +1404,6 @@ abstract class Typers: Analyzer {
private def typedImplicit(pos: int, info: ImplicitInfo, pt: Type, local: boolean): Tree =
if (isCompatible(depoly(info.tpe), pt)) {
- implcnt = implcnt + 1;
var tree: Tree = EmptyTree;
def fail(reason: String): Tree = {
if (settings.debug.value)
@@ -1424,6 +1426,9 @@ abstract class Typers: Analyzer {
private def inferImplicit(pos: int, pt: Type, isView: boolean, reportAmbiguous: boolean): Tree = {
+ if (util.Statistics.enabled) implcnt = implcnt + 1;
+ val startTime = if (util.Statistics.enabled) System.currentTimeMillis() else 0l;
+
def isBetter(sym1: Symbol, tpe1: Type, sym2: Symbol, tpe2: Type): boolean =
sym2.isError ||
(sym1.owner != sym2.owner) && (sym1.owner isSubClass sym2.owner) && (tpe1 matches tpe2);
@@ -1478,6 +1483,7 @@ abstract class Typers: Analyzer {
var tree = searchImplicit(context.implicitss, true);
if (tree == EmptyTree) tree = searchImplicit(implicitsOfType(pt.widen), false);
+ if (util.Statistics.enabled) impltime = impltime + System.currentTimeMillis() - startTime;
tree
}
diff --git a/sources/scala/tools/nsc/util/Statistics.scala b/sources/scala/tools/nsc/util/Statistics.scala
index 4a540104d7..5033ee68af 100644
--- a/sources/scala/tools/nsc/util/Statistics.scala
+++ b/sources/scala/tools/nsc/util/Statistics.scala
@@ -7,6 +7,10 @@
package scala.tools.nsc.util;
+object Statistics {
+ final val enabled = false;
+}
+
abstract class Statistics {
val global: Global;
@@ -19,6 +23,7 @@ abstract class Statistics {
inform("#selections : " + analyzer.selcnt);
inform("#applications: " + analyzer.appcnt);
inform("#implicits : " + analyzer.implcnt);
+ inform("ms implicits : " + analyzer.impltime);
inform("#typecreates : " + accesses);
inform("#uniquetypes : " + uniques);
inform("#collisions : " + collisions);
@@ -28,7 +33,15 @@ abstract class Statistics {
inform("#singleton closures: " + singletonClosureCount);
inform("#compound closures : " + compoundClosureCount);
inform("#typeref closures : " + typerefClosureCount);
+ inform("#findMember : " + findMemberCount);
+ inform("#notfound member: " + noMemberCount);
+ inform("#mulitple member: " + multMemberCount);
+ inform("time findMember: " + findMemberMillis);
+ inform("#norm meth : " + analyzer.normM);
+ inform("#norm poly : " + analyzer.normP);
+ inform("#norm other: " + analyzer.normO);
+ inform("#subtype : " + subtypeCount);
+ inform("ms subtype: " + subtypeMillis);
}
-
}