diff --git a/src/dotty/tools/dotc/config/Settings.scala b/src/dotty/tools/dotc/config/Settings.scala index c1ac1f83a53d..3572a28dd0aa 100644 --- a/src/dotty/tools/dotc/config/Settings.scala +++ b/src/dotty/tools/dotc/config/Settings.scala @@ -33,7 +33,7 @@ object Settings { } } - case class ArgsSummary( + final case class ArgsSummary( sstate: SettingsState, arguments: List[String], errors: List[String]) { @@ -42,7 +42,7 @@ object Settings { ArgsSummary(sstate, arguments, errors :+ msg) } - case class Setting[T: ClassTag] private[Settings] ( + final case class Setting[T: ClassTag] private[Settings] ( name: String, description: String, default: T, diff --git a/src/dotty/tools/dotc/core/Annotations.scala b/src/dotty/tools/dotc/core/Annotations.scala index 2ced6cb8a462..f7c66099069d 100644 --- a/src/dotty/tools/dotc/core/Annotations.scala +++ b/src/dotty/tools/dotc/core/Annotations.scala @@ -4,14 +4,14 @@ import Symbols._, Types._, Positions._, Contexts._, Constants._, TypedTrees.tpd. object Annotations { - abstract class Annotation { + sealed abstract class Annotation { def tree: Tree - def symbol(implicit ctx: Context): Symbol = tree.tpe.typeSymbol - def matches(cls: Symbol)(implicit ctx: Context): Boolean = symbol.isNonBottomSubClass(cls) - def appliesToModule: Boolean = ??? + final def symbol(implicit ctx: Context): Symbol = tree.tpe.typeSymbol + final def matches(cls: Symbol)(implicit ctx: Context): Boolean = symbol.isNonBottomSubClass(cls) + final def appliesToModule: Boolean = ??? } - case class ConcreteAnnotation(val tree: Tree) extends Annotation + final case class ConcreteAnnotation(tree: Tree) extends Annotation object Annotation { diff --git a/src/dotty/tools/dotc/core/Constants.scala b/src/dotty/tools/dotc/core/Constants.scala index 825ce60f1f2e..616124004a0e 100644 --- a/src/dotty/tools/dotc/core/Constants.scala +++ b/src/dotty/tools/dotc/core/Constants.scala @@ -21,7 +21,7 @@ object Constants { // For supporting java enumerations inside java annotations (see ClassfileParser) final val EnumTag = 13 - case class Constant(value: Any) { + final case class Constant(value: Any) { import java.lang.Double.doubleToRawLongBits import java.lang.Float.floatToRawIntBits diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala index 9ca111dc0468..3aae8ed890b4 100644 --- a/src/dotty/tools/dotc/core/Contexts.scala +++ b/src/dotty/tools/dotc/core/Contexts.scala @@ -35,74 +35,74 @@ object Contexts { * of all class fields of type context; allow them only in whitelisted * classes (which should be short-lived). */ - abstract class Context extends Periods - with Substituters - with TypeOps - with Printers - with Symbols - with Cloneable { - implicit val ctx: Context = this + sealed abstract class Context extends Periods + with Substituters + with TypeOps + with Printers + with Symbols + with Cloneable { + final implicit val ctx: Context = this val base: ContextBase - private[this] var _underlying: Context = _ - protected def underlying_=(underlying: Context) = _underlying = underlying - def underlying: Context = _underlying + final private[this] var _underlying: Context = _ + protected final def underlying_=(underlying: Context) = _underlying = underlying + final def underlying: Context = _underlying - private[this] var _period: Period = _ - protected def period_=(period: Period) = _period = period - def period: Period = _period + final private[this] var _period: Period = _ + protected final def period_=(period: Period) = _period = period + final def period: Period = _period - private[this] var _constraints: Constraints = _ - protected def constraints_=(constraints: Constraints) = _constraints = constraints - def constraints: Constraints = _constraints + final private[this] var _constraints: Constraints = _ + protected final def constraints_=(constraints: Constraints) = _constraints = constraints + final def constraints: Constraints = _constraints - private[this] var _typeComparer: TypeComparer = _ - protected def typeComparer_=(typeComparer: TypeComparer) = _typeComparer = typeComparer + final private[this] var _typeComparer: TypeComparer = _ + protected final def typeComparer_=(typeComparer: TypeComparer) = _typeComparer = typeComparer - def typeComparer: TypeComparer = { + final def typeComparer: TypeComparer = { if ((_typeComparer eq underlying.typeComparer) && (constraints ne underlying.constraints)) _typeComparer = new TypeComparer(this) _typeComparer } - private[this] var _position: Position = _ - protected def position_=(position: Position) = _position = position - def position: Position = _position + final private[this] var _position: Position = _ + protected final def position_=(position: Position) = _position = position + final def position: Position = _position private[this] var _plainPrinter: Context => Printer = _ - protected def plainPrinter_=(plainPrinter: Context => Printer) = _plainPrinter = plainPrinter - def plainPrinter: Context => Printer = _plainPrinter + protected final def plainPrinter_=(plainPrinter: Context => Printer) = _plainPrinter = plainPrinter + final def plainPrinter: Context => Printer = _plainPrinter private[this] var _refinedPrinter: Context => Printer = _ - protected def refinedPrinter_=(refinedPrinter: Context => Printer) = _refinedPrinter = refinedPrinter - def refinedPrinter: Context => Printer = _refinedPrinter + protected final def refinedPrinter_=(refinedPrinter: Context => Printer) = _refinedPrinter = refinedPrinter + final def refinedPrinter: Context => Printer = _refinedPrinter - def printer = if (base.settings.debug.value) plainPrinter else refinedPrinter + final def printer = if (base.settings.debug.value) plainPrinter else refinedPrinter private[this] var _owner: Symbol = _ - protected def owner_=(owner: Symbol) = _owner = owner - def owner: Symbol = _owner + protected final def owner_=(owner: Symbol) = _owner = owner + final def owner: Symbol = _owner private[this] var _sstate: SettingsState = _ - protected def sstate_=(sstate: SettingsState) = _sstate = sstate - def sstate: SettingsState = _sstate - - def phase: Phase = ??? // phase(period.phaseId) - def enclClass: Context = ??? - def erasedTypes: Boolean = ??? - def debug: Boolean = ??? - def error(msg: String): Unit = ??? - def warning(msg: String): Unit = ??? - def log(msg: String): Unit = ??? - def debuglog(msg: String): Unit = ??? - def inform(msg: String) = ??? - def informTime(msg: String, start: Long): Unit = ??? - def beforeTyper[T](op: => T): T = ??? - - private var _condensed: CondensedContext = null - def condensed: CondensedContext = { + protected final def sstate_=(sstate: SettingsState) = _sstate = sstate + final def sstate: SettingsState = _sstate + + final def phase: Phase = ??? // phase(period.phaseId) + final def enclClass: Context = ??? + final def erasedTypes: Boolean = ??? + final def debug: Boolean = ??? + final def error(msg: String): Unit = ??? + final def warning(msg: String): Unit = ??? + final def log(msg: String): Unit = ??? + final def debuglog(msg: String): Unit = ??? + final def inform(msg: String) = ??? + final def informTime(msg: String, start: Long): Unit = ??? + final def beforeTyper[T](op: => T): T = ??? + + private final var _condensed: CondensedContext = null + final def condensed: CondensedContext = { if (_condensed == null) _condensed = base.initialCtx.fresh .withPeriod(period) @@ -112,7 +112,7 @@ object Contexts { _condensed } - def fresh: FreshContext = { + final def fresh: FreshContext = { val newctx = super.clone.asInstanceOf[FreshContext] newctx.underlying = this newctx._condensed = null @@ -120,20 +120,20 @@ object Contexts { } } - abstract class CondensedContext extends Context - - abstract class FreshContext extends CondensedContext { - def withPeriod(period: Period): this.type = { this.period = period; this } - def withPhase(pid: PhaseId): this.type = withPeriod(Period(runId, pid)) - def withConstraints(constraints: Constraints): this.type = { this.constraints = constraints; this } - def withPlainPrinter(printer: Context => Printer): this.type = { this.plainPrinter = printer; this } - def withRefinedPrinter(printer: Context => Printer): this.type = { this.refinedPrinter = printer; this } - def withOwner(owner: Symbol): this.type = { this.owner = owner; this } - def withSettings(sstate: SettingsState): this.type = { this.sstate = sstate; this } - def withDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this } + sealed abstract class CondensedContext extends Context + + sealed abstract class FreshContext extends CondensedContext { + final def withPeriod(period: Period): this.type = { this.period = period; this } + final def withPhase(pid: PhaseId): this.type = withPeriod(Period(runId, pid)) + final def withConstraints(constraints: Constraints): this.type = { this.constraints = constraints; this } + final def withPlainPrinter(printer: Context => Printer): this.type = { this.plainPrinter = printer; this } + final def withRefinedPrinter(printer: Context => Printer): this.type = { this.refinedPrinter = printer; this } + final def withOwner(owner: Symbol): this.type = { this.owner = owner; this } + final def withSettings(sstate: SettingsState): this.type = { this.sstate = sstate; this } + final def withDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this } } - private class InitialContext(val base: ContextBase) extends FreshContext { + private final class InitialContext(val base: ContextBase) extends FreshContext { underlying = NoContext period = Nowhere constraints = Map() @@ -146,10 +146,10 @@ object Contexts { lazy val base = unsupported("base") } - class ContextBase extends ContextState - with Transformers.TransformerBase - with Printers.PrinterBase - with Denotations.DenotationsBase { + final class ContextBase extends ContextState + with Transformers.TransformerBase + with Printers.PrinterBase + with Denotations.DenotationsBase { val settings = new ScalaSettings @@ -167,26 +167,26 @@ object Contexts { } /** Mutable state of a context base, collected into a common class */ - class ContextState { + abstract class ContextState { // Symbols state /** A counter for unique ids */ - private[core] var _nextId = 0 + private[core] final var _nextId = 0 - def nextId = { _nextId += 1; _nextId } + final def nextId = { _nextId += 1; _nextId } /** A map from a superclass id to the type-ref of the class that has it */ - private[core] var classOfId = new Array[TypeRef](InitialSuperIdsSize) + private[core] final var classOfId = new Array[TypeRef](InitialSuperIdsSize) /** A map from a the type-ref of a superclass to its superclass id */ - private[core] val superIdOfClass = new mutable.HashMap[TypeRef, Int] + private[core] final val superIdOfClass = new mutable.HashMap[TypeRef, Int] /** The last allocate superclass id */ - private[core] var lastSuperId = -1 + private[core] final var lastSuperId = -1 /** Allocate and return next free superclass id */ - private[core] def nextSuperId: Int = { + private[core] final def nextSuperId: Int = { lastSuperId += 1; if (lastSuperId >= classOfId.length) { val tmp = new Array[TypeRef](classOfId.length * 2) @@ -197,16 +197,16 @@ object Contexts { } // SymDenotations state - private[core] val uniqueBits = new util.HashSet[BitSet]("superbits", 1024) + private[core] final val uniqueBits = new util.HashSet[BitSet]("superbits", 1024) // Types state - private[core] val uniques = new util.HashSet[Type]("uniques", initialUniquesCapacity) { + private[core] final val uniques = new util.HashSet[Type]("uniques", initialUniquesCapacity) { override def hash(x: Type): Int = x.hash } // TypeOps state - private[core] var volatileRecursions: Int = 0 - private[core] val pendingVolatiles = new mutable.HashSet[Type] + private[core] final var volatileRecursions: Int = 0 + private[core] final val pendingVolatiles = new mutable.HashSet[Type] } object Context { diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala index 935369091588..ad511217f467 100644 --- a/src/dotty/tools/dotc/core/Definitions.scala +++ b/src/dotty/tools/dotc/core/Definitions.scala @@ -19,7 +19,7 @@ object Definitions { val MaxFunctionArity, MaxTupleArity = 22 } -class Definitions(implicit ctx: Context) { +final class Definitions(implicit ctx: Context) { import Definitions._ import ctx.{requiredClass, requiredModule, requiredPackage} diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala index c7c257f5cc81..b5560d12976a 100644 --- a/src/dotty/tools/dotc/core/Denotations.scala +++ b/src/dotty/tools/dotc/core/Denotations.scala @@ -120,7 +120,7 @@ object Denotations { * * Then the denotation of `y` is `SingleDenotation(NoSymbol, A | B)`. */ - abstract class Denotation extends DotClass { + sealed abstract class Denotation extends DotClass { /** The referencing symbol, exists only for non-overloaded denotations */ def symbol: Symbol @@ -155,10 +155,10 @@ object Denotations { def exists: Boolean = true - 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 alts(p: Symbol => Boolean)(implicit ctx: Context): List[SingleDenotation] = + final def alts(p: Symbol => Boolean)(implicit ctx: Context): List[SingleDenotation] = altsWith(scala.Function.const(true)) /** The alternatives of this denotation that satisfy the predicate `p`. */ @@ -179,7 +179,7 @@ object Denotations { * single-denotations that do not satisfy the predicate are left alone * (whereas suchThat would map them to NoDenotation). */ - def disambiguate(p: Symbol => Boolean)(implicit ctx: Context): SingleDenotation = this match { + final def disambiguate(p: Symbol => Boolean)(implicit ctx: Context): SingleDenotation = this match { case sdenot: SingleDenotation => sdenot case mdenot => suchThat(p) } @@ -188,7 +188,7 @@ object Denotations { * Throw a `TypeError` if predicate fails to disambiguate symbol. * Return a stubsymbol if no alternative satisfies the predicate. */ - def requiredSymbol(p: Symbol => Boolean, source: AbstractFile = null)(implicit ctx: Context): Symbol = { + final def requiredSymbol(p: Symbol => Boolean, source: AbstractFile = null)(implicit ctx: Context): Symbol = { val sym = disambiguate(p).symbol if (sym.exists) sym else { val owner = if (firstSym.exists) firstSym.owner else NoSymbol @@ -197,7 +197,7 @@ object Denotations { } /** Form a denotation by conjoining with denotation `that` */ - def &(that: Denotation)(implicit ctx: Context): Denotation = + final def &(that: Denotation)(implicit ctx: Context): Denotation = if (this eq that) this else if (!this.exists) that else if (!that.exists) this @@ -241,7 +241,7 @@ object Denotations { } else NoDenotation } - def |(that: Denotation)(pre: Type)(implicit ctx: Context): Denotation = { + final def |(that: Denotation)(pre: Type)(implicit ctx: Context): Denotation = { def lubSym(sym1: Symbol, sym2: Symbol): Symbol = { def qualifies(sym: Symbol) = @@ -278,13 +278,13 @@ object Denotations { } } - def show(implicit ctx: Context): String = ctx.show(this) + final def show(implicit ctx: Context): String = ctx.show(this) } /** The class of overloaded denotations * @param variants The overloaded variants indexed by thheir signatures. */ - case class MultiDenotation(denot1: Denotation, denot2: Denotation) extends Denotation { + final case class MultiDenotation(denot1: Denotation, denot2: Denotation) extends Denotation { final override def isType = false def derivedMultiDenotation(d1: Denotation, d2: Denotation) = if ((d1 eq denot1) && (d2 eq denot2)) this else MultiDenotation(d1, d2) @@ -312,8 +312,8 @@ object Denotations { } abstract class SingleDenotation extends Denotation with DenotationSet { - override def isType = info.isInstanceOf[TypeType] - override def signature: Signature = { + def isType = info.isInstanceOf[TypeType] + override final def signature: Signature = { def sig(tp: Type): Signature = tp match { case tp: PolyType => tp.resultType match { @@ -325,33 +325,33 @@ object Denotations { } if (isType) NullSignature else sig(info) } - def firstSym(implicit ctx: Context): Symbol = symbol + final def firstSym(implicit ctx: Context): Symbol = symbol - def derivedSingleDenotation(s: Symbol, i: Type): SingleDenotation = + final def derivedSingleDenotation(s: Symbol, i: Type): SingleDenotation = if ((s eq symbol) && (i eq info)) this else newLikeThis(s, i) protected def newLikeThis(s: Symbol, i: Type): SingleDenotation = this - def orElse(that: => SingleDenotation) = if (this.exists) this else that + final def orElse(that: => SingleDenotation) = if (this.exists) this else that - def altsWith(p: Symbol => Boolean)(implicit ctx: Context): List[SingleDenotation] = + final def altsWith(p: Symbol => Boolean)(implicit ctx: Context): List[SingleDenotation] = if (p(symbol)) this :: Nil else Nil - def suchThat(p: Symbol => Boolean)(implicit ctx: Context): SingleDenotation = + final def suchThat(p: Symbol => Boolean)(implicit ctx: Context): SingleDenotation = if (p(symbol)) this else NoDenotation - def hasAltWith(p: Symbol => Boolean)(implicit ctx: Context): Boolean = + final def hasAltWith(p: Symbol => Boolean)(implicit ctx: Context): Boolean = p(symbol) - def atSignature(sig: Signature): SingleDenotation = + final def atSignature(sig: Signature): SingleDenotation = if (sig == signature) this else NoDenotation // ------ Transformations ----------------------------------------- private[this] var _validFor: Period = Nowhere - def validFor = _validFor - def validFor_=(p: Period) = + final def validFor = _validFor + final def validFor_=(p: Period) = _validFor = p /** The next SingleDenotation in this run, with wrap-around from last to first. @@ -368,18 +368,18 @@ object Denotations { * 2) the union of all validity periods must be a contiguous * interval starting in FirstPhaseId. */ - var nextInRun: SingleDenotation = this + final var nextInRun: SingleDenotation = this /** The version of this SingleDenotation that was valid in the first phase * of this run. */ - def initial: SingleDenotation = { + final def initial: SingleDenotation = { var current = nextInRun while (current.validFor.code > this._validFor.code) current = current.nextInRun current } - def current(implicit ctx: Context): SingleDenotation = { + final def current(implicit ctx: Context): SingleDenotation = { val currentPeriod = ctx.period val valid = _validFor var current = this @@ -421,35 +421,35 @@ object Denotations { // ------ DenotationSet ops ---------------------------------------------- - def first = this - def toDenot(implicit ctx: Context) = this - def containsSig(sig: Signature)(implicit ctx: Context) = + final def first = this + final def toDenot(implicit ctx: Context) = this + final def containsSig(sig: Signature)(implicit ctx: Context) = signature == sig - def filterDisjoint(denots: DenotationSet)(implicit ctx: Context): DenotationSet = + final def filterDisjoint(denots: DenotationSet)(implicit ctx: Context): DenotationSet = if (denots.containsSig(signature)) NoDenotation else this - def filterExcluded(flags: FlagSet)(implicit ctx: Context): DenotationSet = + final def filterExcluded(flags: FlagSet)(implicit ctx: Context): DenotationSet = if (symbol is flags) NoDenotation else this - def filterAccessibleFrom(pre: Type)(implicit ctx: Context): DenotationSet = + final def filterAccessibleFrom(pre: Type)(implicit ctx: Context): DenotationSet = if (symbol.isAccessibleFrom(pre)) this else NoDenotation - def asSeenFrom(pre: Type, owner: Symbol)(implicit ctx: Context): DenotationSet = + final def asSeenFrom(pre: Type, owner: Symbol)(implicit ctx: Context): DenotationSet = derivedSingleDenotation(symbol, info.asSeenFrom(pre, owner)) } - class UniqueRefDenotation(val symbol: Symbol, + final class UniqueRefDenotation(val symbol: Symbol, val info: Type, initValidFor: Period) extends SingleDenotation { validFor = initValidFor override protected def newLikeThis(s: Symbol, i: Type): SingleDenotation = new UniqueRefDenotation(s, i, validFor) } - class JointRefDenotation(val symbol: Symbol, + final class JointRefDenotation(val symbol: Symbol, val info: Type, initValidFor: Period) extends SingleDenotation { validFor = initValidFor override protected def newLikeThis(s: Symbol, i: Type): SingleDenotation = new JointRefDenotation(s, i, validFor) } - class ErrorDenotation(implicit ctx: Context) extends SingleDenotation { + final class ErrorDenotation(implicit ctx: Context) extends SingleDenotation { val symbol = NoSymbol val info = NoType validFor = Period.allInRun(ctx.runId) @@ -469,13 +469,13 @@ object Denotations { def filterExcluded(flags: FlagSet)(implicit ctx: Context): DenotationSet def filterAccessibleFrom(pre: Type)(implicit ctx: Context): DenotationSet def asSeenFrom(pre: Type, owner: Symbol)(implicit ctx: Context): DenotationSet - def union(that: DenotationSet) = + final def union(that: DenotationSet) = if (!this.exists) that else if (that.exists) this else DenotUnion(this, that) } - case class DenotUnion(denots1: DenotationSet, denots2: DenotationSet) extends DenotationSet { + final case class DenotUnion(denots1: DenotationSet, denots2: DenotationSet) extends DenotationSet { assert(denots1.exists && denots2.exists) private def derivedUnion(s1: DenotationSet, s2: DenotationSet) = if (!s1.exists) s2 @@ -501,7 +501,7 @@ object Denotations { /** Creation method for denotations */ trait DenotationsBase { this: ContextBase => - def staticRef(path: Name)(implicit ctx: Context): Denotation = { + final def staticRef(path: Name)(implicit ctx: Context): Denotation = { def recur(path: Name, len: Int): Denotation = { val point = path.lastIndexOf('.', len - 1) val owner = @@ -523,7 +523,7 @@ object Denotations { recur(path, path.length) } - def missingHook(owner: Symbol, name: Name)(implicit ctx: Context): Symbol = + final def missingHook(owner: Symbol, name: Name)(implicit ctx: Context): Symbol = if (owner.isPackage && name.isTermName) ctx.newPackageSymbols(owner, name.asTermName)._1.entered else diff --git a/src/dotty/tools/dotc/core/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala index 710771fa5075..a527fbafc675 100644 --- a/src/dotty/tools/dotc/core/Flags.scala +++ b/src/dotty/tools/dotc/core/Flags.scala @@ -105,7 +105,7 @@ object Flags { * conjunctively. I.e. for a flag conjunction `fc`, * `x is fc` tests whether `x` contains all flags in `fc`. */ - case class FlagConjunction(bits: Long) + final case class FlagConjunction(bits: Long) private final val TYPESHIFT = 2 private final val TERMindex = 0 diff --git a/src/dotty/tools/dotc/core/Names.scala b/src/dotty/tools/dotc/core/Names.scala index 8a13964e34ed..d9759857728d 100644 --- a/src/dotty/tools/dotc/core/Names.scala +++ b/src/dotty/tools/dotc/core/Names.scala @@ -21,12 +21,12 @@ object Names { /** A name is essentially a string, with three differences * 1. Names belong in one of two universes: they are type names or term names. * The same string can correspond both to a type name and to a term name. - * 2. NAmes are hash-consed. Two names + * 2. Names are hash-consed. Two names * representing the same string in the same universe are always reference identical. * 3. Names are intended to be encoded strings. @see dotc.util.NameTransformer. * The encoding will be applied when converting a string to a name. */ - abstract class Name extends DotClass + sealed abstract class Name extends DotClass with PreName with Seq[Char] with IndexedSeqOptimized[Char, Name] { @@ -65,7 +65,7 @@ object Names { */ def fromChars(cs: Array[Char], offset: Int, len: Int): ThisName - override def toString = new String(chrs, start, length) + override final def toString = new String(chrs, start, length) /** Write to UTF8 representation of this name to given character array. * Start copying to index `to`. Return index of next free byte in array. @@ -79,16 +79,16 @@ object Names { } /** Convert to string replacing operator symbols by corresponding \$op_name. */ - def decode: String = NameTransformer.decode(toString) + final def decode: String = NameTransformer.decode(toString) - def ++ (other: Name): ThisName = ++ (other.toString) + final def ++ (other: Name): ThisName = ++ (other.toString) - def ++ (other: String): ThisName = { + final def ++ (other: String): ThisName = { val s = toString + other fromChars(s.toCharArray, 0, s.length) } - def replace(from: Char, to: Char): ThisName = { + final def replace(from: Char, to: Char): ThisName = { val cs = new Array[Char](length) Array.copy(chrs, start, cs, 0, length) for (i <- 0 until length) { @@ -100,27 +100,27 @@ object Names { // ----- Collections integration ------------------------------------- - override protected[this] def thisCollection: WrappedString = new WrappedString(repr.toString) - override protected[this] def toCollection(repr: Name): WrappedString = new WrappedString(repr.toString) + override protected[this] final def thisCollection: WrappedString = new WrappedString(repr.toString) + override protected[this] final def toCollection(repr: Name): WrappedString = new WrappedString(repr.toString) override protected[this] def newBuilder: Builder[Char, Name] = unsupported("newBuilder") - override def apply(index: Int): Char = chrs(start + index) + override final def apply(index: Int): Char = chrs(start + index) - override def slice(from: Int, until: Int): ThisName = + override final def slice(from: Int, until: Int): ThisName = fromChars(chrs, start + from, start + until) - override def seq = toCollection(this) + override final def seq = toCollection(this) } - class TermName(val start: Int, val length: Int, private[Names] var next: TermName) extends Name { + sealed class TermName(val start: Int, val length: Int, private[Names] var next: TermName) extends Name { type ThisName = TermName - def isTypeName = false - def isTermName = true + final def isTypeName = false + final def isTermName = true @volatile private[this] var _typeName: TypeName = null - def toTypeName: TypeName = { + final def toTypeName: TypeName = { if (_typeName == null) synchronized { if (_typeName == null) @@ -128,35 +128,35 @@ object Names { } _typeName } - def toTermName = this - def asTypeName = throw new ClassCastException(this + " is not a type name") - def asTermName = this + final def toTermName = this + final def asTypeName = throw new ClassCastException(this + " is not a type name") + final def asTermName = this - def toLocalName: LocalName = toTypeName.toLocalName + final def toLocalName: LocalName = toTypeName.toLocalName - override protected[this] def newBuilder: Builder[Char, Name] = termNameBuilder + override protected[this] final def newBuilder: Builder[Char, Name] = termNameBuilder - def fromChars(cs: Array[Char], offset: Int, len: Int): TermName = termName(cs, offset, len) + final def fromChars(cs: Array[Char], offset: Int, len: Int): TermName = termName(cs, offset, len) } class TypeName(val start: Int, val length: Int, initialTermName: TermName) extends Name { type ThisName = TypeName - def isTypeName = true - def isTermName = false - def toTypeName = this - def asTypeName = this - def asTermName = throw new ClassCastException(this + " is not a term name") + final def isTypeName = true + final def isTermName = false + final def toTypeName = this + final def asTypeName = this + final def asTermName = throw new ClassCastException(this + " is not a term name") private[this] var _termName = initialTermName - def toTermName: TermName = _termName match { + final def toTermName: TermName = _termName match { case tn: LocalName => synchronized { tn.toGlobalName } case tn => tn } - def toLocalName: LocalName = _termName match { + final def toLocalName: LocalName = _termName match { case tn: LocalName => tn case _ => @@ -169,7 +169,7 @@ object Names { override protected[this] def newBuilder: Builder[Char, Name] = typeNameBuilder - def fromChars(cs: Array[Char], offset: Int, len: Int): TypeName = typeName(cs, offset, len) + final def fromChars(cs: Array[Char], offset: Int, len: Int): TypeName = typeName(cs, offset, len) } /* A local name representing a field that has otherwise the same name as @@ -198,7 +198,7 @@ object Names { * v | * TypeName */ - class LocalName(start: Int, length: Int, _next: TermName) extends TermName(start, length, _next) { + final class LocalName(start: Int, length: Int, _next: TermName) extends TermName(start, length, _next) { def toGlobalName: TermName = next } diff --git a/src/dotty/tools/dotc/core/Periods.scala b/src/dotty/tools/dotc/core/Periods.scala index 3a91b48cbca4..b1778d4a7238 100644 --- a/src/dotty/tools/dotc/core/Periods.scala +++ b/src/dotty/tools/dotc/core/Periods.scala @@ -11,17 +11,17 @@ abstract class Periods extends DotClass { self: Context => import Periods._ /** The current phase identifier */ - def phaseId = period.phaseId + final def phaseId = period.phaseId /** The current run identifier */ - def runId = period.runId + final def runId = period.runId /** Execute `op` at given period */ - def atPeriod[T](pd: Period)(op: Context => T) = + final def atPeriod[T](pd: Period)(op: Context => T) = op(ctx.fresh.withPeriod(pd)) /** Execute `op` at given phase id */ - def atPhase[T](pid: PhaseId)(op: Context => T) = + final def atPhase[T](pid: PhaseId)(op: Context => T) = op(ctx.fresh.withPhase(pid)) } diff --git a/src/dotty/tools/dotc/core/PluggableTransformers.scala b/src/dotty/tools/dotc/core/PluggableTransformers.scala index 3e3ee7df1ea3..1c66f59ba31c 100644 --- a/src/dotty/tools/dotc/core/PluggableTransformers.scala +++ b/src/dotty/tools/dotc/core/PluggableTransformers.scala @@ -77,7 +77,7 @@ object PluggableTransformers { case _ => postProcess(tree, old, c, plugins) } - protected def postProcess(tree: Tree[T], old: Tree[T], c: Context, plugins: Plugins): Tree[T] = tree match { + protected def postProcess(tree: Tree[T], old: Tree[T], c: Context, plugins: Plugins): Tree[T] = (tree: @unchecked) match { case tree: Ident[_] => finishIdent(tree, old, c, plugins) case tree: Select[_] => finishSelect(tree, old, c, plugins) } diff --git a/src/dotty/tools/dotc/core/Scopes.scala b/src/dotty/tools/dotc/core/Scopes.scala index ee442223dfe0..8a91b8d588d5 100644 --- a/src/dotty/tools/dotc/core/Scopes.scala +++ b/src/dotty/tools/dotc/core/Scopes.scala @@ -29,7 +29,7 @@ object Scopes { */ private final val MaxRecursions = 1000 - class ScopeEntry private[Scopes] (val sym: Symbol, val owner: Scope) { + final class ScopeEntry private[Scopes] (val sym: Symbol, val owner: Scope) { /** the next entry in the hash bucket */ @@ -46,7 +46,7 @@ object Scopes { * This is necessary because when run from reflection every scope needs to have a * SynchronizedScope as mixin. */ - class Scope protected[Scopes](initElems: ScopeEntry, initSize: Int, val nestingLevel: Int = 0) + sealed class Scope protected[Scopes](initElems: ScopeEntry, initSize: Int, val nestingLevel: Int = 0) extends Iterable[Symbol] { protected[Scopes] def this(base: Scope)(implicit ctx: Context) = { @@ -56,12 +56,12 @@ object Scopes { def this() = this(null, 0, 0) - private[dotc] var lastEntry: ScopeEntry = initElems + private[dotc] final var lastEntry: ScopeEntry = initElems /** The size of the scope */ private[this] var _size = initSize - override def size = _size + override final def size = _size private def size_= (x: Int) = _size = x /** the hash table @@ -73,10 +73,10 @@ object Scopes { private var elemsCache: List[Symbol] = null /** Returns a new scope with the same content as this one. */ - def cloneScope(implicit ctx: Context): Scope = newScopeWith(this.toList: _*) + final def cloneScope(implicit ctx: Context): Scope = newScopeWith(this.toList: _*) /** is the scope empty? */ - override def isEmpty: Boolean = lastEntry eq null + override final def isEmpty: Boolean = lastEntry eq null /** create and enter a scope entry */ protected def newScopeEntry(sym: Symbol)(implicit ctx: Context): ScopeEntry = { @@ -94,7 +94,7 @@ object Scopes { e } - private def enterInHash(e: ScopeEntry)(implicit ctx: Context): Unit = { + private final def enterInHash(e: ScopeEntry)(implicit ctx: Context): Unit = { val i = e.sym.name.start & (hashTable.length - 1) e.tail = hashTable(i) hashTable(i) = e @@ -104,7 +104,7 @@ object Scopes { * * @param sym ... */ - def enter[T <: Symbol](sym: T)(implicit ctx: Context): T = { + final def enter[T <: Symbol](sym: T)(implicit ctx: Context): T = { newScopeEntry(sym) sym } @@ -113,7 +113,7 @@ object Scopes { * * @param sym ... */ - def enterUnique(sym: Symbol)(implicit ctx: Context) { + final def enterUnique(sym: Symbol)(implicit ctx: Context) { assert(lookup(sym.name) == NoSymbol, (sym.showLocated, lookup(sym.name).showLocated)) enter(sym) } @@ -146,7 +146,7 @@ object Scopes { } /** remove entry from this scope. */ - def unlink(e: ScopeEntry)(implicit ctx: Context) { + final def unlink(e: ScopeEntry)(implicit ctx: Context) { if (lastEntry == e) { lastEntry = e.prev } else { @@ -169,7 +169,7 @@ object Scopes { } /** remove symbol from this scope */ - def unlink(sym: Symbol)(implicit ctx: Context) { + final def unlink(sym: Symbol)(implicit ctx: Context) { var e = lookupEntry(sym.name) while (e ne null) { if (e.sym == sym) unlink(e); @@ -182,21 +182,21 @@ object Scopes { * @param name ... * @return ... */ - def lookup(name: Name)(implicit ctx: Context): Symbol = { + final def lookup(name: Name)(implicit ctx: Context): Symbol = { val e = lookupEntry(name) if (e eq null) NoSymbol else e.sym } /** Returns an iterator yielding every symbol with given name in this scope. */ - def lookupAll(name: Name)(implicit ctx: Context): Iterator[Symbol] = new Iterator[Symbol] { + final def lookupAll(name: Name)(implicit ctx: Context): Iterator[Symbol] = new Iterator[Symbol] { var e = lookupEntry(name) def hasNext: Boolean = e ne null def next(): Symbol = { val r = e.sym; e = lookupNextEntry(e); r } } /** The denotation set of all the symbols with given name in this scope */ - def denotsNamed(name: Name)(implicit ctx: Context): DenotationSet = { + final def denotsNamed(name: Name)(implicit ctx: Context): DenotationSet = { var syms: DenotationSet = NoDenotation var e = lookupEntry(name) while (e != null) { @@ -211,7 +211,7 @@ object Scopes { * in future versions of the type system. I have reverted the previous * change to use iterators as too costly. */ - def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = { + final def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = { var e: ScopeEntry = null if (hashTable ne null) { e = hashTable(name.start & (hashTable.length - 1)) @@ -228,7 +228,7 @@ object Scopes { } /** lookup next entry with same name as this one */ - def lookupNextEntry(entry: ScopeEntry)(implicit ctx: Context): ScopeEntry = { + final def lookupNextEntry(entry: ScopeEntry)(implicit ctx: Context): ScopeEntry = { var e = entry if (hashTable ne null) do { e = e.tail } while ((e ne null) && e.sym.name != entry.sym.name) @@ -239,7 +239,7 @@ object Scopes { /** Return all symbols as a list in the order they were entered in this scope. */ - override def toList: List[Symbol] = { + override final def toList: List[Symbol] = { if (elemsCache eq null) { elemsCache = Nil var e = lastEntry @@ -253,22 +253,22 @@ object Scopes { /** Vanilla scope - symbols are stored in declaration order. */ - def sorted: List[Symbol] = toList + final def sorted: List[Symbol] = toList /** Return all symbols as an iterator in the order they were entered in this scope. */ - def iterator: Iterator[Symbol] = toList.iterator + final def iterator: Iterator[Symbol] = toList.iterator - override def foreach[U](p: Symbol => U): Unit = toList foreach p + override final def foreach[U](p: Symbol => U): Unit = toList foreach p - def filteredScope(p: Symbol => Boolean)(implicit ctx: Context): Scope = { + final def filteredScope(p: Symbol => Boolean)(implicit ctx: Context): Scope = { val unfiltered = toList val filtered = unfiltered filterConserve p if (filtered eq unfiltered) this else newScopeWith(filtered: _*) } - def show(implicit ctx: Context): String = ctx.show(this) + final def show(implicit ctx: Context): String = ctx.show(this) } /** Create a new scope */ @@ -302,5 +302,5 @@ object Scopes { /** The error scope (mutable) */ - class ErrorScope(owner: Symbol) extends Scope + final class ErrorScope(owner: Symbol) extends Scope } diff --git a/src/dotty/tools/dotc/core/StdNames.scala b/src/dotty/tools/dotc/core/StdNames.scala index 69f3a47450aa..f3b085254e9b 100644 --- a/src/dotty/tools/dotc/core/StdNames.scala +++ b/src/dotty/tools/dotc/core/StdNames.scala @@ -14,16 +14,16 @@ object StdNames { /** Base strings from which synthetic names are derived. */ - abstract class DefinedNames[N <: Name] { + sealed abstract class DefinedNames[N <: Name] { protected implicit def fromString(s: String): N private val kws = mutable.Set[N]() - protected def kw(name: N) = { kws += name; name } + protected final def kw(name: N) = { kws += name; name } final val keywords: collection.Set[N] = kws } - abstract class ScalaNames[N <: Name] extends DefinedNames[N] { + sealed abstract class ScalaNames[N <: Name] extends DefinedNames[N] { private def encode(s: String): N = fromString(NameTransformer.encode(s)) // Keywords, need to come first ----------------------- @@ -81,40 +81,40 @@ object StdNames { final val HASHkw: N = kw("#") final val ATkw: N = kw("@") - val ANON_CLASS: N = "$anon" - val ANON_FUN: N = "$anonfun" - val BITMAP_PREFIX: N = "bitmap$" - val BITMAP_NORMAL: N = BITMAP_PREFIX // initialization bitmap for public/protected lazy vals - val BITMAP_TRANSIENT: N = BITMAP_PREFIX + "trans$" // initialization bitmap for transient lazy vals - val BITMAP_CHECKINIT: N = BITMAP_PREFIX + "init$" // initialization bitmap for checkinit values - val BITMAP_CHECKINIT_TRANSIENT: N = BITMAP_PREFIX + "inittrans$" // initialization bitmap for transient checkinit values - val DEFAULT_GETTER: N = "$default$" - val DEFAULT_GETTER_INIT: N = encode("") - val DO_WHILE_PREFIX: N = "doWhile$" - val EMPTY: N = "" - val EMPTY_PACKAGE: N = "" - val EVIDENCE_PARAM_PREFIX: N = "evidence$" - val EXCEPTION_RESULT_PREFIX: N = "exceptionResult" - val EXPAND_SEPARATOR: N = "$$" - val IMPL_CLASS_SUFFIX: N = "$class" - val IMPORT: N = "" - val INTERPRETER_IMPORT_WRAPPER: N = "$iw" - val INTERPRETER_LINE_PREFIX: N = "line" - val INTERPRETER_VAR_PREFIX: N = "res" - val INTERPRETER_WRAPPER_SUFFIX: N = "$object" - val LOCALDUMMY_PREFIX: N = "") + final val DO_WHILE_PREFIX: N = "doWhile$" + final val EMPTY: N = "" + final val EMPTY_PACKAGE: N = "" + final val EVIDENCE_PARAM_PREFIX: N = "evidence$" + final val EXCEPTION_RESULT_PREFIX: N = "exceptionResult" + final val EXPAND_SEPARATOR: N = "$$" + final val IMPL_CLASS_SUFFIX: N = "$class" + final val IMPORT: N = "" + final val INTERPRETER_IMPORT_WRAPPER: N = "$iw" + final val INTERPRETER_LINE_PREFIX: N = "line" + final val INTERPRETER_VAR_PREFIX: N = "res" + final val INTERPRETER_WRAPPER_SUFFIX: N = "$object" + final val LOCALDUMMY_PREFIX: N = ">") - val DIV = encode("/") - val EQ = encode("==") - val EQL = encode("=") - val GE = encode(">=") - val GT = encode(">") - val HASHHASH = encode("##") - val LE = encode("<=") - val LSL = encode("<<") - val LSR = encode(">>>") - val LT = encode("<") - val MINUS = encode("-") - val MOD = encode("%") - val MUL = encode("*") - val NE = encode("!=") - val OR = encode("|") - val PLUS = ADD // technically redundant, but ADD looks funny with MINUS - val SUB = MINUS // ... as does SUB with PLUS - val XOR = encode("^") - val ZAND = encode("&&") - val ZOR = encode("||") + final val ADD = encode("+") + final val AND = encode("&") + final val ASR = encode(">>") + final val DIV = encode("/") + final val EQ = encode("==") + final val EQL = encode("=") + final val GE = encode(">=") + final val GT = encode(">") + final val HASHHASH = encode("##") + final val LE = encode("<=") + final val LSL = encode("<<") + final val LSR = encode(">>>") + final val LT = encode("<") + final val MINUS = encode("-") + final val MOD = encode("%") + final val MUL = encode("*") + final val NE = encode("!=") + final val OR = encode("|") + final val PLUS = ADD // technically redundant, but ADD looks funny with MINUS + final val SUB = MINUS // ... as does SUB with PLUS + final val XOR = encode("^") + final val ZAND = encode("&&") + final val ZOR = encode("||") // unary operators - val UNARY_~ = encode("unary_~") - val UNARY_+ = encode("unary_+") - val UNARY_- = encode("unary_-") - val UNARY_! = encode("unary_!") + final val UNARY_~ = encode("unary_~") + final val UNARY_+ = encode("unary_+") + final val UNARY_- = encode("unary_-") + final val UNARY_! = encode("unary_!") // Grouped here so Cleanup knows what tests to perform. - val CommonOpNames = Set[Name](OR, XOR, AND, EQ, NE) - val ConversionNames = Set[Name](toByte, toChar, toDouble, toFloat, toInt, toLong, toShort) - val BooleanOpNames = Set[Name](ZOR, ZAND, UNARY_!) ++ CommonOpNames - val NumberOpNames = ( + final val CommonOpNames = Set[Name](OR, XOR, AND, EQ, NE) + final val ConversionNames = Set[Name](toByte, toChar, toDouble, toFloat, toInt, toLong, toShort) + final val BooleanOpNames = Set[Name](ZOR, ZAND, UNARY_!) ++ CommonOpNames + final val NumberOpNames = ( Set[Name](ADD, SUB, MUL, DIV, MOD, LSL, LSR, ASR, LT, LE, GE, GT) ++ Set(UNARY_+, UNARY_-, UNARY_!) ++ ConversionNames ++ CommonOpNames ) - val add: N = "add" - val complement: N = "complement" - val divide: N = "divide" - val multiply: N = "multiply" - val negate: N = "negate" - val positive: N = "positive" - val shiftLogicalRight: N = "shiftLogicalRight" - val shiftSignedLeft: N = "shiftSignedLeft" - val shiftSignedRight: N = "shiftSignedRight" - val subtract: N = "subtract" - val takeAnd: N = "takeAnd" - val takeConditionalAnd: N = "takeConditionalAnd" - val takeConditionalOr: N = "takeConditionalOr" - val takeModulo: N = "takeModulo" - val takeNot: N = "takeNot" - val takeOr: N = "takeOr" - val takeXor: N = "takeXor" - val testEqual: N = "testEqual" - val testGreaterOrEqualThan: N = "testGreaterOrEqualThan" - val testGreaterThan: N = "testGreaterThan" - val testLessOrEqualThan: N = "testLessOrEqualThan" - val testLessThan: N = "testLessThan" - val testNotEqual: N = "testNotEqual" - - val isBoxedNumberOrBoolean: N = "isBoxedNumberOrBoolean" - val isBoxedNumber: N = "isBoxedNumber" - - val reflPolyCacheName: N = "reflPoly$Cache" - val reflClassCacheName: N = "reflClass$Cache" - val reflParamsCacheName: N = "reflParams$Cache" - val reflMethodCacheName: N = "reflMethod$Cache" - val reflMethodName: N = "reflMethod$Method" + final val add: N = "add" + final val complement: N = "complement" + final val divide: N = "divide" + final val multiply: N = "multiply" + final val negate: N = "negate" + final val positive: N = "positive" + final val shiftLogicalRight: N = "shiftLogicalRight" + final val shiftSignedLeft: N = "shiftSignedLeft" + final val shiftSignedRight: N = "shiftSignedRight" + final val subtract: N = "subtract" + final val takeAnd: N = "takeAnd" + final val takeConditionalAnd: N = "takeConditionalAnd" + final val takeConditionalOr: N = "takeConditionalOr" + final val takeModulo: N = "takeModulo" + final val takeNot: N = "takeNot" + final val takeOr: N = "takeOr" + final val takeXor: N = "takeXor" + final val testEqual: N = "testEqual" + final val testGreaterOrEqualThan: N = "testGreaterOrEqualThan" + final val testGreaterThan: N = "testGreaterThan" + final val testLessOrEqualThan: N = "testLessOrEqualThan" + final val testLessThan: N = "testLessThan" + final val testNotEqual: N = "testNotEqual" + + final val isBoxedNumberOrBoolean: N = "isBoxedNumberOrBoolean" + final val isBoxedNumber: N = "isBoxedNumber" + + final val reflPolyCacheName: N = "reflPoly$Cache" + final val reflClassCacheName: N = "reflClass$Cache" + final val reflParamsCacheName: N = "reflParams$Cache" + final val reflMethodCacheName: N = "reflMethod$Cache" + final val reflMethodName: N = "reflMethod$Method" private val reflectionCacheNames = Set[N]( reflPolyCacheName, @@ -592,10 +592,10 @@ object StdNames { reflMethodName ) - def isReflectionCacheName(name: Name) = reflectionCacheNames exists (name startsWith _) + final def isReflectionCacheName(name: Name) = reflectionCacheNames exists (name startsWith _) } - class ScalaTermNames extends ScalaNames[TermName] { + final class ScalaTermNames extends ScalaNames[TermName] { protected def fromString(s: String) = termName(s) @switch def syntheticParamName(i: Int): TermName = i match { @@ -619,7 +619,7 @@ object StdNames { } - class ScalaTypeNames extends ScalaNames[TypeName] { + final class ScalaTypeNames extends ScalaNames[TypeName] { protected def fromString(s: String) = typeName(s) } @@ -707,10 +707,10 @@ object StdNames { final val JavaSerializable: N = "java.io.Serializable" } - class JavaTermNames extends JavaNames[TermName] { + final class JavaTermNames extends JavaNames[TermName] { protected def fromString(s: String): TermName = termName(s) } - class JavaTypeNames extends JavaNames[TypeName] { + final class JavaTypeNames extends JavaNames[TypeName] { protected def fromString(s: String): TypeName = typeName(s) } diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 2bafb77328db..4fcaef75b166 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -16,7 +16,7 @@ object SymDenotations { /** A denotation represents the contents of a definition * during a period. */ - abstract class SymDenotation(initFlags: FlagSet) extends SingleDenotation { + sealed abstract class SymDenotation(initFlags: FlagSet) extends SingleDenotation { // ----- denotation fields and accessors ------------------------------ @@ -40,7 +40,7 @@ object SymDenotations { def info: Type /** The name with which the denoting symbol was created */ - def originalName = + final def originalName = if (flags is ExpandedName) initial.asSymDenotation.name else name /** The encoded full path name of this denotation, where outer names and inner names @@ -52,7 +52,7 @@ object SymDenotations { if (this == NoSymbol || owner == NoSymbol || owner.isEffectiveRoot) name else (effectiveOwner.enclosingClass.fullName(separator) :+ separator) ++ name - /** `fullName` where `.' is the separator character */ + /** `fullName` where `.` is the separator character */ def fullName(implicit ctx: Context): Name = fullName('.') /** The source or class file from which this denotation was generated, null if not applicable. */ @@ -64,38 +64,42 @@ object SymDenotations { /** The source file from which this denotation was generated, null if not applicable. */ final def sourceFile(implicit ctx: Context): AbstractFile = pickFile(associatedFile, classFile = false) - /** Desire to re-use the field in ClassSymbol which stores the source - * file to also store the classfile, but without changing the behavior - * of sourceFile (which is expected at least in the IDE only to - * return actual source code.) So sourceFile has classfiles filtered out. - */ + /** Desire to re-use the field in ClassSymbol which stores the source + * file to also store the classfile, but without changing the behavior + * of sourceFile (which is expected at least in the IDE only to + * return actual source code.) So sourceFile has classfiles filtered out. + */ private def pickFile(file: AbstractFile, classFile: Boolean): AbstractFile = if ((file eq null) || classFile != (file.path endsWith ".class")) null else file private[this] var _flags: FlagSet = initFlags /** The flag set */ - def flags: FlagSet = { ensureCompleted(); _flags } + final def flags: FlagSet = { ensureCompleted(); _flags } /** Update the flag set */ - private[core] def flags_=(flags: FlagSet): Unit = { _flags = flags } + private[core] final def flags_=(flags: FlagSet): Unit = { _flags = flags } /** Set given flags(s) of this denotation */ - def setFlag(flags: FlagSet): Unit = { _flags |= flags } + final def setFlag(flags: FlagSet): Unit = { _flags |= flags } + + /** Unset given flags(s) of this denotation */ + final def resetFlag(flags: FlagSet): Unit = { _flags &~= flags } - /** UnsSet given flags(s) of this denotation */ - def resetFlag(flags: FlagSet): Unit = { _flags &~= flags } + protected final def isLocked: Boolean = _flags is Locked // don't use `flags` or we'll hit an SOE. + protected final def lock(): Unit = setFlag(Locked) + protected final def unlock(): Unit = resetFlag(Locked) private[this] var _annotations: List[Annotation] = Nil /** The annotations of this denotation */ - def annotations: List[Annotation] = { ensureCompleted(); _annotations } + final def annotations: List[Annotation] = { ensureCompleted(); _annotations } /** Update the annotations of this denotation */ - private[core] def annotations_=(annots: List[Annotation]): Unit = { _annotations = annots } + private[core] final def annotations_=(annots: List[Annotation]): Unit = { _annotations = annots } /** Does this denotation have an annotation matching the given class symbol? */ - def hasAnnotation(cls: Symbol)(implicit ctx: Context) = dropOtherAnnotations(annotations, cls).nonEmpty + final def hasAnnotation(cls: Symbol)(implicit ctx: Context) = dropOtherAnnotations(annotations, cls).nonEmpty /** Add given annotation to the annotations of this denotation */ final def addAnnotation(annot: Annotation): Unit = annotations = @@ -155,19 +159,19 @@ object SymDenotations { def exists(implicit ctx: Context) = true /** Is this symbol the root class or its companion object? */ - def isRoot: Boolean = name.toTermName == nme.ROOT + final def isRoot: Boolean = name.toTermName == nme.ROOT /** Is this symbol the empty package class or its companion object? */ - def isEmptyPackage(implicit ctx: Context): Boolean = name.toTermName == nme.EMPTY_PACKAGE && owner.isRoot + final def isEmptyPackage(implicit ctx: Context): Boolean = name.toTermName == nme.EMPTY_PACKAGE && owner.isRoot /** Is this symbol the empty package class or its companion object? */ - def isEffectiveRoot(implicit ctx: Context) = isRoot || isEmptyPackage + final def isEffectiveRoot(implicit ctx: Context) = isRoot || isEmptyPackage /** Is this symbol an anonymous class? */ - def isAnonymousClass(implicit ctx: Context): Boolean = initial.asSymDenotation.name startsWith tpnme.ANON_CLASS + final def isAnonymousClass(implicit ctx: Context): Boolean = initial.asSymDenotation.name startsWith tpnme.ANON_CLASS /** Is this symbol an abstract type? */ - def isAbstractType = isType && info.isRealTypeBounds + final def isAbstractType = isType && info.isRealTypeBounds /** Is this definition contained in `boundary`? * Same as `ownersIterator contains boundary` but more efficient. @@ -182,14 +186,14 @@ object SymDenotations { } /** Is this denotation static (i.e. with no outer instance)? */ - def isStatic(implicit ctx: Context) = (this is Static) || owner.isStaticOwner + final def isStatic(implicit ctx: Context) = (this is Static) || owner.isStaticOwner /** Is this a package class or module class that defines static symbols? */ final def isStaticOwner(implicit ctx: Context): Boolean = isPackageClass || isModuleClass && isStatic /** Is this denotation defined in the same scope and compilation unit as that symbol? */ - def isCoDefinedWith(that: Symbol)(implicit ctx: Context) = + final def isCoDefinedWith(that: Symbol)(implicit ctx: Context) = (this.effectiveOwner == that.effectiveOwner) && ( !(this.effectiveOwner.isPackageClass) || (this.sourceFile == null) @@ -210,29 +214,29 @@ object SymDenotations { def isSubClass(base: Symbol)(implicit ctx: Context) = false /** Is this a user defined "def" method? Excluded are accessors and stable values */ - def isSourceMethod = this is (Method, butNot = Accessor) + final def isSourceMethod = this is (Method, butNot = Accessor) /** Is this NOT a user-defined "def" method that takes parameters? */ - def isParameterless(implicit ctx: Context) = + final def isParameterless(implicit ctx: Context) = !isSourceMethod || info.paramTypess.isEmpty /** Is this a setter? */ - def isGetter = (this is Accessor) && !originalName.isSetterName + final def isGetter = (this is Accessor) && !originalName.isSetterName /** Is this a setter? */ - def isSetter = (this is Accessor) && originalName.isSetterName + final def isSetter = (this is Accessor) && originalName.isSetterName /** is this the constructor of a class? */ - def isClassConstructor = name == nme.CONSTRUCTOR + final def isClassConstructor = name == nme.CONSTRUCTOR /** Is this the constructor of a trait? */ - def isTraitConstructor = name == nme.TRAIT_CONSTRUCTOR + final def isTraitConstructor = name == nme.TRAIT_CONSTRUCTOR /** Is this the constructor of a trait or a class */ - def isConstructor = name.isConstructorName + final def isConstructor = name.isConstructorName /** Is this a local template dummmy? */ - def isLocalDummy: Boolean = name.isLocalDummyName + final def isLocalDummy: Boolean = name.isLocalDummyName /** Does this symbol denote the primary constructor of its enclosing class? */ final def isPrimaryConstructor(implicit ctx: Context) = @@ -249,13 +253,13 @@ object SymDenotations { isModuleClass && linkedClass.isNonBottomSubClass(base) /** Is this symbol a class that does not extend `AnyVal`? */ - def isNonValueClass(implicit ctx: Context): Boolean = + final def isNonValueClass(implicit ctx: Context): Boolean = isClass && !isSubClass(defn.AnyValClass) /** Is this definition accessible whenever `that` symbol is accessible? * Does not take into account status of protected members. */ - def isAsAccessibleAs(that: Symbol)(implicit ctx: Context): Boolean = + final def isAsAccessibleAs(that: Symbol)(implicit ctx: Context): Boolean = (that.accessBoundary(NoSymbol) isContainedIn this.accessBoundary(NoSymbol)) && (this.isStable || !that.isStable) @@ -263,7 +267,7 @@ object SymDenotations { * @param pre The type of the tree from which the selection is made * @param superAccess Access is via super */ - def isAccessibleFrom(pre: Type, superAccess: Boolean = false)(implicit ctx: Context): Boolean = { + final def isAccessibleFrom(pre: Type, superAccess: Boolean = false)(implicit ctx: Context): Boolean = { def accessWithinLinked(boundary: Symbol) = { val linked = boundary.linkedClass @@ -362,7 +366,7 @@ object SymDenotations { /** The class containing this denotation. * If this denotation is already a class, return itself */ - def enclosingClass(implicit ctx: Context): Symbol = + final def enclosingClass(implicit ctx: Context): Symbol = if (isClass) symbol else owner.enclosingClass /** The top-level class containing this denotation, @@ -381,7 +385,7 @@ object SymDenotations { * and which is also defined in the same scope and compilation unit. * NoSymbol if this module does not exist. */ - def companionModule(implicit ctx: Context): Symbol = { + final def companionModule(implicit ctx: Context): Symbol = { owner.info.decl(name.toTermName) .suchThat(sym => sym.isModule && sym.isCoDefinedWith(symbol)) .symbol @@ -391,7 +395,7 @@ object SymDenotations { * and which is also defined in the same scope and compilation unit. * NoSymbol if this class does not exist. */ - def companionClass(implicit ctx: Context): Symbol = + final def companionClass(implicit ctx: Context): Symbol = owner.info.decl(name.toTypeName) .suchThat(sym => sym.isClass && sym.isCoDefinedWith(symbol)) .symbol @@ -400,7 +404,7 @@ object SymDenotations { * If this is a module class, its companion class. * NoSymbol otherwise. */ - def linkedClass(implicit ctx: Context): Symbol = + final def linkedClass(implicit ctx: Context): Symbol = if (this.isModuleClass) companionClass else if (this.isClass) companionModule.moduleClass else NoSymbol @@ -475,23 +479,23 @@ object SymDenotations { /** The symbolic typeref representing the type constructor for this type. * @throws ClassCastException is this is not a type */ - def symbolicRef(implicit ctx: Context): TypeRef = + final def symbolicRef(implicit ctx: Context): TypeRef = TypeRef(owner.thisType, symbol.asType) /** The variance of this type parameter as an Int, with * +1 = Covariant, -1 = Contravariant, 0 = Nonvariant, or not a type parameter */ - def variance: Int = + final def variance: Int = if (this is Covariant) 1 else if (this is Contravariant) -1 else 0 // ----- copies ------------------------------------------------------ - override protected def newLikeThis(s: Symbol, i: Type): SingleDenotation = new UniqueRefDenotation(s, i, validFor) + override protected final def newLikeThis(s: Symbol, i: Type): SingleDenotation = new UniqueRefDenotation(s, i, validFor) /** Copy this denotation, overriding selective fields */ - def copy( + final def copy( sym: Symbol, owner: Symbol = this.owner, name: Name = this.name, @@ -505,7 +509,7 @@ object SymDenotations { * Note: important to leave initctx non-implicit, and to check that it is not * retained after object construction. */ - abstract class ClassDenotation(initFlags: FlagSet, assocFile: AbstractFile)(initctx: Context) + sealed abstract class ClassDenotation(initFlags: FlagSet, assocFile: AbstractFile)(initctx: Context) extends SymDenotation(initFlags) { import NameFilter._ import util.LRU8Cache @@ -527,33 +531,36 @@ object SymDenotations { def name: TypeName - override val info = { + override final val info = { implicit val ctx = initctx ClassInfo(owner.thisType, this) } - override def associatedFile(implicit ctx: Context): AbstractFile = assocFile + override final def associatedFile(implicit ctx: Context): AbstractFile = assocFile private[this] var _typeParams: List[TypeSymbol] = _ /** The type parameters of this class */ override final def typeParams(implicit ctx: Context): List[TypeSymbol] = { val tparams = _typeParams - if (tparams != null) tparams else computeTypeParams + if (tparams != null) tparams else { + _typeParams = computeTypeParams + _typeParams + } } /** The symbols defined in this class when the class is not yet completed. */ protected def preCompleteDecls: Scope - private def computeTypeParams(implicit ctx: Context): List[TypeSymbol] = + private final def computeTypeParams(implicit ctx: Context): List[TypeSymbol] = (preCompleteDecls.toList filter (_ is TypeParam)).asInstanceOf[List[TypeSymbol]] // ------ class-specific operations ----------------------------------- private[this] var _thisType: Type = null - override def thisType(implicit ctx: Context): Type = { + override final def thisType(implicit ctx: Context): Type = { if (_thisType == null) _thisType = computeThisType _thisType } @@ -611,7 +618,7 @@ object SymDenotations { /** The base classes of this class in linearization order, * with the class itself as first element. */ - def baseClasses(implicit ctx: Context): List[ClassSymbol] = { + final def baseClasses(implicit ctx: Context): List[ClassSymbol] = { if (_baseClasses == null) computeSuperClassBits _baseClasses } @@ -629,7 +636,7 @@ object SymDenotations { private[this] var _definedFingerPrint: FingerPrint = null private def computeDefinedFingerPrint(implicit ctx: Context): FingerPrint = { - var bits = newNameFilter + val bits = newNameFilter var e = decls.lastEntry while (e != null) { includeName(bits, name) @@ -660,7 +667,7 @@ object SymDenotations { * Note: We require that this does not happen after the first time * someone does a findMember on a subclass. */ - def enter(sym: Symbol)(implicit ctx: Context) = { + final def enter(sym: Symbol)(implicit ctx: Context) = { require(!(this is Frozen)) decls enter sym if (_definedFingerPrint != null) @@ -673,7 +680,7 @@ object SymDenotations { * Note: We require that this does not happen after the first time * someone does a findMember on a subclass. */ - def delete(sym: Symbol)(implicit ctx: Context) = { + final def delete(sym: Symbol)(implicit ctx: Context) = { require(!(this is Frozen)) decls unlink sym if (_definedFingerPrint != null) @@ -682,7 +689,7 @@ object SymDenotations { memberCache invalidate sym.name } - def definedFingerPrint(implicit ctx: Context): FingerPrint = { + final def definedFingerPrint(implicit ctx: Context): FingerPrint = { val fp = _definedFingerPrint if (fp != null) fp else computeDefinedFingerPrint } @@ -758,7 +765,7 @@ object SymDenotations { private[this] var memberNamesCache: Map[NameFilter, Set[Name]] = Map() - def memberNames(keepOnly: NameFilter)(implicit ctx: Context): Set[Name] = + final def memberNames(keepOnly: NameFilter)(implicit ctx: Context): Set[Name] = memberNamesCache get keepOnly match { case Some(names) => names @@ -784,15 +791,15 @@ object SymDenotations { } // to avoid overloading ambiguities - override def fullName(implicit ctx: Context): Name = super.fullName + override final def fullName(implicit ctx: Context): Name = super.fullName - override def primaryConstructor(implicit ctx: Context): Symbol = { + override final def primaryConstructor(implicit ctx: Context): Symbol = { val cname = if (this is Trait | ImplClass) nme.TRAIT_CONSTRUCTOR else nme.CONSTRUCTOR decls.denotsNamed(cname).first.symbol } - def copyClass( + final def copyClass( sym: ClassSymbol, owner: Symbol = this.owner, name: TypeName = this.name, @@ -807,7 +814,7 @@ object SymDenotations { // -------- Concrete classes for instantiating denotations -------------------------- - class CompleteSymDenotation( + final class CompleteSymDenotation( val symbol: Symbol, val owner: Symbol, val name: Name, @@ -816,11 +823,11 @@ object SymDenotations { val privateWithin: Symbol ) extends SymDenotation(initFlags) - def CompleteSymDenotation(symbol: Symbol, owner: Symbol, name: Name, initFlags: FlagSet, + def CompleteSymDenotation(symbol: Symbol, owner: Symbol, name: Name, initFlags: FlagSet, info: Type, privateWithin: Symbol = NoSymbol) = new CompleteSymDenotation(symbol, owner, name, initFlags, info, privateWithin) - class LazySymDenotation( + final class LazySymDenotation( val symbol: Symbol, val owner: Symbol, val name: Name, @@ -828,19 +835,19 @@ object SymDenotations { var completer: SymCompleter ) extends SymDenotation(initFlags) with isLazy[LazySymDenotation] { - final override def exists(implicit ctx: Context) = + override def exists(implicit ctx: Context) = !isModuleVal || moduleClass.denot.exists private[this] var _info: Type = _ protected[core] def info_=(tp: Type) = if (_info == null) _info = tp - override def info = { if (info == null) tryComplete(); _info } + override def info = { if (_info == null) tryComplete(); _info } } def LazySymDenotation(symbol: Symbol, owner: Symbol, name: Name, initFlags: FlagSet, completer: SymCompleter) = new LazySymDenotation(symbol, owner, name, initFlags, completer) - class CompleteClassDenotation( + final class CompleteClassDenotation( val symbol: ClassSymbol, val owner: Symbol, val name: TypeName, @@ -852,10 +859,10 @@ object SymDenotations { assocFile: AbstractFile)(initctx: Context) extends ClassDenotation(initFlags, assocFile)(initctx) { val selfType = if (optSelfType == NoType) typeConstructor(initctx) else optSelfType - final def preCompleteDecls = decls + def preCompleteDecls = decls } - def CompleteClassDenotation( + def CompleteClassDenotation( symbol: ClassSymbol, owner: Symbol, name: TypeName, initFlags: FlagSet, parents: List[TypeRef], privateWithin: Symbol = NoSymbol, optSelfType: Type = NoType, @@ -864,7 +871,7 @@ object SymDenotations { new CompleteClassDenotation(symbol, owner, name, initFlags, parents, privateWithin, optSelfType, decls, assocFile)(ctx) - class LazyClassDenotation( + final class LazyClassDenotation( val symbol: ClassSymbol, val owner: Symbol, val name: TypeName, @@ -881,13 +888,13 @@ object SymDenotations { protected[core] def selfType_=(tp: Type) = if (_selfType == null) _selfType = tp protected[core] def decls_=(sc: Scope) = if (_decls == null) _decls = sc - final def parents: List[TypeRef] = { if (_parents == null) tryComplete(); _parents } + def parents: List[TypeRef] = { if (_parents == null) tryComplete(); _parents } def selfType: Type = { if (_selfType == null) tryComplete(); _selfType } - final def preCompleteDecls = { if (_decls == null) tryComplete(); _decls } - final def decls: Scope = { ensureCompleted(); _decls } + def preCompleteDecls = { if (_decls == null) tryComplete(); _decls } + def decls: Scope = { ensureCompleted(); _decls } // cannot check on decls because decls might be != null even if class is not completed - final override def exists(implicit ctx: Context) = { ensureCompleted(); _parents != null } + override def exists(implicit ctx: Context) = { ensureCompleted(); _parents != null } } def LazyClassDenotation( @@ -908,29 +915,29 @@ object SymDenotations { // ---- Completion -------------------------------------------------------- - trait isLazy[Denot <: SymDenotation] extends SymDenotation { this: Denot => + sealed trait isLazy[Denot <: SymDenotation] extends SymDenotation { this: Denot => protected def completer: Completer[Denot] protected def completer_= (c: Completer[Denot]) - override def isCompleted = completer == null + override final def isCompleted = completer == null - override protected[core] def tryComplete(): Unit = + override protected[core] final def tryComplete(): Unit = try { - if (flags is Locked) throw new CyclicReference(symbol) - setFlag(Locked) + if (isLocked) throw new CyclicReference(symbol) + lock() val c = completer if (c == null) throw new CompletionError(this) completer = null // set completer to null to avoid space leaks // and to make any subsequent completion attempt a CompletionError c(this) } finally { - flags &~= Locked + unlock() } private[this] var _privateWithin: Symbol = _ - def privateWithin: Symbol = { if (_privateWithin == null) tryComplete(); _privateWithin } - protected[core] def privateWithin_=(sym: Symbol): Unit = { _privateWithin = sym } + final def privateWithin: Symbol = { if (_privateWithin == null) tryComplete(); _privateWithin } + protected[core] final def privateWithin_=(sym: Symbol): Unit = { _privateWithin = sym } } /** When called, complete denotation, setting all its properties */ @@ -938,7 +945,7 @@ object SymDenotations { type SymCompleter = Completer[LazySymDenotation] type ClassCompleter = Completer[LazyClassDenotation] - class ModuleCompleter(cctx: CondensedContext) extends SymCompleter { + final class ModuleCompleter(cctx: CondensedContext) extends SymCompleter { implicit protected def ctx: Context = cctx def apply(denot: LazySymDenotation): Unit = { val from = denot.moduleClass.denot.asInstanceOf[LazyClassDenotation] @@ -949,7 +956,7 @@ object SymDenotations { } /** A completer for missing references */ - class StubCompleter(cctx: CondensedContext) extends ClassCompleter { + final class StubCompleter(cctx: CondensedContext) extends ClassCompleter { implicit protected def ctx: Context = cctx def initializeToDefaults(denot: LazyClassDenotation) = { @@ -976,7 +983,7 @@ object SymDenotations { } } - class CompletionError(denot: SymDenotation) extends Error("Trying to access missing symbol ${denot.symbol.fullName}") + final class CompletionError(denot: SymDenotation) extends Error("Trying to access missing symbol ${denot.symbol.fullName}") // ---- Name filter -------------------------------------------------------- diff --git a/src/dotty/tools/dotc/core/SymbolLoaders.scala b/src/dotty/tools/dotc/core/SymbolLoaders.scala index 2e37d8124834..1b5a3f531f91 100644 --- a/src/dotty/tools/dotc/core/SymbolLoaders.scala +++ b/src/dotty/tools/dotc/core/SymbolLoaders.scala @@ -17,7 +17,7 @@ import pickling.ClassfileParser /** A base class for Symbol loaders with some overridable behavior */ class SymbolLoaders { - protected def enterIfNew(owner: Symbol, member: Symbol, completer: SymbolLoader)(implicit ctx: Context): Symbol = { + protected final def enterIfNew(owner: Symbol, member: Symbol, completer: SymbolLoader)(implicit ctx: Context): Symbol = { assert(owner.info.decls.lookup(member.name) == NoSymbol, owner.fullName + "." + member.name) owner.info.decls enter member member @@ -25,14 +25,14 @@ class SymbolLoaders { /** Enter class with given `name` into scope of `owner`. */ - def enterClass(owner: Symbol, name: PreName, completer: SymbolLoader, flags: FlagSet = EmptyFlags)(implicit ctx: Context): Symbol = { + final def enterClass(owner: Symbol, name: PreName, completer: SymbolLoader, flags: FlagSet = EmptyFlags)(implicit ctx: Context): Symbol = { val cls = ctx.newLazyClassSymbol(owner, name.toTypeName, flags, completer, assocFile = completer.sourceFileOrNull) enterIfNew(owner, cls, completer) } /** Enter module with given `name` into scope of `owner`. */ - def enterModule(owner: Symbol, name: PreName, completer: SymbolLoader, flags: FlagSet = EmptyFlags)(implicit ctx: Context): Symbol = { + final def enterModule(owner: Symbol, name: PreName, completer: SymbolLoader, flags: FlagSet = EmptyFlags)(implicit ctx: Context): Symbol = { val module = ctx.newLazyModuleSymbols(owner, name.toTermName, flags, completer, assocFile = completer.sourceFileOrNull)._1 enterIfNew(owner, module, completer) } @@ -40,7 +40,7 @@ class SymbolLoaders { /** Enter package with given `name` into scope of `owner` * and give them `completer` as type. */ - def enterPackage(owner: Symbol, name: PreName, completer: SymbolLoader)(implicit ctx: Context): Symbol = { + final def enterPackage(owner: Symbol, name: PreName, completer: SymbolLoader)(implicit ctx: Context): Symbol = { val pname = name.toTermName val preExisting = owner.info.decls lookup pname if (preExisting != NoSymbol) { @@ -69,7 +69,7 @@ class SymbolLoaders { /** Enter class and module with given `name` into scope of `owner` * and give them `completer` as type. */ - def enterClassAndModule(owner: Symbol, name: PreName, completer: SymbolLoader, flags: FlagSet = EmptyFlags)(implicit ctx: Context) { + final def enterClassAndModule(owner: Symbol, name: PreName, completer: SymbolLoader, flags: FlagSet = EmptyFlags)(implicit ctx: Context) { val clazz = enterClass(owner, name, completer, flags) val module = enterModule(owner, name, completer, flags) if (!clazz.isAnonymousClass) { @@ -84,7 +84,7 @@ class SymbolLoaders { * with source completer for given `src` as type. * (overridden in interactive.Global). */ - def enterToplevelsFromSource(owner: Symbol, name: PreName, src: AbstractFile)(implicit ctx: Context) { + final def enterToplevelsFromSource(owner: Symbol, name: PreName, src: AbstractFile)(implicit ctx: Context) { ??? // !!! enterClassAndModule(owner, name, new SourcefileLoader(src)) } @@ -95,13 +95,13 @@ class SymbolLoaders { * Note: We do a name-base comparison here because the method is called before we even * have ReflectPackage defined. */ - def binaryOnly(owner: Symbol, name: String)(implicit ctx: Context): Boolean = + final def binaryOnly(owner: Symbol, name: String)(implicit ctx: Context): Boolean = name == "package" && (owner.fullName == "scala" || owner.fullName == "scala.reflect") /** Initialize toplevel class and module symbols in `owner` from class path representation `classRep` */ - def initializeFromClassPath(owner: Symbol, classRep: ClassPath#ClassRep)(implicit ctx: Context) { + final def initializeFromClassPath(owner: Symbol, classRep: ClassPath#ClassRep)(implicit ctx: Context) { ((classRep.binary, classRep.source): @unchecked) match { case (Some(bin), Some(src)) if needCompile(bin, src) && !binaryOnly(owner, classRep.name) => if (ctx.settings.verbose.value) ctx.inform("[symloader] picked up newer source file for " + src.path) @@ -114,12 +114,12 @@ class SymbolLoaders { } } - def needCompile(bin: AbstractFile, src: AbstractFile) = + final def needCompile(bin: AbstractFile, src: AbstractFile) = src.lastModified >= bin.lastModified /** Load contents of a package */ - class PackageLoader(classpath: ClassPath)(cctx: CondensedContext) extends SymbolLoader { + final class PackageLoader(classpath: ClassPath)(cctx: CondensedContext) extends SymbolLoader { implicit val ctx: Context = cctx protected def description = "package loader " + classpath.name @@ -151,7 +151,7 @@ class SymbolLoaders { * Todo: consider factoring out behavior from TopClassCompleter/SymbolLoader into * supertrait SymLoader */ -abstract class SymbolLoader extends ClassCompleter { +sealed abstract class SymbolLoader extends ClassCompleter { implicit val ctx: Context /** Load source or class file for `root`, return */ @@ -164,7 +164,7 @@ abstract class SymbolLoader extends ClassCompleter { */ protected def description: String - override def apply(root: LazyClassDenotation) = { + override final def apply(root: LazyClassDenotation) = { def signalError(ex: Exception) { if (ctx.settings.debug.value) ex.printStackTrace() val msg = ex.getMessage() @@ -180,14 +180,14 @@ abstract class SymbolLoader extends ClassCompleter { case ex: IOException => signalError(ex) } finally { - root.linkedClass.denot match { + (root.linkedClass.denot : @unchecked) match { // TODO JZ really only one case here? case companion: LazyClassDenotation => companion.completer = null } } } } -class ClassfileLoader(val classfile: AbstractFile)(cctx: CondensedContext) extends SymbolLoader { +final class ClassfileLoader(val classfile: AbstractFile)(cctx: CondensedContext) extends SymbolLoader { implicit val ctx: Context = cctx override def sourceFileOrNull: AbstractFile = classfile @@ -209,38 +209,6 @@ class ClassfileLoader(val classfile: AbstractFile)(cctx: CondensedContext) exten } } /* - class MsilFileLoader(msilFile: MsilFile) extends SymbolLoader with FlagAssigningCompleter { - private def typ = msilFile.msilType - private object typeParser extends clr.TypeParser { - val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global - } - - protected def description = "MsilFile "+ typ.FullName + ", assembly "+ typ.Assembly.FullName - protected def doComplete(root: Symbol) { typeParser.parse(typ, root) } - } - - class SourcefileLoader(val srcfile: AbstractFile) extends SymbolLoader with FlagAssigningCompleter { - protected def description = "source file "+ srcfile.toString - override def fromSource = true - override def sourcefile = Some(srcfile) - protected def doComplete(root: Symbol): Unit = global.currentRun.compileLate(srcfile) - } - - object moduleClassLoader extends SymbolLoader with FlagAssigningCompleter { - protected def description = "module class loader" - protected def doComplete(root: Symbol) { root.sourceModule.initialize } - } - - object clrTypes extends clr.CLRTypes { - val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global - if (global.forMSIL) init() - } - - /** used from classfile parser to avoid cyclies */ - var parentsLevel = 0 - var pendingLoadActions: List[() => Unit] = Nil -} - object SymbolLoadersStats { import scala.reflect.internal.TypesStats.typerNanos val classReadNanos = Statistics.newSubTimer ("time classfilereading", typerNanos) diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala index 68579f15f419..a48d753f357d 100644 --- a/src/dotty/tools/dotc/core/Symbols.scala +++ b/src/dotty/tools/dotc/core/Symbols.scala @@ -21,15 +21,15 @@ trait Symbols { this: Context => // ---- Fundamental symbol creation methods ---------------------------------- - def newLazySymbol[N <: Name](owner: Symbol, name: N, initFlags: FlagSet, completer: SymCompleter, coord: Coord = NoCoord) = + final def newLazySymbol[N <: Name](owner: Symbol, name: N, initFlags: FlagSet, completer: SymCompleter, coord: Coord = NoCoord) = new Symbol(coord, new LazySymDenotation(_, owner, name, initFlags, completer)) { type ThisName = N } - def newLazyClassSymbol(owner: Symbol, name: TypeName, initFlags: FlagSet, completer: ClassCompleter, assocFile: AbstractFile = null, coord: Coord = NoCoord) = + final def newLazyClassSymbol(owner: Symbol, name: TypeName, initFlags: FlagSet, completer: ClassCompleter, assocFile: AbstractFile = null, coord: Coord = NoCoord) = new ClassSymbol(coord, new LazyClassDenotation(_, owner, name, initFlags, completer, assocFile)(this)) - def newLazyModuleSymbols(owner: Symbol, + final def newLazyModuleSymbols(owner: Symbol, name: TermName, flags: FlagSet, completer: ClassCompleter, @@ -47,12 +47,12 @@ trait Symbols { this: Context => (module, modcls) } - def newSymbol[N <: Name](owner: Symbol, name: N, flags: FlagSet, info: Type, privateWithin: Symbol = NoSymbol, coord: Coord = NoCoord) = + final def newSymbol[N <: Name](owner: Symbol, name: N, flags: FlagSet, info: Type, privateWithin: Symbol = NoSymbol, coord: Coord = NoCoord) = new Symbol(coord, CompleteSymDenotation(_, owner, name, flags, info, privateWithin)) { type ThisName = N } - def newClassSymbol( + final def newClassSymbol( owner: Symbol, name: TypeName, flags: FlagSet, @@ -66,7 +66,7 @@ trait Symbols { this: Context => new ClassSymbol(coord, new CompleteClassDenotation( _, owner, name, flags, parents, privateWithin, optSelfType, decls, assocFile)(this)) - def newModuleSymbols( + final def newModuleSymbols( owner: Symbol, name: TermName, flags: FlagSet, @@ -89,7 +89,7 @@ trait Symbols { this: Context => (module, modcls) } - def newStubSymbol(owner: Symbol, name: Name, file: AbstractFile = null): Symbol = { + final def newStubSymbol(owner: Symbol, name: Name, file: AbstractFile = null): Symbol = { def stub = new StubCompleter(ctx.condensed) name match { case name: TermName => ctx.newLazyModuleSymbols(owner, name, EmptyFlags, stub, file)._1 @@ -99,36 +99,36 @@ trait Symbols { this: Context => // ---- Derived symbol creation methods ------------------------------------- - def newLazyPackageSymbols(owner: Symbol, name: TermName, completer: ClassCompleter) = + final def newLazyPackageSymbols(owner: Symbol, name: TermName, completer: ClassCompleter) = newLazyModuleSymbols(owner, name, PackageCreationFlags, completer) - def newPackageSymbols( + final def newPackageSymbols( owner: Symbol, name: TermName, decls: Scope = newScope) = newModuleSymbols( owner, name, PackageCreationFlags, PackageCreationFlags, Nil, NoSymbol, decls) - def newLocalDummy(cls: Symbol, coord: Coord = NoCoord) = + final def newLocalDummy(cls: Symbol, coord: Coord = NoCoord) = newSymbol(cls, nme.localDummyName(cls), EmptyFlags, NoType) - def newImportSymbol(expr: TypedTree, coord: Coord = NoCoord) = + final def newImportSymbol(expr: TypedTree, coord: Coord = NoCoord) = newSymbol(NoSymbol, nme.IMPORT, EmptyFlags, ImportType(expr), coord = coord) - def newConstructor(cls: ClassSymbol, flags: FlagSet, paramNames: List[TermName], paramTypes: List[Type], privateWithin: Symbol = NoSymbol, coord: Coord = NoCoord) = + final def newConstructor(cls: ClassSymbol, flags: FlagSet, paramNames: List[TermName], paramTypes: List[Type], privateWithin: Symbol = NoSymbol, coord: Coord = NoCoord) = newSymbol(cls, nme.CONSTRUCTOR, flags, MethodType(paramNames, paramTypes)(_ => cls.typeConstructor), privateWithin, coord) - def newDefaultConstructor(cls: ClassSymbol) = + final def newDefaultConstructor(cls: ClassSymbol) = newConstructor(cls, EmptyFlags, Nil, Nil) - def newSelfSym(cls: ClassSymbol) = + final def newSelfSym(cls: ClassSymbol) = ctx.newSymbol(cls, nme.THIS, SyntheticArtifact, cls.selfType) /** Create new type parameters with given owner, names, and flags. * @param boundsFn A function that, given type refs to the newly created * parameters returns a list of their bounds. */ - def newTypeParams( + final def newTypeParams( owner: Symbol, names: List[TypeName], flags: FlagSet, @@ -146,13 +146,13 @@ trait Symbols { this: Context => // ----- Locating predefined symbols ---------------------------------------- - def requiredPackage(path: PreName): TermSymbol = + final def requiredPackage(path: PreName): TermSymbol = base.staticRef(path.toTermName).requiredSymbol(_.isPackage).asTerm - def requiredClass(path: PreName): ClassSymbol = + final def requiredClass(path: PreName): ClassSymbol = base.staticRef(path.toTypeName).requiredSymbol(_.isClass).asClass - def requiredModule(path: PreName): TermSymbol = + final def requiredModule(path: PreName): TermSymbol = base.staticRef(path.toTermName).requiredSymbol(_.isModule).asTerm } @@ -160,7 +160,7 @@ object Symbols { /** A Symbol represents a Scala definition/declaration or a package. */ - class Symbol(val coord: Coord, denotf: Symbol => SymDenotation) extends DotClass { + sealed class Symbol(val coord: Coord, denotf: Symbol => SymDenotation) extends DotClass { type ThisName <: Name @@ -168,15 +168,15 @@ object Symbols { def exists = true /** This symbol, if it exists, otherwise the result of evaluating `that` */ - def orElse(that: => Symbol) = if (exists) this else that + final def orElse(that: => Symbol) = if (exists) this else that /** If this symbol satisfies predicate `p` this symbol, otherwise `NoSymbol` */ - def filter(p: Symbol => Boolean): Symbol = if (p(this)) this else NoSymbol + final def filter(p: Symbol => Boolean): Symbol = if (p(this)) this else NoSymbol private[this] var _id: Int = _ /** The unique id of this symbol */ - def id(implicit ctx: Context) = { + final def id(implicit ctx: Context) = { if (_id == 0) _id = ctx.nextId _id } @@ -187,7 +187,10 @@ object Symbols { /** The current denotation of this symbol */ final def denot(implicit ctx: Context): SymDenotation = { var denot = lastDenot - if (!(denot.validFor contains ctx.period)) denot = denot.current.asInstanceOf[SymDenotation] + if (!(denot.validFor contains ctx.period)) { + denot = denot.current.asInstanceOf[SymDenotation] + lastDenot = denot + } denot } @@ -212,31 +215,31 @@ object Symbols { } /** Is symbol a primitive value class? */ - def isPrimitiveValueClass(implicit ctx: Context) = defn.ScalaValueClasses contains this + final def isPrimitiveValueClass(implicit ctx: Context) = defn.ScalaValueClasses contains this /** Is symbol a phantom class for which no runtime representation exists? */ - def isPhantomClass(implicit ctx: Context) = defn.PhantomClasses contains this + final def isPhantomClass(implicit ctx: Context) = defn.PhantomClasses contains this /** The current name of this symbol */ final def name(implicit ctx: Context): ThisName = denot.name.asInstanceOf[ThisName] - def show(implicit ctx: Context): String = ctx.show(this) - def showLocated(implicit ctx: Context): String = ctx.showLocated(this) - def showDcl(implicit ctx: Context): String = ctx.showDcl(this) - def showKind(implicit ctx: Context): String = ctx.showKind(this) - def showName(implicit ctx: Context): String = ctx.showName(this) - def showFullName(implicit ctx: Context): String = ctx.showFullName(this) + final def show(implicit ctx: Context): String = ctx.show(this) + final def showLocated(implicit ctx: Context): String = ctx.showLocated(this) + final def showDcl(implicit ctx: Context): String = ctx.showDcl(this) + final def showKind(implicit ctx: Context): String = ctx.showKind(this) + final def showName(implicit ctx: Context): String = ctx.showName(this) + final def showFullName(implicit ctx: Context): String = ctx.showFullName(this) } type TermSymbol = Symbol { type ThisName = TermName } type TypeSymbol = Symbol { type ThisName = TypeName } - class ClassSymbol(coord: Coord, denotf: ClassSymbol => ClassDenotation) extends Symbol(coord, s => denotf(s.asClass)) { + final class ClassSymbol(coord: Coord, denotf: ClassSymbol => ClassDenotation) extends Symbol(coord, s => denotf(s.asClass)) { type ThisName = TypeName - final def classDenot(implicit ctx: Context): ClassDenotation = + def classDenot(implicit ctx: Context): ClassDenotation = denot.asInstanceOf[ClassDenotation] private var superIdHint: Int = -1 @@ -262,7 +265,7 @@ object Symbols { } } - class ErrorSymbol(val underlying: Symbol, msg: => String)(implicit ctx: Context) extends Symbol(NoCoord, sym => underlying.denot) { + final class ErrorSymbol(val underlying: Symbol, msg: => String)(implicit ctx: Context) extends Symbol(NoCoord, sym => underlying.denot) { type ThisName = underlying.ThisName } diff --git a/src/dotty/tools/dotc/core/Trees.scala b/src/dotty/tools/dotc/core/Trees.scala index 6215cfc69ff8..7c339c544431 100644 --- a/src/dotty/tools/dotc/core/Trees.scala +++ b/src/dotty/tools/dotc/core/Trees.scala @@ -6,7 +6,7 @@ import annotation.tailrec object Trees { - case class Modifiers[T]( + final case class Modifiers[T]( flags: FlagSet, privateWithin: TypeName = tpnme.EMPTY, annotations: List[Tree[T]] = Nil) @@ -30,7 +30,7 @@ object Trees { * - Type checking an untyped tree will remove all embedded `TypedSplice` * nodes. */ - abstract class Tree[T] extends DotClass { + sealed abstract class Tree[T] extends DotClass { /** The tree's position. Except * for Shared nodes, it is always ensured that a tree's position @@ -54,7 +54,7 @@ object Trees { /** Copy `tpe` attribute from tree `from` into this tree, independently * whether it is null or not. */ - def copyAttr(from: Tree[T]): ThisTree[T] = { + final def copyAttr(from: Tree[T]): ThisTree[T] = { _tpe = from._tpe this.asInstanceOf[ThisTree[T]] } @@ -92,11 +92,11 @@ object Trees { /** Is this tree either the empty tree or the empty ValDef? */ def isEmpty: Boolean = false - override def hashCode(): Int = System.identityHashCode(this) - override def equals(that: Any) = this eq that.asInstanceOf[AnyRef] + override final def hashCode(): Int = System.identityHashCode(this) + override final def equals(that: Any) = this eq that.asInstanceOf[AnyRef] } - class UnAssignedTypeException[T](tree: Tree[T]) extends RuntimeException { + final class UnAssignedTypeException[T](tree: Tree[T]) extends RuntimeException { override def getMessage: String = s"type of $tree is not assigned" } @@ -108,7 +108,7 @@ object Trees { /** Instances of this class are trees for which isType is definitely true. * Note that some trees have isType = true without being TypTrees (e.g. Ident, AnnotatedTree) */ - trait TypTree[T] extends Tree[T] { + sealed trait TypTree[T] extends Tree[T] { type ThisTree[T] <: TypTree[T] override def isType = true } @@ -116,7 +116,7 @@ object Trees { /** Instances of this class are trees for which isTerm is definitely true. * Note that some trees have isTerm = true without being TermTrees (e.g. Ident, AnnotatedTree) */ - trait TermTree[T] extends Tree[T] { + sealed trait TermTree[T] extends Tree[T] { type ThisTree[T] <: TermTree[T] override def isTerm = true } @@ -124,19 +124,19 @@ object Trees { /** Instances of this class are trees which are not terms but are legal * parts of patterns. */ - trait PatternTree[T] extends Tree[T] { + sealed trait PatternTree[T] extends Tree[T] { type ThisTree[T] <: PatternTree[T] override def isPattern = true } /** Tree's symbol can be derived from its type */ - abstract class SymTree[T] extends Tree[T] { + sealed abstract class SymTree[T] extends Tree[T] { type ThisTree[T] <: SymTree[T] - override def denot(implicit ctx: Context) = tpe match { + override final def denot(implicit ctx: Context) = tpe match { case tpe: NamedType => tpe.denot case _ => NoDenotation } - override def symbol(implicit ctx: Context): Symbol = tpe match { + override final def symbol(implicit ctx: Context): Symbol = tpe match { case tpe: Type => if (isType) tpe.typeSymbol else tpe.termSymbol case _ => NoSymbol } @@ -145,23 +145,23 @@ object Trees { /** Tree's symbol/isType/isTerm properties come from a subtree identified * by `forwardTo`. */ - abstract class ProxyTree[T] extends Tree[T] { + sealed abstract class ProxyTree[T] extends Tree[T] { type ThisTree[T] <: ProxyTree[T] def forwardTo: Tree[T] - override def denot(implicit ctx: Context): Denotation = forwardTo.denot - override def symbol(implicit ctx: Context): Symbol = forwardTo.symbol + override final def denot(implicit ctx: Context): Denotation = forwardTo.denot + override final def symbol(implicit ctx: Context): Symbol = forwardTo.symbol override def isTerm = forwardTo.isTerm override def isType = forwardTo.isType } /** Tree has a name */ - abstract class NameTree[T] extends SymTree[T] { + sealed abstract class NameTree[T] extends SymTree[T] { type ThisTree[T] <: NameTree[T] def name: Name } /** Tree refers by name to a denotation */ - abstract class RefTree[T] extends NameTree[T] { + sealed abstract class RefTree[T] extends NameTree[T] { type ThisTree[T] <: RefTree[T] def qualifier: Tree[T] override def isType = name.isTypeName @@ -169,15 +169,15 @@ object Trees { } /** Tree represents a definition */ - abstract class DefTree[T] extends NameTree[T] { + sealed abstract class DefTree[T] extends NameTree[T] { type ThisTree[T] <: DefTree[T] - override def isDef = true + override final def isDef = true } // ----------- Tree case classes ------------------------------------ /** name */ - case class Ident[T](name: Name)(implicit cpos: Position) + final case class Ident[T](name: Name)(implicit cpos: Position) extends RefTree[T] { type ThisTree[T] = Ident[T] val pos = cpos @@ -185,28 +185,28 @@ object Trees { } /** qualifier.name */ - case class Select[T](qualifier: Tree[T], name: Name)(implicit cpos: Position) + final case class Select[T](qualifier: Tree[T], name: Name)(implicit cpos: Position) extends RefTree[T] { type ThisTree[T] = Select[T] val pos = cpos union qualifier.pos } /** qual.this */ - case class This[T](qual: TypeName)(implicit cpos: Position) + final case class This[T](qual: TypeName)(implicit cpos: Position) extends SymTree[T] with TermTree[T] { type ThisTree[T] = This[T] val pos = cpos } /** C.super[mix], where qual = C.this */ - case class Super[T](qual: Tree[T], mix: TypeName)(implicit cpos: Position) + final case class Super[T](qual: Tree[T], mix: TypeName)(implicit cpos: Position) extends ProxyTree[T] with TermTree[T] { type ThisTree[T] = Super[T] val pos = cpos union qual.pos def forwardTo = qual } - abstract class GenericApply[T] extends ProxyTree[T] with TermTree[T] { + sealed abstract class GenericApply[T] extends ProxyTree[T] with TermTree[T] { type ThisTree[T] <: GenericApply[T] val fun: Tree[T] val args: List[Tree[T]] @@ -214,42 +214,42 @@ object Trees { } /** fun(args) */ - case class Apply[T](fun: Tree[T], args: List[Tree[T]])(implicit cpos: Position) + final case class Apply[T](fun: Tree[T], args: List[Tree[T]])(implicit cpos: Position) extends GenericApply[T] { type ThisTree[T] = Apply[T] val pos = unionPos(cpos union fun.pos, args) } /** fun[args] */ - case class TypeApply[T](fun: Tree[T], args: List[Tree[T]])(implicit cpos: Position) + final case class TypeApply[T](fun: Tree[T], args: List[Tree[T]])(implicit cpos: Position) extends GenericApply[T] { type ThisTree[T] = TypeApply[T] val pos = unionPos(cpos union fun.pos, args) } /** const */ - case class Literal[T](const: Constant)(implicit cpos: Position) + final case class Literal[T](const: Constant)(implicit cpos: Position) extends TermTree[T] { type ThisTree[T] = Literal[T] val pos = cpos } /** new tpt, but no constructor call */ - case class New[T](tpt: Tree[T])(implicit cpos: Position) + final case class New[T](tpt: Tree[T])(implicit cpos: Position) extends TermTree[T] { type ThisTree[T] = New[T] val pos = cpos union tpt.pos } /** (left, right) */ - case class Pair[T](left: Tree[T], right: Tree[T])(implicit cpos: Position) + final case class Pair[T](left: Tree[T], right: Tree[T])(implicit cpos: Position) extends TermTree[T] { type ThisTree[T] = Pair[T] val pos = cpos union left.pos union right.pos } /** expr : tpt */ - case class Typed[T](expr: Tree[T], tpt: Tree[T])(implicit cpos: Position) + final case class Typed[T](expr: Tree[T], tpt: Tree[T])(implicit cpos: Position) extends ProxyTree[T] with TermTree[T] { type ThisTree[T] = Typed[T] val pos = cpos union expr.pos union tpt.pos @@ -257,42 +257,42 @@ object Trees { } /** name = arg, in a parameter list */ - case class NamedArg[T](name: Name, arg: Tree[T])(implicit cpos: Position) + final case class NamedArg[T](name: Name, arg: Tree[T])(implicit cpos: Position) extends Tree[T] { type ThisTree[T] = NamedArg[T] val pos = cpos union arg.pos } /** name = arg, outside a parameter list */ - case class Assign[T](lhs: Tree[T], rhs: Tree[T])(implicit cpos: Position) + final case class Assign[T](lhs: Tree[T], rhs: Tree[T])(implicit cpos: Position) extends TermTree[T] { type ThisTree[T] = Assign[T] val pos = cpos union lhs.pos union rhs.pos } /** { stats; expr } */ - case class Block[T](stats: List[Tree[T]], expr: Tree[T])(implicit cpos: Position) + final case class Block[T](stats: List[Tree[T]], expr: Tree[T])(implicit cpos: Position) extends TermTree[T] { type ThisTree[T] = Block[T] val pos = unionPos(cpos union expr.pos, stats) } /** if cond then thenp else elsep */ - case class If[T](cond: Tree[T], thenp: Tree[T], elsep: Tree[T])(implicit cpos: Position) + final case class If[T](cond: Tree[T], thenp: Tree[T], elsep: Tree[T])(implicit cpos: Position) extends TermTree[T] { type ThisTree[T] = If[T] val pos = cpos union cond.pos union thenp.pos union elsep.pos } /** selector match { cases } */ - case class Match[T](selector: Tree[T], cases: List[CaseDef[T]])(implicit cpos: Position) + final case class Match[T](selector: Tree[T], cases: List[CaseDef[T]])(implicit cpos: Position) extends TermTree[T] { type ThisTree[T] = Match[T] val pos = unionPos(cpos union selector.pos, cases) } /** case pat if guard => body */ - case class CaseDef[T](pat: Tree[T], guard: Tree[T], body: Tree[T])(implicit cpos: Position) + final case class CaseDef[T](pat: Tree[T], guard: Tree[T], body: Tree[T])(implicit cpos: Position) extends Tree[T] { type ThisTree[T] = CaseDef[T] val pos = cpos union pat.pos union guard.pos union body.pos @@ -303,70 +303,70 @@ object Trees { * After program transformations this is not necessarily the enclosing method, because * closures can intervene. */ - case class Return[T](expr: Tree[T], from: Ident[T])(implicit cpos: Position) + final case class Return[T](expr: Tree[T], from: Ident[T])(implicit cpos: Position) extends TermTree[T] { type ThisTree[T] = Return[T] val pos = cpos union expr.pos // from is synthetic, does not influence pos } /** try block catch { catches } */ - case class Try[T](block: Tree[T], catches: List[CaseDef[T]], finalizer: Tree[T])(implicit cpos: Position) + final case class Try[T](block: Tree[T], catches: List[CaseDef[T]], finalizer: Tree[T])(implicit cpos: Position) extends TermTree[T] { type ThisTree[T] = Try[T] val pos = unionPos(cpos union block.pos union finalizer.pos, catches) } /** throw expr */ - case class Throw[T](expr: Tree[T])(implicit cpos: Position) + final case class Throw[T](expr: Tree[T])(implicit cpos: Position) extends TermTree[T] { type ThisTree[T] = Throw[T] val pos = cpos union expr.pos } /** Array[elemtpt](elems) */ - case class SeqLiteral[T](elemtpt: Tree[T], elems: List[Tree[T]])(implicit cpos: Position) + final case class SeqLiteral[T](elemtpt: Tree[T], elems: List[Tree[T]])(implicit cpos: Position) extends Tree[T] { type ThisTree[T] = SeqLiteral[T] val pos = unionPos(cpos union elemtpt.pos, elems) } /** A type tree that represents an existing or inferred type */ - case class TypeTree[T](original: Tree[T] = EmptyTree[T])(implicit cpos: Position) + final case class TypeTree[T](original: Tree[T] = EmptyTree[T])(implicit cpos: Position) extends SymTree[T] with TypTree[T] { type ThisTree[T] = TypeTree[T] val pos = cpos union original.pos } /** ref.type */ - case class SingletonTypeTree[T](ref: Tree[T])(implicit cpos: Position) + final case class SingletonTypeTree[T](ref: Tree[T])(implicit cpos: Position) extends SymTree[T] with TypTree[T] { type ThisTree[T] = SingletonTypeTree[T] val pos = cpos union ref.pos } /** qualifier # name */ - case class SelectFromTypeTree[T](qualifier: Tree[T], name: TypeName)(implicit cpos: Position) + final case class SelectFromTypeTree[T](qualifier: Tree[T], name: TypeName)(implicit cpos: Position) extends RefTree[T] with TypTree[T] { type ThisTree[T] = SelectFromTypeTree[T] val pos = cpos union qualifier.pos } /** left & right */ - case class AndTypeTree[T](left: Tree[T], right: Tree[T])(implicit cpos: Position) + final case class AndTypeTree[T](left: Tree[T], right: Tree[T])(implicit cpos: Position) extends TypTree[T] { type ThisTree[T] = AndTypeTree[T] val pos = cpos union left.pos union right.pos } /** left | right */ - case class OrTypeTree[T](left: Tree[T], right: Tree[T])(implicit cpos: Position) + final case class OrTypeTree[T](left: Tree[T], right: Tree[T])(implicit cpos: Position) extends TypTree[T] { type ThisTree[T] = OrTypeTree[T] val pos = cpos union left.pos union right.pos } /** tpt { refinements } */ - case class RefineTypeTree[T](tpt: Tree[T], refinements: List[DefTree[T]])(implicit cpos: Position) + final case class RefineTypeTree[T](tpt: Tree[T], refinements: List[DefTree[T]])(implicit cpos: Position) extends ProxyTree[T] with TypTree[T] { type ThisTree[T] = RefineTypeTree[T] val pos = unionPos(cpos union tpt.pos, refinements) @@ -374,7 +374,7 @@ object Trees { } /** tpt[args] */ - case class AppliedTypeTree[T](tpt: Tree[T], args: List[Tree[T]])(implicit cpos: Position) + final case class AppliedTypeTree[T](tpt: Tree[T], args: List[Tree[T]])(implicit cpos: Position) extends ProxyTree[T] with TypTree[T] { type ThisTree[T] = AppliedTypeTree[T] val pos = unionPos(cpos union tpt.pos, args) @@ -382,28 +382,28 @@ object Trees { } /** >: lo <: hi */ - case class TypeBoundsTree[T](lo: Tree[T], hi: Tree[T])(implicit cpos: Position) + final case class TypeBoundsTree[T](lo: Tree[T], hi: Tree[T])(implicit cpos: Position) extends Tree[T] { type ThisTree[T] = TypeBoundsTree[T] val pos = cpos union lo.pos union hi.pos } /** name @ body */ - case class Bind[T](name: Name, body: Tree[T])(implicit cpos: Position) + final case class Bind[T](name: Name, body: Tree[T])(implicit cpos: Position) extends DefTree[T] with PatternTree[T] { type ThisTree[T] = Bind[T] val pos = cpos union body.pos } /** tree_1 | ... | tree_n */ - case class Alternative[T](trees: List[Tree[T]])(implicit cpos: Position) + final case class Alternative[T](trees: List[Tree[T]])(implicit cpos: Position) extends Tree[T] with PatternTree[T] { type ThisTree[T] = Alternative[T] val pos = unionPos(cpos, trees) } /** fun(args) in a pattern, if fun is an extractor */ - case class UnApply[T](fun: Tree[T], args: List[Tree[T]])(implicit cpos: Position) + final case class UnApply[T](fun: Tree[T], args: List[Tree[T]])(implicit cpos: Position) extends Tree[T] with PatternTree[T] { type ThisTree[T] = UnApply[T] val pos = unionPos(cpos union fun.pos, args) @@ -423,7 +423,7 @@ object Trees { val pos = (unionPos(cpos union tpt.pos union rhs.pos, tparams) /: vparamss)(unionPos) } - class ImplicitDefDef[T](mods: Modifiers[T], name: Name, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T])(implicit pos: Position) extends DefDef[T](mods, name, tparams, vparamss, tpt, rhs) { + final class ImplicitDefDef[T](mods: Modifiers[T], name: Name, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T])(implicit pos: Position) extends DefDef[T](mods, name, tparams, vparamss, tpt, rhs) { override def copy[T](mods: Modifiers[T], name: Name, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T])(implicit pos: Position) = new ImplicitDefDef[T](mods, name, tparams, vparamss, tpt, rhs) } @@ -431,7 +431,7 @@ object Trees { /** mods type name = rhs or * mods type name >: lo <: hi, if rhs = TypeBoundsTree(lo, hi) */ - case class TypeDef[T](mods: Modifiers[T], name: Name, rhs: Tree[T])(implicit cpos: Position) + final case class TypeDef[T](mods: Modifiers[T], name: Name, rhs: Tree[T])(implicit cpos: Position) extends DefTree[T] { type ThisTree[T] = TypeDef[T] val pos = cpos union rhs.pos @@ -445,7 +445,7 @@ object Trees { } /** mods class name[tparams] impl */ - case class ClassDef[T](mods: Modifiers[T], name: TypeName, tparams: List[TypeDef[T]], impl: Template[T])(implicit cpos: Position) + final case class ClassDef[T](mods: Modifiers[T], name: TypeName, tparams: List[TypeDef[T]], impl: Template[T])(implicit cpos: Position) extends DefTree[T] { type ThisTree[T] = ClassDef[T] val pos = unionPos(cpos union impl.pos, tparams) @@ -455,14 +455,14 @@ object Trees { * where a selector is either an untyped `Ident`, `name` or * an untyped `Pair` `name => rename` */ - case class Import[T](expr: Tree[T], selectors: List[UntypedTree])(implicit cpos: Position) + final case class Import[T](expr: Tree[T], selectors: List[UntypedTree])(implicit cpos: Position) extends SymTree[T] { type ThisTree[T] = Import[T] val pos = unionPos(cpos union expr.pos, selectors) } /** package pid { stats } */ - case class PackageDef[T](pid: RefTree[T], stats: List[Tree[T]])(implicit cpos: Position) + final case class PackageDef[T](pid: RefTree[T], stats: List[Tree[T]])(implicit cpos: Position) extends DefTree[T] { type ThisTree[T] = PackageDef[T] val pos = unionPos(cpos union pid.pos, stats) @@ -470,14 +470,14 @@ object Trees { } /** arg @annot */ - case class Annotated[T](annot: Tree[T], arg: Tree[T])(implicit cpos: Position) + final case class Annotated[T](annot: Tree[T], arg: Tree[T])(implicit cpos: Position) extends ProxyTree[T] { type ThisTree[T] = Annotated[T] val pos = cpos union annot.pos union arg.pos def forwardTo = arg } - trait AlwaysEmpty[T] extends Tree[T] { + sealed trait AlwaysEmpty[T] extends Tree[T] { override val pos = NoPosition override def tpe = unsupported("tpe") override def withType(tpe: Type) = unsupported("withType") @@ -485,7 +485,7 @@ object Trees { } /** A missing tree */ - abstract case class EmptyTree[T]() + sealed abstract case class EmptyTree[T]() extends Tree[T] with AlwaysEmpty[T] { type ThisTree[T] = EmptyTree[T] } @@ -496,7 +496,7 @@ object Trees { def apply[T]: EmptyTree[T] = theEmptyTree.asInstanceOf } - class EmptyValDef[T] extends ValDef[T]( + sealed abstract class EmptyValDef[T] extends ValDef[T]( Modifiers[T](Private), nme.WILDCARD, EmptyTree[T], EmptyTree[T])(NoPosition) with AlwaysEmpty[T] private object theEmptyValDef extends EmptyValDef[Nothing] @@ -506,10 +506,10 @@ object Trees { } /** A tree that can be shared without its position - * polluting containing trees. Accumulators and tranformers + * polluting containing trees. Accumulators and transformers * memoize results of shared subtrees */ - case class Shared[T](shared: Tree[T]) extends Tree[T] { + final case class Shared[T](shared: Tree[T]) extends Tree[T] { type ThisTree[T] = Shared[T] val pos = NoPosition override val isTerm = shared.isTerm @@ -518,20 +518,25 @@ object Trees { // ----- Tree cases that exist in untyped form only ------------------ + /** A marker trait for all Tree[Nothing] descendants. Useful for exhaustively pattern matching over Tree[U] */ + sealed trait UntypedTreeMarker { + self: UntypedTree => + } + /** A typed subtree of an untyped tree needs to be wrapped in a TypedSlice */ - class TypedSplice(tree: TypedTree) extends UntypedTree { + final class TypedSplice(tree: TypedTree) extends UntypedTree with UntypedTreeMarker { val pos = tree.pos } /** mods object name impl */ - case class ModuleDef(mods: Modifiers[Nothing], name: TermName, impl: Template[Nothing])(implicit cpos: Position) - extends DefTree[Nothing] { + final case class ModuleDef(mods: Modifiers[Nothing], name: TermName, impl: Template[Nothing])(implicit cpos: Position) + extends DefTree[Nothing] with UntypedTreeMarker { val pos = cpos union impl.pos } /** (vparams) => body */ - case class Function(vparams: List[ValDef[Nothing]], body: Tree[Nothing])(implicit cpos: Position) - extends TermTree[Nothing] { + final case class Function(vparams: List[ValDef[Nothing]], body: Tree[Nothing])(implicit cpos: Position) + extends TermTree[Nothing] with UntypedTreeMarker { val pos = unionPos(cpos union body.pos, vparams) } @@ -707,7 +712,7 @@ object Trees { } abstract class TreeTransformer[T, C] { - var sharedMemo: Map[Shared[T], Shared[T]] = Map() + final var sharedMemo: Map[Shared[T], Shared[T]] = Map() def transform(tree: Tree[T], c: C): Tree[T] = tree match { case Ident(name) => @@ -800,6 +805,8 @@ object Trees { tree1 }, tree, c, plugins) + case _: UntypedTreeMarker => + tree // TODO should this abort? } def transform(trees: List[Tree[T]], c: C): List[Tree[T]] = trees mapConserve (transform(_, c)) @@ -856,7 +863,7 @@ object Trees { } abstract class TreeAccumulator[T, U] extends ((T, Tree[U]) => T) { - var sharedMemo: Map[Shared[U], T] = Map() + final var sharedMemo: Map[Shared[U], T] = Map() def apply(x: T, tree: Tree[U]): T def apply(x: T, trees: List[Tree[U]]): T = (x /: trees)(apply) def foldOver(x: T, tree: Tree[U]): T = tree match { @@ -948,6 +955,8 @@ object Trees { sharedMemo = sharedMemo.updated(tree, x1) x1 } + case _: UntypedTreeMarker => + x } } } diff --git a/src/dotty/tools/dotc/core/TypeComparers.scala b/src/dotty/tools/dotc/core/TypeComparers.scala index c9c2f17b6b7f..e880a4643509 100644 --- a/src/dotty/tools/dotc/core/TypeComparers.scala +++ b/src/dotty/tools/dotc/core/TypeComparers.scala @@ -11,7 +11,7 @@ object TypeComparers { private final val LogPendingSubTypesThreshold = 50 } - class TypeComparer(_ctx: Context) extends DotClass { + final class TypeComparer(_ctx: Context) extends DotClass { import TypeComparer._ implicit val ctx = _ctx diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala index 77038816ea37..4cfea8f03541 100644 --- a/src/dotty/tools/dotc/core/TypeOps.scala +++ b/src/dotty/tools/dotc/core/TypeOps.scala @@ -55,7 +55,7 @@ trait TypeOps { this: Context => } } - class AsSeenFromMap(pre: Type, clazz: Symbol) extends TypeMap { + final class AsSeenFromMap(pre: Type, clazz: Symbol) extends TypeMap { def apply(tp: Type) = asSeenFrom(tp, pre, clazz, this) } @@ -133,7 +133,7 @@ trait TypeOps { this: Context => final def glb(tps: List[Type]): Type = (defn.AnyType /: tps)(glb) - def lub(tp1: Type, tp2: Type): Type = + final def lub(tp1: Type, tp2: Type): Type = if (tp1 eq tp2) tp1 else if (tp1.isWrong) tp1 else if (tp2.isWrong) tp2 @@ -194,7 +194,7 @@ trait TypeOps { this: Context => * to a list of typerefs, by converting all refinements to member * definitions in scope `decls`. */ - def normalizeToRefs(parents: List[Type], cls: ClassSymbol, decls: Scope): List[TypeRef] = { + final def normalizeToRefs(parents: List[Type], cls: ClassSymbol, decls: Scope): List[TypeRef] = { var refinements = Map[TypeName, Type]() var formals = Map[TypeName, Symbol]() def normalizeToRef(tp: Type): TypeRef = tp match { diff --git a/src/dotty/tools/dotc/core/TypedTrees.scala b/src/dotty/tools/dotc/core/TypedTrees.scala index 65ab956933c9..f95089643053 100644 --- a/src/dotty/tools/dotc/core/TypedTrees.scala +++ b/src/dotty/tools/dotc/core/TypedTrees.scala @@ -573,9 +573,15 @@ object TypedTrees { check(annot.symbol.isClassConstructor) check(annot.symbol.owner.isSubClass(defn.AnnotationClass)) check(arg.isType || arg.isValue) - case tpd.EmptyTree => case Shared(shared) => check(shared.isType || shared.isTerm) + case Try(block, catches, finalizer) => + check(block.isTerm) + check(finalizer.isTerm) + def checkType(t: Tree[Type]) = check(t.tpe <:< tree.tpe) + checkType(block) + catches foreach checkType + case EmptyTree() => } implicit class TreeInfo(val tree: tpd.Tree) extends AnyVal { diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 60facee3c2a4..231e9928349c 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -18,6 +18,7 @@ import collection.mutable object Types { + /** A hash value indicating that the underlying type is not * cached in uniques. */ @@ -248,7 +249,7 @@ object Types { } /** The elements of an AndType or OrType */ - def factors(implicit ctx: Context): List[Type] = this match { + final def factors(implicit ctx: Context): List[Type] = this match { case tp: AndType => def components(tp: Type): List[Type] = tp match { case AndType(tp1, tp2) => components(tp1) ++ components(tp2) @@ -265,7 +266,7 @@ object Types { } /** The parameter types of a PolyType or MethodType, Empty list for others */ - def paramTypess: List[List[Type]] = this match { + final def paramTypess: List[List[Type]] = this match { case mt: MethodType => mt.paramTypes :: mt.resultType.paramTypess case pt: PolyType => pt.paramTypess case _ => Nil @@ -280,13 +281,13 @@ object Types { } /** Map function over elements of an AndType, rebuilding with & */ - def mapAnd(f: Type => Type)(implicit ctx: Context): Type = this match { + final def mapAnd(f: Type => Type)(implicit ctx: Context): Type = this match { case AndType(tp1, tp2) => tp1.mapAnd(f) & tp2.mapAnd(f) case _ => f(this) } /** Map function over elements of an OrType, rebuilding with | */ - def mapOr(f: Type => Type)(implicit ctx: Context): Type = this match { + final def mapOr(f: Type => Type)(implicit ctx: Context): Type = this match { case OrType(tp1, tp2) => tp1.mapOr(f) | tp2.mapOr(f) case _ => f(this) } @@ -401,7 +402,7 @@ object Types { * - Or phase.erasedTypes is false and both types are neither method nor * poly types. */ - def matches(that: Type)(implicit ctx: Context): Boolean = + final def matches(that: Type)(implicit ctx: Context): Boolean = ctx.typeComparer.matchesType(this, that, !ctx.phase.erasedTypes) /** Does this type match that type @@ -613,33 +614,33 @@ object Types { finishHash(hashing.mix(seed, elemHash), arity + 1, tps) } - protected def doHash(x: Any): Int = + protected final def doHash(x: Any): Int = finishHash(hashing.mix(hashSeed, x.hashCode), 1) - protected def doHash(tp: Type): Int = + protected final def doHash(tp: Type): Int = finishHash(hashSeed, 0, tp) - protected def doHash(x1: Any, tp2: Type): Int = + protected final def doHash(x1: Any, tp2: Type): Int = finishHash(hashing.mix(hashSeed, x1.hashCode), 1, tp2) - protected def doHash(tp1: Type, tp2: Type): Int = + protected final def doHash(tp1: Type, tp2: Type): Int = finishHash(hashSeed, 0, tp1, tp2) - protected def doHash(x1: Any, tp2: Type, tp3: Type): Int = + protected final def doHash(x1: Any, tp2: Type, tp3: Type): Int = finishHash(hashing.mix(hashSeed, x1.hashCode), 1, tp2, tp3) - protected def doHash(tp1: Type, tps2: List[Type]): Int = + protected final def doHash(tp1: Type, tps2: List[Type]): Int = finishHash(hashSeed, 0, tp1, tps2) - protected def doHash(x1: Any, tp2: Type, tps3: List[Type]): Int = + protected final def doHash(x1: Any, tp2: Type, tps3: List[Type]): Int = finishHash(hashing.mix(hashSeed, x1.hashCode), 1, tp2, tps3) } // end Type /** A marker trait for cached types */ - trait CachedType extends Type + sealed trait CachedType extends Type - def unique[T <: Type](tp: T)(implicit ctx: Context): T = { + final def unique[T <: Type](tp: T)(implicit ctx: Context): T = { if (tp.hash == NotCached) tp else ctx.uniques.findEntryOrUpdate(tp).asInstanceOf[T] } @@ -647,7 +648,7 @@ object Types { /** A marker trait for type proxies. * Each implementation is expected to redefine the `underlying` method. */ - abstract class TypeProxy extends Type { + sealed abstract class TypeProxy extends Type { /** The type to which this proxy forwards operations. */ def underlying(implicit ctx: Context): Type } @@ -658,42 +659,42 @@ object Types { // is for efficiency. /** Instances of this class are cached and are not proxies. */ - abstract class CachedGroundType extends Type with CachedType { + sealed abstract class CachedGroundType extends Type with CachedType { final val hash = computeHash override final def hashCode = hash def computeHash: Int } /** Instances of this class are cached and are proxies. */ - abstract class CachedProxyType extends TypeProxy with CachedType { + sealed abstract class CachedProxyType extends TypeProxy with CachedType { final val hash = computeHash override final def hashCode = hash def computeHash: Int } /** Instances of this class are uncached and are not proxies. */ - abstract class UncachedGroundType extends Type { + sealed abstract class UncachedGroundType extends Type { final def hash = NotCached } /** Instances of this class are uncached and are proxies. */ - abstract class UncachedProxyType extends TypeProxy { + sealed abstract class UncachedProxyType extends TypeProxy { final def hash = NotCached } /** A marker trait for types that are guaranteed to contain only a * single non-null value (they might contain null in addition). */ - trait SingletonType extends TypeProxy + sealed trait SingletonType extends TypeProxy /** A marker trait for types that apply only to type symbols */ - trait TypeType extends Type + sealed trait TypeType extends Type // --- NamedTypes ------------------------------------------------------------------ /** A NamedType of the form Prefix # name */ - abstract class NamedType extends CachedProxyType { + sealed abstract class NamedType extends CachedProxyType { val prefix: Type val name: Name @@ -701,7 +702,7 @@ object Types { private[this] var lastDenotation: Denotation = null /** The denotation currently denoted by this type */ - def denot(implicit ctx: Context): Denotation = { + final def denot(implicit ctx: Context): Denotation = { val validPeriods = if (lastDenotation != null) lastDenotation.validFor else Nowhere if (!(validPeriods contains ctx.period)) { @@ -727,31 +728,31 @@ object Types { protected def loadDenot(implicit ctx: Context) = prefix.member(name) - def isType = name.isTypeName - def isTerm = name.isTermName + final def isType = name.isTypeName + final def isTerm = name.isTermName def symbol(implicit ctx: Context): Symbol = denot.symbol - def info(implicit ctx: Context): Type = denot.info + final def info(implicit ctx: Context): Type = denot.info override def underlying(implicit ctx: Context): Type = info - def isAbstractType(implicit ctx: Context) = info.isRealTypeBounds + final def isAbstractType(implicit ctx: Context) = info.isRealTypeBounds - def derivedNamedType(prefix: Type, name: Name)(implicit ctx: Context): Type = + final def derivedNamedType(prefix: Type, name: Name)(implicit ctx: Context): Type = if (prefix eq this.prefix) this else NamedType(prefix, name) override def computeHash = doHash(name, prefix) } - abstract case class TermRef(override val prefix: Type, name: TermName) extends NamedType with SingletonType + sealed abstract case class TermRef(override val prefix: Type, name: TermName) extends NamedType with SingletonType - abstract case class TypeRef(override val prefix: Type, name: TypeName) extends NamedType + sealed abstract case class TypeRef(override val prefix: Type, name: TypeName) extends NamedType - trait HasFixedSym extends NamedType { + sealed trait HasFixedSym extends NamedType { protected val fixedSym: Symbol - override def symbol(implicit ctx: Context): Symbol = fixedSym - override def loadDenot(implicit ctx: Context) = { + override final def symbol(implicit ctx: Context): Symbol = fixedSym + override final def loadDenot(implicit ctx: Context) = { val denot = fixedSym.denot val owner = denot.owner if (owner.isTerm) denot else denot.asSeenFrom(prefix, owner).toDenot @@ -802,7 +803,7 @@ object Types { // --- Other SingletonTypes: ThisType/SuperType/ConstantType --------------------------- - abstract case class ThisType(cls: ClassSymbol) extends CachedProxyType with SingletonType { + sealed abstract case class ThisType(cls: ClassSymbol) extends CachedProxyType with SingletonType { override def underlying(implicit ctx: Context) = cls.selfType override def computeHash = doHash(cls) } @@ -816,7 +817,7 @@ object Types { } } - abstract case class SuperType(thistpe: Type, supertpe: Type) extends CachedProxyType with SingletonType { + sealed abstract case class SuperType(thistpe: Type, supertpe: Type) extends CachedProxyType with SingletonType { override def underlying(implicit ctx: Context) = supertpe def derivedSuperType(thistp: Type, supertp: Type)(implicit ctx: Context) = if ((thistp eq thistpe) && (supertp eq supertpe)) this @@ -831,7 +832,7 @@ object Types { unique(new CachedSuperType(thistpe, supertpe)) } - abstract case class ConstantType(value: Constant) extends CachedProxyType with SingletonType { + sealed abstract case class ConstantType(value: Constant) extends CachedProxyType with SingletonType { override def underlying(implicit ctx: Context) = value.tpe override def computeHash = doHash(value) } @@ -845,7 +846,7 @@ object Types { // --- Refined Type --------------------------------------------------------- - abstract case class RefinedType(parent: Type, name: Name)(infof: RefinedType => Type) extends CachedProxyType with BindingType { + sealed abstract case class RefinedType(parent: Type, name: Name)(infof: RefinedType => Type) extends CachedProxyType with BindingType { val info: Type = infof(this) @@ -858,7 +859,7 @@ object Types { override def computeHash = doHash(name, info, parent) } - class CachedRefinedType(parent: Type, name: Name, infof: RefinedType => Type) extends RefinedType(parent, name)(infof) + final class CachedRefinedType(parent: Type, name: Name, infof: RefinedType => Type) extends RefinedType(parent, name)(infof) object RefinedType { def make(parent: Type, names: List[Name], infofs: List[RefinedType => Type])(implicit ctx: Context): Type = @@ -874,11 +875,11 @@ object Types { // --- AndType/OrType --------------------------------------------------------------- - abstract case class AndType(tp1: Type, tp2: Type) extends CachedGroundType { + sealed abstract case class AndType(tp1: Type, tp2: Type) extends CachedGroundType { type This <: AndType - def derivedAndType(t1: Type, t2: Type)(implicit ctx: Context) = + final def derivedAndType(t1: Type, t2: Type)(implicit ctx: Context) = if ((t1 eq tp1) && (t2 eq tp2)) this else AndType(t1, t2) @@ -892,12 +893,12 @@ object Types { unique(new CachedAndType(tp1, tp2)) } - abstract case class OrType(tp1: Type, tp2: Type) extends CachedGroundType { - def derivedOrType(t1: Type, t2: Type)(implicit ctx: Context) = + sealed abstract case class OrType(tp1: Type, tp2: Type) extends CachedGroundType { + final def derivedOrType(t1: Type, t2: Type)(implicit ctx: Context) = if ((t1 eq tp1) && (t2 eq tp2)) this else OrType(t1, t2) - override def computeHash = doHash(tp1, tp2) + override final def computeHash = doHash(tp1, tp2) } final class CachedOrType(tp1: Type, tp2: Type) extends OrType(tp1, tp2) @@ -909,14 +910,14 @@ object Types { // ----- Method types: MethodType/ExprType/PolyType/MethodParam/PolyParam --------------- - trait BindingType extends Type + sealed trait BindingType extends Type // Note: method types are cached whereas poly types are not. // The reason is that most poly types are cyclic via poly params, // and therefore two different poly types would never be equal. - abstract case class MethodType(paramNames: List[TermName], paramTypes: List[Type])(resultTypeExp: MethodType => Type) extends CachedGroundType with BindingType { - override lazy val resultType = resultTypeExp(this) + sealed abstract case class MethodType(paramNames: List[TermName], paramTypes: List[Type])(resultTypeExp: MethodType => Type) extends CachedGroundType with BindingType { + override final lazy val resultType = resultTypeExp(this) def isJava = false def isImplicit = false @@ -925,7 +926,7 @@ object Types { case _ => false } - override lazy val signature: List[TypeName] = { + override final lazy val signature: List[TypeName] = { def paramSig(tp: Type): TypeName = ??? val followSig = resultType match { case rtp: MethodType => rtp.signature @@ -934,7 +935,7 @@ object Types { (paramTypes map paramSig) ++ followSig } - def derivedMethodType(paramNames: List[TermName], paramTypes: List[Type], restpe: Type)(implicit ctx: Context) = + final def derivedMethodType(paramNames: List[TermName], paramTypes: List[Type], restpe: Type)(implicit ctx: Context) = if ((paramNames eq this.paramNames) && (paramTypes eq this.paramTypes) && (restpe eq this.resultType)) this else { val restpeExpr = (x: MethodType) => restpe.subst(this, x) @@ -943,11 +944,11 @@ object Types { else MethodType(paramNames, paramTypes)(restpeExpr) } - def instantiate(argTypes: List[Type])(implicit ctx: Context): Type = + final def instantiate(argTypes: List[Type])(implicit ctx: Context): Type = if (isDependent) new InstMethodMap(this, argTypes) apply resultType else resultType - override def computeHash = doHash(paramNames, resultType, paramTypes) + override final def computeHash = doHash(paramNames, resultType, paramTypes) } final class CachedMethodType(paramNames: List[TermName], paramTypes: List[Type])(resultTypeExp: MethodType => Type) @@ -963,9 +964,9 @@ object Types { override def isImplicit = true } - abstract class GenericMethodType { + sealed abstract class GenericMethodType { def apply(paramNames: List[TermName], paramTypes: List[Type])(resultTypeExp: MethodType => Type)(implicit ctx: Context): MethodType - def fromSymbols(params: List[Symbol], resultType: Type)(implicit ctx: Context) = { + final def fromSymbols(params: List[Symbol], resultType: Type)(implicit ctx: Context) = { def transResult(mt: MethodType) = resultType.subst(params, (0 until params.length).toList map (MethodParam(mt, _))) apply(params map (_.name.asTermName), params map (_.info))(transResult _) @@ -987,7 +988,7 @@ object Types { unique(new ImplicitMethodType(paramNames, paramTypes)(resultTypeExp)) } - abstract case class ExprType(override val resultType: Type) extends CachedProxyType { + sealed abstract case class ExprType(override val resultType: Type) extends CachedProxyType { override def underlying(implicit ctx: Context): Type = resultType override def signature: Signature = Nil def derivedExprType(rt: Type)(implicit ctx: Context) = @@ -1002,7 +1003,7 @@ object Types { unique(new CachedExprType(resultType)) } - case class PolyType(paramNames: List[TypeName])(paramBoundsExp: PolyType => List[TypeBounds], resultTypeExp: PolyType => Type) + final case class PolyType(paramNames: List[TypeName])(paramBoundsExp: PolyType => List[TypeBounds], resultTypeExp: PolyType => Type) extends UncachedGroundType with BindingType { lazy val paramBounds = paramBoundsExp(this) override lazy val resultType = resultTypeExp(this) @@ -1041,27 +1042,27 @@ object Types { } } - abstract class BoundType extends UncachedProxyType { + sealed abstract class BoundType extends UncachedProxyType { type BT <: BindingType def binder: BT def copy(bt: BT): Type } - case class MethodParam(binder: MethodType, paramNum: Int) extends BoundType with SingletonType { + final case class MethodParam(binder: MethodType, paramNum: Int) extends BoundType with SingletonType { type BT = MethodType override def underlying(implicit ctx: Context) = binder.paramTypes(paramNum) override def hashCode = doHash(System.identityHashCode(binder) + paramNum) def copy(bt: BT) = MethodParam(bt, paramNum) } - case class PolyParam(binder: PolyType, paramNum: Int) extends BoundType { + final case class PolyParam(binder: PolyType, paramNum: Int) extends BoundType { type BT = PolyType override def underlying(implicit ctx: Context) = binder.paramBounds(paramNum).hi def copy(bt: BT) = PolyParam(bt, paramNum) // no hashCode needed because cycle is broken in PolyType } - case class RefinedThis(binder: RefinedType) extends BoundType with SingletonType { + final case class RefinedThis(binder: RefinedType) extends BoundType with SingletonType { type BT = RefinedType override def underlying(implicit ctx: Context) = binder.parent def copy(bt: BT) = RefinedThis(bt) @@ -1070,24 +1071,24 @@ object Types { // ------ ClassInfo, Type Bounds ------------------------------------------------------------ - abstract case class ClassInfo(prefix: Type, classd: ClassDenotation) extends CachedGroundType with TypeType { + sealed abstract case class ClassInfo(prefix: Type, classd: ClassDenotation) extends CachedGroundType with TypeType { /* def typeTemplate(implicit ctx: Context): Type = classd.typeTemplate asSeenFrom (prefix, classd.symbol) */ - def typeConstructor(implicit ctx: Context): Type = + final def typeConstructor(implicit ctx: Context): Type = NamedType(prefix, classd.symbol.name) // cached because baseType needs parents - private var parentsCache: List[TypeRef] = null + private final var parentsCache: List[TypeRef] = null - override def parents(implicit ctx: Context): List[TypeRef] = { + override final def parents(implicit ctx: Context): List[TypeRef] = { if (parentsCache == null) parentsCache = classd.parents.mapConserve(_.substThis(classd.symbol, prefix).asInstanceOf[TypeRef]) parentsCache } - override def computeHash = doHash(classd.symbol, prefix) + override final def computeHash = doHash(classd.symbol, prefix) } final class CachedClassInfo(prefix: Type, classd: ClassDenotation) extends ClassInfo(prefix, classd) @@ -1097,26 +1098,26 @@ object Types { unique(new CachedClassInfo(prefix, classd)) } - abstract case class TypeBounds(lo: Type, hi: Type) extends CachedProxyType with TypeType { - override def underlying(implicit ctx: Context): Type = hi - def derivedTypeBounds(lo1: Type, hi1: Type)(implicit ctx: Context) = + sealed abstract case class TypeBounds(lo: Type, hi: Type) extends CachedProxyType with TypeType { + override final def underlying(implicit ctx: Context): Type = hi + final def derivedTypeBounds(lo1: Type, hi1: Type)(implicit ctx: Context) = if ((lo1 eq lo) && (hi1 eq hi)) this else TypeBounds(lo, hi) - def contains(tp: Type)(implicit ctx: Context) = lo <:< tp && tp <:< hi + final def contains(tp: Type)(implicit ctx: Context) = lo <:< tp && tp <:< hi - def &(that: TypeBounds)(implicit ctx: Context): TypeBounds = + final def &(that: TypeBounds)(implicit ctx: Context): TypeBounds = TypeBounds(this.lo | that.lo, this.hi & that.hi) - def |(that: TypeBounds)(implicit ctx: Context): TypeBounds = + final def |(that: TypeBounds)(implicit ctx: Context): TypeBounds = TypeBounds(this.lo & that.lo, this.hi | that.hi) - def substBounds(from: PolyType, to: PolyType)(implicit ctx: Context) = + final def substBounds(from: PolyType, to: PolyType)(implicit ctx: Context) = subst(from, to).asInstanceOf[TypeBounds] - def map(f: Type => Type)(implicit ctx: Context): TypeBounds = + final def map(f: Type => Type)(implicit ctx: Context): TypeBounds = TypeBounds(f(lo), f(hi)) - override def computeHash = doHash(lo, hi) + override final def computeHash = doHash(lo, hi) } final class CachedTypeBounds(lo: Type, hi: Type) extends TypeBounds(lo, hi) @@ -1139,7 +1140,7 @@ object Types { // ----- Annotated and Import types ----------------------------------------------- - case class AnnotatedType(annots: List[Annotation], tpe: Type) extends UncachedProxyType { + final case class AnnotatedType(annots: List[Annotation], tpe: Type) extends UncachedProxyType { override def underlying(implicit ctx: Context): Type = tpe def derivedAnnotatedType(annots1: List[Annotation], tpe1: Type) = if ((annots1 eq annots) && (tpe1 eq tpe)) this @@ -1152,7 +1153,14 @@ object Types { else AnnotatedType(annots, underlying) } - case class ImportType(expr: TypedTree) extends UncachedGroundType + final case class ImportType(expr: TypedTree) extends UncachedGroundType + + // Unpickler Types ----------------------------------------------------------------- + final case class TempPolyType(tparams: List[Symbol], tpe: Type) extends UncachedGroundType + + /** Temporary type for classinfos, will be decomposed on completion of the class */ + final case class TempClassInfoType(parentTypes: List[Type], decls: Scope, clazz: Symbol) extends UncachedGroundType + // Special type objects ------------------------------------------------------------ @@ -1166,7 +1174,7 @@ object Types { override def computeHash = hashSeed } - abstract class ErrorType extends UncachedGroundType + sealed abstract class ErrorType extends UncachedGroundType object ErrorType extends ErrorType @@ -1223,14 +1231,14 @@ object Types { } - class InstMethodMap(mt: MethodType, argtypes: List[Type])(implicit ctx: Context) extends TypeMap { + final class InstMethodMap(mt: MethodType, argtypes: List[Type])(implicit ctx: Context) extends TypeMap { def apply(tp: Type) = tp match { case MethodParam(`mt`, n) => argtypes(n) case _ => mapOver(tp) } } - class InstPolyMap(pt: PolyType, argtypes: List[Type])(implicit ctx: Context) extends TypeMap { + final class InstPolyMap(pt: PolyType, argtypes: List[Type])(implicit ctx: Context) extends TypeMap { def apply(tp: Type) = tp match { case PolyParam(`pt`, n) => argtypes(n) case _ => mapOver(tp) @@ -1279,7 +1287,7 @@ object Types { } } - class ExistsAccumulator(p: Type => Boolean) extends TypeAccumulator[Boolean] { + final class ExistsAccumulator(p: Type => Boolean) extends TypeAccumulator[Boolean] { def apply(x: Boolean, tp: Type) = x || p(tp) || foldOver(x, tp) } diff --git a/src/dotty/tools/dotc/core/pickling/AbstractFileReader.scala b/src/dotty/tools/dotc/core/pickling/AbstractFileReader.scala index 60633370d58a..a0fc079175ba 100644 --- a/src/dotty/tools/dotc/core/pickling/AbstractFileReader.scala +++ b/src/dotty/tools/dotc/core/pickling/AbstractFileReader.scala @@ -14,7 +14,7 @@ import io.AbstractFile * @author Philippe Altherr * @version 1.0, 23/03/2004 */ -class AbstractFileReader(val file: AbstractFile) { +final class AbstractFileReader(val file: AbstractFile) { /** the buffer containing the file */ diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileConstants.scala b/src/dotty/tools/dotc/core/pickling/ClassfileConstants.scala index 5e97f373d28a..b9fa88026463 100644 --- a/src/dotty/tools/dotc/core/pickling/ClassfileConstants.scala +++ b/src/dotty/tools/dotc/core/pickling/ClassfileConstants.scala @@ -324,7 +324,7 @@ object ClassfileConstants { final val impdep1 = 0xfe final val impdep2 = 0xff - abstract class FlagTranslation { + sealed abstract class FlagTranslation { import Flags._ private var isAnnotation = false @@ -360,16 +360,16 @@ object ClassfileConstants { res } - def classFlags(jflags: Int): FlagSet = { + final def classFlags(jflags: Int): FlagSet = { initFields(jflags) isClass = true translateFlags(jflags, EmptyFlags) } - def fieldFlags(jflags: Int): FlagSet = { + final def fieldFlags(jflags: Int): FlagSet = { initFields(jflags) translateFlags(jflags, if ((jflags & JAVA_ACC_FINAL) == 0) Mutable else EmptyFlags) } - def methodFlags(jflags: Int): FlagSet = { + final def methodFlags(jflags: Int): FlagSet = { initFields(jflags) translateFlags(jflags, if ((jflags & JAVA_ACC_BRIDGE) != 0) Bridge else EmptyFlags) } diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala index 2f370fbddfe8..8a2f725f171e 100644 --- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala +++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala @@ -13,7 +13,7 @@ import scala.collection.mutable.{ ListBuffer, ArrayBuffer } import scala.annotation.switch import io.AbstractFile -class ClassfileParser( +final class ClassfileParser( classfile: AbstractFile, classRoot: LazyClassDenotation, moduleRoot: LazyClassDenotation)(implicit cctx: CondensedContext) { @@ -608,7 +608,7 @@ class ClassfileParser( } /** An entry in the InnerClasses attribute of this class file. */ - case class InnerClassEntry(external: Int, outer: Int, name: Int, jflags: Int) { + final case class InnerClassEntry(external: Int, outer: Int, name: Int, jflags: Int) { def externalName = pool.getClassName(external) def outerName = pool.getClassName(outer) def originalName = pool.getName(name) diff --git a/src/dotty/tools/dotc/core/pickling/PickleBuffer.scala b/src/dotty/tools/dotc/core/pickling/PickleBuffer.scala index 9e58c549144b..92748fc03981 100644 --- a/src/dotty/tools/dotc/core/pickling/PickleBuffer.scala +++ b/src/dotty/tools/dotc/core/pickling/PickleBuffer.scala @@ -11,7 +11,7 @@ import Flags._ * @param from The first index where defined data are found * @param to The first index where new data can be written */ -class PickleBuffer(data: Array[Byte], from: Int, to: Int) { +abstract class PickleBuffer(data: Array[Byte], from: Int, to: Int) { var bytes = data var readIndex = from @@ -24,13 +24,13 @@ class PickleBuffer(data: Array[Byte], from: Int, to: Int) { bytes = bytes1 } - def ensureCapacity(capacity: Int) = + final def ensureCapacity(capacity: Int) = while (bytes.length < writeIndex + capacity) dble() // -- Basic output routines -------------------------------------------- /** Write a byte of data */ - def writeByte(b: Int) { + final def writeByte(b: Int) { if (writeIndex == bytes.length) dble() bytes(writeIndex) = b.toByte writeIndex += 1 @@ -39,7 +39,7 @@ class PickleBuffer(data: Array[Byte], from: Int, to: Int) { /** Write a natural number in big endian format, base 128. * All but the last digits have bit 0x80 set. */ - def writeNat(x: Int) = + final def writeNat(x: Int) = writeLongNat(x.toLong & 0x00000000FFFFFFFFL) /** @@ -49,7 +49,7 @@ class PickleBuffer(data: Array[Byte], from: Int, to: Int) { * if the long value is in the range Int.MIN_VALUE to * Int.MAX_VALUE. */ - def writeLongNat(x: Long) { + final def writeLongNat(x: Long) { def writeNatPrefix(x: Long) { val y = x >>> 7 if (y != 0L) writeNatPrefix(y) @@ -66,7 +66,7 @@ class PickleBuffer(data: Array[Byte], from: Int, to: Int) { * @param pos ... * @param x ... */ - def patchNat(pos: Int, x: Int) { + final def patchNat(pos: Int, x: Int) { def patchNatPrefix(x: Int) { writeByte(0) Array.copy(bytes, pos, bytes, pos+1, writeIndex - (pos+1)) @@ -83,7 +83,7 @@ class PickleBuffer(data: Array[Byte], from: Int, to: Int) { * * @param x The long number to be written. */ - def writeLong(x: Long) { + final def writeLong(x: Long) { val y = x >> 8 val z = x & 0xff if (-y != (z >> 7)) writeLong(y) @@ -93,18 +93,18 @@ class PickleBuffer(data: Array[Byte], from: Int, to: Int) { // -- Basic input routines -------------------------------------------- /** Peek at the current byte without moving the read index */ - def peekByte(): Int = bytes(readIndex) + final def peekByte(): Int = bytes(readIndex) /** Read a byte */ - def readByte(): Int = { + final def readByte(): Int = { val x = bytes(readIndex); readIndex += 1; x } /** Read a natural number in big endian format, base 128. * All but the last digits have bit 0x80 set.*/ - def readNat(): Int = readLongNat().toInt + final def readNat(): Int = readLongNat().toInt - def readLongNat(): Long = { + final def readLongNat(): Long = { var b = 0L var x = 0L do { @@ -115,7 +115,7 @@ class PickleBuffer(data: Array[Byte], from: Int, to: Int) { } /** Read a long number in signed big endian format, base 256. */ - def readLong(len: Int): Long = { + final def readLong(len: Int): Long = { var x = 0L var i = 0 while (i < len) { @@ -129,8 +129,7 @@ class PickleBuffer(data: Array[Byte], from: Int, to: Int) { /** Returns the buffer as a sequence of (Int, Array[Byte]) representing * (tag, data) of the individual entries. Saves and restores buffer state. */ - - def toIndexedSeq: IndexedSeq[(Int, Array[Byte])] = { + final def toIndexedSeq: IndexedSeq[(Int, Array[Byte])] = { val saved = readIndex readIndex = 0 readNat() ; readNat() // discarding version @@ -157,14 +156,14 @@ class PickleBuffer(data: Array[Byte], from: Int, to: Int) { * @param op ... * @return ... */ - def until[T](end: Int, op: () => T): List[T] = + final def until[T](end: Int, op: () => T): List[T] = if (readIndex == end) List() else op() :: until(end, op); /** Perform operation op the number of * times specified. Concatenate the results into a list. */ - def times[T](n: Int, op: ()=>T): List[T] = + final def times[T](n: Int, op: ()=>T): List[T] = if (n == 0) List() else op() :: times(n-1, op) - def unpickleScalaFlags(sflags: Long): FlagSet = ??? + final def unpickleScalaFlags(sflags: Long): FlagSet = ??? } diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala index 71601fedf7de..9e418bcdb872 100644 --- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala +++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala @@ -21,11 +21,6 @@ object UnPickler { /** Exception thrown if classfile is corrupted */ class BadSignature(msg: String) extends RuntimeException(msg) - case class TempPolyType(tparams: List[Symbol], tpe: Type) extends UncachedGroundType - - /** Temporary type for classinfos, will be decomposed on completion of the class */ - case class TempClassInfoType(parentTypes: List[Type], decls: Scope, clazz: Symbol) extends UncachedGroundType - def depoly(tp: Type)(implicit ctx: Context): Type = tp match { case TempPolyType(tparams, restpe) => PolyType.fromSymbols(tparams, restpe) case tp => tp @@ -72,7 +67,7 @@ object UnPickler { * @param moduleroot the top-level module class which is unpickled, or NoSymbol if inapplicable * @param filename filename associated with bytearray, only used for error messages */ -class UnPickler(bytes: Array[Byte], classRoot: LazyClassDenotation, moduleRoot: LazyClassDenotation)(implicit cctx: CondensedContext) +final class UnPickler(bytes: Array[Byte], classRoot: LazyClassDenotation, moduleRoot: LazyClassDenotation)(implicit cctx: CondensedContext) extends PickleBuffer(bytes, 0, -1) { import UnPickler._