summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-09-28 17:59:44 +0000
committerPaul Phillips <paulp@improving.org>2011-09-28 17:59:44 +0000
commit08845f2ce3959b6da4beb619cd045e60b655ce3f (patch)
treec048a58e6dd186559d92b0fc745d2c631a85dde3
parentf7a4cdd56ffa204b514c3ab1c2b9218ac3679178 (diff)
downloadscala-08845f2ce3959b6da4beb619cd045e60b655ce3f.tar.gz
scala-08845f2ce3959b6da4beb619cd045e60b655ce3f.tar.bz2
scala-08845f2ce3959b6da4beb619cd045e60b655ce3f.zip
More consistent usage of atPhase.
Some improvables I noticed while working on a fingerprint phase. This eliminates fifty classes from the compiler. My new hobby is reading the whole bytecode diff anytime I'm touching something like unsafeTypeParams where I know someone is liable to start praying for my network access to fail, so I hope knowing that fills you with new confidence. Anyway, review by moors.
-rw-r--r--src/compiler/scala/reflect/internal/Phase.scala5
-rw-r--r--src/compiler/scala/reflect/internal/SymbolTable.scala6
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala44
3 files changed, 27 insertions, 28 deletions
diff --git a/src/compiler/scala/reflect/internal/Phase.scala b/src/compiler/scala/reflect/internal/Phase.scala
index 5637a86de3..acd3360c4f 100644
--- a/src/compiler/scala/reflect/internal/Phase.scala
+++ b/src/compiler/scala/reflect/internal/Phase.scala
@@ -35,6 +35,10 @@ abstract class Phase(val prev: Phase) {
def erasedTypes: Boolean = false
def flatClasses: Boolean = false
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.)
+ */
def keepsTypeParams = true
def run(): Unit
@@ -48,6 +52,7 @@ abstract class Phase(val prev: Phase) {
object NoPhase extends Phase(null) {
def name = "<no phase>"
+ override def keepsTypeParams = false
def run() { throw new Error("NoPhase.run") }
}
diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala
index b92a1bb5d7..873821e790 100644
--- a/src/compiler/scala/reflect/internal/SymbolTable.scala
+++ b/src/compiler/scala/reflect/internal/SymbolTable.scala
@@ -97,17 +97,17 @@ abstract class SymbolTable extends api.Universe
(currentRunId << 8) + pid
/** Perform given operation at given phase. */
- final def atPhase[T](ph: Phase)(op: => T): T = {
+ @inline final def atPhase[T](ph: Phase)(op: => T): T = {
val current = phase
phase = ph
try op
finally phase = current
}
- final def afterPhase[T](ph: Phase)(op: => T): T =
+ @inline final def afterPhase[T](ph: Phase)(op: => T): T =
atPhase(ph.next)(op)
- final def atPhaseNotLaterThan[T](target: Phase)(op: => T): T =
+ @inline final def atPhaseNotLaterThan[T](target: Phase)(op: => T): T =
if (target != null && phase.id > target.id) atPhase(target)(op) else op
final def isValid(period: Period): Boolean =
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index 84b54167ec..160fbf7f77 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -999,7 +999,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
protected def doCookJavaRawInfo(): Unit
-
/** The type constructor of a symbol is:
* For a type symbol, the type corresponding to the symbol itself,
* excluding parameters.
@@ -1008,42 +1007,37 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def typeConstructor: Type =
abort("typeConstructor inapplicable for " + this)
+ /** The logic approximately boils down to finding the phase following
+ * the most recent of namer, typer, or erasure.
+ */
+ private def unsafeTypeParamPhase = {
+ var ph = phase
+ while (ph.prev.keepsTypeParams)
+ ph = ph.prev
+ if (ph ne phase) { // Can anyone comment as to what this condition accomplishes?
+ ph = ph.next
+ debuglog("checking unsafeTypeParams(" + this + ") at: " + phase + " reading at: " + ph)
+ }
+ ph
+ }
/** The type parameters of this symbol, without ensuring type completion.
* assumption: if a type starts out as monomorphic, it will not acquire
* type parameters later.
*/
def unsafeTypeParams: List[Symbol] =
- if (isMonomorphicType) List()
- else {
- val current = phase
- try {
- while ((phase.prev ne NoPhase) && phase.prev.keepsTypeParams) phase = phase.prev
- if (phase ne current) phase = phase.next
- if (settings.debug.value && settings.verbose.value && (phase ne current))
- log("checking unsafeTypeParams(" + this + ") at: " + current + " reading at: " + phase)
- rawInfo.typeParams
- } finally {
- phase = current
- }
- }
+ if (isMonomorphicType) Nil
+ else atPhase(unsafeTypeParamPhase)(rawInfo.typeParams)
/** The type parameters of this symbol.
* assumption: if a type starts out as monomorphic, it will not acquire
* type parameters later.
*/
def typeParams: List[Symbol] =
- if (isMonomorphicType)
- List()
+ if (isMonomorphicType) Nil
else {
- if (validTo == NoPeriod) {
- val current = phase
- try {
- phase = phaseOf(infos.validFrom)
- rawInfo.load(this)
- } finally {
- phase = current
- }
- }
+ if (validTo == NoPeriod)
+ atPhase(phaseOf(infos.validFrom))(rawInfo load this)
+
rawInfo.typeParams
}