summaryrefslogtreecommitdiff
path: root/src/reflect
diff options
context:
space:
mode:
Diffstat (limited to 'src/reflect')
-rw-r--r--src/reflect/scala/reflect/api/FlagSets.scala1
-rw-r--r--src/reflect/scala/reflect/api/Symbols.scala35
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala9
-rw-r--r--src/reflect/scala/reflect/internal/Mirrors.scala11
-rw-r--r--src/reflect/scala/reflect/internal/Reporting.scala17
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala1
-rw-r--r--src/reflect/scala/reflect/internal/SymbolTable.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala38
-rw-r--r--src/reflect/scala/reflect/internal/TreeGen.scala15
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala1
-rw-r--r--src/reflect/scala/reflect/internal/Trees.scala14
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala79
-rw-r--r--src/reflect/scala/reflect/internal/pickling/UnPickler.scala1
-rw-r--r--src/reflect/scala/reflect/internal/tpe/TypeMaps.scala9
-rw-r--r--src/reflect/scala/reflect/internal/transform/Erasure.scala11
-rw-r--r--src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala30
-rw-r--r--src/reflect/scala/reflect/runtime/JavaUniverseForce.scala1
17 files changed, 203 insertions, 72 deletions
diff --git a/src/reflect/scala/reflect/api/FlagSets.scala b/src/reflect/scala/reflect/api/FlagSets.scala
index d3294dad9b..2d5d1d5d6b 100644
--- a/src/reflect/scala/reflect/api/FlagSets.scala
+++ b/src/reflect/scala/reflect/api/FlagSets.scala
@@ -173,6 +173,7 @@ trait FlagSets { self: Universe =>
* - the enum's class
* - enum constants
**/
+ @deprecated("Use `isJavaEnum` on the corresponding symbol instead.", since = "2.11.8")
val ENUM: FlagSet
/** Flag indicating that tree represents a parameter of the primary constructor of some class
diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala
index c01029d067..9e9fe5d67b 100644
--- a/src/reflect/scala/reflect/api/Symbols.scala
+++ b/src/reflect/scala/reflect/api/Symbols.scala
@@ -228,7 +228,7 @@ trait Symbols { self: Universe =>
throw new ScalaReflectionException(s"$this $msg")
}
- /** Used to provide a better error message for `asMethod`
+ /** Used to provide a better error message for `asMethod`.
*
* @group Tests
*/
@@ -257,7 +257,7 @@ trait Symbols { self: Universe =>
def isClass: Boolean = false
/** Does this symbol represent the definition of a class implicitly associated
- * with an object definition (module class in scala compiler parlance).
+ * with an object definition (module class in scala compiler parlance)?
* If yes, `isType` is also guaranteed to be true.
*
* Note to compiler developers: During the "mixin" phase, trait implementation class symbols
@@ -294,7 +294,7 @@ trait Symbols { self: Universe =>
/** For a class: the module or case class factory with the same name in the same package.
* For a module: the class with the same name in the same package.
- * For all others: NoSymbol
+ * For all others: NoSymbol.
*
* This API may return unexpected results for module classes, packages and package classes.
* Use `companion` instead in order to get predictable results.
@@ -345,7 +345,7 @@ trait Symbols { self: Universe =>
*/
def overrides: List[Symbol]
- /** The overloaded alternatives of this symbol
+ /** The overloaded alternatives of this symbol.
*
* @group Basics
*/
@@ -370,7 +370,7 @@ trait Symbols { self: Universe =>
/** Does this symbol represent a declaration or definition written in a source file as `private[this]`
* or generated in tree/symbol form with the combination of flags LOCAL and PRIVATE?
- * If yes, `isPrivate` is guaranteed to be true,
+ * If yes, `isPrivate` is guaranteed to be true.
*
* @group Tests
*/
@@ -504,6 +504,18 @@ trait Symbols { self: Universe =>
*/
def isImplicit: Boolean
+ /** Does this symbol represent a java enum class or a java enum value?
+ *
+ * @group Tests
+ */
+ def isJavaEnum: Boolean
+
+ /** Does this symbol represent a java annotation interface?
+ *
+ * @group Tests
+ */
+ def isJavaAnnotation: Boolean
+
/******************* helpers *******************/
/** Provides an alternate if symbol is a NoSymbol.
@@ -678,7 +690,7 @@ trait Symbols { self: Universe =>
*/
def toTypeIn(site: Type): Type
- /** 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.
*
@@ -727,7 +739,7 @@ trait Symbols { self: Universe =>
*/
def isExistential : Boolean
- /** For a polymorphic type, its type parameters, the empty list for all other types
+ /** For a polymorphic type, its type parameters, the empty list for all other types.
*
* @group Type
*/
@@ -756,12 +768,13 @@ trait Symbols { self: Universe =>
*/
def typeParams: List[Symbol]
- /** @see [[paramLists]] */
+ /** @see [[paramLists]]
+ *
+ * The name ending with "ss" indicates that the result type is a list of lists. */
@deprecated("Use `paramLists` instead", "2.11.0")
def paramss: List[List[Symbol]]
/** All parameter lists of the method.
- * The name ending with "ss" indicates that the result type is a list of lists.
*
* Can be used to distinguish nullary methods and methods with empty parameter lists.
* For a nullary method, returns the empty list (i.e. `List()`).
@@ -777,7 +790,7 @@ trait Symbols { self: Universe =>
*/
def isVarargs: Boolean
- /** The return type of the method
+ /** The return type of the method.
*
* @group Method
*/
@@ -911,7 +924,7 @@ trait Symbols { self: Universe =>
*/
def superPrefix(supertpe: Type): Type
- /** For a polymorphic class/trait, its type parameters, the empty list for all other classes/trait
+ /** For a polymorphic class/trait, its type parameters, the empty list for all other classes/trait.
*
* @group Class
*/
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 0bdf5b4647..5ce5c39145 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -233,6 +233,8 @@ trait Definitions extends api.StandardDefinitions {
|| tp =:= AnyRefTpe
)
+ def isUnitType(tp: Type) = tp.typeSymbol == UnitClass && tp.annotations.isEmpty
+
def hasMultipleNonImplicitParamLists(member: Symbol): Boolean = hasMultipleNonImplicitParamLists(member.info)
def hasMultipleNonImplicitParamLists(info: Type): Boolean = info match {
case PolyType(_, restpe) => hasMultipleNonImplicitParamLists(restpe)
@@ -795,7 +797,9 @@ trait Definitions extends api.StandardDefinitions {
* The class defining the method is a supertype of `tp` that
* has a public no-arg primary constructor.
*/
- def samOf(tp: Type): Symbol = if (!settings.Xexperimental) NoSymbol else {
+ def samOf(tp: Type): Symbol = if (!settings.Xexperimental) NoSymbol else findSam(tp)
+
+ def findSam(tp: Type): Symbol = {
// if tp has a constructor, it must be public and must not take any arguments
// (not even an implicit argument list -- to keep it simple for now)
val tpSym = tp.typeSymbol
@@ -1103,6 +1107,7 @@ trait Definitions extends api.StandardDefinitions {
lazy val BridgeClass = requiredClass[scala.annotation.bridge]
lazy val ElidableMethodClass = requiredClass[scala.annotation.elidable]
lazy val ImplicitNotFoundClass = requiredClass[scala.annotation.implicitNotFound]
+ lazy val ImplicitAmbiguousClass = getClassIfDefined("scala.annotation.implicitAmbiguous")
lazy val MigrationAnnotationClass = requiredClass[scala.annotation.migration]
lazy val ScalaStrictFPAttr = requiredClass[scala.annotation.strictfp]
lazy val SwitchClass = requiredClass[scala.annotation.switch]
@@ -1517,7 +1522,7 @@ trait Definitions extends api.StandardDefinitions {
def isPolymorphicSignature(sym: Symbol) = PolySigMethods(sym)
private lazy val PolySigMethods: Set[Symbol] = Set[Symbol](MethodHandle.info.decl(sn.Invoke), MethodHandle.info.decl(sn.InvokeExact)).filter(_.exists)
- lazy val Scala_Java8_CompatPackage = rootMirror.getPackageIfDefined("scala.compat.java8")
+ lazy val Scala_Java8_CompatPackage = rootMirror.getPackageIfDefined("scala.runtime.java8")
lazy val Scala_Java8_CompatPackage_JFunction = (0 to MaxFunctionArity).toArray map (i => getMemberIfDefined(Scala_Java8_CompatPackage.moduleClass, TypeName("JFunction" + i)))
}
}
diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala
index 0cbb976a98..0f0f16574e 100644
--- a/src/reflect/scala/reflect/internal/Mirrors.scala
+++ b/src/reflect/scala/reflect/internal/Mirrors.scala
@@ -180,7 +180,7 @@ trait Mirrors extends api.Mirrors {
def getPackageObject(fullname: String): ModuleSymbol = getPackageObject(newTermName(fullname))
def getPackageObject(fullname: TermName): ModuleSymbol =
- (getPackage(fullname).info member nme.PACKAGE) match {
+ (getPackage(fullname).packageObject) match {
case x: ModuleSymbol => x
case _ => MissingRequirementError.notFound("package object " + fullname)
}
@@ -191,15 +191,6 @@ trait Mirrors extends api.Mirrors {
def getPackageObjectIfDefined(fullname: TermName): Symbol =
wrapMissing(getPackageObject(fullname))
- final def getPackageObjectWithMember(pre: Type, sym: Symbol): Symbol = {
- // The owner of a symbol which requires package qualification may be the
- // package object iself, but it also could be any superclass of the package
- // object. In the latter case, we must go through the qualifier's info
- // to obtain the right symbol.
- if (sym.owner.isModuleClass) sym.owner.sourceModule // fast path, if the member is owned by a module class, that must be linked to the package object
- else pre member nme.PACKAGE // otherwise we have to findMember
- }
-
override def staticPackage(fullname: String): ModuleSymbol =
try ensurePackageSymbol(fullname.toString, getModuleOrClass(newTermNameCached(fullname)), allowModules = false)
catch { case mre: MissingRequirementError => throw new ScalaReflectionException(mre.msg) }
diff --git a/src/reflect/scala/reflect/internal/Reporting.scala b/src/reflect/scala/reflect/internal/Reporting.scala
index f2de83bc5d..2534f59c97 100644
--- a/src/reflect/scala/reflect/internal/Reporting.scala
+++ b/src/reflect/scala/reflect/internal/Reporting.scala
@@ -8,11 +8,11 @@ package reflect
package internal
/** Provides delegates to the reporter doing the actual work.
- * All forwarding methods should be marked final,
- * but some subclasses out of our reach stil override them.
+ * All forwarding methods should be marked final,
+ * but some subclasses out of our reach stil override them.
*
- * Eventually, this interface should be reduced to one method: `reporter`,
- * and clients should indirect themselves (reduce duplication of forwarders).
+ * Eventually, this interface should be reduced to one method: `reporter`,
+ * and clients should indirect themselves (reduce duplication of forwarders).
*/
trait Reporting { self : Positions =>
def reporter: Reporter
@@ -71,8 +71,8 @@ import util.Position
/** Report information, warnings and errors.
*
- * This describes the (future) external interface for issuing information, warnings and errors.
- * Currently, scala.tools.nsc.Reporter is used by sbt/ide/partest.
+ * This describes the (future) external interface for issuing information, warnings and errors.
+ * Currently, scala.tools.nsc.Reporter is used by sbt/ide/partest.
*/
abstract class Reporter {
protected def info0(pos: Position, msg: String, severity: Severity, force: Boolean): Unit
@@ -101,7 +101,10 @@ abstract class Reporter {
resetCount(ERROR)
}
- def flush(): Unit = { }
+ def flush(): Unit = ()
+
+ /** Finish reporting: print summaries, release resources. */
+ def finish(): Unit = ()
}
// TODO: move into superclass once partest cuts tie on Severity
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 52558d9395..f1016e1b76 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -111,6 +111,7 @@ trait StdNames {
val PACKAGE: NameType = "package"
val ROOT: NameType = "<root>"
val SPECIALIZED_SUFFIX: NameType = "$sp"
+ val CASE_ACCESSOR: NameType = "$access"
val NESTED_IN: String = "$nestedIn"
val NESTED_IN_ANON_CLASS: String = NESTED_IN + ANON_CLASS_NAME.toString.replace("$", "")
diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala
index ef63078f90..b0145f8a89 100644
--- a/src/reflect/scala/reflect/internal/SymbolTable.scala
+++ b/src/reflect/scala/reflect/internal/SymbolTable.scala
@@ -332,7 +332,7 @@ abstract class SymbolTable extends macros.Universe
/** if there's a `package` member object in `pkgClass`, enter its members into it. */
def openPackageModule(pkgClass: Symbol) {
- val pkgModule = pkgClass.info.decl(nme.PACKAGEkw)
+ val pkgModule = pkgClass.packageObject
def fromSource = pkgModule.rawInfo match {
case ltp: SymLoader => ltp.fromSource
case _ => false
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 4bdb8e6da8..c3b2a8da08 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -102,6 +102,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def isPrivateThis = (this hasFlag PRIVATE) && (this hasFlag LOCAL)
def isProtectedThis = (this hasFlag PROTECTED) && (this hasFlag LOCAL)
+ def isJavaEnum: Boolean = hasJavaEnumFlag
+ def isJavaAnnotation: Boolean = hasJavaAnnotationFlag
+
def newNestedSymbol(name: Name, pos: Position, newFlags: Long, isClass: Boolean): Symbol = name match {
case n: TermName => newTermSymbol(n, pos, newFlags)
case n: TypeName => if (isClass) newClassSymbol(n, pos, newFlags) else newNonClassSymbol(n, pos, newFlags)
@@ -832,6 +835,12 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
def skipPackageObject: Symbol = this
+ /** The package object symbol corresponding to this package or package class symbol, or NoSymbol otherwise */
+ def packageObject: Symbol =
+ if (isPackageClass) tpe.packageObject
+ else if (isPackage) moduleClass.packageObject
+ else NoSymbol
+
/** If this is a constructor, its owner: otherwise this.
*/
final def skipConstructor: Symbol = if (isConstructor) owner else this
@@ -871,7 +880,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def isDeprecated = hasAnnotation(DeprecatedAttr)
def deprecationMessage = getAnnotation(DeprecatedAttr) flatMap (_ stringArg 0)
def deprecationVersion = getAnnotation(DeprecatedAttr) flatMap (_ stringArg 1)
- def deprecatedParamName = getAnnotation(DeprecatedNameAttr) flatMap (_ symbolArg 0)
+ def deprecatedParamName = getAnnotation(DeprecatedNameAttr) flatMap (_ symbolArg 0 orElse Some(nme.NO_NAME))
def hasDeprecatedInheritanceAnnotation
= hasAnnotation(DeprecatedInheritanceAttr)
def deprecatedInheritanceMessage
@@ -888,10 +897,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// string. So this needs attention. For now the fact that migration is
// private[scala] ought to provide enough protection.
def hasMigrationAnnotation = hasAnnotation(MigrationAnnotationClass)
- def migrationMessage = getAnnotation(MigrationAnnotationClass) flatMap { _.stringArg(0) }
- def migrationVersion = getAnnotation(MigrationAnnotationClass) flatMap { _.stringArg(1) }
- def elisionLevel = getAnnotation(ElidableMethodClass) flatMap { _.intArg(0) }
- def implicitNotFoundMsg = getAnnotation(ImplicitNotFoundClass) flatMap { _.stringArg(0) }
+ def migrationMessage = getAnnotation(MigrationAnnotationClass) flatMap { _.stringArg(0) }
+ def migrationVersion = getAnnotation(MigrationAnnotationClass) flatMap { _.stringArg(1) }
+ def elisionLevel = getAnnotation(ElidableMethodClass) flatMap { _.intArg(0) }
+ def implicitNotFoundMsg = getAnnotation(ImplicitNotFoundClass) flatMap { _.stringArg(0) }
+ def implicitAmbiguousMsg = getAnnotation(ImplicitAmbiguousClass) flatMap { _.stringArg(0) }
def isCompileTimeOnly = hasAnnotation(CompileTimeOnlyAttr)
def compileTimeOnlyMessage = getAnnotation(CompileTimeOnlyAttr) flatMap (_ stringArg 0)
@@ -987,7 +997,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
private def isNotOverridden = (
owner.isClass && (
owner.isEffectivelyFinal
- || owner.isSealed && owner.children.forall(c => c.isEffectivelyFinal && (overridingSymbol(c) == NoSymbol))
+ || (owner.isSealed && owner.sealedChildren.forall(c => c.isEffectivelyFinal && (overridingSymbol(c) == NoSymbol)))
)
)
@@ -999,6 +1009,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
isPrivate
|| isLocalToBlock
)
+ || isClass && originalOwner.isTerm && children.isEmpty // we track known subclasses of term-owned classes, use that infer finality
)
/** Is this symbol effectively final or a concrete term member of sealed class whose children do not override it */
final def isEffectivelyFinalOrNotOverridden: Boolean = isEffectivelyFinal || (isTerm && !isDeferred && isNotOverridden)
@@ -2502,14 +2513,15 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def associatedFile: AbstractFile = enclosingTopLevelClass.associatedFile
def associatedFile_=(f: AbstractFile) { abort("associatedFile_= inapplicable for " + this) }
- /** If this is a sealed class, its known direct subclasses.
+ /** If this is a sealed or local class, its known direct subclasses.
* Otherwise, the empty set.
*/
def children: Set[Symbol] = Set()
+ final def sealedChildren: Set[Symbol] = if (!isSealed) Set.empty else children
/** Recursively assemble all children of this symbol.
*/
- def sealedDescendants: Set[Symbol] = children.flatMap(_.sealedDescendants) + this
+ final def sealedDescendants: Set[Symbol] = if (!isSealed) Set(this) else children.flatMap(_.sealedDescendants) + this
@inline final def orElse(alt: => Symbol): Symbol = if (this ne NoSymbol) this else alt
@inline final def andAlso(f: Symbol => Unit): Symbol = { if (this ne NoSymbol) f(this) ; this }
@@ -3391,13 +3403,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def implicitMembers: Scope = {
val tp = info
if ((implicitMembersCacheKey1 ne tp) || (implicitMembersCacheKey2 ne tp.decls.elems)) {
- // Skip a package object class, because the members are also in
- // the package and we wish to avoid spurious ambiguities as in pos/t3999.
- if (!isPackageObjectClass) {
- implicitMembersCacheValue = tp.implicitMembers
- implicitMembersCacheKey1 = tp
- implicitMembersCacheKey2 = tp.decls.elems
- }
+ implicitMembersCacheValue = tp.membersBasedOnFlags(BridgeFlags, IMPLICIT)
+ implicitMembersCacheKey1 = tp
+ implicitMembersCacheKey2 = tp.decls.elems
}
implicitMembersCacheValue
}
diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala
index 201b727ed6..2933aa3892 100644
--- a/src/reflect/scala/reflect/internal/TreeGen.scala
+++ b/src/reflect/scala/reflect/internal/TreeGen.scala
@@ -129,7 +129,16 @@ abstract class TreeGen {
/** Builds a reference to given symbol. */
def mkAttributedRef(sym: Symbol): RefTree =
- if (sym.owner.isClass) mkAttributedRef(sym.owner.thisType, sym)
+ if (sym.owner.isStaticOwner) {
+ if (sym.owner.isRoot)
+ mkAttributedIdent(sym)
+ else {
+ val ownerModule = sym.owner.sourceModule
+ assert(ownerModule != NoSymbol, sym.owner)
+ mkAttributedSelect(mkAttributedRef(sym.owner.sourceModule), sym)
+ }
+ }
+ else if (sym.owner.isClass) mkAttributedRef(sym.owner.thisType, sym)
else mkAttributedIdent(sym)
def mkUnattributedRef(sym: Symbol): RefTree = mkUnattributedRef(sym.fullNameAsName('.'))
@@ -191,8 +200,8 @@ abstract class TreeGen {
)
val pkgQualifier =
if (needsPackageQualifier) {
- val packageObject = rootMirror.getPackageObjectWithMember(qual.tpe, sym)
- Select(qual, nme.PACKAGE) setSymbol packageObject setType singleType(qual.tpe, packageObject)
+ val packageObject = qualsym.packageObject
+ Select(qual, nme.PACKAGE) setSymbol packageObject setType packageObject.typeOfThis
}
else qual
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index 4657fa0000..7ad5fdf096 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -128,6 +128,7 @@ abstract class TreeInfo {
symOk(tree.symbol)
&& tree.symbol.isStable
&& !definitions.isByNameParamType(tree.tpe)
+ && !definitions.isByName(tree.symbol)
&& (allowVolatile || !tree.symbol.hasVolatileType) // TODO SPEC: not required by spec
)
diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala
index bbd9df05d2..49554d6d0f 100644
--- a/src/reflect/scala/reflect/internal/Trees.scala
+++ b/src/reflect/scala/reflect/internal/Trees.scala
@@ -1617,21 +1617,9 @@ trait Trees extends api.Trees {
}
def apply[T <: Tree](tree: T): T = {
val tree1 = transform(tree)
- invalidateSingleTypeCaches(tree1)
+ invalidateTreeTpeCaches(tree1, mutatedSymbols)
tree1.asInstanceOf[T]
}
- private def invalidateSingleTypeCaches(tree: Tree): Unit = {
- if (mutatedSymbols.nonEmpty)
- for (t <- tree if t.tpe != null)
- for (tp <- t.tpe) {
- tp match {
- case s: SingleType if mutatedSymbols contains s.sym =>
- s.underlyingPeriod = NoPeriod
- s.underlyingCache = NoType
- case _ =>
- }
- }
- }
override def toString() = "TreeSymSubstituter/" + substituterString("Symbol", "Symbol", from, to)
}
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 9697e16da7..33592bbd86 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -589,7 +589,12 @@ trait Types
def nonPrivateMembersAdmitting(admit: Long): Scope = membersBasedOnFlags(BridgeAndPrivateFlags & ~admit, 0)
/** A list of all implicit symbols of this type (defined or inherited) */
- def implicitMembers: Scope = membersBasedOnFlags(BridgeFlags, IMPLICIT)
+ def implicitMembers: Scope = {
+ typeSymbolDirect match {
+ case sym: ModuleClassSymbol => sym.implicitMembers
+ case _ => membersBasedOnFlags(BridgeFlags, IMPLICIT)
+ }
+ }
/** A list of all deferred symbols of this type (defined or inherited) */
def deferredMembers: Scope = membersBasedOnFlags(BridgeFlags, DEFERRED)
@@ -606,6 +611,8 @@ trait Types
def nonPrivateMember(name: Name): Symbol =
memberBasedOnName(name, BridgeAndPrivateFlags)
+ def packageObject: Symbol = member(nme.PACKAGE)
+
/** The non-private member with given name, admitting members with given flags `admit`.
* "Admitting" refers to the fact that members with a PRIVATE, BRIDGE, or VBRIDGE
* flag are usually excluded from findMember results, but supplying any of those flags
@@ -659,7 +666,7 @@ trait Types
)
if (trivial) this
else {
- val m = newAsSeenFromMap(pre.normalize, clazz)
+ val m = new AsSeenFromMap(pre.normalize, clazz)
val tp = m(this)
val tp1 = existentialAbstraction(m.capturedParams, tp)
@@ -1207,6 +1214,10 @@ trait Types
private[reflect] var underlyingCache: Type = NoType
private[reflect] var underlyingPeriod = NoPeriod
+ private[Types] def invalidateSingleTypeCaches(): Unit = {
+ underlyingCache = NoType
+ underlyingPeriod = NoPeriod
+ }
override def underlying: Type = {
val cache = underlyingCache
if (underlyingPeriod == currentPeriod && cache != null) cache
@@ -1347,6 +1358,12 @@ trait Types
private[reflect] var baseTypeSeqPeriod = NoPeriod
private[reflect] var baseClassesCache: List[Symbol] = _
private[reflect] var baseClassesPeriod = NoPeriod
+ private[Types] def invalidatedCompoundTypeCaches() {
+ baseTypeSeqCache = null
+ baseTypeSeqPeriod = NoPeriod
+ baseClassesCache = null
+ baseClassesPeriod = NoPeriod
+ }
override def baseTypeSeq: BaseTypeSeq = {
val cached = baseTypeSeqCache
@@ -1600,7 +1617,14 @@ trait Types
private var normalized: Type = _
private def normalizeImpl = {
// TODO see comments around def intersectionType and def merge
- def flatten(tps: List[Type]): List[Type] = tps flatMap { case RefinedType(parents, ds) if ds.isEmpty => flatten(parents) case tp => List(tp) }
+ // SI-8575 The dealias is needed here to keep subtyping transitive, example in run/t8575b.scala
+ def flatten(tps: List[Type]): List[Type] = {
+ def dealiasRefinement(tp: Type) = if (tp.dealias.isInstanceOf[RefinedType]) tp.dealias else tp
+ tps map dealiasRefinement flatMap {
+ case RefinedType(parents, ds) if ds.isEmpty => flatten(parents)
+ case tp => List(tp)
+ }
+ }
val flattened = flatten(parents).distinct
if (decls.isEmpty && hasLength(flattened, 1)) {
flattened.head
@@ -1898,6 +1922,9 @@ trait Types
narrowedCache
}
+ private[Types] def invalidateModuleTypeRefCaches(): Unit = {
+ narrowedCache = null
+ }
override protected def finishPrefix(rest: String) = objectPrefix + rest
override def directObjectString = super.safeToString
override def toLongString = toString
@@ -1977,6 +2004,10 @@ trait Types
*/
private var relativeInfoCache: Type = _
private var relativeInfoPeriod: Period = NoPeriod
+ private[Types] def invalidateNonClassTypeRefCaches(): Unit = {
+ relativeInfoCache = NoType
+ relativeInfoPeriod = NoPeriod
+ }
private[Types] def relativeInfo = /*trace(s"relativeInfo(${safeToString}})")*/{
if (relativeInfoPeriod != currentPeriod) {
@@ -2109,6 +2140,10 @@ trait Types
}
thisInfoCache
}
+ private[Types] def invalidateAbstractTypeRefCaches(): Unit = {
+ symInfoCache = null
+ thisInfoCache = null
+ }
override def bounds = thisInfo.bounds
override protected[Types] def baseTypeSeqImpl: BaseTypeSeq = transform(bounds.hi).baseTypeSeq prepend this
override def kind = "AbstractTypeRef"
@@ -2128,9 +2163,12 @@ trait Types
trivial = fromBoolean(!sym.isTypeParameter && pre.isTrivial && areTrivialTypes(args))
toBoolean(trivial)
}
- private[scala] def invalidateCaches(): Unit = {
+ private[Types] def invalidateTypeRefCaches(): Unit = {
+ parentsCache = null
parentsPeriod = NoPeriod
+ baseTypeSeqCache = null
baseTypeSeqPeriod = NoPeriod
+ normalized = null
}
private[reflect] var parentsCache: List[Type] = _
private[reflect] var parentsPeriod = NoPeriod
@@ -4555,6 +4593,39 @@ trait Types
if (!phase.erasedTypes && tp.typeSymbol == ObjectClass) AnyTpe
else tp
+ def invalidateTreeTpeCaches(tree: Tree, updatedSyms: List[Symbol]) = if (updatedSyms.nonEmpty)
+ for (t <- tree if t.tpe != null)
+ for (tp <- t.tpe) {
+ invalidateCaches(tp, updatedSyms)
+ }
+
+ def invalidateCaches(t: Type, updatedSyms: List[Symbol]) = {
+ t match {
+ case st: SingleType if updatedSyms.contains(st.sym) => st.invalidateSingleTypeCaches()
+ case _ =>
+ }
+ t match {
+ case tr: NonClassTypeRef if updatedSyms.contains(tr.sym) => tr.invalidateNonClassTypeRefCaches()
+ case _ =>
+ }
+ t match {
+ case tr: AbstractTypeRef if updatedSyms.contains(tr.sym) => tr.invalidateAbstractTypeRefCaches()
+ case _ =>
+ }
+ t match {
+ case tr: TypeRef if updatedSyms.contains(tr.sym) => tr.invalidateTypeRefCaches()
+ case _ =>
+ }
+ t match {
+ case tr: ModuleTypeRef if updatedSyms.contains(tr.sym) => tr.invalidateModuleTypeRefCaches()
+ case _ =>
+ }
+ t match {
+ case ct: CompoundType if ct.baseClasses.exists(updatedSyms.contains) => ct.invalidatedCompoundTypeCaches()
+ case _ =>
+ }
+ }
+
val shorthands = Set(
"scala.collection.immutable.List",
"scala.collection.immutable.Nil",
diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
index a9020a3d4c..277e89d656 100644
--- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
@@ -239,7 +239,6 @@ abstract class UnPickler {
if (missing.startsWith("scala.xml")) Some(("org.scala-lang.modules", "scala-xml"))
else if (missing.startsWith("scala.util.parsing")) Some(("org.scala-lang.modules", "scala-parser-combinators"))
else if (missing.startsWith("scala.swing")) Some(("org.scala-lang.modules", "scala-swing"))
- else if (missing.startsWith("scala.util.continuations")) Some(("org.scala-lang.plugins", "scala-continuations-library"))
else None
(module map { case (group, art) =>
diff --git a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
index b8d4050d7d..28a7fb37a6 100644
--- a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
+++ b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
@@ -449,12 +449,15 @@ private[internal] trait TypeMaps {
(pre eq NoType) || (pre eq NoPrefix) || !isPossiblePrefix(clazz)
)
- def newAsSeenFromMap(pre: Type, clazz: Symbol): AsSeenFromMap =
- new AsSeenFromMap(pre, clazz)
+ @deprecated("Use new AsSeenFromMap instead", "2.12.0")
+ final def newAsSeenFromMap(pre: Type, clazz: Symbol): AsSeenFromMap = new AsSeenFromMap(pre, clazz)
/** A map to compute the asSeenFrom method.
*/
- class AsSeenFromMap(seenFromPrefix: Type, seenFromClass: Symbol) extends TypeMap with KeepOnlyTypeConstraints {
+ class AsSeenFromMap(seenFromPrefix0: Type, seenFromClass: Symbol) extends TypeMap with KeepOnlyTypeConstraints {
+ private val seenFromPrefix: Type = if (seenFromPrefix0.typeSymbolDirect.hasPackageFlag && !seenFromClass.hasPackageFlag)
+ seenFromPrefix0.packageObject.typeOfThis
+ else seenFromPrefix0
// Some example source constructs relevant in asSeenFrom:
//
// object CaptureThis {
diff --git a/src/reflect/scala/reflect/internal/transform/Erasure.scala b/src/reflect/scala/reflect/internal/transform/Erasure.scala
index 01e28e5642..9853a0fa0c 100644
--- a/src/reflect/scala/reflect/internal/transform/Erasure.scala
+++ b/src/reflect/scala/reflect/internal/transform/Erasure.scala
@@ -282,8 +282,17 @@ trait Erasure {
}
object boxingErasure extends ScalaErasureMap {
+ private var boxPrimitives = true
+
+ override def applyInArray(tp: Type): Type = {
+ val saved = boxPrimitives
+ boxPrimitives = false
+ try super.applyInArray(tp)
+ finally boxPrimitives = saved
+ }
+
override def eraseNormalClassRef(tref: TypeRef) =
- if (isPrimitiveValueClass(tref.sym)) boxedClass(tref.sym).tpe
+ if (boxPrimitives && isPrimitiveValueClass(tref.sym)) boxedClass(tref.sym).tpe
else super.eraseNormalClassRef(tref)
override def eraseDerivedValueClassRef(tref: TypeRef) =
super.eraseNormalClassRef(tref)
diff --git a/src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala b/src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala
index 41011f6c6b..296934e253 100644
--- a/src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala
+++ b/src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala
@@ -11,7 +11,8 @@ import java.lang.reflect.{ Constructor, Modifier, Method }
import java.io.{ File => JFile }
import java.net.{ URLClassLoader => JURLClassLoader }
import java.net.URL
-import scala.reflect.runtime.ReflectionUtils.unwrapHandler
+import scala.reflect.internal.FatalError
+import scala.reflect.runtime.ReflectionUtils.{ show, unwrapHandler }
import ScalaClassLoader._
import scala.util.control.Exception.{ catching }
import scala.language.implicitConversions
@@ -46,6 +47,33 @@ trait ScalaClassLoader extends JClassLoader {
def create(path: String): AnyRef =
tryToInitializeClass[AnyRef](path).map(_.newInstance()).orNull
+ /** Create an instance with ctor args, or invoke errorFn before throwing. */
+ def create[T <: AnyRef : ClassTag](path: String, errorFn: String => Unit)(args: AnyRef*): T = {
+ def fail(msg: String) = error(msg, new IllegalArgumentException(msg))
+ def error(msg: String, e: Throwable) = { errorFn(msg) ; throw e }
+ try {
+ val clazz = Class.forName(path, /*initialize =*/ true, /*loader =*/ this)
+ if (classTag[T].runtimeClass isAssignableFrom clazz) {
+ val ctor = {
+ val maybes = clazz.getConstructors filter (c => c.getParameterCount == args.size &&
+ (c.getParameterTypes zip args).forall { case (k, a) => k isAssignableFrom a.getClass })
+ if (maybes.size == 1) maybes.head
+ else fail(s"Constructor must accept arg list (${args map (_.getClass.getName) mkString ", "}): ${path}")
+ }
+ (ctor.newInstance(args: _*)).asInstanceOf[T]
+ } else {
+ errorFn(s"""Loader for ${classTag[T]}: [${show(classTag[T].runtimeClass.getClassLoader)}]
+ |Loader for ${clazz.getName}: [${show(clazz.getClassLoader)}]""".stripMargin)
+ fail(s"Not a ${classTag[T]}: ${path}")
+ }
+ } catch {
+ case e: ClassNotFoundException =>
+ error(s"Class not found: ${path}", e)
+ case e @ (_: LinkageError | _: ReflectiveOperationException) =>
+ error(s"Unable to create instance: ${path}: ${e.toString}", e)
+ }
+ }
+
/** The actual bytes for a class file, or an empty array if it can't be found. */
def classBytes(className: String): Array[Byte] = classAsStream(className) match {
case null => Array()
diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
index 7725e4a2f0..1e9a4fe8a5 100644
--- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
+++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
@@ -369,6 +369,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
definitions.BridgeClass
definitions.ElidableMethodClass
definitions.ImplicitNotFoundClass
+ definitions.ImplicitAmbiguousClass
definitions.MigrationAnnotationClass
definitions.ScalaStrictFPAttr
definitions.SwitchClass