diff options
author | Martin Odersky <odersky@gmail.com> | 2005-09-23 12:28:07 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2005-09-23 12:28:07 +0000 |
commit | fcc3a4867d2df32377b56c908c46617a92745ce8 (patch) | |
tree | 534c4deb305f19ca3c3a76b3472b87c7dadb868d | |
parent | 14c330159a76b428b4ca5aa25c112d61836bd79a (diff) | |
download | scala-fcc3a4867d2df32377b56c908c46617a92745ce8.tar.gz scala-fcc3a4867d2df32377b56c908c46617a92745ce8.tar.bz2 scala-fcc3a4867d2df32377b56c908c46617a92745ce8.zip |
*** empty log message ***
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); } - } |