diff options
author | Paul Phillips <paulp@improving.org> | 2012-03-01 13:36:12 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-03-01 22:31:50 -0800 |
commit | 54b541b103f79bdfff96227eeeac1d92d68165d8 (patch) | |
tree | 27ceb751880c6aa85b3406dbf251f6458c78303f /src | |
parent | ee4fa5449e25bae11891f23907114ff5ea5e12b8 (diff) | |
download | scala-54b541b103f79bdfff96227eeeac1d92d68165d8.tar.gz scala-54b541b103f79bdfff96227eeeac1d92d68165d8.tar.bz2 scala-54b541b103f79bdfff96227eeeac1d92d68165d8.zip |
More consistent use of atPhase.
Diffstat (limited to 'src')
13 files changed, 120 insertions, 98 deletions
diff --git a/src/compiler/scala/reflect/internal/Phase.scala b/src/compiler/scala/reflect/internal/Phase.scala index acd3360c4f..89d643aacf 100644 --- a/src/compiler/scala/reflect/internal/Phase.scala +++ b/src/compiler/scala/reflect/internal/Phase.scala @@ -26,6 +26,8 @@ abstract class Phase(val prev: Phase) { if ((prev ne null) && (prev ne NoPhase)) prev.nx = this def next: Phase = nx + def hasNext = next != this + def iterator = Iterator.iterate(this)(_.next) takeWhile (p => p.next != p) def name: String def description: String = name @@ -37,7 +39,7 @@ abstract class Phase(val prev: Phase) { def refChecked: Boolean = false /** This is used only in unsafeTypeParams, and at this writing is - * overridden to false in namer, typer, and erasure. (And NoPhase.) + * overridden to false in parser, namer, typer, and erasure. (And NoPhase.) */ def keepsTypeParams = true def run(): Unit diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala index 221fb46d12..ce54c32273 100644 --- a/src/compiler/scala/reflect/internal/SymbolTable.scala +++ b/src/compiler/scala/reflect/internal/SymbolTable.scala @@ -93,6 +93,16 @@ abstract class SymbolTable extends api.Universe ph = p per = period(currentRunId, p.id) } + final def pushPhase(ph: Phase): Phase = { + val current = phase + phase = ph + phStack ::= ph + current + } + final def popPhase(ph: Phase) { + phStack = phStack.tail + phase = ph + } /** The current compiler run identifier. */ def currentRunId: RunId @@ -120,20 +130,19 @@ abstract class SymbolTable extends api.Universe /** Perform given operation at given phase. */ @inline final def atPhase[T](ph: Phase)(op: => T): T = { - val current = phase - phase = ph - phStack ::= ph + val saved = pushPhase(ph) try op - finally { - phase = current - phStack = phStack.tail - } + finally popPhase(saved) } + + /** Since when it is to be "at" a phase is inherently ambiguous, * a couple unambiguously named methods. */ @inline final def beforePhase[T](ph: Phase)(op: => T): T = atPhase(ph)(op) @inline final def afterPhase[T](ph: Phase)(op: => T): T = atPhase(ph.next)(op) + @inline final def afterCurrentPhase[T](op: => T): T = atPhase(phase.next)(op) + @inline final def beforePrevPhase[T](op: => T): T = atPhase(phase.prev)(op) @inline final def atPhaseNotLaterThan[T](target: Phase)(op: => T): T = if (target != NoPhase && phase.id > target.id) atPhase(target)(op) else op diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 334436bfbe..62b0206c28 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -1166,7 +1166,13 @@ trait Symbols extends api.Symbols { self: SymbolTable => abort("typeConstructor inapplicable for " + this) /** The logic approximately boils down to finding the most recent phase - * which immediately follows any of namer, typer, or erasure. + * which immediately follows any of parser, namer, typer, or erasure. + * In effect that means this will return one of: + * + * - packageobjects (follows namer) + * - superaccessors (follows typer) + * - lazyvals (follows erasure) + * - null */ private def unsafeTypeParamPhase = { var ph = phase @@ -2752,5 +2758,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => assert(validFrom != NoPeriod) override def toString() = "TypeHistory(" + phaseOf(validFrom)+":"+runId(validFrom) + "," + info + "," + prev + ")" + + def toList: List[TypeHistory] = this :: ( if (prev eq null) Nil else prev.toList ) } } diff --git a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala index 9f93108420..34163d54f8 100644 --- a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala +++ b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala @@ -846,10 +846,11 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ { private val p = phase override def complete(sym: Symbol) : Unit = try { val tp = at(i, () => readType(sym.isTerm)) // after NMT_TRANSITION, revert `() => readType(sym.isTerm)` to `readType` - if (p != phase) atPhase(p) (sym setInfo tp) - else sym setInfo tp - if (currentRunId != definedAtRunId) sym.setInfo(adaptToNewRunMap(tp)) - } catch { + atPhase(p) (sym setInfo tp) + if (currentRunId != definedAtRunId) + sym.setInfo(adaptToNewRunMap(tp)) + } + catch { case e: MissingRequirementError => throw toTypeError(e) } override def load(sym: Symbol) { complete(sym) } diff --git a/src/compiler/scala/reflect/internal/util/Collections.scala b/src/compiler/scala/reflect/internal/util/Collections.scala index cc48be1684..d26a1abadb 100644 --- a/src/compiler/scala/reflect/internal/util/Collections.scala +++ b/src/compiler/scala/reflect/internal/util/Collections.scala @@ -74,6 +74,10 @@ trait Collections { index += 1 } } + + @inline final def findOrElse[A](xs: TraversableOnce[A])(p: A => Boolean)(orElse: => A): A = { + xs find p getOrElse orElse + } final def mapWithIndex[A, B](xs: List[A])(f: (A, Int) => B): List[B] = { val lb = new ListBuffer[B] diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index f0f53ec315..44dc2fe384 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -59,7 +59,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb type AbstractFileType = scala.tools.nsc.io.AbstractFile def mkAttributedQualifier(tpe: Type, termSym: Symbol): Tree = gen.mkAttributedQualifier(tpe, termSym) - + def picklerPhase: Phase = if (currentRun.isDefined) currentRun.picklerPhase else NoPhase // platform specific elements @@ -869,26 +869,26 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb def currentSource: SourceFile = if (currentUnit.exists) currentUnit.source else lastSeenSourceFile // TODO - trim these to the absolute minimum. - @inline final def afterErasure[T](op: => T): T = afterPhase(currentRun.erasurePhase)(op) - @inline final def afterExplicitOuter[T](op: => T): T = afterPhase(currentRun.explicitouterPhase)(op) - @inline final def afterFlatten[T](op: => T): T = afterPhase(currentRun.flattenPhase)(op) - @inline final def afterIcode[T](op: => T): T = afterPhase(currentRun.icodePhase)(op) - @inline final def afterMixin[T](op: => T): T = afterPhase(currentRun.mixinPhase)(op) - @inline final def afterPickler[T](op: => T): T = afterPhase(currentRun.picklerPhase)(op) - @inline final def afterRefchecks[T](op: => T): T = afterPhase(currentRun.refchecksPhase)(op) - @inline final def afterSpecialize[T](op: => T): T = afterPhase(currentRun.specializePhase)(op) - @inline final def afterTyper[T](op: => T): T = afterPhase(currentRun.typerPhase)(op) - @inline final def afterUncurry[T](op: => T): T = afterPhase(currentRun.uncurryPhase)(op) - @inline final def beforeErasure[T](op: => T): T = beforePhase(currentRun.erasurePhase)(op) + @inline final def afterErasure[T](op: => T): T = afterPhase(currentRun.erasurePhase)(op) + @inline final def afterExplicitOuter[T](op: => T): T = afterPhase(currentRun.explicitouterPhase)(op) + @inline final def afterFlatten[T](op: => T): T = afterPhase(currentRun.flattenPhase)(op) + @inline final def afterIcode[T](op: => T): T = afterPhase(currentRun.icodePhase)(op) + @inline final def afterMixin[T](op: => T): T = afterPhase(currentRun.mixinPhase)(op) + @inline final def afterPickler[T](op: => T): T = afterPhase(currentRun.picklerPhase)(op) + @inline final def afterRefchecks[T](op: => T): T = afterPhase(currentRun.refchecksPhase)(op) + @inline final def afterSpecialize[T](op: => T): T = afterPhase(currentRun.specializePhase)(op) + @inline final def afterTyper[T](op: => T): T = afterPhase(currentRun.typerPhase)(op) + @inline final def afterUncurry[T](op: => T): T = afterPhase(currentRun.uncurryPhase)(op) + @inline final def beforeErasure[T](op: => T): T = beforePhase(currentRun.erasurePhase)(op) @inline final def beforeExplicitOuter[T](op: => T): T = beforePhase(currentRun.explicitouterPhase)(op) - @inline final def beforeFlatten[T](op: => T): T = beforePhase(currentRun.flattenPhase)(op) - @inline final def beforeIcode[T](op: => T): T = beforePhase(currentRun.icodePhase)(op) - @inline final def beforeMixin[T](op: => T): T = beforePhase(currentRun.mixinPhase)(op) - @inline final def beforePickler[T](op: => T): T = beforePhase(currentRun.picklerPhase)(op) - @inline final def beforeRefchecks[T](op: => T): T = beforePhase(currentRun.refchecksPhase)(op) - @inline final def beforeSpecialize[T](op: => T): T = beforePhase(currentRun.specializePhase)(op) - @inline final def beforeTyper[T](op: => T): T = beforePhase(currentRun.typerPhase)(op) - @inline final def beforeUncurry[T](op: => T): T = beforePhase(currentRun.uncurryPhase)(op) + @inline final def beforeFlatten[T](op: => T): T = beforePhase(currentRun.flattenPhase)(op) + @inline final def beforeIcode[T](op: => T): T = beforePhase(currentRun.icodePhase)(op) + @inline final def beforeMixin[T](op: => T): T = beforePhase(currentRun.mixinPhase)(op) + @inline final def beforePickler[T](op: => T): T = beforePhase(currentRun.picklerPhase)(op) + @inline final def beforeRefchecks[T](op: => T): T = beforePhase(currentRun.refchecksPhase)(op) + @inline final def beforeSpecialize[T](op: => T): T = beforePhase(currentRun.specializePhase)(op) + @inline final def beforeTyper[T](op: => T): T = beforePhase(currentRun.typerPhase)(op) + @inline final def beforeUncurry[T](op: => T): T = beforePhase(currentRun.uncurryPhase)(op) /** Don't want to introduce new errors trying to report errors, * so swallow exceptions. @@ -997,16 +997,18 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb // Each subcomponent supplies a phase, which are chained together. // If -Ystop:phase is given, neither that phase nor any beyond it is added. // If -Yskip:phase is given, that phase will be skipped. - val lastPhase = phaseDescriptors.tail . - takeWhile (pd => !stopPhase(pd.phaseName)) . - filterNot (pd => skipPhase(pd.phaseName)) . - foldLeft (parserPhase) ((chain, ph) => ph newPhase chain) - - // Ensure there is a terminal phase at the end, since -Ystop may have limited the phases. - terminalPhase = - if (lastPhase.name == "terminal") lastPhase - else terminal newPhase lastPhase - + val phaseLinks = { + val phs = ( + phaseDescriptors.tail + takeWhile (pd => !stopPhase(pd.phaseName)) + filterNot (pd => skipPhase(pd.phaseName)) + ) + // Ensure there is a terminal phase at the end, since -Ystop may have limited the phases. + if (phs.isEmpty || (phs.last ne terminal)) phs :+ terminal + else phs + } + // Link them together. + phaseLinks.foldLeft(parserPhase)((chain, ph) => ph newPhase chain) parserPhase } @@ -1090,32 +1092,38 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb // ----- finding phases -------------------------------------------- - def phaseNamed(name: String): Phase = { - var p: Phase = firstPhase - while (p.next != p && p.name != name) p = p.next - if (p.name != name) NoPhase else p - } - - val parserPhase = phaseNamed("parser") - val namerPhase = phaseNamed("namer") - // packageobjects - val typerPhase = phaseNamed("typer") - // superaccessors - val picklerPhase = phaseNamed("pickler") - val refchecksPhase = phaseNamed("refchecks") - val uncurryPhase = phaseNamed("uncurry") - // tailcalls, specialize - val specializePhase = phaseNamed("specialize") - val explicitouterPhase = phaseNamed("explicitouter") - val erasurePhase = phaseNamed("erasure") - // lazyvals, lambdalift, constructors - val lambdaLiftPhase = phaseNamed("lambdalift") - val flattenPhase = phaseNamed("flatten") - val mixinPhase = phaseNamed("mixin") - val cleanupPhase = phaseNamed("cleanup") - val icodePhase = phaseNamed("icode") - // inliner, closelim, dce - val jvmPhase = phaseNamed("jvm") + def phaseNamed(name: String): Phase = + findOrElse(firstPhase.iterator)(_.name == name)(NoPhase) + + /** All phases as of 3/2012 here for handiness; the ones in + * active use uncommented. + */ + val parserPhase = phaseNamed("parser") + val namerPhase = phaseNamed("namer") + // val packageobjectsPhase = phaseNamed("packageobjects") + val typerPhase = phaseNamed("typer") + // val superaccessorsPhase = phaseNamed("superaccessors") + val picklerPhase = phaseNamed("pickler") + val refchecksPhase = phaseNamed("refchecks") + // val selectiveanfPhase = phaseNamed("selectiveanf") + // val selectivecpsPhase = phaseNamed("selectivecps") + val uncurryPhase = phaseNamed("uncurry") + // val tailcallsPhase = phaseNamed("tailcalls") + val specializePhase = phaseNamed("specialize") + val explicitouterPhase = phaseNamed("explicitouter") + val erasurePhase = phaseNamed("erasure") + // val lazyvalsPhase = phaseNamed("lazyvals") + val lambdaliftPhase = phaseNamed("lambdalift") + // val constructorsPhase = phaseNamed("constructors") + val flattenPhase = phaseNamed("flatten") + val mixinPhase = phaseNamed("mixin") + val cleanupPhase = phaseNamed("cleanup") + val icodePhase = phaseNamed("icode") + // val inlinerPhase = phaseNamed("inliner") + // val inlineExceptionHandlersPhase = phaseNamed("inlineExceptionHandlers") + // val closelimPhase = phaseNamed("closelim") + // val dcePhase = phaseNamed("dce") + val jvmPhase = phaseNamed("jvm") def runIsAt(ph: Phase) = globalPhase.id == ph.id def runIsPast(ph: Phase) = globalPhase.id > ph.id @@ -1269,7 +1277,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb checkDeprecatedSettings(unitbuf.head) globalPhase = fromPhase - while (globalPhase != terminalPhase && !reporter.hasErrors) { + while (globalPhase.hasNext && !reporter.hasErrors) { val startTime = currentTime phase = globalPhase @@ -1390,19 +1398,13 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb /** Compile abstract file until `globalPhase`, but at least to phase "namer". */ def compileLate(unit: CompilationUnit) { - def stop(ph: Phase) = ph == null || ph.id >= (globalPhase.id max typerPhase.id) - def loop(ph: Phase) { - if (stop(ph)) refreshProgress - else { - atPhase(ph)(ph.asInstanceOf[GlobalPhase] applyPhase unit) - loop(ph.next match { - case `ph` => null // ph == ph.next implies terminal, and null ends processing - case x => x - }) - } - } + val maxId = math.max(globalPhase.id, typerPhase.id) addUnit(unit) - loop(firstPhase) + + firstPhase.iterator takeWhile (_.id < maxId) foreach (ph => + atPhase(ph)(ph.asInstanceOf[GlobalPhase] applyPhase unit) + ) + refreshProgress } /** diff --git a/src/compiler/scala/tools/nsc/SubComponent.scala b/src/compiler/scala/tools/nsc/SubComponent.scala index df63035007..a3e451f32f 100644 --- a/src/compiler/scala/tools/nsc/SubComponent.scala +++ b/src/compiler/scala/tools/nsc/SubComponent.scala @@ -47,8 +47,8 @@ abstract class SubComponent { private var ownPhaseCache: WeakReference[Phase] = new WeakReference(null) private var ownPhaseRunId = global.NoRunId - @inline final def atOwnPhase[T](op: => T) = global.atPhase(ownPhase)(op) - @inline final def afterOwnPhase[T](op: => T) = global.afterPhase(ownPhase)(op) + @inline final def beforeOwnPhase[T](op: => T) = global.beforePhase(ownPhase)(op) + @inline final def afterOwnPhase[T](op: => T) = global.afterPhase(ownPhase)(op) /** The phase corresponding to this subcomponent in the current compiler run */ def ownPhase: Phase = { diff --git a/src/compiler/scala/tools/nsc/backend/icode/Members.scala b/src/compiler/scala/tools/nsc/backend/icode/Members.scala index 97247dd89b..36651541b2 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Members.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Members.scala @@ -183,12 +183,7 @@ trait Members { this } - def addLocal(l: Local): Local = - locals find (_ == l) getOrElse { - locals ::= l - l - } - + def addLocal(l: Local): Local = findOrElse(locals)(_ == l) { locals ::= l ; l } def addParam(p: Local): Unit = if (params contains p) () diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala index 2398f8406c..e91bab8367 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala @@ -724,6 +724,7 @@ abstract class Inliners extends SubComponent { def failureReason(stackLength: Int) = if (!inc.m.hasCode) "bytecode was unavailable" + else if (inc.m.symbol.hasFlag(Flags.SYNCHRONIZED)) "method is synchronized" else if (!isSafeToInline(stackLength)) "it is unsafe (target may reference private fields)" else "of a bug (run with -Ylog:inline -Ydebug for more information)" diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index 25ae6f33d2..758f870d6b 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -77,7 +77,7 @@ abstract class Pickler extends SubComponent { private var entries = new Array[AnyRef](256) private var ep = 0 private val index = new LinkedHashMap[AnyRef, Int] - private lazy val nonClassRoot = root.ownersIterator.find(! _.isClass) getOrElse NoSymbol + private lazy val nonClassRoot = findOrElse(root.ownersIterator)(!_.isClass)(NoSymbol) private def isRootSym(sym: Symbol) = sym.name.toTermName == rootName && sym.owner == rootOwner diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index 45045b1909..595c1486b6 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -89,8 +89,8 @@ abstract class ExplicitOuter extends InfoTransform def outerAccessor(clazz: Symbol): Symbol = { val firstTry = clazz.info.decl(nme.expandedName(nme.OUTER, clazz)) if (firstTry != NoSymbol && firstTry.outerSource == clazz) firstTry - else clazz.info.decls find (_.outerSource == clazz) getOrElse NoSymbol - } + else findOrElse(clazz.info.decls)(_.outerSource == clazz)(NoSymbol) + } def newOuterAccessor(clazz: Symbol) = { val accFlags = SYNTHETIC | METHOD | STABLE | ( if (clazz.isTrait) DEFERRED else 0 ) val sym = clazz.newMethodSymbol(nme.OUTER, clazz.pos, accFlags) diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index 050425c558..c9794cc20f 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -147,7 +147,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { member.hasAccessorFlag && (!member.isDeferred || (member hasFlag lateDEFERRED)) /** Is member overridden (either directly or via a bridge) in base class sequence `bcs`? */ - def isOverriddenAccessor(member: Symbol, bcs: List[Symbol]): Boolean = atOwnPhase { + def isOverriddenAccessor(member: Symbol, bcs: List[Symbol]): Boolean = beforeOwnPhase { def hasOverridingAccessor(clazz: Symbol) = { clazz.info.nonPrivateDecl(member.name).alternatives.exists( sym => @@ -1160,7 +1160,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { def implSym = implClass(sym.owner).info.member(sym.name) assert(target ne NoSymbol, List(sym + ":", sym.tpe, sym.owner, implClass(sym.owner), implSym, - atPhase(phase.prev)(implSym.tpe), phase) mkString " " + beforePrevPhase(implSym.tpe), phase) mkString " " ) typedPos(tree.pos)(Apply(staticRef(target), transformSuper(qual) :: args)) } @@ -1185,7 +1185,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { val sym1 = sym.overridingSymbol(currentOwner.enclClass) typedPos(tree.pos)((transformSuper(qual) DOT sym1)()) } else { - staticCall(atPhase(phase.prev)(sym.overridingSymbol(implClass(sym.owner)))) + staticCall(beforePrevPhase(sym.overridingSymbol(implClass(sym.owner)))) } } else { assert(!currentOwner.enclClass.isImplClass, currentOwner.enclClass) diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index be6200b353..0851dad0c2 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -1505,10 +1505,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { deriveValDef(newValDef)(transform) case Apply(sel @ Select(sup @ Super(qual, name), name1), args) - if (sup.symbol.info.parents != atPhase(phase.prev)(sup.symbol.info.parents)) => + if (sup.symbol.info.parents != beforePrevPhase(sup.symbol.info.parents)) => def parents = sup.symbol.info.parents - debuglog(tree + " parents changed from: " + atPhase(phase.prev)(parents) + " to: " + parents) + debuglog(tree + " parents changed from: " + beforePrevPhase(parents) + " to: " + parents) val res = localTyper.typed( Apply(Select(Super(qual, name) setPos sup.pos, name1) setPos sel.pos, transformTrees(args)) setPos tree.pos) |