summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/reflect/internal/AnnotationCheckers.scala1
-rw-r--r--src/compiler/scala/reflect/internal/AnnotationInfos.scala2
-rw-r--r--src/compiler/scala/reflect/internal/BaseTypeSeqs.scala51
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala119
-rw-r--r--src/compiler/scala/reflect/internal/Importers.scala4
-rw-r--r--src/compiler/scala/reflect/internal/InfoTransformers.scala2
-rw-r--r--src/compiler/scala/reflect/internal/Scopes.scala50
-rw-r--r--src/compiler/scala/reflect/internal/SymbolTable.scala5
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala135
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala457
-rw-r--r--src/compiler/scala/reflect/runtime/ConversionUtil.scala48
-rw-r--r--src/compiler/scala/reflect/runtime/JavaToScala.scala2
-rw-r--r--src/compiler/scala/reflect/runtime/Loaders.scala4
-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.scala51
-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.scala9
-rw-r--r--src/detach/plugin/scala/tools/detach/Detach.scala4
-rwxr-xr-xsrc/library/scala/reflect/api/Names.scala33
-rwxr-xr-xsrc/library/scala/reflect/api/StandardDefinitions.scala4
-rwxr-xr-xsrc/library/scala/reflect/api/Symbols.scala91
-rw-r--r--src/library/scala/reflect/api/Trees.scala3
-rwxr-xr-xsrc/library/scala/reflect/api/Types.scala39
-rw-r--r--test/files/run/reflection-implClass.scala16
46 files changed, 932 insertions, 467 deletions
diff --git a/src/compiler/scala/reflect/internal/AnnotationCheckers.scala b/src/compiler/scala/reflect/internal/AnnotationCheckers.scala
index 666c1d74cb..449b0ca0bc 100644
--- a/src/compiler/scala/reflect/internal/AnnotationCheckers.scala
+++ b/src/compiler/scala/reflect/internal/AnnotationCheckers.scala
@@ -49,6 +49,7 @@ trait AnnotationCheckers {
def adaptAnnotations(tree: Tree, mode: Int, pt: Type): Tree = tree
}
+ // Syncnote: Annotation checkers inaccessible to reflection, so no sync in var necessary.
/** The list of annotation checkers that have been registered */
private var annotationCheckers: List[AnnotationChecker] = Nil
diff --git a/src/compiler/scala/reflect/internal/AnnotationInfos.scala b/src/compiler/scala/reflect/internal/AnnotationInfos.scala
index 255e69c3c6..c3dde3e6d1 100644
--- a/src/compiler/scala/reflect/internal/AnnotationInfos.scala
+++ b/src/compiler/scala/reflect/internal/AnnotationInfos.scala
@@ -178,7 +178,7 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
private var rawpos: Position = NoPosition
def pos = rawpos
- def setPos(pos: Position): this.type = {
+ def setPos(pos: Position): this.type = { // Syncnote: Setpos inaccessible to reflection, so no sync in rawpos necessary.
rawpos = pos
this
}
diff --git a/src/compiler/scala/reflect/internal/BaseTypeSeqs.scala b/src/compiler/scala/reflect/internal/BaseTypeSeqs.scala
index 38277b5a09..9e5c93753f 100644
--- a/src/compiler/scala/reflect/internal/BaseTypeSeqs.scala
+++ b/src/compiler/scala/reflect/internal/BaseTypeSeqs.scala
@@ -29,7 +29,14 @@ 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)
+
+ /** Note: constructor is protected to force everyone to use the factory method newBaseTypeSeq instead.
+ * This is necessary because when run from reflection every base type sequence needs to have a
+ * SynchronizedBaseTypeSeq as mixin.
+ */
+ class BaseTypeSeq protected[BaseTypeSeqs] (private[BaseTypeSeqs] val parents: List[Type], private[BaseTypeSeqs] val elems: Array[Type]) {
self =>
incCounter(baseTypeSeqCount)
incCounter(baseTypeSeqLenTotal, elems.length)
@@ -41,7 +48,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 +96,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 +120,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 +173,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 +240,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 02d6737bdb..1490d80d7a 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)
@@ -211,7 +211,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
}
@@ -357,7 +357,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")
@@ -615,7 +615,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val ValueTypeClass: Symbol = getClass(sn.ValueType)
// System.MulticastDelegate
lazy val DelegateClass: Symbol = getClass(sn.Delegate)
- var Delegate_scalaCallers: List[Symbol] = List()
+ var Delegate_scalaCallers: List[Symbol] = List() // Syncnote: No protection necessary yet as only for .NET where reflection is not supported.
// Symbol -> (Symbol, Type): scalaCaller -> (scalaMethodSym, DelegateType)
// var Delegate_scalaCallerInfos: HashMap[Symbol, (Symbol, Type)] = _
lazy val Delegate_scalaCallerTargets: mutable.HashMap[Symbol, Symbol] = mutable.HashMap()
@@ -635,31 +635,47 @@ trait Definitions extends reflect.api.StandardDefinitions {
case _ => false
})
}
-
+
// members of class scala.Any
- var Any_== : Symbol = _
- var Any_!= : Symbol = _
- var Any_equals : Symbol = _
- var Any_hashCode : Symbol = _
- var Any_toString : Symbol = _
- var Any_getClass : Symbol = _
- var Any_isInstanceOf: Symbol = _
- var Any_asInstanceOf: Symbol = _
- var Any_## : Symbol = _
-
- // members of class java.lang.{Object, String}
- var Object_eq : Symbol = _
- var Object_ne : Symbol = _
- var Object_== : Symbol = _
- var Object_!= : Symbol = _
- var Object_## : Symbol = _
- var Object_synchronized: Symbol = _
+ lazy val Any_== = newMethod(AnyClass, nme.EQ, anyparam, booltype, FINAL)
+ lazy val Any_!= = newMethod(AnyClass, nme.NE, anyparam, booltype, FINAL)
+ lazy val Any_equals = newMethod(AnyClass, nme.equals_, anyparam, booltype)
+ lazy val Any_hashCode = newMethod(AnyClass, nme.hashCode_, Nil, inttype)
+ lazy val Any_toString = newMethod(AnyClass, nme.toString_, Nil, stringtype)
+ lazy val Any_## = newMethod(AnyClass, nme.HASHHASH, Nil, inttype, FINAL)
+
+ // Any_getClass requires special handling. The return type is determined on
+ // a per-call-site basis as if the function being called were actually:
+ //
+ // // Assuming `target.getClass()`
+ // def getClass[T](target: T): Class[_ <: T]
+ //
+ // Since getClass is not actually a polymorphic method, this requires compiler
+ // participation. At the "Any" level, the return type is Class[_] as it is in
+ // java.lang.Object. Java also special cases the return type.
+ lazy val Any_getClass =
+ newMethod(AnyClass, nme.getClass_, Nil, getMember(ObjectClass, nme.getClass_).tpe.resultType, DEFERRED)
+ lazy val Any_isInstanceOf = newPolyMethod(
+ AnyClass, nme.isInstanceOf_, tparam => NullaryMethodType(booltype)) setFlag FINAL
+ lazy val Any_asInstanceOf = newPolyMethod(
+ AnyClass, nme.asInstanceOf_, tparam => NullaryMethodType(tparam.typeConstructor)) setFlag FINAL
+
+ // members of class java.lang.{ Object, String }
+ lazy val Object_## = newMethod(ObjectClass, nme.HASHHASH, Nil, inttype, FINAL)
+ lazy val Object_== = newMethod(ObjectClass, nme.EQ, anyrefparam, booltype, FINAL)
+ lazy val Object_!= = newMethod(ObjectClass, nme.NE, anyrefparam, booltype, FINAL)
+ lazy val Object_eq = newMethod(ObjectClass, nme.eq, anyrefparam, booltype, FINAL)
+ lazy val Object_ne = newMethod(ObjectClass, nme.ne, anyrefparam, booltype, FINAL)
+ lazy val Object_synchronized = newPolyMethodCon(
+ ObjectClass, nme.synchronized_,
+ tparam => msym => MethodType(msym.newSyntheticValueParams(List(tparam.typeConstructor)), tparam.typeConstructor)) setFlag FINAL
lazy val Object_isInstanceOf = newPolyMethod(
ObjectClass, newTermName("$isInstanceOf"),
tparam => MethodType(List(), booltype)) setFlag (FINAL | SYNTHETIC)
lazy val Object_asInstanceOf = newPolyMethod(
ObjectClass, newTermName("$asInstanceOf"),
tparam => MethodType(List(), tparam.typeConstructor)) setFlag (FINAL | SYNTHETIC)
+ lazy val String_+ = newMethod(StringClass, nme.raw.PLUS, anyparam, stringtype, FINAL)
def Object_getClass = getMember(ObjectClass, nme.getClass_)
def Object_clone = getMember(ObjectClass, nme.clone_)
@@ -670,7 +686,6 @@ trait Definitions extends reflect.api.StandardDefinitions {
def Object_hashCode = getMember(ObjectClass, nme.hashCode_)
def Object_toString = getMember(ObjectClass, nme.toString_)
- var String_+ : Symbol = _
// boxed classes
lazy val ObjectRefClass = getRequiredClass("scala.runtime.ObjectRef")
@@ -829,7 +844,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 =
@@ -946,43 +961,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
RootClass.info.decls enter EmptyPackage
RootClass.info.decls enter RootPackage
-
- // members of class scala.Any
- Any_== = newMethod(AnyClass, nme.EQ, anyparam, booltype, FINAL)
- Any_!= = newMethod(AnyClass, nme.NE, anyparam, booltype, FINAL)
- Any_equals = newMethod(AnyClass, nme.equals_, anyparam, booltype)
- Any_hashCode = newMethod(AnyClass, nme.hashCode_, Nil, inttype)
- Any_toString = newMethod(AnyClass, nme.toString_, Nil, stringtype)
- Any_## = newMethod(AnyClass, nme.HASHHASH, Nil, inttype, FINAL)
-
- // Any_getClass requires special handling. The return type is determined on
- // a per-call-site basis as if the function being called were actually:
- //
- // // Assuming `target.getClass()`
- // def getClass[T](target: T): Class[_ <: T]
- //
- // Since getClass is not actually a polymorphic method, this requires compiler
- // participation. At the "Any" level, the return type is Class[_] as it is in
- // java.lang.Object. Java also special cases the return type.
- Any_getClass =
- newMethod(AnyClass, nme.getClass_, Nil, getMember(ObjectClass, nme.getClass_).tpe.resultType, DEFERRED)
- Any_isInstanceOf = newPolyMethod(
- AnyClass, nme.isInstanceOf_, tparam => NullaryMethodType(booltype)) setFlag FINAL
- Any_asInstanceOf = newPolyMethod(
- AnyClass, nme.asInstanceOf_, tparam => NullaryMethodType(tparam.typeConstructor)) setFlag FINAL
-
- // members of class java.lang.{ Object, String }
- Object_## = newMethod(ObjectClass, nme.HASHHASH, Nil, inttype, FINAL)
- Object_== = newMethod(ObjectClass, nme.EQ, anyrefparam, booltype, FINAL)
- Object_!= = newMethod(ObjectClass, nme.NE, anyrefparam, booltype, FINAL)
- Object_eq = newMethod(ObjectClass, nme.eq, anyrefparam, booltype, FINAL)
- Object_ne = newMethod(ObjectClass, nme.ne, anyrefparam, booltype, FINAL)
- Object_synchronized = newPolyMethodCon(
- ObjectClass, nme.synchronized_,
- tparam => msym => MethodType(msym.newSyntheticValueParams(List(tparam.typeConstructor)), tparam.typeConstructor)) setFlag FINAL
-
- String_+ = newMethod(StringClass, nme.raw.PLUS, anyparam, stringtype, FINAL)
-
+
val forced = List( // force initialization of every symbol that is entered as a side effect
AnnotationDefaultAttr, // #2264
RepeatedParamClass,
@@ -995,8 +974,24 @@ trait Definitions extends reflect.api.StandardDefinitions {
NothingClass,
SingletonClass,
EqualsPatternClass,
+ Any_==,
+ Any_!=,
+ Any_equals,
+ Any_hashCode,
+ Any_toString,
+ Any_getClass,
+ Any_isInstanceOf,
+ Any_asInstanceOf,
+ Any_##,
+ Object_eq,
+ Object_ne,
+ Object_==,
+ Object_!=,
+ Object_##,
+ Object_synchronized,
Object_isInstanceOf,
- Object_asInstanceOf
+ Object_asInstanceOf,
+ String_+
)
/** Removing the anyref parent they acquire from having a source file.
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/InfoTransformers.scala b/src/compiler/scala/reflect/internal/InfoTransformers.scala
index 9c54b1b4cd..96d9d8f076 100644
--- a/src/compiler/scala/reflect/internal/InfoTransformers.scala
+++ b/src/compiler/scala/reflect/internal/InfoTransformers.scala
@@ -9,6 +9,8 @@ package internal
trait InfoTransformers {
self: SymbolTable =>
+ /* Syncnote: This should not need to be protected, as reflection does not run in multiple phases.
+ */
abstract class InfoTransformer {
var prev: InfoTransformer = this
var next: InfoTransformer = this
diff --git a/src/compiler/scala/reflect/internal/Scopes.scala b/src/compiler/scala/reflect/internal/Scopes.scala
index fb3012adff..54d3de09cd 100644
--- a/src/compiler/scala/reflect/internal/Scopes.scala
+++ b/src/compiler/scala/reflect/internal/Scopes.scala
@@ -37,9 +37,18 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
def unapplySeq(decls: Scope): Some[Seq[Symbol]] = Some(decls.toList)
}
- class Scope(initElems: ScopeEntry) extends Iterable[Symbol] {
+ /** Note: constructor is protected to force everyone to use the factory methods newScope or newNestedScope instead.
+ * This is necessary because when run from reflection every scope needs to have a
+ * SynchronizedScope as mixin.
+ */
+ class Scope protected[Scopes] (initElems: ScopeEntry = null) extends Iterable[Symbol] {
+
+ protected[Scopes] 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 +74,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 +308,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 +318,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 +349,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 6b4080c6ad..9f8476a6fe 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 =
@@ -68,7 +72,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
/** The class for all symbols */
- abstract class Symbol(initOwner: Symbol, initPos: Position, initName: Name)
+ abstract class Symbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: Name)
extends AbsSymbolImpl
with HasFlags
with Annotatable[Symbol] {
@@ -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): Boolean = {
+ private[scala] def lock(handler: => Unit): Boolean = {
if ((rawflags & LOCKED) != 0L) {
if (settings.Yrecursion.value != 0) {
recursionTable get this match {
@@ -371,11 +385,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
// 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
}
@@ -740,7 +754,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).
@@ -748,8 +762,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
@@ -782,7 +796,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
@@ -791,7 +805,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
ifs = ifs.prev
}
}
- rawname = name
+ _rawname = name
}
}
@@ -859,20 +873,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
@@ -958,7 +972,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
throw CyclicReference(this, tp)
}
} else {
- rawflags |= LOCKED
+ _rawflags |= LOCKED
// activeLocks += 1
// lockedSyms += this
}
@@ -987,7 +1001,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. */
@@ -1006,11 +1020,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
}
@@ -1048,11 +1062,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
@@ -1063,7 +1077,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 {
@@ -1072,7 +1087,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 = (
@@ -1088,6 +1103,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
}
}
+ }
/** Initialize the symbol */
final def initialize: this.type = {
@@ -1097,6 +1113,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
@@ -1104,6 +1121,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
@@ -1215,7 +1233,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def reset(completer: Type) {
resetFlags()
infos = null
- validTo = NoPeriod
+ _validTo = NoPeriod
//limit = NoPhase.id
setInfo(completer)
}
@@ -1242,7 +1260,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("(", ", ", ")")
@@ -2052,15 +2070,18 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
/** A class for term symbols */
- class TermSymbol(initOwner: Symbol, initPos: Position, initName: TermName)
+ class TermSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TermName)
extends Symbol(initOwner, initPos, initName) {
final override def isTerm = true
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 =
@@ -2142,7 +2163,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
/** A class for module symbols */
- class ModuleSymbol(initOwner: Symbol, initPos: Position, initName: TermName)
+ class ModuleSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TermName)
extends TermSymbol(initOwner, initPos, initName) {
private var flatname: TermName = null
@@ -2165,7 +2186,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
/** A class for method symbols */
- class MethodSymbol(initOwner: Symbol, initPos: Position, initName: TermName)
+ class MethodSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TermName)
extends TermSymbol(initOwner, initPos, initName) {
private var mtpePeriod = NoPeriod
private var mtpePre: Type = _
@@ -2191,7 +2212,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
}
- class AliasTypeSymbol(initOwner: Symbol, initPos: Position, initName: TypeName)
+ class AliasTypeSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName)
extends TypeSymbol(initOwner, initPos, initName) {
// Temporary programmatic help tracking down who might do such a thing
override def setFlag(mask: Long): this.type = {
@@ -2232,7 +2253,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 protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName) extends Symbol(initOwner, initPos, initName) {
privateWithin = NoSymbol
private var tyconCache: Type = null
private var tyconRunId = NoRunId
@@ -2370,7 +2391,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*
* origin.isInstanceOf[Symbol] == !hasFlag(EXISTENTIAL)
*/
- class TypeSkolem(initOwner: Symbol, initPos: Position, initName: TypeName, origin: AnyRef)
+ class TypeSkolem protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName, origin: AnyRef)
extends TypeSymbol(initOwner, initPos, initName) {
/** The skolemization level in place when the skolem was constructed */
@@ -2399,11 +2420,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
/** A class for class symbols */
- class ClassSymbol(initOwner: Symbol, initPos: Position, initName: TypeName)
+ class ClassSymbol protected[Symbols] (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
@@ -2465,7 +2486,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
typeOfThisCache
}
- else thissym.tpe
+ else thisSym.tpe
}
/** Sets the self type of the class */
@@ -2485,7 +2506,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 }
@@ -2496,7 +2517,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* Note: Not all module classes are of this type; when unpickled, we get
* plain class symbols!
*/
- class ModuleClassSymbol(owner: Symbol, pos: Position, name: TypeName)
+ class ModuleClassSymbol protected[Symbols] (owner: Symbol, pos: Position, name: TypeName)
extends ClassSymbol(owner, pos, name) {
private var module: Symbol = null
private var implicitMembersCacheValue: List[Symbol] = List()
@@ -2529,10 +2550,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 protected[Symbols]() 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
@@ -2563,6 +2586,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
abort("no-symbol does not have a type constructor (this may indicate scalac cannot find fundamental classes)")
}
+ 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 8ca00dd5c5..35d26493f8 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,36 @@ 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)
+ if (baseTypeSeqCache eq undetBaseTypeSeq)
+ throw new RecoverableCyclicReference(typeSymbol)
+
+ baseTypeSeqCache
}
- if (baseTypeSeqCache eq undetBaseTypeSeq)
- throw new RecoverableCyclicReference(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)
+ if (baseClassesCache eq null)
+ throw new RecoverableCyclicReference(typeSymbol)
+
+ baseClassesCache
}
- if (baseClassesCache eq null)
- throw new RecoverableCyclicReference(typeSymbol)
- baseClassesCache
}
/** The slightly less idiomatic use of Options is due to
@@ -1475,6 +1415,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 +1614,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 +1628,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 +1787,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 +1872,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 +1892,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 +1960,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 +1988,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 +2006,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 +2017,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 +2081,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 +2098,19 @@ 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)
+ if (baseTypeSeqCache == undetBaseTypeSeq)
+ throw new RecoverableCyclicReference(sym)
+
+ baseTypeSeqCache
}
- if (baseTypeSeqCache == undetBaseTypeSeq)
- throw new RecoverableCyclicReference(sym)
- baseTypeSeqCache
}
private def preString = (
@@ -2151,6 +2196,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 +2648,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 +3124,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
@@ -3352,7 +3428,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)
@@ -3376,6 +3452,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
@@ -3648,7 +3730,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 */
@@ -3713,6 +3795,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 = _
@@ -3767,7 +3854,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 {
@@ -4381,15 +4468,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.
@@ -4406,12 +4498,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
@@ -5848,7 +5943,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
@@ -5999,7 +6094,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
@@ -6298,7 +6393,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)
@@ -6343,4 +6438,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/ConversionUtil.scala b/src/compiler/scala/reflect/runtime/ConversionUtil.scala
index bd40200310..e75fd78590 100644
--- a/src/compiler/scala/reflect/runtime/ConversionUtil.scala
+++ b/src/compiler/scala/reflect/runtime/ConversionUtil.scala
@@ -17,36 +17,42 @@ trait ConversionUtil { self: SymbolTable =>
private val toScalaMap = new HashMap[J, S]
private val toJavaMap = new HashMap[S, J]
- def enter(j: J, s: S) = {
+ def enter(j: J, s: S) = synchronized {
debugInfo("cached: "+j+"/"+s)
toScalaMap(j) = s
toJavaMap(s) = j
}
- def toScala(key: J)(body: => S): S = toScalaMap get key match {
- case Some(v) =>
- v
- case none =>
- val result = body
- enter(key, result)
- result
+ def toScala(key: J)(body: => S): S = synchronized {
+ toScalaMap get key match {
+ case Some(v) =>
+ v
+ case none =>
+ val result = body
+ enter(key, result)
+ result
+ }
}
- def toJava(key: S)(body: => J): J = toJavaMap get key match {
- case Some(v) =>
- v
- case none =>
- val result = body
- enter(result, key)
- result
+ def toJava(key: S)(body: => J): J = synchronized {
+ toJavaMap get key match {
+ case Some(v) =>
+ v
+ case none =>
+ val result = body
+ enter(result, key)
+ result
+ }
}
- def toJavaOption(key: S)(body: => Option[J]): Option[J] = toJavaMap get key match {
- case None =>
- val result = body
- for (value <- result) enter(value, key)
- result
- case some => some
+ def toJavaOption(key: S)(body: => Option[J]): Option[J] = synchronized {
+ toJavaMap get key match {
+ case None =>
+ val result = body
+ for (value <- result) enter(value, key)
+ result
+ case some => some
+ }
}
}
diff --git a/src/compiler/scala/reflect/runtime/JavaToScala.scala b/src/compiler/scala/reflect/runtime/JavaToScala.scala
index bc5d616ae3..b4bcc52a23 100644
--- a/src/compiler/scala/reflect/runtime/JavaToScala.scala
+++ b/src/compiler/scala/reflect/runtime/JavaToScala.scala
@@ -175,7 +175,7 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
load(sym)
completeRest()
}
- def completeRest(): Unit = {
+ def completeRest(): Unit = self.synchronized {
val tparams = clazz.rawInfo.typeParams
val parents = try {
diff --git a/src/compiler/scala/reflect/runtime/Loaders.scala b/src/compiler/scala/reflect/runtime/Loaders.scala
index 7aca052fa9..4b35a5b37e 100644
--- a/src/compiler/scala/reflect/runtime/Loaders.scala
+++ b/src/compiler/scala/reflect/runtime/Loaders.scala
@@ -97,9 +97,9 @@ 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]()
+ private val negatives = mutable.Set[Name]() // Syncnote: Performance only, so need not be protected.
override def lookupEntry(name: Name): ScopeEntry = {
val e = super.lookupEntry(name)
if (e != null)
diff --git a/src/compiler/scala/reflect/runtime/Mirror.scala b/src/compiler/scala/reflect/runtime/Mirror.scala
index 09a4bbe198..4808326902 100644
--- a/src/compiler/scala/reflect/runtime/Mirror.scala
+++ b/src/compiler/scala/reflect/runtime/Mirror.scala
@@ -51,7 +51,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..72adbd4004
--- /dev/null
+++ b/src/compiler/scala/reflect/runtime/SynchronizedOps.scala
@@ -0,0 +1,51 @@
+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
+
+ 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 e805b4e75e..426700f3b2 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 b818927ceb..811bb6ee05 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 17d63ea439..1c41e68532 100644
--- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
+++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
@@ -139,7 +139,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 bdd6a73b79..ab4a2141a9 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 d828b019f9..a1ade61dad 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -253,7 +253,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 6cb1d562ce..eaf1b1ffbc 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 701c69a4bb..0ff2b418f4 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -89,7 +89,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
@@ -838,7 +838,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 dc5e248631..73a43bf4a1 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
@@ -1457,7 +1457,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 0405163ef3..1a54b26307 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 da7e54af5c..889c04a59b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1404,7 +1404,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
assert(clazz != NoSymbol)
reenterTypeParams(cdef.tparams)
val tparams1 = cdef.tparams mapConserve (typedTypeDef)
- val impl1 = typerReportAnyContextErrors(context.make(cdef.impl, clazz, new Scope)){
+ val impl1 = typerReportAnyContextErrors(context.make(cdef.impl, clazz, newScope)) {
_.typedTemplate(cdef.impl, parentTypes(cdef.impl))
}
val impl2 = finishMethodSynthesis(impl1, clazz, context)
@@ -1439,7 +1439,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
val clazz = mdef.symbol.moduleClass
val typedMods = removeAnnotations(mdef.mods)
assert(clazz != NoSymbol, mdef)
- val impl1 = typerReportAnyContextErrors(context.make(mdef.impl, clazz, new Scope)){
+ val impl1 = typerReportAnyContextErrors(context.make(mdef.impl, clazz, newScope)) {
_.typedTemplate(mdef.impl, {
parentTypes(mdef.impl) ++ (
if (linkedClass == NoSymbol || !linkedClass.isSerializable || clazz.isSerializable) Nil
@@ -1448,7 +1448,8 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
List(TypeTree(SerializableClass.tpe) setPos clazz.pos.focus)
}
)
- })}
+ })
+ }
val impl2 = finishMethodSynthesis(impl1, clazz, context)
treeCopy.ModuleDef(mdef, typedMods, mdef.name, impl2) setType NoType
@@ -4043,7 +4044,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
val parents1 = templ.parents mapConserve (typedType(_, mode))
if (parents1 exists (_.isErrorTyped)) 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/Names.scala b/src/library/scala/reflect/api/Names.scala
index e226d2265a..9498f0af36 100755
--- a/src/library/scala/reflect/api/Names.scala
+++ b/src/library/scala/reflect/api/Names.scala
@@ -1,32 +1,59 @@
package scala.reflect
package api
+/** A trait that manages names.
+ * A name is a string in one of two name universes: terms and types.
+ * The same string can be a name in both universes.
+ * Two names are equal if they represent the same string and they are
+ * members of the same universe.
+ *
+ * Names are interned. That is, for two names `name11 and `name2`,
+ * `name1 == name2` implies `name1 eq name2`.
+ */
trait Names {
-
+
+ /** The abstract type of names */
type Name >: Null <: AbsName
+
+ /** The abstract type of names representing terms */
type TypeName <: Name
+
+ /** The abstract type of names representing types */
type TermName <: Name
abstract class AbsName {
+ /** Is this name a term name? */
def isTermName: Boolean
+
+ /** Is this name a type name? */
def isTypeName: Boolean
+
+ /** Returns a term name that represents the same string as this name */
def toTermName: TermName
+
+ /** Returns a type name that represents the same string as this name */
def toTypeName: TypeName
- /** Replace all occurrences of $op_names in this name by corresponding operator symbols.
+ /** Replaces all occurrences of $op_names in this name by corresponding operator symbols.
* Example: `foo_+=` becomes `foo_$plus$eq`.
*/
def decode: String
- /** Replace all occurrences of operator symbols in this name by corresponding $op_names.
+ /** Replaces all occurrences of operator symbols in this name by corresponding $op_names.
* Example: `foo_$plus$eq` becomes `foo_+=`
*/
def encode: Name
}
+ /** Create a new term name.
+ */
def newTermName(s: String): TermName
+
+ /** Creates a new type name.
+ */
def newTypeName(s: String): TypeName
def EmptyTermName: TermName = newTermName("")
+
def EmptyTypeName: TypeName = EmptyTermName.toTypeName
}
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/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala
index 8b4b170847..01c1a0f2ae 100755
--- a/src/library/scala/reflect/api/Symbols.scala
+++ b/src/library/scala/reflect/api/Symbols.scala
@@ -15,7 +15,14 @@ trait Symbols { self: Universe =>
*/
def hasModifier(mod: Modifier.Value): Boolean
- /** The owner of this symbol.
+ /** The owner of this symbol. This is the symbol
+ * that directly contains the current symbol's definition.
+ * The `NoSymbol` symbol does not have an owner, and calling this method
+ * on one causes an internal error.
+ * The owner of the Scala root class [[scala.reflect.api.mirror.RootClass]]
+ * and the Scala root object [[scala.reflect.api.mirror.RootPackage]] is `NoSymbol`.
+ * Every other symbol has a chain of owners that ends in
+ * [[scala.reflect.api.mirror.RootClass]].
*/
def owner: Symbol
@@ -74,23 +81,6 @@ trait Symbols { self: Universe =>
*/
def annotations: List[self.AnnotationInfo]
- /** The type of the symbol
- */
- def tpe: Type
-
- /** The info of the symbol. This is like tpe, except for class symbols where the `info`
- * describes the contents of the class whereas the `tpe` is a reference to the class.
- */
- def info: Type
-
- /** If this symbol is a class or trait, its self type, otherwise the type of the symbol itself
- */
- def typeOfThis: Type
-
- /** The type `C.this`, where `C` is the current class.
- */
- def thisType: Type
-
/** For a class: the module or case class factory with the same name in the same package.
* For all others: NoSymbol
*/
@@ -114,20 +104,43 @@ trait Symbols { self: Universe =>
/** The top-level class containing this symbol. */
def toplevelClass: Symbol
- /** The next enclosing class */
+ /** The next enclosing class, or `NoSymbol` if none exists */
def enclClass : Symbol
- /** The next enclosing method */
+ /** The next enclosing method, or `NoSymbol` if none exists */
def enclMethod : Symbol
+ /** Does this symbol represent the definition of term?
+ * Note that every symbol is either a term or a type.
+ * So for every symbol `sym`, either `sym.isTerm` is true
+ * or `sym.isType` is true.
+ */
def isTerm : Boolean
+
+ /** Does this symbol represent the definition of type?
+ * Note that every symbol is either a term or a type.
+ * So for every symbol `sym`, either `sym.isTerm` is true
+ * or `sym.isType` is true.
+ */
def isType : Boolean
+
+ /** Does this symbol represent the definition of class?
+ * If yes, `isType` is also guaranteed to be true.
+ */
def isClass : Boolean
+
+ /** Does this symbol represent the definition of a type alias?
+ * If yes, `isType` is also guaranteed to be true.
+ */
def isAliasType : Boolean
+
+ /** Does this symbol represent the definition of an abstract type?
+ * If yes, `isType` is also guaranteed to be true.
+ */
def isAbstractType : Boolean
/** The type signature of this symbol.
- * Note if symbol is a member of a class, one almost always is interested
+ * Note if the symbol is a member of a class, one almost always is interested
* in `typeSigIn` with a site type instead.
*/
def typeSig: Type
@@ -136,22 +149,44 @@ trait Symbols { self: Universe =>
*/
def typeSigIn(site: Type): Type
- /** The type constructor corresponding to this type symbol.
- */
- def asTypeConstructor: Type // needed by LiftCode
-
- /** A type reference that refers to this type symbol
+ /** A type reference that refers to this type symbol
* Note if symbol is a member of a class, one almost always is interested
* in `asTypeIn` with a site type instead.
+ *
+ * Example: Given a class declaration `class C[T] { ... } `, that generates a symbol
+ * `C`. Then `C.asType` is the type `C[T]`.
+ *
+ * By contrast, `C.typeSig` would be a type signature of form
+ * `PolyType(ClassInfoType(...))` that describes type parameters, value
+ * parameters, parent types, and members of `C`.
*/
def asType: Type
- /** A type reference that refers to this type symbol seen as a member of given type `site`.
+ /** A type reference that refers to this type symbol seen
+ * as a member of given type `site`.
*/
def asTypeIn(site: Type): Type
+ /** The type constructor corresponding to this type symbol.
+ * This is different from `asType` in that type parameters
+ * are part of results of `asType`, but not of `asTypeConstructor`.
+ *
+ * Example: Given a class declaration `class C[T] { ... } `, that generates a symbol
+ * `C`. Then `C.asType` is the type `C[T]`, but `C.asTypeCponstructor` is `C`.
+ */
+ def asTypeConstructor: Type // needed by LiftCode
+
+ /** If this symbol is a class or trait, its self type, otherwise the type
+ * of the symbol itself.
+ */
+ def typeOfThis: Type
+
+ /** If this symbol is a class, the type `C.this`, otherwise `NoPrefix`.
+ */
+ def thisType: Type
+
/** A fresh symbol with given name `name`, position `pos` and flags `flags` that has
- * the current symbol as its owner.
+ * the current symbol as its owner.
*/
def newNestedSymbol(name: Name, pos: Position, flags: Long): Symbol // needed by LiftCode
diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala
index 27f2ab1d08..03b043c188 100644
--- a/src/library/scala/reflect/api/Trees.scala
+++ b/src/library/scala/reflect/api/Trees.scala
@@ -8,7 +8,8 @@ package api
import scala.collection.mutable.ListBuffer
-trait Trees /*extends reflect.generic.Trees*/ { self: Universe =>
+// Syncnote: Trees are currently not thread-safe.
+trait Trees { self: Universe =>
private[scala] var nodeCount = 0
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)