From 76f07f7a5e03ac685270c7af4aa736ca84a00f1f Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 28 Nov 2013 14:24:11 +0100 Subject: Hoisting out commonly used values into util.common ... because this cuts down on object creations. Also, some polishings in Denotations. --- src/dotty/tools/dotc/core/Denotations.scala | 66 +++++++++++++----------- src/dotty/tools/dotc/core/SymDenotations.scala | 2 +- src/dotty/tools/dotc/core/TypeApplications.scala | 3 +- src/dotty/tools/dotc/core/Types.scala | 15 +++--- src/dotty/tools/dotc/typer/Typer.scala | 3 +- src/dotty/tools/dotc/util/common.scala | 16 ++++++ 6 files changed, 62 insertions(+), 43 deletions(-) create mode 100644 src/dotty/tools/dotc/util/common.scala (limited to 'src/dotty/tools/dotc') 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 -- cgit v1.2.3