summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2012-01-25 15:04:53 +0100
committerMartin Odersky <odersky@gmail.com>2012-01-25 15:04:53 +0100
commitc749710859d32252291802d55d48abe518ddd118 (patch)
treefef90dd9afa4c595b533cb137d27c64b66cb2ce6
parent65a1e8bd2dbd796bedc0232615cfc3caf18fd4b3 (diff)
downloadscala-c749710859d32252291802d55d48abe518ddd118.tar.gz
scala-c749710859d32252291802d55d48abe518ddd118.tar.bz2
scala-c749710859d32252291802d55d48abe518ddd118.zip
Making reflection thread-safe.
The idea is that all operations that need to be synchronized are overriden in classes reflect.runtime.Synchronized*. Sometimes this applies to operations defined in SymbolTable, which can be directly overridden. Sometimes it is more convenient to generate SynchronizedClazz subclasses of SymbolTable classes Clazz. In the latter case, all instance creation must go over factory methods that can be overridden in the Synchronized traits.
-rw-r--r--src/compiler/scala/reflect/internal/BaseTypeSeqs.scala47
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala8
-rw-r--r--src/compiler/scala/reflect/internal/Importers.scala4
-rw-r--r--src/compiler/scala/reflect/internal/Scopes.scala46
-rw-r--r--src/compiler/scala/reflect/internal/SymbolTable.scala5
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala121
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala448
-rw-r--r--src/compiler/scala/reflect/runtime/Loaders.scala2
-rw-r--r--src/compiler/scala/reflect/runtime/Mirror.scala3
-rw-r--r--src/compiler/scala/reflect/runtime/SymbolTable.scala2
-rw-r--r--src/compiler/scala/reflect/runtime/SynchronizedOps.scala52
-rw-r--r--src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala119
-rw-r--r--src/compiler/scala/reflect/runtime/SynchronizedTypes.scala87
-rw-r--r--src/compiler/scala/reflect/runtime/ToolBoxes.scala2
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala2
-rw-r--r--src/compiler/scala/tools/nsc/matching/Patterns.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala4
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala4
-rw-r--r--src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala8
-rw-r--r--src/compiler/scala/tools/nsc/transform/AddInterfaces.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Flatten.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala6
-rw-r--r--src/compiler/scala/tools/nsc/transform/OverridingPairs.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala6
-rw-r--r--src/detach/plugin/scala/tools/detach/Detach.scala4
-rwxr-xr-xsrc/library/scala/reflect/api/StandardDefinitions.scala4
-rwxr-xr-xsrc/library/scala/reflect/api/Types.scala39
-rw-r--r--test/files/run/reflection-implClass.scala16
38 files changed, 726 insertions, 345 deletions
diff --git a/src/compiler/scala/reflect/internal/BaseTypeSeqs.scala b/src/compiler/scala/reflect/internal/BaseTypeSeqs.scala
index 38277b5a09..53e89b3d1e 100644
--- a/src/compiler/scala/reflect/internal/BaseTypeSeqs.scala
+++ b/src/compiler/scala/reflect/internal/BaseTypeSeqs.scala
@@ -29,7 +29,10 @@ trait BaseTypeSeqs {
this: SymbolTable =>
import definitions._
- class BaseTypeSeq(parents: List[Type], elems: Array[Type]) {
+ protected def newBaseTypeSeq(parents: List[Type], elems: Array[Type]) =
+ new BaseTypeSeq(parents, elems)
+
+ class BaseTypeSeq(private[BaseTypeSeqs] val parents: List[Type], private[BaseTypeSeqs] val elems: Array[Type]) {
self =>
incCounter(baseTypeSeqCount)
incCounter(baseTypeSeqLenTotal, elems.length)
@@ -41,7 +44,7 @@ trait BaseTypeSeqs {
// (while NoType is in there to indicate a cycle in this BTS, during the execution of
// the mergePrefixAndArgs below, the elems get copied without the pending map,
// so that NoType's are seen instead of the original type --> spurious compile error)
- val pending = new mutable.BitSet(length)
+ private val pending = new mutable.BitSet(length)
/** The type at i'th position in this sequence; lazy types are returned evaluated. */
def apply(i: Int): Type =
@@ -89,11 +92,11 @@ trait BaseTypeSeqs {
/** Return all evaluated types in this sequence as a list */
def toList: List[Type] = elems.toList
- protected def copy(head: Type, offset: Int): BaseTypeSeq = {
+ def copy(head: Type, offset: Int): BaseTypeSeq = {
val arr = new Array[Type](elems.length + offset)
compat.Platform.arraycopy(elems, 0, arr, offset, elems.length)
arr(0) = head
- new BaseTypeSeq(parents, arr)
+ newBaseTypeSeq(parents, arr)
}
/** Compute new base type sequence with `tp` prepended to this sequence */
@@ -113,21 +116,10 @@ trait BaseTypeSeqs {
arr(i) = f(elems(i))
i += 1
}
- new BaseTypeSeq(parents, arr)
+ newBaseTypeSeq(parents, arr)
}
- def lateMap(f: Type => Type): BaseTypeSeq = new BaseTypeSeq(parents map f, elems) {
- override def apply(i: Int) = f(self.apply(i))
- override def rawElem(i: Int) = f(self.rawElem(i))
- override def typeSymbol(i: Int) = self.typeSymbol(i)
- override def toList = self.toList map f
- override protected def copy(head: Type, offset: Int) = (self map f).copy(head, offset)
- override def map(g: Type => Type) = lateMap(g)
- override def lateMap(g: Type => Type) = self.lateMap(x => g(f(x)))
- override def exists(p: Type => Boolean) = elems exists (x => p(f(x)))
- override protected def maxDepthOfElems: Int = elems map (x => maxDpth(f(x))) max
- override def toString = elems.mkString("MBTS(", ",", ")")
- }
+ def lateMap(f: Type => Type): BaseTypeSeq = new MappedBaseTypeSeq(this, f)
def exists(p: Type => Boolean): Boolean = elems exists p
@@ -177,10 +169,10 @@ trait BaseTypeSeqs {
/** A merker object for a base type sequence that's no yet computed.
* used to catch inheritance cycles
*/
- val undetBaseTypeSeq: BaseTypeSeq = new BaseTypeSeq(List(), Array())
+ val undetBaseTypeSeq: BaseTypeSeq = newBaseTypeSeq(List(), Array())
/** Create a base type sequence consisting of a single type */
- def baseTypeSingletonSeq(tp: Type): BaseTypeSeq = new BaseTypeSeq(List(), Array(tp))
+ def baseTypeSingletonSeq(tp: Type): BaseTypeSeq = newBaseTypeSeq(List(), Array(tp))
/** Create the base type sequence of a compound type wuth given tp.parents */
def compoundBaseTypeSeq(tp: Type): BaseTypeSeq = {
@@ -244,8 +236,21 @@ trait BaseTypeSeqs {
val elems = new Array[Type](btsSize)
buf.copyToArray(elems, 0)
// Console.println("computed baseTypeSeq of " + tsym.tpe + " " + parents + ": "+elems.toString)//DEBUG
- new BaseTypeSeq(parents, elems)
+ newBaseTypeSeq(parents, elems)
}
-
+
+ class MappedBaseTypeSeq(orig: BaseTypeSeq, f: Type => Type) extends BaseTypeSeq(orig.parents map f, orig.elems) {
+ override def apply(i: Int) = f(orig.apply(i))
+ override def rawElem(i: Int) = f(orig.rawElem(i))
+ override def typeSymbol(i: Int) = orig.typeSymbol(i)
+ override def toList = orig.toList map f
+ override def copy(head: Type, offset: Int) = (orig map f).copy(head, offset)
+ override def map(g: Type => Type) = lateMap(g)
+ override def lateMap(g: Type => Type) = orig.lateMap(x => g(f(x)))
+ override def exists(p: Type => Boolean) = elems exists (x => p(f(x)))
+ override protected def maxDepthOfElems: Int = elems map (x => maxDpth(f(x))) max
+ override def toString = elems.mkString("MBTS(", ",", ")")
+ }
+
val CyclicInheritance = new Throwable
}
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index d38b62cbb4..a733f0d1ee 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -16,7 +16,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
private def newClass(owner: Symbol, name: TypeName, parents: List[Type], flags: Long = 0L): Symbol = {
val clazz = owner.newClassSymbol(name, NoPosition, flags)
- clazz setInfoAndEnter ClassInfoType(parents, new Scope, clazz)
+ clazz setInfoAndEnter ClassInfoType(parents, newScope, clazz)
}
private def newMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type, flags: Long = 0L): Symbol = {
val msym = owner.newMethod(name.encode, NoPosition, flags)
@@ -206,7 +206,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
sealed abstract class BottomClassSymbol(name: TypeName, parent: Symbol) extends ClassSymbol(ScalaPackageClass, NoPosition, name) {
locally {
this initFlags ABSTRACT | TRAIT | FINAL
- this setInfoAndEnter ClassInfoType(List(parent.tpe), new Scope, this)
+ this setInfoAndEnter ClassInfoType(List(parent.tpe), newScope, this)
}
final override def isBottomClass = true
}
@@ -352,7 +352,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
)
lazy val EqualsPatternClass = {
val clazz = newClass(ScalaPackageClass, tpnme.EQUALS_PATTERN_NAME, Nil)
- clazz setInfo polyType(List(newTypeParam(clazz, 0)), ClassInfoType(anyparam, new Scope, clazz))
+ clazz setInfo polyType(List(newTypeParam(clazz, 0)), ClassInfoType(anyparam, newScope, clazz))
}
lazy val MatchingStrategyClass = getRequiredClass("scala.MatchingStrategy")
@@ -823,7 +823,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
clazz.setInfo(
polyType(
List(tparam),
- ClassInfoType(List(AnyRefClass.tpe, p), new Scope, clazz)))
+ ClassInfoType(List(AnyRefClass.tpe, p), newScope, clazz)))
}
private def newAlias(owner: Symbol, name: TypeName, alias: Type): Symbol =
diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala
index 53380952c0..23b443919a 100644
--- a/src/compiler/scala/reflect/internal/Importers.scala
+++ b/src/compiler/scala/reflect/internal/Importers.scala
@@ -210,9 +210,9 @@ trait Importers { self: SymbolTable =>
result
}
- // !!! todo: override to vcater for PackageScopes
+ // !!! todo: override to cater for PackageScopes
def importScope(decls: from.Scope): Scope =
- new Scope(decls.toList map importSymbol)
+ newScopeWith(decls.toList map importSymbol: _*)
def importName(name: from.Name): Name =
if (name.isTypeName) newTypeName(name.toString) else newTermName(name.toString)
diff --git a/src/compiler/scala/reflect/internal/Scopes.scala b/src/compiler/scala/reflect/internal/Scopes.scala
index fb3012adff..8861386bc8 100644
--- a/src/compiler/scala/reflect/internal/Scopes.scala
+++ b/src/compiler/scala/reflect/internal/Scopes.scala
@@ -37,9 +37,14 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
def unapplySeq(decls: Scope): Some[Seq[Symbol]] = Some(decls.toList)
}
- class Scope(initElems: ScopeEntry) extends Iterable[Symbol] {
+ class Scope(initElems: ScopeEntry = null) extends Iterable[Symbol] {
+
+ def this(base: Scope) = {
+ this(base.elems)
+ nestinglevel = base.nestinglevel + 1
+ }
- var elems: ScopeEntry = initElems
+ private[scala] var elems: ScopeEntry = initElems
/** The number of times this scope is nested in another
*/
@@ -65,20 +70,8 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
if (size >= MIN_HASH) createHash()
- def this() = this(null: ScopeEntry)
-
- def this(base: Scope) = {
- this(base.elems)
- nestinglevel = base.nestinglevel + 1
- }
-
- def this(decls: List[Symbol]) = {
- this()
- decls foreach enter
- }
-
/** Returns a new scope with the same content as this one. */
- def cloneScope: Scope = new Scope(this.toList)
+ def cloneScope: Scope = newScopeWith(this.toList: _*)
/** is the scope empty? */
override def isEmpty: Boolean = elems eq null
@@ -311,7 +304,7 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
override def foreach[U](p: Symbol => U): Unit = toList foreach p
override def filter(p: Symbol => Boolean): Scope =
- if (!(toList forall p)) new Scope(toList filter p) else this
+ if (!(toList forall p)) newScopeWith(toList filter p: _*) else this
override def mkString(start: String, sep: String, end: String) =
toList.map(_.defString).mkString(start, sep, end)
@@ -321,21 +314,26 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
}
/** Create a new scope */
- def newScope: Scope = new Scope
+ def newScope: Scope = new Scope()
+
+ /** Create a new scope nested in another one with which it shares its elements */
+ def newNestedScope(outer: Scope): Scope = new Scope(outer)
+
+ /** Create a new scope with given initial elements */
+ def newScopeWith(elems: Symbol*): Scope = {
+ val scope = newScope
+ elems foreach scope.enter
+ scope
+ }
/** Create new scope for the members of package `pkg` */
- def newPackageScope(pkgClass: Symbol): Scope = new Scope
+ def newPackageScope(pkgClass: Symbol): Scope = newScope
/** Transform scope of members of `owner` using operation `op`
* This is overridden by the reflective compiler to avoid creating new scopes for packages
*/
def scopeTransform(owner: Symbol)(op: => Scope): Scope = op
- def newScopeWith(elems: Symbol*): Scope = {
- val scope = newScope
- elems foreach scope.enter
- scope
- }
/** The empty scope (immutable).
*/
@@ -347,7 +345,7 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
/** The error scope.
*/
- class ErrorScope(owner: Symbol) extends Scope(null: ScopeEntry)
+ class ErrorScope(owner: Symbol) extends Scope
private final val maxRecursions = 1000
diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala
index ace4d55b90..717693fa1f 100644
--- a/src/compiler/scala/reflect/internal/SymbolTable.scala
+++ b/src/compiler/scala/reflect/internal/SymbolTable.scala
@@ -271,4 +271,9 @@ abstract class SymbolTable extends api.Universe
/** The phase which has given index as identifier. */
val phaseWithId: Array[Phase]
+
+ /** Is this symbol table part of reflexive mirror? In this case
+ * operations need to be made thread safe.
+ */
+ def inReflexiveMirror = false
}
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index b4d2b1531f..ecd2de6f56 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -16,10 +16,13 @@ import api.Modifier
trait Symbols extends api.Symbols { self: SymbolTable =>
import definitions._
- private var ids = 0
+ protected var ids = 0
+
+ val emptySymbolArray = new Array[Symbol](0)
+
def symbolCount = ids // statistics
- val emptySymbolArray = new Array[Symbol](0)
+ protected def nextId() = { ids += 1; ids }
/** Used for deciding in the IDE whether we can interrupt the compiler */
//protected var activeLocks = 0
@@ -31,7 +34,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
private var recursionTable = immutable.Map.empty[Symbol, Int]
private var nextexid = 0
- private def freshExistentialName(suffix: String) = {
+ protected def freshExistentialName(suffix: String) = {
nextexid += 1
newTypeName("_" + nextexid + suffix)
}
@@ -42,6 +45,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
m setModuleClass moduleClass
m
}
+
/** Create a new free variable. Its owner is NoSymbol.
*/
def newFreeVar(name: TermName, tpe: Type, value: Any, newFlags: Long = 0L): FreeVar =
@@ -77,14 +81,24 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
type AccessBoundaryType = Symbol
type AnnotationType = AnnotationInfo
- var rawowner = initOwner
- var rawname = initName
- var rawflags = 0L
-
+ private[this] var _rawowner = initOwner // Syncnote: need not be protected, as only assignment happens in owner_=, which is not exposed to api
+ private[this] var _rawname = initName
+ private[this] var _rawflags = 0L
+
+ def rawowner = _rawowner
+ def rawname = _rawname
+ def rawflags = _rawflags
+
+ protected def rawflags_=(x: FlagsType) { _rawflags = x }
+
private var rawpos = initPos
- val id = { ids += 1; ids } // identity displayed when -uniqid
+
+ val id = nextId() // identity displayed when -uniqid
- var validTo: Period = NoPeriod
+ private[this] var _validTo: Period = NoPeriod
+
+ def validTo = _validTo
+ def validTo_=(x: Period) { _validTo = x}
def pos = rawpos
def setPos(pos: Position): this.type = { this.rawpos = pos; this }
@@ -336,7 +350,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// True if the symbol is unlocked.
// True if the symbol is locked but still below the allowed recursion depth.
// False otherwise
- def lockOK: Boolean = {
+ private[scala] def lockOK: Boolean = {
((rawflags & LOCKED) == 0L) ||
((settings.Yrecursion.value != 0) &&
(recursionTable get this match {
@@ -345,7 +359,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
// Lock a symbol, using the handler if the recursion depth becomes too great.
- def lock(handler: => Unit) = {
+ private[scala] def lock(handler: => Unit) = {
if ((rawflags & LOCKED) != 0L) {
if (settings.Yrecursion.value != 0) {
recursionTable get this match {
@@ -360,18 +374,18 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
} else { handler }
} else {
- rawflags |= LOCKED
+ _rawflags |= LOCKED
// activeLocks += 1
// lockedSyms += this
}
}
// Unlock a symbol
- def unlock() = {
+ private[scala] def unlock() = {
if ((rawflags & LOCKED) != 0L) {
// activeLocks -= 1
// lockedSyms -= this
- rawflags = rawflags & ~LOCKED
+ _rawflags = rawflags & ~LOCKED
if (settings.Yrecursion.value != 0)
recursionTable -= this
}
@@ -736,7 +750,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// ------ owner attribute --------------------------------------------------------------
def owner: Symbol = rawowner
- final def owner_=(owner: Symbol) {
+ def owner_=(owner: Symbol) {
// don't keep the original owner in presentation compiler runs
// (the map will grow indefinitely, and the only use case is the
// backend).
@@ -744,8 +758,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
if (originalOwner contains this) ()
else originalOwner(this) = rawowner
}
-
- rawowner = owner
+ assert(!inReflexiveMirror, "owner_= is not thread-safe; cannot be run in reflexive code")
+ _rawowner = owner
}
def ownerChain: List[Symbol] = this :: owner.ownerChain
@@ -778,7 +792,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def name: Name = rawname
- final def name_=(name: Name) {
+ def name_=(name: Name) {
if (name != rawname) {
if (owner.isClass) {
var ifs = owner.infos
@@ -787,7 +801,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
ifs = ifs.prev
}
}
- rawname = name
+ _rawname = name
}
}
@@ -855,20 +869,20 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
val fs = rawflags & phase.flagMask
(fs | ((fs & LateFlags) >>> LateShift)) & ~(fs >>> AntiShift)
}
- final def flags_=(fs: Long) = rawflags = fs
+ def flags_=(fs: Long) = _rawflags = fs
/** Set the symbol's flags to the given value, asserting
* that the previous value was 0.
*/
def initFlags(mask: Long): this.type = {
assert(rawflags == 0L, this)
- rawflags = mask
+ _rawflags = mask
this
}
- def setFlag(mask: Long): this.type = { rawflags = rawflags | mask ; this }
- def resetFlag(mask: Long): this.type = { rawflags = rawflags & ~mask ; this }
+ def setFlag(mask: Long): this.type = { _rawflags = rawflags | mask ; this }
+ def resetFlag(mask: Long): this.type = { _rawflags = rawflags & ~mask ; this }
final def getFlag(mask: Long): Long = flags & mask
- final def resetFlags() { rawflags = rawflags & TopLevelCreationFlags }
+ final def resetFlags() { _rawflags = rawflags & TopLevelCreationFlags }
/** Does symbol have ANY flag in `mask` set? */
final def hasFlag(mask: Long): Boolean = (flags & mask) != 0L
@@ -954,7 +968,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
throw CyclicReference(this, tp)
}
} else {
- rawflags |= LOCKED
+ _rawflags |= LOCKED
// activeLocks += 1
// lockedSyms += this
}
@@ -984,7 +998,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
assert(info ne null)
infos = TypeHistory(currentPeriod, info, null)
unlock()
- validTo = if (info.isComplete) currentPeriod else NoPeriod
+ _validTo = if (info.isComplete) currentPeriod else NoPeriod
}
/** Set initial info. */
@@ -1003,11 +1017,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
/** Set new info valid from start of this phase. */
- final def updateInfo(info: Type): Symbol = {
+ def updateInfo(info: Type): Symbol = {
assert(phaseId(infos.validFrom) <= phase.id)
if (phaseId(infos.validFrom) == phase.id) infos = infos.prev
infos = TypeHistory(currentPeriod, info, infos)
- validTo = if (info.isComplete) currentPeriod else NoPeriod
+ _validTo = if (info.isComplete) currentPeriod else NoPeriod
this
}
@@ -1045,11 +1059,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
infos = TypeHistory(currentPeriod + 1, info1, infos)
this.infos = infos
}
- validTo = currentPeriod + 1 // to enable reads from same symbol during info-transform
+ _validTo = currentPeriod + 1 // to enable reads from same symbol during info-transform
itr = itr.next
}
- validTo = if (itr.pid == NoPhase.id) curPeriod
- else period(currentRunId, itr.pid)
+ _validTo = if (itr.pid == NoPhase.id) curPeriod
+ else period(currentRunId, itr.pid)
}
} finally {
phase = current
@@ -1060,7 +1074,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
// adapt to new run in fsc.
- private def adaptInfos(infos: TypeHistory): TypeHistory =
+ private def adaptInfos(infos: TypeHistory): TypeHistory = {
+ assert(!inReflexiveMirror)
if (infos == null || runId(infos.validFrom) == currentRunId) {
infos
} else {
@@ -1069,7 +1084,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
else {
val pid = phaseId(infos.validFrom)
- validTo = period(currentRunId, pid)
+ _validTo = period(currentRunId, pid)
phase = phaseWithId(pid)
val info1 = (
@@ -1085,6 +1100,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
}
}
+ }
/** Initialize the symbol */
final def initialize: this.type = {
@@ -1094,6 +1110,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Was symbol's type updated during given phase? */
final def isUpdatedAt(pid: Phase#Id): Boolean = {
+ assert(!inReflexiveMirror)
var infos = this.infos
while ((infos ne null) && phaseId(infos.validFrom) != pid + 1) infos = infos.prev
infos ne null
@@ -1101,6 +1118,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Was symbol's type updated during given phase? */
final def hasTypeAt(pid: Phase#Id): Boolean = {
+ assert(!inReflexiveMirror)
var infos = this.infos
while ((infos ne null) && phaseId(infos.validFrom) > pid) infos = infos.prev
infos ne null
@@ -1212,7 +1230,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def reset(completer: Type) {
resetFlags()
infos = null
- validTo = NoPeriod
+ _validTo = NoPeriod
//limit = NoPhase.id
setInfo(completer)
}
@@ -1239,7 +1257,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// ----- annotations ------------------------------------------------------------
// null is a marker that they still need to be obtained.
- private var _annotations: List[AnnotationInfo] = Nil
+ private[this] var _annotations: List[AnnotationInfo] = Nil
def annotationsString = if (annotations.isEmpty) "" else annotations.mkString("(", ", ", ")")
@@ -2053,8 +2071,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def name: TermName = rawname.toTermName
privateWithin = NoSymbol
- var referenced: Symbol = NoSymbol
-
+ private[this] var _referenced: Symbol = NoSymbol
+
+ def referenced: Symbol = _referenced
+ def referenced_=(x: Symbol) { _referenced = x }
+
def existentialBound = singletonBounds(this.tpe)
def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol =
@@ -2226,7 +2247,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** A class of type symbols. Alias and abstract types are direct instances
* of this class. Classes are instances of a subclass.
*/
- sealed abstract class TypeSymbol(initOwner: Symbol, initPos: Position, initName: TypeName) extends Symbol(initOwner, initPos, initName) {
+ abstract class TypeSymbol(initOwner: Symbol, initPos: Position, initName: TypeName) extends Symbol(initOwner, initPos, initName) {
privateWithin = NoSymbol
private var tyconCache: Type = null
private var tyconRunId = NoRunId
@@ -2395,9 +2416,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** A class for class symbols */
class ClassSymbol(initOwner: Symbol, initPos: Position, initName: TypeName)
extends TypeSymbol(initOwner, initPos, initName) {
- private var flatname: TypeName = null
- private var source: AbstractFileType = null
- private var thissym: Symbol = this
+ private[this] var flatname: TypeName = null
+ private[this] var source: AbstractFileType = null
+ private[this] var thissym: Symbol = this
final override def isClass = true
final override def isNonClassType = false
@@ -2459,7 +2480,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
typeOfThisCache
}
- else thissym.tpe
+ else thisSym.tpe
}
/** Sets the self type of the class */
@@ -2479,7 +2500,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def sourceModule =
if (isModuleClass) companionModule else NoSymbol
- private var childSet: Set[Symbol] = Set()
+ private[this] var childSet: Set[Symbol] = Set()
override def children = childSet
override def addChild(sym: Symbol) { childSet = childSet + sym }
@@ -2523,10 +2544,12 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
/** An object representing a missing symbol */
- object NoSymbol extends Symbol(null, NoPosition, nme.NO_NAME) {
- setInfo(NoType)
- privateWithin = this
- override def info_=(info: Type) {
+ class NoSymbol extends Symbol(null, NoPosition, nme.NO_NAME) {
+ synchronized {
+ setInfo(NoType)
+ privateWithin = this
+ }
+ override def info_=(info: Type) = {
infos = TypeHistory(1, NoType, null)
unlock()
validTo = currentPeriod
@@ -2553,6 +2576,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def originalEnclosingMethod = this
}
+ protected def makeNoSymbol = new NoSymbol
+
+ lazy val NoSymbol = makeNoSymbol
+
/** Derives a new list of symbols from the given list by mapping the given
* list across the given function. Then fixes the info of all the new symbols
* by substituting the new symbols for the original symbols.
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index 73f1f3db84..4f4715498e 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -109,15 +109,19 @@ trait Types extends api.Types { self: SymbolTable =>
/** A log of type variable with their original constraints. Used in order
* to undo constraints in the case of isSubType/isSameType failure.
*/
- object undoLog {
- private type UndoLog = List[(TypeVar, TypeConstraint)]
- private[scala] var log: UndoLog = List()
-
+ lazy val undoLog = newUndoLog
+
+ protected def newUndoLog = new UndoLog
+
+ class UndoLog {
+ private type UndoPairs = List[(TypeVar, TypeConstraint)]
+ private var log: UndoPairs = List()
+
// register with the auto-clearing cache manager
perRunCaches.recordCache(this)
/** Undo all changes to constraints to type variables upto `limit`. */
- private def undoTo(limit: UndoLog) {
+ private def undoTo(limit: UndoPairs) {
while ((log ne limit) && log.nonEmpty) {
val (tv, constr) = log.head
tv.constr = constr
@@ -125,9 +129,14 @@ trait Types extends api.Types { self: SymbolTable =>
}
}
- private[Types] def record(tv: TypeVar) = {
+ /** No sync necessary, because record should only
+ * be called from within a undo or undoUnless block,
+ * which is already synchronized.
+ */
+ private[reflect] def record(tv: TypeVar) = {
log ::= ((tv, tv.constr.cloneInternal))
}
+
private[scala] def clear() {
if (settings.debug.value)
self.log("Clearing " + log.size + " entries from the undoLog.")
@@ -249,8 +258,7 @@ trait Types extends api.Types { self: SymbolTable =>
abstract class AbsTypeImpl extends AbsType { this: Type =>
def declaration(name: Name): Symbol = decl(name)
def nonPrivateDeclaration(name: Name): Symbol = nonPrivateDecl(name)
- def allDeclarations = decls
- def allMembers = members
+ def declarations = decls
def typeArguments = typeArgs
def erasedType = transformedType(this)
}
@@ -873,16 +881,7 @@ trait Types extends api.Types { self: SymbolTable =>
* after `maxTostringRecursions` recursion levels. Uses `safeToString`
* to produce a string on each level.
*/
- override def toString: String =
- if (tostringRecursions >= maxTostringRecursions)
- "..."
- else
- try {
- tostringRecursions += 1
- safeToString
- } finally {
- tostringRecursions -= 1
- }
+ override def toString: String = typeToString(this)
/** Method to be implemented in subclasses.
* Converts this type to a string in calling toString for its parts.
@@ -992,7 +991,9 @@ trait Types extends api.Types { self: SymbolTable =>
if (membertpe eq null) membertpe = self.memberType(member)
(membertpe matches self.memberType(sym))
})) {
- members = new Scope(List(member, sym))
+ members = newScope
+ members enter member
+ members enter sym
}
} else {
var prevEntry = members.lookupEntry(sym.name)
@@ -1105,7 +1106,7 @@ trait Types extends api.Types { self: SymbolTable =>
/** A base class for types that represent a single value
* (single-types and this-types).
*/
- abstract class SingletonType extends SubType with SimpleTypeProxy with AbsSingletonType {
+ abstract class SingletonType extends SubType with SimpleTypeProxy {
def supertype = underlying
override def isTrivial = false
override def isStable = true
@@ -1231,18 +1232,15 @@ trait Types extends api.Types { self: SymbolTable =>
override val isTrivial: Boolean = pre.isTrivial
// override def isNullable = underlying.isNullable
override def isNotNull = underlying.isNotNull
- private var underlyingCache: Type = NoType
- private var underlyingPeriod = NoPeriod
+ private[reflect] var underlyingCache: Type = NoType
+ private[reflect] var underlyingPeriod = NoPeriod
override def underlying: Type = {
- val period = underlyingPeriod
- if (period != currentPeriod) {
- underlyingPeriod = currentPeriod
- if (!isValid(period)) {
- underlyingCache = pre.memberType(sym).resultType;
- assert(underlyingCache ne this, this)
- }
+ val cache = underlyingCache
+ if (underlyingPeriod == currentPeriod && cache != null) cache
+ else {
+ defineUnderlyingOfSingleType(this)
+ underlyingCache
}
- underlyingCache
}
// more precise conceptually, but causes cyclic errors: (paramss exists (_ contains sym))
@@ -1281,6 +1279,17 @@ trait Types extends api.Types { self: SymbolTable =>
unique(new UniqueSingleType(pre, sym))
}
}
+
+ protected def defineUnderlyingOfSingleType(tpe: SingleType) = {
+ val period = tpe.underlyingPeriod
+ if (period != currentPeriod) {
+ tpe.underlyingPeriod = currentPeriod
+ if (!isValid(period)) {
+ tpe.underlyingCache = tpe.pre.memberType(tpe.sym).resultType;
+ assert(tpe.underlyingCache ne tpe, tpe)
+ }
+ }
+ }
abstract case class SuperType(thistpe: Type, supertpe: Type) extends SingletonType {
override val isTrivial: Boolean = thistpe.isTrivial && supertpe.isTrivial
@@ -1333,105 +1342,30 @@ trait Types extends api.Types { self: SymbolTable =>
*/
abstract class CompoundType extends Type {
- var baseTypeSeqCache: BaseTypeSeq = _
- private var baseTypeSeqPeriod = NoPeriod
- private var baseClassesCache: List[Symbol] = _
- private var baseClassesPeriod = NoPeriod
+ private[reflect] var baseTypeSeqCache: BaseTypeSeq = _
+ private[reflect] var baseTypeSeqPeriod = NoPeriod
+ private[reflect] var baseClassesCache: List[Symbol] = _
+ private[reflect] var baseClassesPeriod = NoPeriod
override def baseTypeSeq: BaseTypeSeq = {
- val period = baseTypeSeqPeriod;
- if (period != currentPeriod) { // no caching in IDE
- baseTypeSeqPeriod = currentPeriod
- if (!isValidForBaseClasses(period)) {
- if (parents.exists(_.exists(_.isInstanceOf[TypeVar]))) {
- // rename type vars to fresh type params, take base type sequence of
- // resulting type, and rename back all the entries in that sequence
- var tvs = Set[TypeVar]()
- for (p <- parents)
- for (t <- p) t match {
- case tv: TypeVar => tvs += tv
- case _ =>
- }
- val varToParamMap: Map[Type, Symbol] = tvs map (tv => tv -> tv.origin.typeSymbol.cloneSymbol) toMap
- val paramToVarMap = varToParamMap map (_.swap)
- val varToParam = new TypeMap {
- def apply(tp: Type) = varToParamMap get tp match {
- case Some(sym) => sym.tpe
- case _ => mapOver(tp)
- }
- }
- val paramToVar = new TypeMap {
- def apply(tp: Type) = tp match {
- case TypeRef(_, tsym, _) if paramToVarMap.isDefinedAt(tsym) => paramToVarMap(tsym)
- case _ => mapOver(tp)
- }
- }
- val bts = copyRefinedType(this.asInstanceOf[RefinedType], parents map varToParam, varToParam mapOver decls).baseTypeSeq
- baseTypeSeqCache = bts lateMap paramToVar
- } else {
- incCounter(compoundBaseTypeSeqCount)
- baseTypeSeqCache = undetBaseTypeSeq
- baseTypeSeqCache = if (typeSymbol.isRefinementClass)
- memo(compoundBaseTypeSeq(this))(_.baseTypeSeq updateHead typeSymbol.tpe)
- else
- compoundBaseTypeSeq(this)
- // [Martin] suppressing memo-ization solves the problem with "same type after erasure" errors
- // when compiling with
- // scalac scala.collection.IterableViewLike.scala scala.collection.IterableLike.scala
- // I have not yet figured out precisely why this is the case.
- // My current assumption is that taking memos forces baseTypeSeqs to be computed
- // at stale types (i.e. the underlying typeSymbol has already another type).
- // I do not yet see precisely why this would cause a problem, but it looks
- // fishy in any case.
- }
- }
- //Console.println("baseTypeSeq(" + typeSymbol + ") = " + baseTypeSeqCache.toList);//DEBUG
+ val cached = baseTypeSeqCache
+ if (baseTypeSeqPeriod == currentPeriod && cached != null && cached != undetBaseTypeSeq)
+ cached
+ else {
+ defineBaseTypeSeqOfCompoundType(this)
+ baseTypeSeqCache
}
- if (baseTypeSeqCache eq undetBaseTypeSeq)
- throw new TypeError("illegal cyclic inheritance involving " + typeSymbol)
- baseTypeSeqCache
}
override def baseTypeSeqDepth: Int = baseTypeSeq.maxDepth
override def baseClasses: List[Symbol] = {
- def computeBaseClasses: List[Symbol] =
- if (parents.isEmpty) List(typeSymbol)
- else {
- //Console.println("computing base classes of " + typeSymbol + " at phase " + phase);//DEBUG
- // optimized, since this seems to be performance critical
- val superclazz = parents.head
- var mixins = parents.tail
- val sbcs = superclazz.baseClasses
- var bcs = sbcs
- def isNew(clazz: Symbol): Boolean = (
- superclazz.baseTypeIndex(clazz) < 0 &&
- { var p = bcs;
- while ((p ne sbcs) && (p.head != clazz)) p = p.tail;
- p eq sbcs
- }
- );
- while (!mixins.isEmpty) {
- def addMixinBaseClasses(mbcs: List[Symbol]): List[Symbol] =
- if (mbcs.isEmpty) bcs
- else if (isNew(mbcs.head)) mbcs.head :: addMixinBaseClasses(mbcs.tail)
- else addMixinBaseClasses(mbcs.tail);
- bcs = addMixinBaseClasses(mixins.head.baseClasses)
- mixins = mixins.tail
- }
- typeSymbol :: bcs
- }
- val period = baseClassesPeriod
- if (period != currentPeriod) {
- baseClassesPeriod = currentPeriod
- if (!isValidForBaseClasses(period)) {
- baseClassesCache = null
- baseClassesCache = memo(computeBaseClasses)(typeSymbol :: _.baseClasses.tail)
- }
+ val cached = baseClassesCache
+ if (baseClassesPeriod == currentPeriod && cached != null) cached
+ else {
+ defineBaseClassesOfCompoundType(this)
+ baseClassesCache
}
- if (baseClassesCache eq null)
- throw new TypeError("illegal cyclic reference involving " + typeSymbol)
- baseClassesCache
}
/** The slightly less idiomatic use of Options is due to
@@ -1475,6 +1409,97 @@ trait Types extends api.Types { self: SymbolTable =>
(if (settings.debug.value || parents.isEmpty || (decls.elems ne null))
decls.mkString("{", "; ", "}") else "")
}
+
+ protected def defineBaseTypeSeqOfCompoundType(tpe: CompoundType) = {
+ val period = tpe.baseTypeSeqPeriod;
+ if (period != currentPeriod) {
+ tpe.baseTypeSeqPeriod = currentPeriod
+ if (!isValidForBaseClasses(period)) {
+ if (tpe.parents.exists(_.exists(_.isInstanceOf[TypeVar]))) {
+ // rename type vars to fresh type params, take base type sequence of
+ // resulting type, and rename back all the entries in that sequence
+ var tvs = Set[TypeVar]()
+ for (p <- tpe.parents)
+ for (t <- p) t match {
+ case tv: TypeVar => tvs += tv
+ case _ =>
+ }
+ val varToParamMap: Map[Type, Symbol] = tvs map (tv => tv -> tv.origin.typeSymbol.cloneSymbol) toMap
+ val paramToVarMap = varToParamMap map (_.swap)
+ val varToParam = new TypeMap {
+ def apply(tp: Type) = varToParamMap get tp match {
+ case Some(sym) => sym.tpe
+ case _ => mapOver(tp)
+ }
+ }
+ val paramToVar = new TypeMap {
+ def apply(tp: Type) = tp match {
+ case TypeRef(_, tsym, _) if paramToVarMap.isDefinedAt(tsym) => paramToVarMap(tsym)
+ case _ => mapOver(tp)
+ }
+ }
+ val bts = copyRefinedType(tpe.asInstanceOf[RefinedType], tpe.parents map varToParam, varToParam mapOver tpe.decls).baseTypeSeq
+ tpe.baseTypeSeqCache = bts lateMap paramToVar
+ } else {
+ incCounter(compoundBaseTypeSeqCount)
+ tpe.baseTypeSeqCache = undetBaseTypeSeq
+ tpe.baseTypeSeqCache = if (tpe.typeSymbol.isRefinementClass)
+ tpe.memo(compoundBaseTypeSeq(tpe))(_.baseTypeSeq updateHead tpe.typeSymbol.tpe)
+ else
+ compoundBaseTypeSeq(tpe)
+ // [Martin] suppressing memo-ization solves the problem with "same type after erasure" errors
+ // when compiling with
+ // scalac scala.collection.IterableViewLike.scala scala.collection.IterableLike.scala
+ // I have not yet figured out precisely why this is the case.
+ // My current assumption is that taking memos forces baseTypeSeqs to be computed
+ // at stale types (i.e. the underlying typeSymbol has already another type).
+ // I do not yet see precisely why this would cause a problem, but it looks
+ // fishy in any case.
+ }
+ }
+ }
+ //Console.println("baseTypeSeq(" + typeSymbol + ") = " + baseTypeSeqCache.toList);//DEBUG
+ if (tpe.baseTypeSeqCache eq undetBaseTypeSeq)
+ throw new TypeError("illegal cyclic inheritance involving " + tpe.typeSymbol)
+ }
+
+ protected def defineBaseClassesOfCompoundType(tpe: CompoundType) = {
+ def computeBaseClasses: List[Symbol] =
+ if (tpe.parents.isEmpty) List(tpe.typeSymbol)
+ else {
+ //Console.println("computing base classes of " + typeSymbol + " at phase " + phase);//DEBUG
+ // optimized, since this seems to be performance critical
+ val superclazz = tpe.parents.head
+ var mixins = tpe.parents.tail
+ val sbcs = superclazz.baseClasses
+ var bcs = sbcs
+ def isNew(clazz: Symbol): Boolean =
+ superclazz.baseTypeIndex(clazz) < 0 &&
+ { var p = bcs;
+ while ((p ne sbcs) && (p.head != clazz)) p = p.tail;
+ p eq sbcs
+ }
+ while (!mixins.isEmpty) {
+ def addMixinBaseClasses(mbcs: List[Symbol]): List[Symbol] =
+ if (mbcs.isEmpty) bcs
+ else if (isNew(mbcs.head)) mbcs.head :: addMixinBaseClasses(mbcs.tail)
+ else addMixinBaseClasses(mbcs.tail)
+ bcs = addMixinBaseClasses(mixins.head.baseClasses)
+ mixins = mixins.tail
+ }
+ tpe.typeSymbol :: bcs
+ }
+ val period = tpe.baseClassesPeriod
+ if (period != currentPeriod) {
+ tpe.baseClassesPeriod = currentPeriod
+ if (!isValidForBaseClasses(period)) {
+ tpe.baseClassesCache = null
+ tpe.baseClassesCache = tpe.memo(computeBaseClasses)(tpe.typeSymbol :: _.baseClasses.tail)
+ }
+ }
+ if (tpe.baseClassesCache eq null)
+ throw new TypeError("illegal cyclic reference involving " + tpe.typeSymbol)
+ }
/** A class representing intersection types with refinements of the form
* `<parents_0> with ... with <parents_n> { decls }`
@@ -1583,7 +1608,7 @@ trait Types extends api.Types { self: SymbolTable =>
* by a path which contains at least one expansive reference.
* @See Kennedy, Pierce: On Decidability of Nominal Subtyping with Variance
*/
- def expansiveRefs(tparam: Symbol) = {
+ private[scala] def expansiveRefs(tparam: Symbol) = {
if (state == UnInitialized) {
computeRefs()
while (state != Initialized) propagate()
@@ -1597,10 +1622,16 @@ trait Types extends api.Types { self: SymbolTable =>
/** The type parameters which are referenced type parameters of this class.
* Two entries: refs(0): Non-expansive references
* refs(1): Expansive references
+ * Syncnote: This var need not be protected with synchronized, because
+ * it is accessed only from expansiveRefs, which is called only from
+ * Typer.
*/
private var refs: Array[RefMap] = _
/** The initialization state of the class: UnInialized --> Initializing --> Initialized
+ * Syncnote: This var need not be protected with synchronized, because
+ * it is accessed only from expansiveRefs, which is called only from
+ * Typer.
*/
private var state = UnInitialized
@@ -1750,6 +1781,10 @@ trait Types extends api.Types { self: SymbolTable =>
}
}
+ /* Syncnote: The `volatile` var and `pendingVolatiles` mutable set need not be protected
+ * with synchronized, because they are accessed only from isVolatile, which is called only from
+ * Typer.
+ */
private var volatileRecursions: Int = 0
private val pendingVolatiles = new mutable.HashSet[Symbol]
@@ -1831,13 +1866,18 @@ trait Types extends api.Types { self: SymbolTable =>
if (sym == clazz) this
else transform(sym.info.baseType(clazz))
}
+
trait NonClassTypeRef extends TypeRef {
require(sym.isNonClassType, sym)
+ /* Syncnote: These are pure caches for performance; no problem to evaluate these
+ * several times. Hence, no need to protected with synchronzied in a mutli-threaded
+ * usage scenario.
+ */
private var relativeInfoCache: Type = _
private var memberInfoCache: Type = _
- private def relativeInfo = {
+ private[Types] def relativeInfo = {
val memberInfo = pre.memberInfo(sym)
if (relativeInfoCache == null || (memberInfo ne memberInfoCache)) {
memberInfoCache = memberInfo
@@ -1846,25 +1886,27 @@ trait Types extends api.Types { self: SymbolTable =>
relativeInfoCache
}
- override def baseType(clazz: Symbol): Type = (
- if (sym == clazz) this else try {
- basetypeRecursions += 1
- if (basetypeRecursions < LogPendingBaseTypesThreshold)
- relativeInfo.baseType(clazz)
- else if (pendingBaseTypes contains this)
- if (clazz == AnyClass) clazz.tpe else NoType
- else
- try {
- pendingBaseTypes += this
- relativeInfo.baseType(clazz)
- } finally {
- pendingBaseTypes -= this
- }
+ override def baseType(clazz: Symbol): Type =
+ if (sym == clazz) this else baseTypeOfNonClassTypeRef(this, clazz)
+ }
+
+ protected def baseTypeOfNonClassTypeRef(tpe: NonClassTypeRef, clazz: Symbol) = try {
+ basetypeRecursions += 1
+ if (basetypeRecursions < LogPendingBaseTypesThreshold)
+ tpe.relativeInfo.baseType(clazz)
+ else if (pendingBaseTypes contains tpe)
+ if (clazz == AnyClass) clazz.tpe else NoType
+ else
+ try {
+ pendingBaseTypes += tpe
+ tpe.relativeInfo.baseType(clazz)
} finally {
- basetypeRecursions -= 1
+ pendingBaseTypes -= tpe
}
- )
+ } finally {
+ basetypeRecursions -= 1
}
+
trait AliasTypeRef extends NonClassTypeRef {
require(sym.isAliasType, sym)
@@ -1912,6 +1954,8 @@ trait Types extends api.Types { self: SymbolTable =>
trait AbstractTypeRef extends NonClassTypeRef {
require(sym.isAbstractType, sym)
+ /** Syncnote: Pure performance caches; no need to synchronize in multi-threaded environment
+ */
private var symInfoCache: Type = _
private var thisInfoCache: Type = _
@@ -1938,6 +1982,7 @@ trait Types extends api.Types { self: SymbolTable =>
volatileRecursions -= 1
}
}
+
override def thisInfo = {
val symInfo = sym.info
if (thisInfoCache == null || (symInfo ne symInfoCache)) {
@@ -1955,7 +2000,7 @@ trait Types extends api.Types { self: SymbolTable =>
override def isStable = bounds.hi.typeSymbol isSubClass SingletonClass
override def bounds = thisInfo.bounds
// def transformInfo(tp: Type): Type = appliedType(tp.asSeenFrom(pre, sym.owner), typeArgsOrDummies)
- override protected def baseTypeSeqImpl: BaseTypeSeq = transform(bounds.hi).baseTypeSeq prepend this
+ override protected[Types] def baseTypeSeqImpl: BaseTypeSeq = transform(bounds.hi).baseTypeSeq prepend this
}
/** A class for named types of the form
@@ -1966,11 +2011,11 @@ trait Types extends api.Types { self: SymbolTable =>
* @M: a higher-kinded type is represented as a TypeRef with sym.typeParams.nonEmpty, but args.isEmpty
*/
abstract case class TypeRef(pre: Type, sym: Symbol, args: List[Type]) extends Type {
- private var parentsCache: List[Type] = _
- private var parentsPeriod = NoPeriod
- private var baseTypeSeqCache: BaseTypeSeq = _
- private var baseTypeSeqPeriod = NoPeriod
- private var normalized: Type = _
+ private[reflect] var parentsCache: List[Type] = _
+ private[reflect] var parentsPeriod = NoPeriod
+ private[reflect] var baseTypeSeqCache: BaseTypeSeq = _
+ private[reflect] var baseTypeSeqPeriod = NoPeriod
+ private var normalized: Type = _
// @M: propagate actual type params (args) to `tp`, by replacing
// formal type parameters with actual ones. If tp is higher kinded,
@@ -2030,16 +2075,12 @@ trait Types extends api.Types { self: SymbolTable =>
sym.isModuleClass || sym == NothingClass || isValueClass(sym) || super.isNotNull
override def parents: List[Type] = {
- val period = parentsPeriod
- if (period != currentPeriod) {
- parentsPeriod = currentPeriod
- if (!isValidForBaseClasses(period)) {
- parentsCache = thisInfo.parents map transform
- } else if (parentsCache == null) { // seems this can happen if things are corrupted enough, see #2641
- parentsCache = List(AnyClass.tpe)
- }
+ val cache = parentsCache
+ if (parentsPeriod == currentPeriod && cache != null) cache
+ else {
+ defineParentsOfTypeRef(this)
+ parentsCache
}
- parentsCache
}
override def decls: Scope = {
@@ -2051,21 +2092,16 @@ trait Types extends api.Types { self: SymbolTable =>
thisInfo.decls
}
- protected def baseTypeSeqImpl: BaseTypeSeq = sym.info.baseTypeSeq map transform
+ protected[Types] def baseTypeSeqImpl: BaseTypeSeq = sym.info.baseTypeSeq map transform
override def baseTypeSeq: BaseTypeSeq = {
- val period = baseTypeSeqPeriod
- if (period != currentPeriod) {
- baseTypeSeqPeriod = currentPeriod
- if (!isValidForBaseClasses(period)) {
- incCounter(typerefBaseTypeSeqCount)
- baseTypeSeqCache = undetBaseTypeSeq
- baseTypeSeqCache = baseTypeSeqImpl
- }
+ val cache = baseTypeSeqCache
+ if (baseTypeSeqPeriod == currentPeriod && cache != null && cache != undetBaseTypeSeq)
+ cache
+ else {
+ defineBaseTypeSeqOfTypeRef(this)
+ baseTypeSeqCache
}
- if (baseTypeSeqCache == undetBaseTypeSeq)
- throw new TypeError("illegal cyclic inheritance involving " + sym)
- baseTypeSeqCache
}
private def preString = (
@@ -2151,6 +2187,32 @@ trait Types extends api.Types { self: SymbolTable =>
}
})
}
+
+ protected def defineParentsOfTypeRef(tpe: TypeRef) = {
+ val period = tpe.parentsPeriod
+ if (period != currentPeriod) {
+ tpe.parentsPeriod = currentPeriod
+ if (!isValidForBaseClasses(period)) {
+ tpe.parentsCache = tpe.thisInfo.parents map tpe.transform
+ } else if (tpe.parentsCache == null) { // seems this can happen if things are corrupted enough, see #2641
+ tpe.parentsCache = List(AnyClass.tpe)
+ }
+ }
+ }
+
+ protected def defineBaseTypeSeqOfTypeRef(tpe: TypeRef) = {
+ val period = tpe.baseTypeSeqPeriod
+ if (period != currentPeriod) {
+ tpe.baseTypeSeqPeriod = currentPeriod
+ if (!isValidForBaseClasses(period)) {
+ incCounter(typerefBaseTypeSeqCount)
+ tpe.baseTypeSeqCache = undetBaseTypeSeq
+ tpe.baseTypeSeqCache = tpe.baseTypeSeqImpl
+ }
+ }
+ if (tpe.baseTypeSeqCache == undetBaseTypeSeq)
+ throw new TypeError("illegal cyclic inheritance involving " + tpe.sym)
+ }
/** A class representing a method type with parameters.
* Note that a parameterless method is represented by a NullaryMethodType:
@@ -2577,7 +2639,12 @@ trait Types extends api.Types { self: SymbolTable =>
override def typeArgs: List[Type] = Nil
override def isHigherKinded = false
- /** The constraint associated with the variable */
+ /** The constraint associated with the variable
+ * Syncnote: Type variables are assumed to be used from only one
+ * thread. They are not exposed in api.Types and are used only locally
+ * in operations that are exposed from types. Hence, no syncing of `constr`
+ * or `encounteredHigherLevel` or `suspended` accesses should be necessary.
+ */
var constr = constr0
def instValid = constr.instValid
@@ -3048,7 +3115,7 @@ trait Types extends api.Types { self: SymbolTable =>
* @return ...
*/
def refinedType(parents: List[Type], owner: Symbol): Type =
- refinedType(parents, owner, new Scope, owner.pos)
+ refinedType(parents, owner, newScope, owner.pos)
def copyRefinedType(original: RefinedType, parents: List[Type], decls: Scope) =
if ((parents eq original.parents) && (decls eq original.decls)) original
@@ -3338,7 +3405,7 @@ trait Types extends api.Types { self: SymbolTable =>
private var uniques: util.HashSet[Type] = _
private var uniqueRunId = NoRunId
- private def unique[T <: Type](tp: T): T = {
+ protected def unique[T <: Type](tp: T): T = {
incCounter(rawTypeCount)
if (uniqueRunId != currentRunId) {
uniques = util.HashSet[Type]("uniques", initialUniquesCapacity)
@@ -3362,6 +3429,12 @@ trait Types extends api.Types { self: SymbolTable =>
def this(lo0: List[Type], hi0: List[Type]) = this(lo0, hi0, NoType, NoType)
def this(bounds: TypeBounds) = this(List(bounds.lo), List(bounds.hi))
def this() = this(List(), List())
+
+ /* Syncnote: Type constraints are assumed to be used from only one
+ * thread. They are not exposed in api.Types and are used only locally
+ * in operations that are exposed from types. Hence, no syncing of any
+ * variables should be ncessesary.
+ */
/** Guard these lists against AnyClass and NothingClass appearing,
* else loBounds.isEmpty will have different results for an empty
@@ -3634,7 +3707,7 @@ trait Types extends api.Types { self: SymbolTable =>
val elems = scope.toList
val elems1 = mapOver(elems)
if (elems1 eq elems) scope
- else new Scope(elems1)
+ else newScopeWith(elems1: _*)
}
/** Map this function over given list of symbols */
@@ -3699,6 +3772,11 @@ trait Types extends api.Types { self: SymbolTable =>
def traverse(tp: Type): Unit
def apply(tp: Type): Type = { traverse(tp); tp }
}
+
+ abstract class TypeTraverserWithResult[T] extends TypeTraverser {
+ def result: T
+ def clear(): Unit
+ }
abstract class TypeCollector[T](initial: T) extends TypeTraverser {
var result: T = _
@@ -3753,7 +3831,7 @@ trait Types extends api.Types { self: SymbolTable =>
* the conversion of raw types to existential types might not have taken place
* in ClassFileparser.sigToType (where it is usually done).
*/
- object rawToExistential extends TypeMap {
+ def rawToExistential = new TypeMap {
private var expanded = immutable.Set[Symbol]()
private var generated = immutable.Set[Type]()
def apply(tp: Type): Type = tp match {
@@ -4365,15 +4443,20 @@ trait Types extends api.Types { self: SymbolTable =>
private def commonOwner(tps: List[Type]): Symbol = {
if (tps.isEmpty) NoSymbol
else {
- commonOwnerMap.result = null
+ commonOwnerMap.clear()
tps foreach (commonOwnerMap traverse _)
val result = if (commonOwnerMap.result ne null) commonOwnerMap.result else NoSymbol
debuglog(tps.mkString("commonOwner(", ", ", ") == " + result))
result
}
}
- private object commonOwnerMap extends TypeTraverser {
+
+ protected def commonOwnerMap: CommonOwnerMap = commonOwnerMapObj
+
+ protected class CommonOwnerMap extends TypeTraverserWithResult[Symbol] {
var result: Symbol = _
+
+ def clear() { result = null }
private def register(sym: Symbol) {
// First considered type is the trivial result.
@@ -4390,12 +4473,15 @@ trait Types extends api.Types { self: SymbolTable =>
case _ => mapOver(tp)
}
}
+
+ private lazy val commonOwnerMapObj = new CommonOwnerMap
class MissingAliasControl extends ControlThrowable
val missingAliasException = new MissingAliasControl
class MissingTypeControl extends ControlThrowable
object adaptToNewRunMap extends TypeMap {
+
private def adaptToNewRun(pre: Type, sym: Symbol): Symbol = {
if (phase.flatClasses) {
sym
@@ -5832,7 +5918,7 @@ trait Types extends api.Types { self: SymbolTable =>
}
/** The least upper bound wrt <:< of a list of types */
- def lub(ts: List[Type], depth: Int): Type = {
+ private def lub(ts: List[Type], depth: Int): Type = {
def lub0(ts0: List[Type]): Type = elimSub(ts0, depth) match {
case List() => NothingClass.tpe
case List(t) => t
@@ -5983,7 +6069,7 @@ trait Types extends api.Types { self: SymbolTable =>
/** The greatest lower bound wrt <:< of a list of types, which have been normalized
* wrt elimSuper */
- private def glbNorm(ts: List[Type], depth: Int): Type = {
+ protected def glbNorm(ts: List[Type], depth: Int): Type = {
def glb0(ts0: List[Type]): Type = ts0 match {
case List() => AnyClass.tpe
case List(t) => t
@@ -6279,7 +6365,7 @@ trait Types extends api.Types { self: SymbolTable =>
private var indent: String = ""
/** Perform operation `p` on arguments `tp1`, `arg2` and print trace of computation. */
- private def explain[T](op: String, p: (Type, T) => Boolean, tp1: Type, arg2: T): Boolean = {
+ protected def explain[T](op: String, p: (Type, T) => Boolean, tp1: Type, arg2: T): Boolean = {
Console.println(indent + tp1 + " " + op + " " + arg2 + "?" /* + "("+tp1.getClass+","+arg2.getClass+")"*/)
indent = indent + " "
val result = p(tp1, arg2)
@@ -6324,4 +6410,16 @@ trait Types extends api.Types { self: SymbolTable =>
final val maxTostringRecursions = 50
private var tostringRecursions = 0
+
+ protected def typeToString(tpe: Type): String =
+ if (tostringRecursions >= maxTostringRecursions)
+ "..."
+ else
+ try {
+ tostringRecursions += 1
+ tpe.safeToString
+ } finally {
+ tostringRecursions -= 1
+ }
+
}
diff --git a/src/compiler/scala/reflect/runtime/Loaders.scala b/src/compiler/scala/reflect/runtime/Loaders.scala
index 7aca052fa9..0a5a21de1e 100644
--- a/src/compiler/scala/reflect/runtime/Loaders.scala
+++ b/src/compiler/scala/reflect/runtime/Loaders.scala
@@ -97,7 +97,7 @@ trait Loaders { self: SymbolTable =>
0 < dp && dp < (name.length - 1)
}
- class PackageScope(pkgClass: Symbol) extends Scope {
+ class PackageScope(pkgClass: Symbol) extends Scope() with SynchronizedScope {
assert(pkgClass.isType)
private var negatives = mutable.Set[Name]()
override def lookupEntry(name: Name): ScopeEntry = {
diff --git a/src/compiler/scala/reflect/runtime/Mirror.scala b/src/compiler/scala/reflect/runtime/Mirror.scala
index 9490dc4ad7..47fc9f2dcf 100644
--- a/src/compiler/scala/reflect/runtime/Mirror.scala
+++ b/src/compiler/scala/reflect/runtime/Mirror.scala
@@ -40,7 +40,8 @@ class Mirror extends Universe with RuntimeTypes with TreeBuildUtil with ToolBoxe
override def typeToClass(tpe: Type): java.lang.Class[_] = typeToJavaClass(tpe)
override def symbolToClass(sym: Symbol): java.lang.Class[_] = classToJava(sym)
-
+
+ override def inReflexiveMirror = true
}
object Mirror extends Mirror
diff --git a/src/compiler/scala/reflect/runtime/SymbolTable.scala b/src/compiler/scala/reflect/runtime/SymbolTable.scala
index d1a806bcef..5331f0a53e 100644
--- a/src/compiler/scala/reflect/runtime/SymbolTable.scala
+++ b/src/compiler/scala/reflect/runtime/SymbolTable.scala
@@ -6,7 +6,7 @@ package runtime
* It can be used either from the reflexive mirror itself (class Universe), or else from
* a runtime compiler that uses reflection to get a class information (class scala.tools.nsc.ReflectGlobal)
*/
-trait SymbolTable extends internal.SymbolTable with JavaToScala with ScalaToJava with Loaders {
+trait SymbolTable extends internal.SymbolTable with JavaToScala with ScalaToJava with Loaders with SynchronizedOps {
/** If `owner` is a package class (but not the empty package) and `name` is a term name, make a new package
* <owner>.<name>, otherwise return NoSymbol.
diff --git a/src/compiler/scala/reflect/runtime/SynchronizedOps.scala b/src/compiler/scala/reflect/runtime/SynchronizedOps.scala
new file mode 100644
index 0000000000..98694c2ddf
--- /dev/null
+++ b/src/compiler/scala/reflect/runtime/SynchronizedOps.scala
@@ -0,0 +1,52 @@
+package scala.reflect
+package runtime
+
+trait SynchronizedOps extends internal.SymbolTable
+ with SynchronizedSymbols
+ with SynchronizedTypes { self: SymbolTable =>
+
+// Names
+
+ private lazy val nameLock = new Object
+
+ override def newTermName(s: String): TermName = nameLock.synchronized { super.newTermName(s) }
+ override def newTypeName(s: String): TypeName = nameLock.synchronized { super.newTypeName(s) }
+
+// BaseTypeSeqs
+
+ override protected def newBaseTypeSeq(parents: List[Type], elems: Array[Type]) =
+ new BaseTypeSeq(parents, elems) with SynchronizedBaseTypeSeq
+
+ trait SynchronizedBaseTypeSeq extends BaseTypeSeq {
+ override def apply(i: Int): Type = synchronized { super.apply(i) }
+ override def rawElem(i: Int) = synchronized { super.rawElem(i) }
+ override def typeSymbol(i: Int): Symbol = synchronized { super.typeSymbol(i) }
+ override def toList: List[Type] = synchronized { super.toList }
+ override def copy(head: Type, offset: Int): BaseTypeSeq = synchronized { super.copy(head, offset) }
+ override def map(f: Type => Type): BaseTypeSeq = synchronized { super.map(f) }
+ override def exists(p: Type => Boolean): Boolean = synchronized { super.exists(p) }
+ override lazy val maxDepth = synchronized { maxDepthOfElems }
+ override def toString = synchronized { super.toString }
+
+ override def lateMap(f: Type => Type): BaseTypeSeq = new MappedBaseTypeSeq(this, f) with SynchronizedBaseTypeSeq
+ }
+
+// Scopes
+
+ override def newScope = new Scope() with SynchronizedScope
+ override def newNestedScope(outer: Scope): Scope = new Scope(outer) with SynchronizedScope
+// override def newScopeWith(elems: ScopeEntry): Scope = new Scope(elems) with SynchronizedScope
+
+ trait SynchronizedScope extends Scope {
+ override def isEmpty: Boolean = synchronized { super.isEmpty }
+ override def size: Int = synchronized { super.size }
+ override def enter(sym: Symbol) = synchronized { super.enter(sym) }
+ override def rehash(sym: Symbol, newname: Name) = synchronized { super.rehash(sym, newname) }
+ override def unlink(e: ScopeEntry) = synchronized { super.unlink(e) }
+ override def unlink(sym: Symbol) = synchronized { super.unlink(sym) }
+ override def lookupAll(name: Name) = synchronized { super.lookupAll(name) }
+ override def lookupEntry(name: Name) = synchronized { super.lookupEntry(name) }
+ override def lookupNextEntry(entry: ScopeEntry) = synchronized { super.lookupNextEntry(entry) }
+ override def toList: List[Symbol] = synchronized { super.toList }
+ }
+}
diff --git a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
new file mode 100644
index 0000000000..9baf94f71d
--- /dev/null
+++ b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
@@ -0,0 +1,119 @@
+package scala.reflect
+package runtime
+
+import internal.Flags.DEFERRED
+
+trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable =>
+
+ override protected def nextId() = synchronized { super.nextId() }
+
+ override protected def freshExistentialName(suffix: String) =
+ synchronized { super.freshExistentialName(suffix) }
+
+ // Set the fields which point companions at one another. Returns the module.
+ override def connectModuleToClass(m: ModuleSymbol, moduleClass: ClassSymbol): ModuleSymbol =
+ synchronized { super.connectModuleToClass(m, moduleClass) }
+
+ override def newFreeVar(name: TermName, tpe: Type, value: Any, newFlags: Long = 0L): FreeVar =
+ new FreeVar(name, value) with SynchronizedTermSymbol initFlags newFlags setInfo tpe
+
+ override protected def makeNoSymbol = new NoSymbol with SynchronizedSymbol
+
+ trait SynchronizedSymbol extends Symbol {
+
+ override def rawowner = synchronized { super.rawowner }
+ override def rawname = synchronized { super.rawname }
+ override def rawflags = synchronized { super.rawflags }
+
+ override def rawflags_=(x: FlagsType) = synchronized { super.rawflags_=(x) }
+ override def name_=(x: Name) = synchronized { super.name_=(x) }
+ override def owner_=(owner: Symbol) = synchronized { super.owner_=(owner) }
+
+ override def validTo = synchronized { super.validTo }
+ override def validTo_=(x: Period) = synchronized { super.validTo_=(x) }
+
+ override def pos = synchronized { super.pos }
+ override def setPos(pos: Position): this.type = { synchronized { super.setPos(pos) }; this }
+
+ override def privateWithin = synchronized { super.privateWithin }
+ override def privateWithin_=(sym: Symbol) = synchronized { super.privateWithin_=(sym) }
+
+ override def info = synchronized { super.info }
+ override def info_=(info: Type) = synchronized { super.info_=(info) }
+ override def updateInfo(info: Type): Symbol = synchronized { super.updateInfo(info) }
+ override def rawInfo: Type = synchronized { super.rawInfo }
+
+ override def typeParams: List[Symbol] = synchronized { super.typeParams }
+
+ override def reset(completer: Type) = synchronized { super.reset(completer) }
+
+ override def infosString: String = synchronized { super.infosString }
+
+ override def annotations: List[AnnotationInfo] = synchronized { super.annotations }
+ override def setAnnotations(annots: List[AnnotationInfo]): this.type = { synchronized { super.setAnnotations(annots) }; this }
+
+
+// ------ creators -------------------------------------------------------------------
+
+ override def newTermSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): TermSymbol =
+ new TermSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags
+
+ override def newAbstractTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): AbstractTypeSymbol =
+ new AbstractTypeSymbol(this, pos, name) with SynchronizedTypeSymbol initFlags newFlags
+
+ override def newAliasTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): AliasTypeSymbol =
+ new AliasTypeSymbol(this, pos, name) with SynchronizedTypeSymbol initFlags newFlags
+
+ override def newModuleSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol =
+ new ModuleSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags
+
+ override def newMethodSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): MethodSymbol =
+ new MethodSymbol(this, pos, name) with SynchronizedMethodSymbol initFlags newFlags
+
+ override def newClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol =
+ new ClassSymbol(this, pos, name) with SynchronizedClassSymbol initFlags newFlags
+
+ override def newModuleClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleClassSymbol =
+ new ModuleClassSymbol(this, pos, name) with SynchronizedModuleClassSymbol initFlags newFlags
+
+ override def newTypeSkolemSymbol(name: TypeName, origin: AnyRef, pos: Position = NoPosition, newFlags: Long = 0L): TypeSkolem =
+ if ((newFlags & DEFERRED) == 0L)
+ new TypeSkolem(this, pos, name, origin) with SynchronizedTypeSymbol initFlags newFlags
+ else
+ new TypeSkolem(this, pos, name, origin) with AbstractTypeMixin with SynchronizedTypeSymbol initFlags newFlags
+ }
+
+// ------- subclasses ---------------------------------------------------------------------
+
+ trait SynchronizedTermSymbol extends TermSymbol with SynchronizedSymbol {
+ override def referenced: Symbol = synchronized { super.referenced }
+ override def referenced_=(x: Symbol) = synchronized { super.referenced_=(x) }
+ }
+
+ trait SynchronizedMethodSymbol extends MethodSymbol with SynchronizedTermSymbol {
+ override def typeAsMemberOf(pre: Type): Type = synchronized { super.typeAsMemberOf(pre) }
+ }
+
+ trait SynchronizedTypeSymbol extends TypeSymbol with SynchronizedSymbol {
+ override def typeConstructor: Type = synchronized { super.typeConstructor }
+ override def tpe: Type = synchronized { super.tpe }
+ }
+
+ trait SynchronizedClassSymbol extends ClassSymbol with SynchronizedTypeSymbol {
+ override def sourceFile = synchronized { super.sourceFile }
+ override def sourceFile_=(f: AbstractFileType) = synchronized { super.sourceFile_=(f) }
+ override def thisSym: Symbol = synchronized { super.thisSym }
+ override def thisType: Type = synchronized { super.thisType }
+ override def typeOfThis: Type = synchronized { super.typeOfThis }
+ override def typeOfThis_=(tp: Type) = synchronized { super.typeOfThis_=(tp) }
+ override def children = synchronized { super.children }
+ override def addChild(sym: Symbol) = synchronized { super.addChild(sym) }
+ }
+
+ trait SynchronizedModuleClassSymbol extends ModuleClassSymbol with SynchronizedClassSymbol {
+ override def sourceModule = synchronized { super.sourceModule }
+ override def sourceModule_=(module: Symbol) = synchronized { super.sourceModule_=(module: Symbol) }
+ override def implicitMembers: List[Symbol] = synchronized { super.implicitMembers }
+ }
+}
+
diff --git a/src/compiler/scala/reflect/runtime/SynchronizedTypes.scala b/src/compiler/scala/reflect/runtime/SynchronizedTypes.scala
new file mode 100644
index 0000000000..c842d3dd01
--- /dev/null
+++ b/src/compiler/scala/reflect/runtime/SynchronizedTypes.scala
@@ -0,0 +1,87 @@
+package scala.reflect
+package runtime
+
+/** This trait overrides methods in reflect.internal, bracketing
+ * them in synchronized { ... } to make them thread-safe
+ */
+trait SynchronizedTypes extends internal.Types { self: SymbolTable =>
+
+ // No sharing of map objects:
+ override protected def commonOwnerMap = new CommonOwnerMap
+
+ private val uniqueLock = new Object
+ override def unique[T <: Type](tp: T): T = uniqueLock.synchronized { super.unique(tp) }
+
+ class SynchronizedUndoLog extends UndoLog {
+
+ override def clear() =
+ synchronized { super.clear() }
+
+ override def undo[T](block: => T): T =
+ synchronized { super.undo(block) }
+
+ override def undoUnless(block: => Boolean): Boolean =
+ synchronized { super.undoUnless(block) }
+ }
+
+ override protected def newUndoLog = new SynchronizedUndoLog
+
+ override protected def baseTypeOfNonClassTypeRef(tpe: NonClassTypeRef, clazz: Symbol) =
+ synchronized { super.baseTypeOfNonClassTypeRef(tpe, clazz) }
+
+ private val subsametypeLock = new Object
+
+ override def isSameType(tp1: Type, tp2: Type): Boolean =
+ subsametypeLock.synchronized { super.isSameType(tp1, tp2) }
+
+ override def isDifferentType(tp1: Type, tp2: Type): Boolean =
+ subsametypeLock.synchronized { super.isDifferentType(tp1, tp2) }
+
+ override def isSubType(tp1: Type, tp2: Type, depth: Int): Boolean =
+ subsametypeLock.synchronized { super.isSubType(tp1, tp2, depth) }
+
+ private val lubglbLock = new Object
+
+ override def glb(ts: List[Type]): Type =
+ lubglbLock.synchronized { super.glb(ts) }
+
+ override def lub(ts: List[Type]): Type =
+ lubglbLock.synchronized { super.lub(ts) }
+
+ private val indentLock = new Object
+
+ override protected def explain[T](op: String, p: (Type, T) => Boolean, tp1: Type, arg2: T): Boolean = {
+ indentLock.synchronized { super.explain(op, p, tp1, arg2) }
+ }
+
+ private val toStringLock = new Object
+
+ override protected def typeToString(tpe: Type): String =
+ toStringLock.synchronized(super.typeToString(tpe))
+
+ /* The idea of caches is as follows.
+ * When in reflexive mode, a cache is either null, or one sentinal
+ * value representing undefined or the final defined
+ * value. Hence, we can ask in non-synchronized ode whether the cache field
+ * is non null and different from the sentinel (if a sentinel exists).
+ * If that's true, the cache value is current.
+ * Otherwise we arrive in one of the defined... methods listed below
+ * which go through all steps in synchronized mode.
+ */
+
+ override protected def defineUnderlyingOfSingleType(tpe: SingleType) =
+ tpe.synchronized { super.defineUnderlyingOfSingleType(tpe) }
+
+ override protected def defineBaseTypeSeqOfCompoundType(tpe: CompoundType) =
+ tpe.synchronized { super.defineBaseTypeSeqOfCompoundType(tpe) }
+
+ override protected def defineBaseClassesOfCompoundType(tpe: CompoundType) =
+ tpe.synchronized { super.defineBaseClassesOfCompoundType(tpe) }
+
+ override protected def defineParentsOfTypeRef(tpe: TypeRef) =
+ tpe.synchronized { super.defineParentsOfTypeRef(tpe) }
+
+ override protected def defineBaseTypeSeqOfTypeRef(tpe: TypeRef) =
+ tpe.synchronized { super.defineBaseTypeSeqOfTypeRef(tpe) }
+
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/runtime/ToolBoxes.scala b/src/compiler/scala/reflect/runtime/ToolBoxes.scala
index 8afd6d2231..9ab12c6a86 100644
--- a/src/compiler/scala/reflect/runtime/ToolBoxes.scala
+++ b/src/compiler/scala/reflect/runtime/ToolBoxes.scala
@@ -57,7 +57,7 @@ trait ToolBoxes extends { self: Universe =>
def wrapInObject(expr: Tree, fvs: List[Symbol]): ModuleDef = {
val obj = EmptyPackageClass.newModule(nextWrapperModuleName())
- val minfo = ClassInfoType(List(ObjectClass.tpe, ScalaObjectClass.tpe), new Scope, obj.moduleClass)
+ val minfo = ClassInfoType(List(ObjectClass.tpe, ScalaObjectClass.tpe), newScope, obj.moduleClass)
obj.moduleClass setInfo minfo
obj setInfo obj.moduleClass.tpe
val meth = obj.moduleClass.newMethod(newTermName(wrapperMethodName))
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index c8db996de2..9ec1256ca8 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -615,7 +615,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
object icodeChecker extends icodeCheckers.ICodeChecker()
object typer extends analyzer.Typer(
- analyzer.NoContext.make(EmptyTree, Global.this.definitions.RootClass, new Scope)
+ analyzer.NoContext.make(EmptyTree, Global.this.definitions.RootClass, newScope)
)
/** Add the internal compiler phases to the phases set.
diff --git a/src/compiler/scala/tools/nsc/matching/Patterns.scala b/src/compiler/scala/tools/nsc/matching/Patterns.scala
index e5748b7c23..18409cfffe 100644
--- a/src/compiler/scala/tools/nsc/matching/Patterns.scala
+++ b/src/compiler/scala/tools/nsc/matching/Patterns.scala
@@ -37,7 +37,7 @@ trait Patterns extends ast.TreeDSL {
// }
private lazy val dummyMethod =
- new TermSymbol(NoSymbol, NoPosition, newTermName("matching$dummy"))
+ NoSymbol.newTermSymbol(newTermName("matching$dummy"))
// Fresh patterns
def emptyPatterns(i: Int): List[Pattern] = List.fill(i)(NoPattern)
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
index 4205c2ff36..942ec1fa86 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
@@ -207,7 +207,7 @@ abstract class SymbolLoaders {
protected def doComplete(root: Symbol) {
assert(root.isPackageClass, root)
- root.setInfo(new PackageClassInfoType(new Scope(), root))
+ root.setInfo(new PackageClassInfoType(newScope, root))
val sourcepaths = classpath.sourcepaths
for (classRep <- classpath.classes if platform.doLoad(classRep)) {
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 099145d3ae..a61c323824 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -536,8 +536,8 @@ abstract class ClassfileParser {
addEnclosingTParams(clazz)
parseInnerClasses() // also sets the isScala / isScalaRaw / hasMeta flags, see r15956
// get the class file parser to reuse scopes.
- instanceDefs = new Scope
- staticDefs = new Scope
+ instanceDefs = newScope
+ staticDefs = newScope
val classInfo = ClassInfoType(parseParents, instanceDefs, clazz)
val staticInfo = ClassInfoType(List(), staticDefs, statics)
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala
index ead431c8d7..eb8e7a14a5 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala
@@ -108,7 +108,7 @@ abstract class MetaParser{
}
protected def parseClass() {
- locals = new Scope
+ locals = newScope
def parse(): Type = {
nextToken()
if (token == "[") {
@@ -130,7 +130,7 @@ abstract class MetaParser{
protected def parseMethod() {
val globals = locals
- locals = if (locals eq null) new Scope else new Scope(locals)
+ locals = if (locals eq null) newScope else newNestedScope(locals)
def parse(): Type = {
nextToken();
if (token == "[") PolyType(parseTypeParams(), parse())
diff --git a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
index 6c238f52cc..e11a5a4ad9 100644
--- a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
@@ -165,7 +165,7 @@ abstract class TypeParser {
clrTypes.sym2type(typMgdPtr) = clazzMgdPtr
/* clazzMgdPtr but not clazzBoxed is mapped by clrTypes.types into an msil.Type instance,
because there's no metadata-level representation for a "boxed valuetype" */
- val instanceDefsMgdPtr = new Scope
+ val instanceDefsMgdPtr = newScope
val classInfoMgdPtr = ClassInfoType(definitions.anyvalparam, instanceDefsMgdPtr, clazzMgdPtr)
clazzMgdPtr.setFlag(flags)
clazzMgdPtr.setInfo(classInfoMgdPtr)
@@ -196,8 +196,8 @@ abstract class TypeParser {
}
}
/* END CLR generics (snippet 2) */
- instanceDefs = new Scope
- staticDefs = new Scope
+ instanceDefs = newScope
+ staticDefs = newScope
val classInfoAsInMetadata = {
val ifaces: Array[MSILType] = typ.getInterfaces()
@@ -212,7 +212,7 @@ abstract class TypeParser {
}
// methods, properties, events, fields are entered in a moment
if (canBeTakenAddressOf) {
- val instanceDefsBoxed = new Scope
+ val instanceDefsBoxed = newScope
ClassInfoType(parents.toList, instanceDefsBoxed, clazzBoxed)
} else
ClassInfoType(parents.toList, instanceDefs, clazz)
diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
index 8f5d308b8f..05b2b7a437 100644
--- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
+++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
@@ -119,7 +119,7 @@ abstract class AddInterfaces extends InfoTransform {
* given the decls ifaceDecls of its interface.
*/
private def implDecls(implClass: Symbol, ifaceDecls: Scope): Scope = {
- val decls = new Scope
+ val decls = newScope
if ((ifaceDecls lookup nme.MIXIN_CONSTRUCTOR) == NoSymbol)
decls enter (
implClass.newMethod(nme.MIXIN_CONSTRUCTOR, implClass.pos)
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index 23817545e2..d1c71faf1e 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -447,7 +447,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
val closureClass = clazz.newClass(nme.delayedInitArg.toTypeName, impl.pos, SYNTHETIC | FINAL)
val closureParents = List(AbstractFunctionClass(0).tpe, ScalaObjectClass.tpe)
- closureClass setInfoAndEnter new ClassInfoType(closureParents, new Scope, closureClass)
+ closureClass setInfoAndEnter new ClassInfoType(closureParents, newScope, closureClass)
val outerField = (
closureClass
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 71696c24e6..b342b95742 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -742,7 +742,7 @@ abstract class Erasure extends AddInterfaces
//println("computing bridges for " + owner)//DEBUG
assert(phase == currentRun.erasurePhase)
val site = owner.thisType
- val bridgesScope = new Scope
+ val bridgesScope = newScope
val bridgeTarget = new mutable.HashMap[Symbol, Symbol]
var bridges: List[Tree] = List()
val opc = atPhase(currentRun.explicitouterPhase) {
diff --git a/src/compiler/scala/tools/nsc/transform/Flatten.scala b/src/compiler/scala/tools/nsc/transform/Flatten.scala
index b17fd7b9b0..4fa5b52de3 100644
--- a/src/compiler/scala/tools/nsc/transform/Flatten.scala
+++ b/src/compiler/scala/tools/nsc/transform/Flatten.scala
@@ -65,7 +65,7 @@ abstract class Flatten extends InfoTransform {
case ClassInfoType(parents, decls, clazz) =>
var parents1 = parents
val decls1 = scopeTransform(clazz) {
- val decls1 = new Scope()
+ val decls1 = newScope
if (clazz.isPackageClass) {
atPhase(phase.next)(decls foreach (decls1 enter _))
} else {
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index bf19cf10e9..bd29336703 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -403,12 +403,12 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
assert(clazz.sourceModule != NoSymbol || clazz.isAnonymousClass,
clazz + " has no sourceModule: sym = " + sym + " sym.tpe = " + sym.tpe)
parents1 = List()
- decls1 = new Scope(decls.toList filter isImplementedStatically)
+ decls1 = newScopeWith(decls.toList filter isImplementedStatically: _*)
} else if (!parents.isEmpty) {
parents1 = parents.head :: (parents.tail map toInterface)
}
}
- //decls1 = atPhase(phase.next)(new Scope(decls1.toList))//debug
+ //decls1 = atPhase(phase.next)(newScopeWith(decls1.toList: _*))//debug
if ((parents1 eq parents) && (decls1 eq decls)) tp
else ClassInfoType(parents1, decls1, clazz)
@@ -480,7 +480,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
/** The rootContext used for typing */
private val rootContext =
- erasure.NoContext.make(EmptyTree, RootClass, new Scope)
+ erasure.NoContext.make(EmptyTree, RootClass, newScope)
/** The typer */
private var localTyper: erasure.Typer = _
diff --git a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
index 70f8d37585..1200e973c5 100644
--- a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
+++ b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
@@ -74,7 +74,7 @@ abstract class OverridingPairs {
}
/** The symbols that can take part in an overriding pair */
- private val decls = new Scope
+ private val decls = newScope
// fill `decls` with overriding shadowing overridden */
{ def fillDecls(bcs: List[Symbol], deferredflag: Int) {
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index fd826fb6d8..4a104857db 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -502,7 +502,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
typeEnv(sClass) = env
this.specializedClass((clazz, env0)) = sClass
- val decls1 = new Scope // declarations of the newly specialized class 'sClass'
+ val decls1 = newScope // declarations of the newly specialized class 'sClass'
var oldClassTParams: List[Symbol] = Nil // original unspecialized type parameters
var newClassTParams: List[Symbol] = Nil // unspecialized type parameters of 'specializedClass' (cloned)
@@ -1089,7 +1089,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
if (tparams.nonEmpty) " (poly)" else "",
clazz, parents1, phase)
)
- val newScope = new Scope(specializeClass(clazz, typeEnv(clazz)) ++ specialOverrides(clazz))
+ val newScope = newScopeWith(specializeClass(clazz, typeEnv(clazz)) ++ specialOverrides(clazz): _*)
// If tparams.isEmpty, this is just the ClassInfoType.
polyType(tparams, ClassInfoType(parents1, newScope, clazz))
case _ =>
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 56d9658377..bf41ddab9b 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -259,7 +259,7 @@ abstract class UnCurry extends InfoTransform
else if (isPartial) List(appliedType(AbstractPartialFunctionClass.typeConstructor, targs), SerializableClass.tpe)
else List(ObjectClass.tpe, fun.tpe, SerializableClass.tpe)
- anonClass setInfo ClassInfoType(parents, new Scope, anonClass)
+ anonClass setInfo ClassInfoType(parents, newScope, anonClass)
val applyMethod = anonClass.newMethod(nme.apply, fun.pos, FINAL)
applyMethod setInfoAndEnter MethodType(applyMethod newSyntheticValueParams formals, restpe)
anonClass addAnnotation serialVersionUIDAnnotation
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index faff4ccab2..c2647c709a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -218,7 +218,7 @@ trait Contexts { self: Analyzer =>
make(unit, tree, owner, scope, imports)
def makeNewScope(tree: Tree, owner: Symbol): Context =
- make(tree, owner, new Scope(scope))
+ make(tree, owner, newNestedScope(scope))
// IDE stuff: distinguish between scopes created for typing and scopes created for naming.
def make(tree: Tree, owner: Symbol): Context =
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 53e88b33c8..d0492c2f63 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -213,7 +213,7 @@ trait Implicits {
/** An extractor for types of the form ? { name: (? >: argtpe <: Any*)restp }
*/
object HasMethodMatching {
- val dummyMethod = new TermSymbol(NoSymbol, NoPosition, newTermName("typer$dummy"))
+ val dummyMethod = NoSymbol.newTermSymbol(newTermName("typer$dummy"))
def templateArgType(argtpe: Type) = new BoundedWildcardType(TypeBounds.lower(argtpe))
def apply(name: Name, argtpes: List[Type], restpe: Type): Type = {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 354b8caaa3..b19a471214 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -87,7 +87,7 @@ trait Namers extends MethodSynthesis {
newNamer(context.makeNewScope(tree, sym))
}
def createInnerNamer() = {
- newNamer(context.make(context.tree, owner, new Scope))
+ newNamer(context.make(context.tree, owner, newScope))
}
def createPrimaryConstructorParameterNamer: Namer = { //todo: can we merge this with SCCmode?
val classContext = context.enclClass
@@ -832,7 +832,7 @@ trait Namers extends MethodSynthesis {
val parents = typer.parentTypes(templ) map checkParent
enterSelf(templ.self)
- val decls = new Scope
+ val decls = newScope
val templateNamer = newNamer(context.make(templ, clazz, decls))
templateNamer enterSyms templ.body
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
index 4104803194..b28a717049 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
@@ -1471,7 +1471,7 @@ defined class Foo */
def freshSym(pos: Position, tp: Type = NoType, prefix: String = "x") = {ctr += 1;
// assert(owner ne null)
// assert(owner ne NoSymbol)
- new TermSymbol(NoSymbol, pos, vpmName.counted(prefix, ctr)) setInfo repackExistential(tp)
+ NoSymbol.newTermSymbol(vpmName.counted(prefix, ctr), pos) setInfo repackExistential(tp)
}
def repeatedToSeq(tp: Type): Type = (tp baseType RepeatedParamClass) match {
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 112aa47114..ee2e292bba 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -955,7 +955,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
// Forward reference checking ---------------------------------------------------
class LevelInfo(val outer: LevelInfo) {
- val scope: Scope = if (outer eq null) new Scope else new Scope(outer.scope)
+ val scope: Scope = if (outer eq null) newScope else newNestedScope(outer.scope)
var maxindex: Int = Int.MinValue
var refpos: Position = _
var refsym: Symbol = _
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index b4221365be..d6248891a2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1360,7 +1360,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
assert(clazz != NoSymbol)
reenterTypeParams(cdef.tparams)
val tparams1 = cdef.tparams mapConserve (typedTypeDef)
- val impl1 = newTyper(context.make(cdef.impl, clazz, new Scope))
+ val impl1 = newTyper(context.make(cdef.impl, clazz, newScope))
.typedTemplate(cdef.impl, parentTypes(cdef.impl))
val impl2 = finishMethodSynthesis(impl1, clazz, context)
if ((clazz != ClassfileAnnotationClass) &&
@@ -1395,7 +1395,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
val typedMods = removeAnnotations(mdef.mods)
assert(clazz != NoSymbol, mdef)
- val typer0 = newTyper(context.make(mdef.impl, clazz, new Scope))
+ val typer0 = newTyper(context.make(mdef.impl, clazz, newScope))
val impl1 = typer0.typedTemplate(mdef.impl, {
parentTypes(mdef.impl) ++ (
if (linkedClass == NoSymbol || !linkedClass.isSerializable || clazz.isSerializable) Nil
@@ -3983,7 +3983,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
val parents1 = templ.parents mapConserve (typedType(_, mode))
if (parents1 exists (_.tpe.isError)) tree setType ErrorType
else {
- val decls = new Scope
+ val decls = newScope
//Console.println("Owner: " + context.enclClass.owner + " " + context.enclClass.owner.id)
val self = refinedType(parents1 map (_.tpe), context.enclClass.owner, decls, templ.pos)
newTyper(context.make(templ, self.typeSymbol, decls)).typedRefinement(templ.body)
diff --git a/src/detach/plugin/scala/tools/detach/Detach.scala b/src/detach/plugin/scala/tools/detach/Detach.scala
index e9cd474b82..fee2c5a273 100644
--- a/src/detach/plugin/scala/tools/detach/Detach.scala
+++ b/src/detach/plugin/scala/tools/detach/Detach.scala
@@ -735,7 +735,7 @@ abstract class Detach extends PluginComponent
iface.sourceFile = clazz.sourceFile
iface setFlag (ABSTRACT | TRAIT | INTERFACE) // Java interface
val iparents = List(ObjectClass.tpe, RemoteClass.tpe, ScalaObjectClass.tpe)
- iface setInfo ClassInfoType(iparents, new Scope, iface)
+ iface setInfo ClassInfoType(iparents, newScope, iface)
// methods must throw RemoteException
iface addAnnotation remoteAnnotationInfo
@@ -749,7 +749,7 @@ abstract class Detach extends PluginComponent
// Variant 2: un-/exportObject
//val cparents = List(ObjectClass.tpe, iface.tpe,
// UnreferencedClass.tpe, ScalaObjectClass.tpe)
- iclaz setInfo ClassInfoType(cparents, new Scope, iclaz)
+ iclaz setInfo ClassInfoType(cparents, newScope, iclaz)
val proxy = (iface, iclaz, new mutable.HashMap[Symbol, Symbol])
proxies(clazz) = proxy
proxy
diff --git a/src/library/scala/reflect/api/StandardDefinitions.scala b/src/library/scala/reflect/api/StandardDefinitions.scala
index 6b480ab83d..08071660a2 100755
--- a/src/library/scala/reflect/api/StandardDefinitions.scala
+++ b/src/library/scala/reflect/api/StandardDefinitions.scala
@@ -12,9 +12,7 @@ trait StandardDefinitions { self: Universe =>
abstract class AbsDefinitions {
// outer packages and their classes
- // Under consideration
- // def RootPackage: Symbol
-
+ def RootPackage: Symbol
def RootClass: Symbol
def EmptyPackage: Symbol
def EmptyPackageClass: Symbol
diff --git a/src/library/scala/reflect/api/Types.scala b/src/library/scala/reflect/api/Types.scala
index 4b959649fd..6185a788ae 100755
--- a/src/library/scala/reflect/api/Types.scala
+++ b/src/library/scala/reflect/api/Types.scala
@@ -20,7 +20,7 @@ trait Types { self: Universe =>
/** The collection of declarations in this type
*/
- def allDeclarations: Iterable[Symbol]
+ def declarations: Iterable[Symbol]
/** The member with given name, either directly declared or inherited,
* an OverloadedSymbol if several exist, NoSymbol if none exist.
@@ -36,7 +36,7 @@ trait Types { self: Universe =>
* Members appear in the linearization order of their owners.
* Members with the same owner appear in reverse order of their declarations.
*/
- def allMembers: Iterable[Symbol]
+ def members: Iterable[Symbol]
/** An iterable containing all non-private members of this type (directly declared or inherited)
* Members appear in the linearization order of their owners.
@@ -125,19 +125,23 @@ trait Types { self: Universe =>
/** Does this type contain a reference to given symbol? */
def contains(sym: Symbol): Boolean
- }
- /** This class declares methods that are visible in a `SingleType`.
- */
- trait AbsSingletonType extends AbsType {
+ /** If this is a compound type, the list of its parent types;
+ * otherwise the empty list
+ */
+ def parents: List[Type]
- /** The type underlying a singleton type */
+ /** If this is a singleton type, returns the type underlying it;
+ * otherwise returns this type itself.
+ */
def underlying: Type
- /** Widen from singleton type to its underlying non-singleton
- * base type by applying one or more `underlying` dereferences,
- * identity for all other types.
+ /** If this is a singleton type, widen it to its nearest underlying non-singleton
+ * base type by applying one or more `underlying` dereferences.
+ * If this is not a singlecon type, returns this type itself.
*
+ * Example:
+ *
* class Outer { class C ; val x: C }
* val o: Outer
* <o.x.type>.widen = o.C
@@ -145,19 +149,6 @@ trait Types { self: Universe =>
def widen: Type
}
- /** This class declares methods that are visible in a `CompoundType` (i.e.
- * a class/trait/object template or refined type of the form
- * {{{
- * P_1 with ... with P_m { D_1; ...; D_n }
- * }}}
- * P_n
- */
- trait AbsCompoundType extends AbsType {
-
- /** The list of parent types of this compound type */
- def parents: List[Type]
- }
-
/** The type of Scala types, and also Scala type signatures.
* (No difference is internally made between the two).
*/
@@ -293,7 +284,7 @@ trait Types { self: Universe =>
/** A subtype of Type representing refined types as well as `ClassInfo` signatures.
*/
- type CompoundType <: /*AbsCompoundType with*/ Type
+ type CompoundType <: Type
/** The `RefinedType` type defines types of any of the forms on the left,
* with their RefinedType representations to the right.
diff --git a/test/files/run/reflection-implClass.scala b/test/files/run/reflection-implClass.scala
index b91f122a23..2b30e29bb3 100644
--- a/test/files/run/reflection-implClass.scala
+++ b/test/files/run/reflection-implClass.scala
@@ -8,19 +8,19 @@
object Test extends App with Outer {
import scala.reflect.mirror
- assert(mirror.classToSymbol(manifest[Foo].erasure).info.declaration(mirror.newTermName("bar")).info ==
- mirror.classToSymbol(manifest[Bar].erasure).info.declaration(mirror.newTermName("foo")).info)
+ assert(mirror.classToSymbol(manifest[Foo].erasure).typeSig.declaration(mirror.newTermName("bar")).typeSig ==
+ mirror.classToSymbol(manifest[Bar].erasure).typeSig.declaration(mirror.newTermName("foo")).typeSig)
val s1 = implClass(manifest[Foo].erasure)
assert(s1 != mirror.NoSymbol)
- assert(s1.info != mirror.NoType)
- assert(s1.companionModule.info != mirror.NoType)
- assert(s1.companionModule.info.declaration(mirror.newTermName("bar")) != mirror.NoSymbol)
+ assert(s1.typeSig != mirror.NoType)
+ assert(s1.companionModule.typeSig != mirror.NoType)
+ assert(s1.companionModule.typeSig.declaration(mirror.newTermName("bar")) != mirror.NoSymbol)
val s2 = implClass(manifest[Bar].erasure)
assert(s2 != mirror.NoSymbol)
- assert(s2.info != mirror.NoType)
- assert(s2.companionModule.info != mirror.NoType)
- assert(s2.companionModule.info.declaration(mirror.newTermName("foo")) != mirror.NoSymbol)
+ assert(s2.typeSig != mirror.NoType)
+ assert(s2.companionModule.typeSig != mirror.NoType)
+ assert(s2.companionModule.typeSig.declaration(mirror.newTermName("foo")) != mirror.NoSymbol)
def implClass(clazz: Class[_]) = {
val implClass = Class.forName(clazz.getName + "$class")
mirror.classToSymbol(implClass)