aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-11-28 14:24:11 +0100
committerMartin Odersky <odersky@gmail.com>2013-11-28 14:41:21 +0100
commit76f07f7a5e03ac685270c7af4aa736ca84a00f1f (patch)
tree7f59a4ed0d26792070c3d0b1e9c3f257e4b023e3
parentc39c2af036e9e69fc339b805a0869126efadae0f (diff)
downloaddotty-76f07f7a5e03ac685270c7af4aa736ca84a00f1f.tar.gz
dotty-76f07f7a5e03ac685270c7af4aa736ca84a00f1f.tar.bz2
dotty-76f07f7a5e03ac685270c7af4aa736ca84a00f1f.zip
Hoisting out commonly used values into util.common
... because this cuts down on object creations. Also, some polishings in Denotations.
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala66
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala2
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala3
-rw-r--r--src/dotty/tools/dotc/core/Types.scala15
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala3
-rw-r--r--src/dotty/tools/dotc/util/common.scala16
6 files changed, 62 insertions, 43 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index 223079570..c0b805eeb 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -14,6 +14,7 @@ import printing.Texts._
import printing.Printer
import io.AbstractFile
import config.Config
+import util.common._
import Decorators.SymbolIteratorDecorator
@@ -109,7 +110,7 @@ object Denotations {
def isTerm: Boolean = !isType
/** Is this denotation overloaded? */
- def isOverloaded = isInstanceOf[MultiDenotation]
+ final def isOverloaded = isInstanceOf[MultiDenotation]
/** The signature of the denotation */
def signature(implicit ctx: Context): Signature
@@ -124,11 +125,10 @@ object Denotations {
def exists: Boolean = true
/** If this denotation does not exist, fallback to alternative */
- def orElse(that: => Denotation) = if (this.exists) this else that
+ final def orElse(that: => Denotation) = if (this.exists) this else that
/** The set of alternative single-denotations making up this denotation */
- def alternatives: List[SingleDenotation] =
- altsWith(scala.Function.const(true))
+ final def alternatives: List[SingleDenotation] = altsWith(alwaysTrue)
/** The alternatives of this denotation that satisfy the predicate `p`. */
def altsWith(p: Symbol => Boolean): List[SingleDenotation]
@@ -167,7 +167,7 @@ object Denotations {
}
/** Return symbol in this denotation that satisfies the given predicate.
- * Return a stubsymbol denotation is a missing ref.
+ * Return a stubsymbol if denotation is a missing ref.
* Throw a `TypeError` if predicate fails to disambiguate symbol or no alternative matches.
*/
def requiredSymbol(p: Symbol => Boolean, source: AbstractFile = null)(implicit ctx: Context): Symbol =
@@ -192,7 +192,7 @@ object Denotations {
else if (exists && !(site.memberInfo(symbol) matches targetType))
NoDenotation
else
- this.asInstanceOf[SingleDenotation]
+ asSingleDenotation
/** Form a denotation by conjoining with denotation `that` */
def & (that: Denotation, pre: Type)(implicit ctx: Context): Denotation = {
@@ -266,11 +266,15 @@ object Denotations {
def sym1Accessible = sym1.isAccessibleFrom(pre)
if (info2 <:< info1 && sym1Accessible) denot1
else {
+ val owner2 = sym2.owner
+ /** Determine a symbol which is overridden by both sym1 and sym2.
+ * Preference is given to accessible symbols.
+ */
def lubSym(overrides: Iterator[Symbol], previous: Symbol): Symbol =
if (!overrides.hasNext) previous
else {
val candidate = overrides.next
- if (sym2.owner.isSubClass(candidate.owner))
+ if (owner2 derivesFrom candidate.owner)
if (candidate isAccessibleFrom pre) candidate
else lubSym(overrides, previous orElse candidate)
else
@@ -285,31 +289,24 @@ object Denotations {
}
else NoDenotation
- def throwError = throw new MatchError(s"$this | $that")
-
if (this eq that) this
else if (!this.exists) this
else if (!that.exists) that
else this match {
case denot1 @ MultiDenotation(denot11, denot12) =>
denot1.derivedMultiDenotation(denot11 | (that, pre), denot12 | (that, pre))
- case _ =>
+ case denot1: SingleDenotation =>
that match {
case denot2 @ MultiDenotation(denot21, denot22) =>
denot2.derivedMultiDenotation(this | (denot21, pre), this | (denot22, pre))
case denot2: SingleDenotation =>
- this match {
- case denot1: SingleDenotation =>
- unionDenot(denot1, denot2)
- case _ =>
- throwError
- }
- case _ =>
- throwError
+ unionDenot(denot1, denot2)
}
}
}
+ final def asSingleDenotation = asInstanceOf[SingleDenotation]
+
def toText(printer: Printer): Text = printer.toText(this)
}
@@ -356,9 +353,11 @@ object Denotations {
/** A non-overloaded denotation */
abstract class SingleDenotation extends Denotation with PreDenotation {
def hasUniqueSym: Boolean
- override def isType = info.isInstanceOf[TypeType]
- override def signature(implicit ctx: Context): Signature = {
- if (isType) Signature.NotAMethod
+ protected def newLikeThis(symbol: Symbol, info: Type): SingleDenotation
+
+ def isType = info.isInstanceOf[TypeType]
+ final def signature(implicit ctx: Context): Signature = {
+ if (isType) Signature.NotAMethod // don't force info if this is a type SymDenotation
else info match {
case info: SignedType => info.signature
case _ => Signature.NotAMethod
@@ -369,7 +368,6 @@ object Denotations {
if ((symbol eq this.symbol) && (info eq this.info)) this
else newLikeThis(symbol, info)
- protected def newLikeThis(symbol: Symbol, info: Type): SingleDenotation = this
def orElse(that: => SingleDenotation) = if (this.exists) this else that
@@ -432,7 +430,6 @@ object Denotations {
* is still a member of its enclosing package, then the whole flock
* is brought forward to be valid in the new runId. Otherwise
* the symbol is stale, which constitutes an internal error.
- * TODO: Ensure that a subclass is renewed whenever one of its parents is.
*/
def current(implicit ctx: Context): SingleDenotation = {
val currentPeriod = ctx.period
@@ -454,8 +451,7 @@ object Denotations {
if (currentPeriod.code > valid.code) {
// search for containing period as long as nextInRun increases.
var next = nextInRun
- while (next.validFor.code > valid.code &&
- !(next.validFor contains currentPeriod)) {
+ while (next.validFor.code > valid.code && !(next.validFor contains currentPeriod)) {
cur = next
next = next.nextInRun
}
@@ -507,8 +503,7 @@ object Denotations {
final def first = this
final def toDenot(pre: Type)(implicit ctx: Context) = this
- final def containsSym(sym: Symbol): Boolean =
- hasUniqueSym && (symbol eq sym)
+ final def containsSym(sym: Symbol): Boolean = hasUniqueSym && (symbol eq sym)
final def containsSig(sig: Signature)(implicit ctx: Context) =
exists && (signature matches sig)
final def filterWithPredicate(p: SingleDenotation => Boolean): SingleDenotation =
@@ -545,7 +540,7 @@ object Denotations {
initValidFor: Period) extends SingleDenotation {
validFor = initValidFor
override def hasUniqueSym: Boolean = true
- override protected def newLikeThis(s: Symbol, i: Type): SingleDenotation = new UniqueRefDenotation(s, i, validFor)
+ protected def newLikeThis(s: Symbol, i: Type): SingleDenotation = new UniqueRefDenotation(s, i, validFor)
}
class JointRefDenotation(
@@ -554,7 +549,7 @@ object Denotations {
initValidFor: Period) extends SingleDenotation {
validFor = initValidFor
override def hasUniqueSym = false
- override protected def newLikeThis(s: Symbol, i: Type): SingleDenotation = new JointRefDenotation(s, i, validFor)
+ protected def newLikeThis(s: Symbol, i: Type): SingleDenotation = new JointRefDenotation(s, i, validFor)
}
class ErrorDenotation(implicit ctx: Context) extends SingleDenotation {
@@ -563,10 +558,18 @@ object Denotations {
val symbol = NoSymbol
val info = NoType
validFor = Period.allInRun(ctx.runId)
+ protected def newLikeThis(s: Symbol, i: Type): SingleDenotation = this
}
+ /** An error denotation that provides more info about the missing reference.
+ * Produced by staticRef, consumed by requiredSymbol.
+ */
case class MissingRef(val owner: SingleDenotation, name: Name)(implicit ctx: Context) extends ErrorDenotation
+ /** An error denotation that provides more info about alternatives
+ * that were found but that do not qualify.
+ * Produced by staticRef, consumed by requiredSymbol.
+ */
case class NoQualifyingRef(alts: List[SingleDenotation])(implicit ctx: Context) extends ErrorDenotation
// --------------- PreDenotations -------------------------------------------------
@@ -591,6 +594,7 @@ object Denotations {
/** Group contains a denotation with given signature */
def containsSig(sig: Signature)(implicit ctx: Context): Boolean
+ /** Keep only those denotations in this group which satisfy predicate `p`. */
def filterWithPredicate(p: SingleDenotation => Boolean): PreDenotation
/** Keep only those denotations in this group which have a signature
@@ -680,8 +684,7 @@ object Denotations {
if (point > 0) recur(path.toTermName, point).disambiguate(_.info.isParameterless)
else if (path.isTermName) defn.RootClass.denot
else defn.EmptyPackageClass.denot
- if (!owner.exists) owner
- else {
+ if (owner.exists) {
val name = path slice (point + 1, len)
val result = owner.info.member(name)
if (result ne NoDenotation) result
@@ -691,6 +694,7 @@ object Denotations {
else MissingRef(owner, name)
}
}
+ else owner
}
recur(path, path.length)
}
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 2a0b9e9ce..f0ba4ad12 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -694,7 +694,7 @@ object SymDenotations {
// ----- copies ------------------------------------------------------
- override protected def newLikeThis(s: Symbol, i: Type): SingleDenotation = new UniqueRefDenotation(s, i, validFor)
+ protected def newLikeThis(s: Symbol, i: Type): SingleDenotation = new UniqueRefDenotation(s, i, validFor)
/** Copy this denotation, overriding selective fields */
final def copySymDenotation(
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala
index 66b21eb5e..fd661aab1 100644
--- a/src/dotty/tools/dotc/core/TypeApplications.scala
+++ b/src/dotty/tools/dotc/core/TypeApplications.scala
@@ -6,6 +6,7 @@ import Contexts._
import Symbols._
import Decorators._
import util.Stats._
+import util.common._
import Names._
import Flags._
import util.Positions.Position
@@ -102,7 +103,7 @@ class TypeApplications(val self: Type) extends AnyVal {
if (tsym.isClass || !self.typeSymbol.isCompleting) typeParams
else {
ctx.warning("encountered F-bounded higher-kinded type parameters; assuming they are invariant")
- defn.hkTrait(args map Function.const(0)).typeParams
+ defn.hkTrait(args map alwaysZero).typeParams
}
if (args.isEmpty) self
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 55d1cf45f..aba462456 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -2,6 +2,7 @@ package dotty.tools.dotc
package core
import util.HashSet
+import util.common._
import Symbols._
import Flags._
import Names._
@@ -187,7 +188,7 @@ object Types {
/** The parts of this type which are type or term refs */
final def namedParts(implicit ctx: Context): collection.Set[NamedType] =
- namedPartsWith(Function.const(true))
+ namedPartsWith(alwaysTrue)
/** The parts of this type which are type or term refs and which
* satisfy predicate `p`.
@@ -354,7 +355,7 @@ object Types {
if (name eq tp.refinedName) {
val rinfo = tp.refinedInfo.substThis(tp, pre)
if (name.isTypeName) // simplified case that runs more efficiently
- pdenot.asInstanceOf[SingleDenotation].derivedSingleDenotation(pdenot.symbol, rinfo)
+ pdenot.asSingleDenotation.derivedSingleDenotation(pdenot.symbol, rinfo)
else
pdenot & (new JointRefDenotation(NoSymbol, rinfo, Period.allInRun(ctx.runId)), pre)
} else pdenot
@@ -432,13 +433,13 @@ object Types {
/** The set of abstract type members of this type. */
final def abstractTypeMembers(implicit ctx: Context): Seq[SingleDenotation] = track("abstractTypeMembers") {
memberDenots(abstractTypeNameFilter,
- (name, buf) => buf += member(name).asInstanceOf[SingleDenotation])
+ (name, buf) => buf += member(name).asSingleDenotation)
}
/** The set of type members of this type */
final def typeMembers(implicit ctx: Context): Seq[SingleDenotation] = track("typeMembers") {
memberDenots(typeNameFilter,
- (name, buf) => buf += member(name).asInstanceOf[SingleDenotation])
+ (name, buf) => buf += member(name).asSingleDenotation)
}
/** The set of implicit members of this type */
@@ -1373,7 +1374,7 @@ object Types {
private[this] var mySignatureRunId: Int = NoRunId
protected def computeSignature(implicit ctx: Context): Signature
-
+
protected def resultSignature(implicit ctx: Context) = resultType match {
case rtp: SignedType => rtp.signature
case tp => Signature(tp)
@@ -2221,10 +2222,6 @@ object Types {
class MergeError(msg: String) extends FatalTypeError(msg)
- // ----- Values hoisted out for performance -----------------------------
-
- val emptyDNF = (Nil, Set[Name]()) :: Nil
-
// ----- Debug ---------------------------------------------------------
var debugTrace = false
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index e4081f633..5fd995839 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -23,6 +23,7 @@ import ErrorReporting._
import Inferencing.{FunProto, PolyProto, Compatibility, normalize}
import EtaExpansion.etaExpand
import util.Positions._
+import util.common._
import util.SourcePosition
import collection.mutable
import annotation.tailrec
@@ -482,7 +483,7 @@ class Typer extends Namer with Applications with Implicits {
val MethodType(_, paramTypes) = meth.info
paramTypes
case _ =>
- params map Function.const(WildcardType)
+ params map alwaysWildcardType
}
val inferredParams: List[untpd.ValDef] =
for ((param, formal) <- params zip protoFormals) yield
diff --git a/src/dotty/tools/dotc/util/common.scala b/src/dotty/tools/dotc/util/common.scala
new file mode 100644
index 000000000..5f133b079
--- /dev/null
+++ b/src/dotty/tools/dotc/util/common.scala
@@ -0,0 +1,16 @@
+package dotty.tools.dotc
+package util
+
+import core.Names.Name
+import core.Types.WildcardType
+
+/** Common values hoisted out for performance */
+object common {
+
+ val emptyDNF = (Nil, Set[Name]()) :: Nil
+
+ val alwaysTrue = Function.const(true) _
+ val alwaysZero = Function.const(0) _
+ val alwaysWildcardType = Function.const(WildcardType) _
+
+} \ No newline at end of file