summaryrefslogtreecommitdiff
path: root/src/reflect/scala/reflect
diff options
context:
space:
mode:
Diffstat (limited to 'src/reflect/scala/reflect')
-rw-r--r--src/reflect/scala/reflect/api/FlagSets.scala1
-rw-r--r--src/reflect/scala/reflect/api/Internals.scala2
-rw-r--r--src/reflect/scala/reflect/api/Printers.scala2
-rw-r--r--src/reflect/scala/reflect/api/Symbols.scala41
-rw-r--r--src/reflect/scala/reflect/api/TypeTags.scala2
-rw-r--r--src/reflect/scala/reflect/internal/AnnotationInfos.scala33
-rw-r--r--src/reflect/scala/reflect/internal/BaseTypeSeqs.scala3
-rw-r--r--src/reflect/scala/reflect/internal/Chars.scala5
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala103
-rw-r--r--src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala1
-rw-r--r--src/reflect/scala/reflect/internal/Flags.scala16
-rw-r--r--src/reflect/scala/reflect/internal/HasFlags.scala1
-rw-r--r--src/reflect/scala/reflect/internal/Internals.scala22
-rw-r--r--src/reflect/scala/reflect/internal/JMethodOrConstructor.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Kinds.scala1
-rw-r--r--src/reflect/scala/reflect/internal/Mirrors.scala11
-rw-r--r--src/reflect/scala/reflect/internal/Names.scala4
-rw-r--r--src/reflect/scala/reflect/internal/Phase.scala12
-rw-r--r--src/reflect/scala/reflect/internal/Positions.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Printers.scala74
-rw-r--r--src/reflect/scala/reflect/internal/ReificationSupport.scala10
-rw-r--r--src/reflect/scala/reflect/internal/Reporting.scala17
-rw-r--r--src/reflect/scala/reflect/internal/StdAttachments.scala17
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala19
-rw-r--r--src/reflect/scala/reflect/internal/SymbolTable.scala32
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala127
-rw-r--r--src/reflect/scala/reflect/internal/TreeGen.scala50
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala3
-rw-r--r--src/reflect/scala/reflect/internal/Trees.scala24
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala413
-rw-r--r--src/reflect/scala/reflect/internal/Variances.scala2
-rw-r--r--src/reflect/scala/reflect/internal/pickling/UnPickler.scala3
-rw-r--r--src/reflect/scala/reflect/internal/settings/MutableSettings.scala1
-rw-r--r--src/reflect/scala/reflect/internal/tpe/TypeComparers.scala46
-rw-r--r--src/reflect/scala/reflect/internal/tpe/TypeMaps.scala9
-rw-r--r--src/reflect/scala/reflect/internal/transform/Erasure.scala23
-rw-r--r--src/reflect/scala/reflect/internal/transform/Transforms.scala6
-rw-r--r--src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala4
-rw-r--r--src/reflect/scala/reflect/internal/util/FreshNameCreator.scala1
-rw-r--r--src/reflect/scala/reflect/internal/util/Origins.scala2
-rw-r--r--src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala40
-rw-r--r--src/reflect/scala/reflect/internal/util/TraceSymbolActivity.scala3
-rw-r--r--src/reflect/scala/reflect/internal/util/WeakHashSet.scala17
-rw-r--r--src/reflect/scala/reflect/internal/util/package.scala1
-rw-r--r--src/reflect/scala/reflect/io/AbstractFile.scala3
-rw-r--r--src/reflect/scala/reflect/io/File.scala8
-rw-r--r--src/reflect/scala/reflect/io/Path.scala7
-rw-r--r--src/reflect/scala/reflect/io/PlainFile.scala2
-rw-r--r--src/reflect/scala/reflect/io/Streamable.scala4
-rw-r--r--src/reflect/scala/reflect/io/ZipArchive.scala6
-rw-r--r--src/reflect/scala/reflect/macros/Enclosures.scala2
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala27
-rw-r--r--src/reflect/scala/reflect/runtime/JavaUniverseForce.scala14
-rw-r--r--src/reflect/scala/reflect/runtime/ReflectionUtils.scala7
-rw-r--r--src/reflect/scala/reflect/runtime/Settings.scala1
-rw-r--r--src/reflect/scala/reflect/runtime/SymbolLoaders.scala5
-rw-r--r--src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala3
57 files changed, 703 insertions, 594 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/Internals.scala b/src/reflect/scala/reflect/api/Internals.scala
index f57d7efa00..1457fdc133 100644
--- a/src/reflect/scala/reflect/api/Internals.scala
+++ b/src/reflect/scala/reflect/api/Internals.scala
@@ -939,7 +939,7 @@ trait Internals { self: Universe =>
/** Marks underlying reference to id as boxed.
*
- * <b>Precondition:</b> id must refer to a captured variable
+ * <b>Precondition:<\b> id must refer to a captured variable
* A reference such marked will refer to the boxed entity, no dereferencing
* with `.elem` is done on it.
* This tree node can be emitted by macros such as reify that call referenceCapturedVariable.
diff --git a/src/reflect/scala/reflect/api/Printers.scala b/src/reflect/scala/reflect/api/Printers.scala
index c0abc5120c..257dd6c43e 100644
--- a/src/reflect/scala/reflect/api/Printers.scala
+++ b/src/reflect/scala/reflect/api/Printers.scala
@@ -232,7 +232,7 @@ trait Printers { self: Universe =>
* @group Printers
*/
def showRaw(any: Any, printTypes: BooleanFlag = None, printIds: BooleanFlag = None, printOwners: BooleanFlag = None, printKinds: BooleanFlag = None, printMirrors: BooleanFlag = None, printPositions: BooleanFlag = None): String =
- render(any, newRawTreePrinter(_), printTypes, printIds, printOwners, printKinds, printMirrors, printPositions)
+ render(any, newRawTreePrinter, printTypes, printIds, printOwners, printKinds, printMirrors, printPositions)
/** Hook to define what `showRaw(...)` means.
* @group Printers
diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala
index c01029d067..b9fb323a4c 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,12 +257,9 @@ 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
- * receive the `lateMODULE` flag, hence `isImplClass && isModuleClass` becomes true.
- *
* @group Tests
*/
def isModuleClass: Boolean = false
@@ -294,7 +291,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 +342,7 @@ trait Symbols { self: Universe =>
*/
def overrides: List[Symbol]
- /** The overloaded alternatives of this symbol
+ /** The overloaded alternatives of this symbol.
*
* @group Basics
*/
@@ -354,8 +351,7 @@ trait Symbols { self: Universe =>
/******************* tests *******************/
/** Does this symbol represent a synthetic (i.e. a compiler-generated) entity?
- * Examples of synthetic entities are accessors for vals and vars
- * or mixin constructors in trait implementation classes.
+ * Examples of synthetic entities are accessors for vals and vars.
*
* @group Tests
*/
@@ -370,7 +366,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 +500,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 +686,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 +735,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 +764,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 +786,7 @@ trait Symbols { self: Universe =>
*/
def isVarargs: Boolean
- /** The return type of the method
+ /** The return type of the method.
*
* @group Method
*/
@@ -911,7 +920,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/api/TypeTags.scala b/src/reflect/scala/reflect/api/TypeTags.scala
index bc239ca870..cad318dbed 100644
--- a/src/reflect/scala/reflect/api/TypeTags.scala
+++ b/src/reflect/scala/reflect/api/TypeTags.scala
@@ -7,8 +7,6 @@ package scala
package reflect
package api
-import java.lang.{ Class => jClass }
-import scala.language.implicitConversions
import java.io.ObjectStreamException
/**
diff --git a/src/reflect/scala/reflect/internal/AnnotationInfos.scala b/src/reflect/scala/reflect/internal/AnnotationInfos.scala
index b923541b56..fa19103d0c 100644
--- a/src/reflect/scala/reflect/internal/AnnotationInfos.scala
+++ b/src/reflect/scala/reflect/internal/AnnotationInfos.scala
@@ -7,7 +7,6 @@ package scala
package reflect
package internal
-import pickling.ByteCodecs
import scala.annotation.tailrec
import scala.collection.immutable.ListMap
import scala.language.postfixOps
@@ -30,12 +29,6 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
def staticAnnotations = annotations filter (_.isStatic)
- /** Symbols of any @throws annotations on this symbol.
- */
- def throwsAnnotations(): List[Symbol] = annotations collect {
- case ThrownException(exc) => exc
- }
-
def addThrowsAnnotation(throwableSym: Symbol): Self = {
val throwableTpe = if (throwableSym.isMonomorphicType) throwableSym.tpe else {
debuglog(s"Encountered polymorphic exception `${throwableSym.fullName}` while parsing class file.")
@@ -175,6 +168,22 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
def unapply(info: AnnotationInfo): Option[(Type, List[Tree], List[(Name, ClassfileAnnotArg)])] =
Some((info.atp, info.args, info.assocs))
+
+ def mkFilter(category: Symbol, defaultRetention: Boolean)(ann: AnnotationInfo) =
+ (ann.metaAnnotations, ann.defaultTargets) match {
+ case (Nil, Nil) => defaultRetention
+ case (Nil, defaults) => defaults contains category
+ case (metas, _) => metas exists (_ matches category)
+ }
+
+ def mkFilter(categories: List[Symbol], defaultRetention: Boolean)(ann: AnnotationInfo) =
+ (ann.metaAnnotations, ann.defaultTargets) match {
+ case (Nil, Nil) => defaultRetention
+ case (Nil, defaults) => categories exists defaults.contains
+ case (metas, _) =>
+ val metaSyms = metas collect { case ann if !ann.symbol.isInstanceOf[StubSymbol] => ann.symbol }
+ categories exists (category => metaSyms exists (_ isNonBottomSubClass category))
+ }
}
class CompleteAnnotationInfo(
@@ -406,24 +415,24 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
class ErroneousAnnotation() extends CompleteAnnotationInfo(ErrorType, Nil, Nil)
- /** Extracts symbol of thrown exception from AnnotationInfo.
+ /** Extracts the type of the thrown exception from an AnnotationInfo.
*
* Supports both “old-style” `@throws(classOf[Exception])`
* as well as “new-stye” `@throws[Exception]("cause")` annotations.
*/
object ThrownException {
- def unapply(ann: AnnotationInfo): Option[Symbol] = {
+ def unapply(ann: AnnotationInfo): Option[Type] = {
ann match {
case AnnotationInfo(tpe, _, _) if tpe.typeSymbol != ThrowsClass =>
None
// old-style: @throws(classOf[Exception]) (which is throws[T](classOf[Exception]))
case AnnotationInfo(_, List(Literal(Constant(tpe: Type))), _) =>
- Some(tpe.typeSymbol)
+ Some(tpe)
// new-style: @throws[Exception], @throws[Exception]("cause")
case AnnotationInfo(TypeRef(_, _, arg :: _), _, _) =>
- Some(arg.typeSymbol)
+ Some(arg)
case AnnotationInfo(TypeRef(_, _, Nil), _, _) =>
- Some(ThrowableClass)
+ Some(ThrowableTpe)
}
}
}
diff --git a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
index 54f64153c1..81281b5eb4 100644
--- a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
+++ b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
@@ -7,8 +7,7 @@ package reflect
package internal
// todo implement in terms of BitSet
-import scala.collection.{ mutable, immutable }
-import scala.math.max
+import scala.collection.mutable
import util.Statistics
/** A base type sequence (BaseTypeSeq) is an ordered sequence spanning all the base types
diff --git a/src/reflect/scala/reflect/internal/Chars.scala b/src/reflect/scala/reflect/internal/Chars.scala
index 74413fdaba..daee8a49ee 100644
--- a/src/reflect/scala/reflect/internal/Chars.scala
+++ b/src/reflect/scala/reflect/internal/Chars.scala
@@ -6,10 +6,11 @@ package scala
package reflect
package internal
-import scala.annotation.{ tailrec, switch }
-import java.lang.{ Character => JCharacter }
import scala.language.postfixOps
+import scala.annotation.switch
+import java.lang.{ Character => JCharacter }
+
/** Contains constants and classifier methods for characters */
trait Chars {
// Be very careful touching these.
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 0bdf5b4647..db8ac9b0cb 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -8,8 +8,9 @@ package reflect
package internal
import scala.language.postfixOps
-import scala.annotation.{ switch, meta }
-import scala.collection.{ mutable, immutable }
+
+import scala.annotation.meta
+import scala.collection.mutable
import Flags._
import scala.reflect.api.{Universe => ApiUniverse}
@@ -93,6 +94,10 @@ trait Definitions extends api.StandardDefinitions {
lazy val refClass = classesMap(x => getRequiredClass("scala.runtime." + x + "Ref"))
lazy val volatileRefClass = classesMap(x => getRequiredClass("scala.runtime.Volatile" + x + "Ref"))
+ lazy val allRefClasses: Set[Symbol] = {
+ refClass.values.toSet ++ volatileRefClass.values.toSet ++ Set(VolatileObjectRefClass, ObjectRefClass)
+ }
+
def isNumericSubClass(sub: Symbol, sup: Symbol) = (
(numericWeight contains sub)
&& (numericWeight contains sup)
@@ -233,6 +238,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)
@@ -421,13 +428,15 @@ trait Definitions extends api.StandardDefinitions {
def elementType(container: Symbol, tp: Type): Type = elementExtract(container, tp)
// collections classes
- lazy val ConsClass = requiredClass[scala.collection.immutable.::[_]]
- lazy val IteratorClass = requiredClass[scala.collection.Iterator[_]]
- lazy val IterableClass = requiredClass[scala.collection.Iterable[_]]
- lazy val ListClass = requiredClass[scala.collection.immutable.List[_]]
- lazy val SeqClass = requiredClass[scala.collection.Seq[_]]
- lazy val StringBuilderClass = requiredClass[scala.collection.mutable.StringBuilder]
- lazy val TraversableClass = requiredClass[scala.collection.Traversable[_]]
+ lazy val ConsClass = requiredClass[scala.collection.immutable.::[_]]
+ lazy val IteratorClass = requiredClass[scala.collection.Iterator[_]]
+ lazy val IterableClass = requiredClass[scala.collection.Iterable[_]]
+ lazy val ListClass = requiredClass[scala.collection.immutable.List[_]]
+ lazy val SeqClass = requiredClass[scala.collection.Seq[_]]
+ lazy val JavaStringBuilderClass = requiredClass[java.lang.StringBuilder]
+ lazy val JavaStringBufferClass = requiredClass[java.lang.StringBuffer]
+ lazy val JavaCharSequenceClass = requiredClass[java.lang.CharSequence]
+ lazy val TraversableClass = requiredClass[scala.collection.Traversable[_]]
lazy val ListModule = requiredModule[scala.collection.immutable.List.type]
def List_apply = getMemberMethod(ListModule, nme.apply)
@@ -452,6 +461,16 @@ trait Definitions extends api.StandardDefinitions {
lazy val MethodCacheClass = requiredClass[scala.runtime.MethodCache]
def methodCache_find = getMemberMethod(MethodCacheClass, nme.find_)
def methodCache_add = getMemberMethod(MethodCacheClass, nme.add_)
+ lazy val StructuralCallSite = getClassIfDefined("scala.runtime.StructuralCallSite")
+ def StructuralCallSite_bootstrap = getMemberMethod(StructuralCallSite.linkedClassOfClass, sn.Bootstrap)
+ // Marker for invokedynamic runtime.StructuralCall.bootstrap
+ lazy val StructuralCallSite_dummy = NoSymbol.newMethodSymbol(nme.apply).setInfo(NullaryMethodType(StructuralCallSite.tpe))
+ def StructuralCallSite_find = getMemberIfDefined(StructuralCallSite, nme.find_)
+ def StructuralCallSite_add = getMemberIfDefined(StructuralCallSite, nme.add_)
+ def StructuralCallSite_getParameterTypes = getMemberIfDefined(StructuralCallSite, nme.parameterTypes)
+ lazy val SymbolLiteral = getClassIfDefined("scala.runtime.SymbolLiteral")
+ def SymbolLiteral_bootstrap = getMemberIfDefined(SymbolLiteral.linkedClassOfClass, sn.Bootstrap)
+ def SymbolLiteral_dummy = NoSymbol.newMethodSymbol(nme.apply).setInfo(NullaryMethodType(SymbolModule.companionClass.tpe))
// XML
lazy val ScalaXmlTopScope = getModuleIfDefined("scala.xml.TopScope")
@@ -516,7 +535,6 @@ trait Definitions extends api.StandardDefinitions {
lazy val ScalaSignatureAnnotation = requiredClass[scala.reflect.ScalaSignature]
lazy val ScalaLongSignatureAnnotation = requiredClass[scala.reflect.ScalaLongSignature]
- lazy val LambdaMetaFactory = getClassIfDefined("java.lang.invoke.LambdaMetafactory")
lazy val MethodHandle = getClassIfDefined("java.lang.invoke.MethodHandle")
// Option classes
@@ -657,6 +675,32 @@ trait Definitions extends api.StandardDefinitions {
// Note that these call .dealiasWiden and not .normalize, the latter of which
// tends to change the course of events by forcing types.
def isFunctionType(tp: Type) = isFunctionTypeDirect(tp.dealiasWiden)
+ // the number of arguments expected by the function described by `tp` (a FunctionN or SAM type),
+ // or `-1` if `tp` does not represent a function type or SAM
+ def functionArityFromType(tp: Type) = {
+ val dealiased = tp.dealiasWiden
+ if (isFunctionTypeDirect(dealiased)) dealiased.typeArgs.length - 1
+ else samOf(tp) match {
+ case samSym if samSym.exists => samSym.info.params.length
+ case _ => -1
+ }
+ }
+
+ // the result type of a function or corresponding SAM type
+ def functionResultType(tp: Type): Type = {
+ val dealiased = tp.dealiasWiden
+ if (isFunctionTypeDirect(dealiased)) dealiased.typeArgs.last
+ else samOf(tp) match {
+ case samSym if samSym.exists => tp.memberInfo(samSym).resultType.deconst
+ case _ => NoType
+ }
+ }
+
+ // the SAM's parameters and the Function's formals must have the same length
+ // (varargs etc don't come into play, as we're comparing signatures, not checking an application)
+ def samMatchesFunctionBasedOnArity(sam: Symbol, formals: List[Any]): Boolean =
+ sam.exists && sameLength(sam.info.params, formals)
+
def isTupleType(tp: Type) = isTupleTypeDirect(tp.dealiasWiden)
def tupleComponents(tp: Type) = tp.dealiasWiden.typeArgs
@@ -775,10 +819,6 @@ trait Definitions extends api.StandardDefinitions {
private[this] var volatileRecursions: Int = 0
private[this] val pendingVolatiles = mutable.HashSet[Symbol]()
- def abstractFunctionForFunctionType(tp: Type) = {
- assert(isFunctionType(tp), tp)
- abstractFunctionType(tp.typeArgs.init, tp.typeArgs.last)
- }
def functionNBaseType(tp: Type): Type = tp.baseClasses find isFunctionSymbol match {
case Some(sym) => tp baseType unspecializedSymbol(sym)
case _ => tp
@@ -789,20 +829,29 @@ trait Definitions extends api.StandardDefinitions {
(sym eq PartialFunctionClass) || (sym eq AbstractPartialFunctionClass)
}
+ private[this] val doSam = settings.isScala212 || (settings.isScala211 && settings.Xexperimental)
+
/** The single abstract method declared by type `tp` (or `NoSymbol` if it cannot be found).
*
* The method must be monomorphic and have exactly one parameter list.
* 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 {
- // 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
- val ctor = tpSym.primaryConstructor
- val ctorOk = !ctor.exists || (!ctor.isOverloaded && ctor.isPublic && ctor.info.params.isEmpty && ctor.info.paramSectionCount <= 1)
-
- if (tpSym.exists && ctorOk) {
+ def samOf(tp: Type): Symbol = if (!doSam) NoSymbol else {
+ // look at erased type because we (only) care about what ends up in bytecode
+ // (e.g., an alias type or intersection type is fine as long as the intersection dominator compiles to an interface)
+ val tpSym: Symbol = erasure.javaErasure(tp).typeSymbol
+
+ if (tpSym.exists && tpSym.isClass
+ // if tp has a constructor (its class is not a trait), it must be public and must not take any arguments
+ // (implementation restriction: implicit argument lists are excluded to simplify type inference in adaptToSAM)
+ && { val ctor = tpSym.primaryConstructor
+ !ctor.exists || (!ctor.isOverloaded && ctor.isPublic && ctor.info.params.isEmpty && ctor.info.paramSectionCount <= 1)}
+ // we won't be able to create an instance of tp if it doesn't correspond to its self type
+ // (checking conformance gets complicated when tp is not fully defined, so let's just rule out self types entirely)
+ && !tpSym.hasSelfType
+ ) {
+
// find the single abstract member, if there is one
// don't go out requiring DEFERRED members, as you will get them even if there's a concrete override:
// scala> abstract class X { def m: Int }
@@ -901,7 +950,6 @@ trait Definitions extends api.StandardDefinitions {
def neverHasTypeParameters(sym: Symbol) = sym match {
case _: RefinementClassSymbol => true
case _: ModuleClassSymbol => true
- case _: ImplClassSymbol => true
case _ =>
(
sym.isPrimitiveValueClass
@@ -1103,6 +1151,8 @@ 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 JUnitTestClass = getClassIfDefined("org.junit.Test")
lazy val MigrationAnnotationClass = requiredClass[scala.annotation.migration]
lazy val ScalaStrictFPAttr = requiredClass[scala.annotation.strictfp]
lazy val SwitchClass = requiredClass[scala.annotation.switch]
@@ -1393,8 +1443,8 @@ trait Definitions extends api.StandardDefinitions {
if (isInitialized) return
ObjectClass.initialize
ScalaPackageClass.initialize
- val forced1 = symbolsNotPresentInBytecode
- val forced2 = NoSymbol
+ symbolsNotPresentInBytecode
+ NoSymbol
isInitialized = true
} //init
@@ -1517,8 +1567,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_JFunction = (0 to MaxFunctionArity).toArray map (i => getMemberIfDefined(Scala_Java8_CompatPackage.moduleClass, TypeName("JFunction" + i)))
+ lazy val Scala_Java8_CompatPackage = rootMirror.getPackageIfDefined("scala.runtime.java8")
}
}
}
diff --git a/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala b/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala
index 3e18f88f80..cc9f379cfe 100644
--- a/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala
+++ b/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala
@@ -7,7 +7,6 @@ package scala
package reflect
package internal
-import scala.collection.{ mutable, immutable }
/** The name of this trait defines the eventual intent better than
* it does the initial contents.
diff --git a/src/reflect/scala/reflect/internal/Flags.scala b/src/reflect/scala/reflect/internal/Flags.scala
index 754b96a9dd..f058acb7c0 100644
--- a/src/reflect/scala/reflect/internal/Flags.scala
+++ b/src/reflect/scala/reflect/internal/Flags.scala
@@ -7,8 +7,6 @@ package scala
package reflect
package internal
-import scala.collection.{ mutable, immutable }
-
// Flags at each index of a flags Long. Those marked with /M are used in
// Parsers/JavaParsers and therefore definitely appear on Modifiers; but the
// absence of /M on the other flags does not imply they aren't.
@@ -52,7 +50,7 @@ import scala.collection.{ mutable, immutable }
// 34: LIFTED
// 35: EXISTENTIAL MIXEDIN
// 36: EXPANDEDNAME
-// 37: IMPLCLASS PRESUPER/M
+// 37: PRESUPER/M
// 38: TRANS_FLAG
// 39: LOCKED
// 40: SPECIALIZED
@@ -159,7 +157,6 @@ class Flags extends ModifierFlags {
final val MIXEDIN = 1L << 35 // term member has been mixed in
final val EXISTENTIAL = 1L << 35 // type is an existential parameter or skolem
final val EXPANDEDNAME = 1L << 36 // name has been expanded with class suffix
- final val IMPLCLASS = 1L << 37 // symbol is an implementation class
final val TRANS_FLAG = 1L << 38 // transient flag guaranteed to be reset after each phase.
final val LOCKED = 1L << 39 // temporary flag to catch cyclic dependencies
@@ -201,8 +198,7 @@ class Flags extends ModifierFlags {
// 17: CONTRAVARIANT/M INCONSTRUCTOR LABEL
// 25: DEFAULTPARAM/M TRAIT/M
// 35: EXISTENTIAL MIXEDIN
- // 37: IMPLCLASS PRESUPER/M
- val OverloadedFlagsMask = 0L | BYNAMEPARAM | CONTRAVARIANT | DEFAULTPARAM | EXISTENTIAL | IMPLCLASS
+ val OverloadedFlagsMask = 0L | BYNAMEPARAM | CONTRAVARIANT | DEFAULTPARAM | EXISTENTIAL
// ------- late flags (set by a transformer phase) ---------------------------------
//
@@ -212,7 +208,7 @@ class Flags extends ModifierFlags {
// refchecks 7 [START] <latemethod>
// specialize 13 [START] <latefinal> <notprivate>
// explicitouter 14 [START] <notprotected>
- // erasure 15 [START] <latedeferred> <lateinterface>
+ // erasure 15 [START] <latedeferred>
// mixin 20 [START] <latemodule> <notoverride>
//
// lateMETHOD set in RefChecks#transformInfo.
@@ -220,13 +216,11 @@ class Flags extends ModifierFlags {
// notPRIVATE set in Symbols#makeNotPrivate, IExplicitOuter#transform, Inliners.
// notPROTECTED set in ExplicitOuter#transform.
// lateDEFERRED set in AddInterfaces, Mixin, etc.
- // lateINTERFACE set in AddInterfaces#transformMixinInfo.
// lateMODULE set in Mixin#transformInfo.
// notOVERRIDE set in Mixin#preTransform.
final val lateDEFERRED = (DEFERRED: Long) << LateShift
final val lateFINAL = (FINAL: Long) << LateShift
- final val lateINTERFACE = (INTERFACE: Long) << LateShift
final val lateMETHOD = (METHOD: Long) << LateShift
final val lateMODULE = (MODULE: Long) << LateShift
@@ -441,7 +435,7 @@ class Flags extends ModifierFlags {
case LIFTED => "<lifted>" // (1L << 34)
case EXISTENTIAL => "<existential/mixedin>" // (1L << 35)
case EXPANDEDNAME => "<expandedname>" // (1L << 36)
- case IMPLCLASS => "<implclass/presuper>" // (1L << 37)
+ case PRESUPER => "<presuper>" // (1L << 37)
case TRANS_FLAG => "<trans_flag>" // (1L << 38)
case LOCKED => "<locked>" // (1L << 39)
case SPECIALIZED => "<specialized>" // (1L << 40)
@@ -458,7 +452,7 @@ class Flags extends ModifierFlags {
case `lateDEFERRED` => "<latedeferred>" // (1L << 51)
case `lateFINAL` => "<latefinal>" // (1L << 52)
case `lateMETHOD` => "<latemethod>" // (1L << 53)
- case `lateINTERFACE` => "<lateinterface>" // (1L << 54)
+ case 0x80000000000000L => "" // (1L << 54)
case `lateMODULE` => "<latemodule>" // (1L << 55)
case `notPROTECTED` => "<notprotected>" // (1L << 56)
case `notOVERRIDE` => "<notoverride>" // (1L << 57)
diff --git a/src/reflect/scala/reflect/internal/HasFlags.scala b/src/reflect/scala/reflect/internal/HasFlags.scala
index 5162b15206..673ea4fdef 100644
--- a/src/reflect/scala/reflect/internal/HasFlags.scala
+++ b/src/reflect/scala/reflect/internal/HasFlags.scala
@@ -120,6 +120,7 @@ trait HasFlags {
def isSuperAccessor = hasFlag(SUPERACCESSOR)
def isSynthetic = hasFlag(SYNTHETIC)
def isTrait = hasFlag(TRAIT) && !hasFlag(PARAM)
+ def isTraitOrInterface = isTrait || isInterface
def isDeferredOrJavaDefault = hasFlag(DEFERRED | JAVA_DEFAULTMETHOD)
def isDeferredNotJavaDefault = isDeferred && !hasFlag(JAVA_DEFAULTMETHOD)
diff --git a/src/reflect/scala/reflect/internal/Internals.scala b/src/reflect/scala/reflect/internal/Internals.scala
index ad4cec5b4d..1a48701ca7 100644
--- a/src/reflect/scala/reflect/internal/Internals.scala
+++ b/src/reflect/scala/reflect/internal/Internals.scala
@@ -3,13 +3,9 @@ package reflect
package internal
import scala.language.implicitConversions
-import scala.language.higherKinds
-import scala.collection.mutable.WeakHashMap
-import scala.ref.WeakReference
+
import scala.reflect.api.Universe
import scala.reflect.macros.Attachments
-import scala.reflect.internal.util.FreshNameCreator
-import scala.reflect.internal.util.ListOfNil
trait Internals extends api.Internals {
self: SymbolTable =>
@@ -60,19 +56,7 @@ trait Internals extends api.Internals {
def typeDef(sym: Symbol): TypeDef = self.TypeDef(sym)
def labelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef = self.LabelDef(sym, params, rhs)
- def changeOwner(tree: Tree, prev: Symbol, next: Symbol): tree.type = {
- object changeOwnerAndModuleClassTraverser extends ChangeOwnerTraverser(prev, next) {
- override def traverse(tree: Tree) {
- tree match {
- case _: DefTree => change(tree.symbol.moduleClass)
- case _ => // do nothing
- }
- super.traverse(tree)
- }
- }
- changeOwnerAndModuleClassTraverser.traverse(tree)
- tree
- }
+ def changeOwner(tree: Tree, prev: Symbol, next: Symbol): tree.type = { new ChangeOwnerTraverser(prev, next).traverse(tree); tree }
lazy val gen = self.treeBuild
@@ -170,4 +154,4 @@ trait Internals extends api.Internals {
def mkZero(tp: Type): Tree = self.gen.mkZero(tp)
def mkCast(tree: Tree, pt: Type): Tree = self.gen.mkCast(tree, pt)
}
-} \ No newline at end of file
+}
diff --git a/src/reflect/scala/reflect/internal/JMethodOrConstructor.scala b/src/reflect/scala/reflect/internal/JMethodOrConstructor.scala
index fb1cdb34e1..b9cc167933 100644
--- a/src/reflect/scala/reflect/internal/JMethodOrConstructor.scala
+++ b/src/reflect/scala/reflect/internal/JMethodOrConstructor.scala
@@ -7,7 +7,7 @@ package reflect
package internal
import scala.language.implicitConversions
-import java.lang.{ Class => jClass }
+
import java.lang.annotation.{ Annotation => jAnnotation }
import java.lang.reflect.{
Member => jMember, Constructor => jConstructor, Method => jMethod,
diff --git a/src/reflect/scala/reflect/internal/Kinds.scala b/src/reflect/scala/reflect/internal/Kinds.scala
index 902ba9fa80..a7e462d8de 100644
--- a/src/reflect/scala/reflect/internal/Kinds.scala
+++ b/src/reflect/scala/reflect/internal/Kinds.scala
@@ -7,7 +7,6 @@ package scala
package reflect
package internal
-import scala.collection.{ mutable, immutable }
import scala.reflect.internal.util.StringOps.{ countAsString, countElementsAsString }
trait Kinds {
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/Names.scala b/src/reflect/scala/reflect/internal/Names.scala
index 32d12d305e..97f51149ba 100644
--- a/src/reflect/scala/reflect/internal/Names.scala
+++ b/src/reflect/scala/reflect/internal/Names.scala
@@ -7,10 +7,10 @@ package scala
package reflect
package internal
-import scala.io.Codec
-import java.security.MessageDigest
import scala.language.implicitConversions
+import scala.io.Codec
+
trait Names extends api.Names {
private final val HASH_SIZE = 0x8000
private final val HASH_MASK = 0x7FFF
diff --git a/src/reflect/scala/reflect/internal/Phase.scala b/src/reflect/scala/reflect/internal/Phase.scala
index 1ecc202a07..a761f686e6 100644
--- a/src/reflect/scala/reflect/internal/Phase.scala
+++ b/src/reflect/scala/reflect/internal/Phase.scala
@@ -39,10 +39,14 @@ abstract class Phase(val prev: Phase) {
def description: String = name
// Will running with -Ycheck:name work?
def checkable: Boolean = true
- def specialized: Boolean = false
- def erasedTypes: Boolean = false
- def flatClasses: Boolean = false
- def refChecked: Boolean = false
+
+ // NOTE: sbt injects its own phases which extend this class, and not GlobalPhase, so we must implement this logic here
+ private val _erasedTypes = ((prev ne null) && (prev ne NoPhase)) && (prev.name == "erasure" || prev.erasedTypes)
+ def erasedTypes: Boolean = _erasedTypes // overridden in back-end
+ final val flatClasses: Boolean = ((prev ne null) && (prev ne NoPhase)) && (prev.name == "flatten" || prev.flatClasses)
+ final val specialized: Boolean = ((prev ne null) && (prev ne NoPhase)) && (prev.name == "specialize" || prev.specialized)
+ final val refChecked: Boolean = ((prev ne null) && (prev ne NoPhase)) && (prev.name == "refchecks" || prev.refChecked)
+
/** This is used only in unsafeTypeParams, and at this writing is
* overridden to false in parser, namer, typer, and erasure. (And NoPhase.)
diff --git a/src/reflect/scala/reflect/internal/Positions.scala b/src/reflect/scala/reflect/internal/Positions.scala
index 15d68bcdfe..95b3b7fb14 100644
--- a/src/reflect/scala/reflect/internal/Positions.scala
+++ b/src/reflect/scala/reflect/internal/Positions.scala
@@ -254,7 +254,7 @@ trait Positions extends api.Positions { self: SymbolTable =>
case mdef: MemberDef =>
val annTrees = mdef.mods.annotations match {
case Nil if mdef.symbol != null =>
- // After typechecking, annotations are mvoed from the modifiers
+ // After typechecking, annotations are moved from the modifiers
// to the annotation on the symbol of the anotatee.
mdef.symbol.annotations.map(_.original)
case anns => anns
diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala
index b44c4022f6..37b99c4345 100644
--- a/src/reflect/scala/reflect/internal/Printers.scala
+++ b/src/reflect/scala/reflect/internal/Printers.scala
@@ -9,7 +9,7 @@ package scala
package reflect
package internal
-import java.io.{ OutputStream, PrintWriter, StringWriter, Writer }
+import java.io.{ OutputStream, PrintWriter, Writer }
import Flags._
import scala.compat.Platform.EOL
@@ -73,10 +73,10 @@ trait Printers extends api.Printers { self: SymbolTable =>
def indent() = indentMargin += indentStep
def undent() = indentMargin -= indentStep
- def printPosition(tree: Tree) =
+ def printPosition(tree: Tree) =
if (printPositions) comment(print(tree.pos.show))
-
- protected def printTypesInfo(tree: Tree) =
+
+ protected def printTypesInfo(tree: Tree) =
if (printTypes && tree.isTerm && tree.canHaveAttrs)
comment{
print("{", if (tree.tpe eq null) "<null>" else tree.tpe.toString, "}")
@@ -313,7 +313,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
protected def printBlock(stats: List[Tree], expr: Tree) =
printColumn(stats ::: List(expr), "{", ";", "}")
-
+
def printTree(tree: Tree) = {
tree match {
case EmptyTree =>
@@ -639,14 +639,14 @@ trait Printers extends api.Printers { self: SymbolTable =>
case _ => true
}
- protected def syntheticToRemove(tree: Tree) =
+ protected def syntheticToRemove(tree: Tree) =
tree match {
case _: ValDef | _: TypeDef => false // don't remove ValDef and TypeDef
case md: MemberDef if md.mods.isSynthetic => true
case _ => false
}
- override def printOpt(prefix: String, tree: Tree) =
+ override def printOpt(prefix: String, tree: Tree) =
if (!isEmptyTree(tree)) super.printOpt(prefix, tree)
override def printColumn(ts: List[Tree], start: String, sep: String, end: String) = {
@@ -959,13 +959,13 @@ trait Printers extends api.Printers { self: SymbolTable =>
printFunction(f)(printValueParams(vparams, inParentheses = printParentheses))
case Typed(expr, tp) =>
- def printTp = print("(", tp, ")")
+ def printTp() = print("(", tp, ")")
tp match {
- case EmptyTree | EmptyTypeTree() => printTp
+ case EmptyTree | EmptyTypeTree() => printTp()
// case for untypechecked trees
- case Annotated(annot, arg) if (expr ne null) && (arg ne null) && expr.equalsStructure(arg) => printTp // remove double arg - 5: 5: @unchecked
- case tt: TypeTree if tt.original.isInstanceOf[Annotated] => printTp
+ case Annotated(annot, arg) if (expr ne null) && (arg ne null) && expr.equalsStructure(arg) => printTp() // remove double arg - 5: 5: @unchecked
+ case tt: TypeTree if tt.original.isInstanceOf[Annotated] => printTp()
case Function(List(), EmptyTree) => print("(", expr, " _)") //func _
// parentheses required when (a match {}) : Type
case _ => print("((", expr, "): ", tp, ")")
@@ -1000,7 +1000,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
}
case _ => print(fun)
}
- printRow(args, "(", ", ", ")")
+ printRow(args, "(", ", ", ")")
case st @ Super(This(qual), mix) =>
printSuper(st, printedName(qual), checkSymbol = false)
@@ -1016,7 +1016,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
print(qual)
case Select(qual, name) =>
- def checkRootPackage(tr: Tree): Boolean =
+ def checkRootPackage(tr: Tree): Boolean =
(currentParent match { //check that Select is not for package def name
case Some(_: PackageDef) => false
case _ => true
@@ -1134,11 +1134,12 @@ trait Printers extends api.Printers { self: SymbolTable =>
def newRawTreePrinter(writer: PrintWriter): RawTreePrinter = new RawTreePrinter(writer)
// provides footnotes for types and mirrors
- import scala.collection.mutable.{Map, WeakHashMap, SortedSet}
- private val footnoteIndex = new FootnoteIndex
- private class FootnoteIndex {
+ private class Footnotes {
+ import scala.collection.mutable.{Map, WeakHashMap, SortedSet}
+
private val index = Map[Class[_], WeakHashMap[Any, Int]]()
private def classIndex[T: ClassTag] = index.getOrElseUpdate(classTag[T].runtimeClass, WeakHashMap[Any, Int]())
+
private val counters = Map[Class[_], Int]()
private def nextCounter[T: ClassTag] = {
val clazz = classTag[T].runtimeClass
@@ -1147,29 +1148,26 @@ trait Printers extends api.Printers { self: SymbolTable =>
counters(clazz)
}
- def mkFootnotes() = new Footnotes
- class Footnotes {
- private val footnotes = Map[Class[_], SortedSet[Int]]()
- private def classFootnotes[T: ClassTag] = footnotes.getOrElseUpdate(classTag[T].runtimeClass, SortedSet[Int]())
+ private val footnotes = Map[Class[_], SortedSet[Int]]()
+ private def classFootnotes[T: ClassTag] = footnotes.getOrElseUpdate(classTag[T].runtimeClass, SortedSet[Int]())
- def put[T: ClassTag](any: T): Int = {
- val index = classIndex[T].getOrElseUpdate(any, nextCounter[T])
- classFootnotes[T] += index
- index
- }
+ def put[T: ClassTag](any: T): Int = {
+ val index = classIndex[T].getOrElseUpdate(any, nextCounter[T])
+ classFootnotes[T] += index
+ index
+ }
- def get[T: ClassTag]: List[(Int, Any)] =
- classFootnotes[T].toList map (fi => (fi, classIndex[T].find{ case (any, ii) => ii == fi }.get._1))
-
- def print[T: ClassTag](printer: Printers.super.TreePrinter): Unit = {
- val footnotes = get[T]
- if (footnotes.nonEmpty) {
- printer.print(EOL)
- footnotes.zipWithIndex foreach {
- case ((fi, any), ii) =>
- printer.print("[", fi, "] ", any)
- if (ii < footnotes.length - 1) printer.print(EOL)
- }
+ def get[T: ClassTag]: List[(Int, Any)] =
+ classFootnotes[T].toList map (fi => (fi, classIndex[T].find{ case (any, ii) => ii == fi }.get._1))
+
+ def print[T: ClassTag](printer: Printers.super.TreePrinter): Unit = {
+ val footnotes = get[T]
+ if (footnotes.nonEmpty) {
+ printer.print(EOL)
+ footnotes.zipWithIndex foreach {
+ case ((fi, any), ii) =>
+ printer.print("[", fi, "] ", any)
+ if (ii < footnotes.length - 1) printer.print(EOL)
}
}
}
@@ -1180,7 +1178,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
private var depth = 0
private var printTypesInFootnotes = true
private var printingFootnotes = false
- private val footnotes = footnoteIndex.mkFootnotes()
+ private val footnotes = new Footnotes()
def print(args: Any*): Unit = {
// don't print type footnotes if the argument is a mere type
diff --git a/src/reflect/scala/reflect/internal/ReificationSupport.scala b/src/reflect/scala/reflect/internal/ReificationSupport.scala
index d393a841b7..30f2efd7e3 100644
--- a/src/reflect/scala/reflect/internal/ReificationSupport.scala
+++ b/src/reflect/scala/reflect/internal/ReificationSupport.scala
@@ -287,6 +287,8 @@ trait ReificationSupport { self: SymbolTable =>
val evdefs = gvdefs.zip(lvdefs).map {
case (gvdef @ ValDef(_, _, tpt: TypeTree, _), ValDef(_, _, _, rhs)) =>
copyValDef(gvdef)(tpt = tpt.original, rhs = rhs)
+ case (tr1, tr2) =>
+ throw new MatchError((tr1, tr2))
}
val edefs = evdefs ::: etdefs
if (ctorMods.isTrait)
@@ -726,7 +728,7 @@ trait ReificationSupport { self: SymbolTable =>
protected object FilterCall {
def unapply(tree: Tree): Option[(Tree,Tree)] = tree match {
case Apply(Select(obj, nme.withFilter | nme.filter), arg :: Nil) =>
- Some(obj, arg)
+ Some((obj, arg))
case _ => None
}
}
@@ -760,10 +762,10 @@ trait ReificationSupport { self: SymbolTable =>
def unapply(tree: Tree) = tree match {
case SyntacticApplied(SyntacticTypeApplied(sel @ Select(lhs, meth), _), (f :: Nil) :: Nil)
if name == meth && sel.hasAttachment[ForAttachment.type] =>
- Some(lhs, f)
+ Some((lhs, f))
case SyntacticApplied(SyntacticTypeApplied(sel @ Select(lhs, meth), _), (f :: Nil) :: _ :: Nil)
if name == meth && sel.hasAttachment[ForAttachment.type] =>
- Some(lhs, f)
+ Some((lhs, f))
case _ => None
}
}
@@ -1132,7 +1134,7 @@ trait ReificationSupport { self: SymbolTable =>
def apply(tpt: Tree, where: List[Tree]): ExistentialTypeTree =
ExistentialTypeTree(tpt, where.map {
case md: MemberDef => md
- case tree => throw new IllegalArgumentException("$tree is not legal forSome definition")
+ case tree => throw new IllegalArgumentException(s"$tree is not legal forSome definition")
})
def unapply(tree: Tree): Option[(Tree, List[MemberDef])] = tree match {
case MaybeTypeTreeOriginal(ExistentialTypeTree(tpt, where)) =>
diff --git a/src/reflect/scala/reflect/internal/Reporting.scala b/src/reflect/scala/reflect/internal/Reporting.scala
index f2de83bc5d..afdae81289 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 still 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/StdAttachments.scala b/src/reflect/scala/reflect/internal/StdAttachments.scala
index cca33253be..0243dd48d2 100644
--- a/src/reflect/scala/reflect/internal/StdAttachments.scala
+++ b/src/reflect/scala/reflect/internal/StdAttachments.scala
@@ -38,6 +38,19 @@ trait StdAttachments {
*/
case class CompoundTypeTreeOriginalAttachment(parents: List[Tree], stats: List[Tree])
+ /** Attached to a Function node during type checking when the expected type is a SAM type (and not a built-in FunctionN).
+ *
+ * Ideally, we'd move to Dotty's Closure AST, which tracks the environment,
+ * the lifted method that has the implementation, and the target type.
+ * For backwards compatibility, an attachment is the best we can do right now.
+ *
+ * @param samTp the expected type that triggered sam conversion (may be a subtype of the type corresponding to sam's owner)
+ * @param sam the single abstract method implemented by the Function we're attaching this to
+ *
+ * @since 2.12.0-M4
+ */
+ case class SAMFunction(samTp: Type, sam: Symbol) extends PlainAttachment
+
/** When present, indicates that the host `Ident` has been created from a backquoted identifier.
*/
case object BackquotedIdentifierAttachment extends PlainAttachment
@@ -52,4 +65,8 @@ trait StdAttachments {
/** Untyped list of subpatterns attached to selector dummy. */
case class SubpatternsAttachment(patterns: List[Tree])
+
+ abstract class InlineAnnotatedAttachment
+ case object NoInlineCallsiteAttachment extends InlineAnnotatedAttachment
+ case object InlineCallsiteAttachment extends InlineAnnotatedAttachment
}
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 52558d9395..0ac72e7d8b 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -7,11 +7,11 @@ package scala
package reflect
package internal
+import scala.language.implicitConversions
+
import java.security.MessageDigest
-import java.util.UUID.randomUUID
import Chars.isOperatorPart
import scala.annotation.switch
-import scala.language.implicitConversions
import scala.collection.immutable
import scala.io.Codec
@@ -104,13 +104,13 @@ trait StdNames {
val ANON_FUN_NAME: NameType = "$anonfun"
val EMPTY: NameType = ""
val EMPTY_PACKAGE_NAME: NameType = "<empty>"
- val IMPL_CLASS_SUFFIX = "$class"
val IMPORT: NameType = "<import>"
val MODULE_SUFFIX_NAME: NameType = MODULE_SUFFIX_STRING
val MODULE_VAR_SUFFIX: NameType = "$module"
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("$", "")
@@ -290,6 +290,7 @@ trait StdNames {
final val DeprecatedATTR: NameType = "Deprecated"
final val ExceptionsATTR: NameType = "Exceptions"
final val InnerClassesATTR: NameType = "InnerClasses"
+ final val MethodParametersATTR: NameType = "MethodParameters"
final val RuntimeAnnotationATTR: NameType = "RuntimeVisibleAnnotations" // RetentionPolicy.RUNTIME
final val ScalaATTR: NameType = "Scala"
final val ScalaSignatureATTR: NameType = "ScalaSig"
@@ -301,8 +302,6 @@ trait StdNames {
def dropSingletonName(name: Name): TypeName = (name dropRight SINGLETON_SUFFIX.length).toTypeName
def singletonName(name: Name): TypeName = (name append SINGLETON_SUFFIX).toTypeName
- def implClassName(name: Name): TypeName = (name append IMPL_CLASS_SUFFIX).toTypeName
- def interfaceName(implname: Name): TypeName = (implname dropRight IMPL_CLASS_SUFFIX.length).toTypeName
}
abstract class TermNames extends Keywords with TermNamesApi {
@@ -376,7 +375,6 @@ trait StdNames {
def isConstructorName(name: Name) = name == CONSTRUCTOR || name == MIXIN_CONSTRUCTOR
def isExceptionResultName(name: Name) = name startsWith EXCEPTION_RESULT_PREFIX
- def isImplClassName(name: Name) = name endsWith IMPL_CLASS_SUFFIX
def isLocalDummyName(name: Name) = name startsWith LOCALDUMMY_PREFIX
def isLocalName(name: Name) = name endsWith LOCAL_SUFFIX_STRING
def isLoopHeaderLabel(name: Name) = (name startsWith WHILE_PREFIX) || (name startsWith DO_WHILE_PREFIX)
@@ -643,6 +641,7 @@ trait StdNames {
val accessor: NameType = "accessor"
val add_ : NameType = "add"
val annotation: NameType = "annotation"
+ val anyHash: NameType = "anyHash"
val anyValClass: NameType = "anyValClass"
val apply: NameType = "apply"
val applyDynamic: NameType = "applyDynamic"
@@ -672,6 +671,7 @@ trait StdNames {
val delayedInit: NameType = "delayedInit"
val delayedInitArg: NameType = "delayedInit$body"
val dollarScope: NameType = "$scope"
+ val doubleHash: NameType = "doubleHash"
val drop: NameType = "drop"
val elem: NameType = "elem"
val noSelfType: NameType = "noSelfType"
@@ -690,12 +690,13 @@ trait StdNames {
val finalize_ : NameType = "finalize"
val find_ : NameType = "find"
val flatMap: NameType = "flatMap"
+ val floatHash: NameType = "floatHash"
val foreach: NameType = "foreach"
val freshTermName: NameType = "freshTermName"
val freshTypeName: NameType = "freshTypeName"
val get: NameType = "get"
+ val parameterTypes: NameType = "parameterTypes"
val hashCode_ : NameType = "hashCode"
- val hash_ : NameType = "hash"
val head : NameType = "head"
val immutable: NameType = "immutable"
val implicitly: NameType = "implicitly"
@@ -712,6 +713,7 @@ trait StdNames {
val lang: NameType = "lang"
val length: NameType = "length"
val lengthCompare: NameType = "lengthCompare"
+ val longHash: NameType = "longHash"
val macroContext : NameType = "c"
val main: NameType = "main"
val manifestToTypeTag: NameType = "manifestToTypeTag"
@@ -875,7 +877,7 @@ trait StdNames {
val toCharacter: NameType = "toCharacter"
val toInteger: NameType = "toInteger"
- def newLazyValSlowComputeName(lzyValName: Name) = lzyValName append LAZY_SLOW_SUFFIX
+ def newLazyValSlowComputeName(lzyValName: Name) = (lzyValName stripSuffix MODULE_VAR_SUFFIX append LAZY_SLOW_SUFFIX).toTermName
// ASCII names for operators
val ADD = encode("+")
@@ -1168,6 +1170,7 @@ trait StdNames {
final val InvokeExact: TermName = newTermName("invokeExact")
final val AltMetafactory: TermName = newTermName("altMetafactory")
+ final val Bootstrap: TermName = newTermName("bootstrap")
val Boxed = immutable.Map[TypeName, TypeName](
tpnme.Boolean -> BoxedBoolean,
diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala
index ef63078f90..6d988479af 100644
--- a/src/reflect/scala/reflect/internal/SymbolTable.scala
+++ b/src/reflect/scala/reflect/internal/SymbolTable.scala
@@ -8,7 +8,7 @@ package reflect
package internal
import scala.annotation.elidable
-import scala.collection.{ mutable, immutable }
+import scala.collection.mutable
import util._
import java.util.concurrent.TimeUnit
import scala.reflect.internal.{TreeGen => InternalTreeGen}
@@ -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
@@ -375,20 +375,30 @@ abstract class SymbolTable extends macros.Universe
def newWeakSet[K <: AnyRef]() = recordCache(new WeakHashSet[K]())
def newAnyRefMap[K <: AnyRef, V]() = recordCache(mutable.AnyRefMap[K, V]())
- def newGeneric[T](f: => T): () => T = {
+ /**
+ * Register a cache specified by a factory function and (optionally) a cleanup function.
+ *
+ * @return A function that will return cached value, or create a fresh value when a new run is started.
+ */
+ def newGeneric[T](f: => T, cleanup: T => Unit = (x: Any) => ()): () => T = {
val NoCached: T = null.asInstanceOf[T]
var cached: T = NoCached
var cachedRunId = NoRunId
- recordCache(new Clearable {
- def clear(): Unit = cached = NoCached
- })
- () => {
- if (currentRunId != cachedRunId || cached == NoCached) {
- cached = f
- cachedRunId = currentRunId
+ val clearable = new Clearable with (() => T) {
+ def clear(): Unit = {
+ if (cached != NoCached)
+ cleanup(cached)
+ cached = NoCached
+ }
+ def apply(): T = {
+ if (currentRunId != cachedRunId || cached == NoCached) {
+ cached = f
+ cachedRunId = currentRunId
+ }
+ cached
}
- cached
}
+ recordCache(clearable)
}
}
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 3b9ee9048a..ed51414382 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -7,7 +7,7 @@ package scala
package reflect
package internal
-import scala.collection.{ mutable, immutable }
+import scala.collection.immutable
import scala.collection.mutable.ListBuffer
import util.{ Statistics, shortClassOfInstance }
import Flags._
@@ -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)
@@ -320,7 +323,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def newModuleVarSymbol(accessor: Symbol): TermSymbol = {
val newName = nme.moduleVarName(accessor.name.toTermName)
val newFlags = MODULEVAR | ( if (this.isClass) PrivateLocal | SYNTHETIC else 0 )
- val newInfo = accessor.tpe.finalResultType
+ val newInfo = thisType.memberType(accessor).finalResultType
val mval = newVariable(newName, accessor.pos.focus, newFlags.toLong) addAnnotation VolatileAttr
if (this.isClass)
@@ -475,10 +478,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def newAnonymousFunctionValue(pos: Position, newFlags: Long = 0L): TermSymbol =
newTermSymbol(nme.ANON_FUN_NAME, pos, SYNTHETIC | newFlags) setInfo NoType
- def newImplClass(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol = {
- newClassSymbol(name, pos, newFlags | IMPLCLASS)
- }
-
/** Refinement types P { val x: String; type T <: Number }
* also have symbols, they are refinementClasses
*/
@@ -585,7 +584,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def isAnonymousClass = false
def isCaseClass = false
def isConcreteClass = false
- def isImplClass = false // the implementation class of a trait
+ @deprecated("Trait implementation classes have been removed in Scala 2.12", "2.12.0")
+ def isImplClass = false
def isJavaInterface = false
def isNumericValueClass = false
def isPrimitiveValueClass = false
@@ -832,6 +832,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 (hasPackageFlag) moduleClass.packageObject
+ else NoSymbol
+
/** If this is a constructor, its owner: otherwise this.
*/
final def skipConstructor: Symbol = if (isConstructor) owner else this
@@ -871,7 +877,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 +894,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)
@@ -926,21 +933,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isCaseCopy =
isMethod && owner.isCase && isSynthetic && name == nme.copy
- /** Is this symbol a trait which needs an implementation class? */
- final def needsImplClass = (
- isTrait
- && (!isInterface || hasFlag(lateINTERFACE))
- && !isImplClass
- )
-
- /** Is this a symbol which exists only in the implementation class, not in its trait? */
- final def isImplOnly = isPrivate || (
- (owner.isTrait || owner.isImplClass) && (
- hasAllFlags(LIFTED | MODULE | METHOD)
- || isConstructor
- || hasFlag(notPRIVATE | LIFTED) && !hasFlag(ACCESSOR | SUPERACCESSOR | MODULE)
- )
- )
final def isModuleVar = hasFlag(MODULEVAR)
/**
@@ -964,10 +956,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* method `owner` returns the class C.
*
* Why not make a stable version of `isStatic`? Maybe some parts of the compiler depend on the
- * current implementation. For example
- * trait T { def foo = 1 }
- * The method `foo` in the implementation class T$impl will be `isStatic`, because trait
- * impl classes get the `lateMODULE` flag (T$impl.isStaticOwner is true).
+ * current implementation.
*/
def isStatic = (this hasFlag STATIC) || owner.isStaticOwner
@@ -977,7 +966,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Is this symbol a static member of its class? (i.e. needs to be implemented as a Java static?) */
final def isStaticMember: Boolean =
- hasFlag(STATIC) || owner.isImplClass
+ hasFlag(STATIC)
/** Does this symbol denote a class that defines static symbols? */
final def isStaticOwner: Boolean =
@@ -987,7 +976,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 +988,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)
@@ -1250,7 +1240,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def needsModuleSuffix = (
hasModuleFlag
&& !isMethod
- && !isImplClass
&& !isJavaDefined
)
/** These should be moved somewhere like JavaPlatform.
@@ -1323,9 +1312,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
protected def createPackageObjectClassSymbol(pos: Position, newFlags: Long): PackageObjectClassSymbol =
new PackageObjectClassSymbol(this, pos) initFlags newFlags
- protected def createImplClassSymbol(name: TypeName, pos: Position, newFlags: Long): ClassSymbol =
- new ClassSymbol(this, pos, name) with ImplClassSymbol initFlags newFlags
-
protected def createMethodSymbol(name: TermName, pos: Position, newFlags: Long): MethodSymbol =
new MethodSymbol(this, pos, name) initFlags newFlags
@@ -1364,8 +1350,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
createPackageObjectClassSymbol(pos, newFlags)
else if ((newFlags & MODULE) != 0)
createModuleClassSymbol(name, pos, newFlags)
- else if ((newFlags & IMPLCLASS) != 0)
- createImplClassSymbol(name, pos, newFlags)
else
createClassSymbol(name, pos, newFlags)
}
@@ -2013,7 +1997,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
def thisSym: Symbol = this
- def hasSelfType = thisSym.tpeHK != this.tpeHK
+ def hasSelfType = (thisSym ne this) && (typeOfThis.typeConstructor ne typeConstructor)
/** The type of `this` in a class, or else the type of the symbol itself. */
def typeOfThis = thisSym.tpe_*
@@ -2074,12 +2058,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
def sourceModule: Symbol = NoSymbol
- /** The implementation class of a trait. If available it will be the
- * symbol with the same owner, and the name of this symbol with $class
- * appended to it.
- */
- final def implClass: Symbol = owner.info.decl(tpnme.implClassName(name))
-
/** The class that is logically an outer class of given `clazz`.
* This is the enclosing class, except for classes defined locally to constructors,
* where it is the outer class of the enclosing class.
@@ -2283,16 +2261,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
owner.rawInfo
}
- /** If this symbol is an implementation class, its interface, otherwise the symbol itself
- * The method follows two strategies to determine the interface.
- * - during or after erasure, it takes the last parent of the implementation class
- * (which is always the interface, by convention)
- * - before erasure, it looks up the interface name in the scope of the owner of the class.
- * This only works for implementation classes owned by other classes or traits.
- * !!! Why?
- */
- def toInterface: Symbol = this
-
/** The module class corresponding to this module.
*/
def moduleClass: Symbol = NoSymbol
@@ -2412,8 +2380,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
var bcs = base.info.baseClasses dropWhile (owner != _) drop 1
var sym: Symbol = NoSymbol
while (!bcs.isEmpty && sym == NoSymbol) {
- if (!bcs.head.isImplClass)
- sym = matchingSymbol(bcs.head, base.thisType).suchThat(!_.isDeferred)
+ sym = matchingSymbol(bcs.head, base.thisType).suchThat(!_.isDeferred)
bcs = bcs.tail
}
sym
@@ -2514,14 +2481,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 }
@@ -2546,7 +2514,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** String representation of symbol's definition key word */
final def keyString: String =
if (isJavaInterface) "interface"
- else if (isTrait && !isImplClass) "trait"
+ else if (isTrait) "trait"
else if (isClass) "class"
else if (isType && !isParameter) "type"
else if (isVariable) "var"
@@ -2573,7 +2541,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
else if (isSetter) ("setter", if (isSourceMethod) "method" else "value", "SET")
else if (isTerm && isLazy) ("lazy value", "lazy value", "LAZ")
else if (isVariable) ("field", "variable", "VAR")
- else if (isImplClass) ("implementation class", "class", "IMPL")
else if (isTrait) ("trait", "trait", "TRT")
else if (isClass) ("class", "class", "CLS")
else if (isType) ("type", "type", "TPE")
@@ -2810,7 +2777,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
case DEFAULTPARAM => "<defaultparam>" // TRAIT
case MIXEDIN => "<mixedin>" // EXISTENTIAL
case LABEL => "<label>" // CONTRAVARIANT / INCONSTRUCTOR
- case PRESUPER => "<presuper>" // IMPLCLASS
case BYNAMEPARAM => if (this.isValueParameter) "<bynameparam>" else "<captured>" // COVARIANT
case _ => super.resolveOverloadedFlag(flag)
}
@@ -2964,7 +2930,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
loop(info)
}
- override def exceptions = annotations flatMap ThrownException.unapply
+ override def exceptions = for (ThrownException(tp) <- annotations) yield tp.typeSymbol
}
implicit val MethodSymbolTag = ClassTag[MethodSymbol](classOf[MethodSymbol])
@@ -3211,7 +3177,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def resolveOverloadedFlag(flag: Long) = flag match {
case INCONSTRUCTOR => "<inconstructor>" // INCONSTRUCTOR / CONTRAVARIANT / LABEL
case EXISTENTIAL => "<existential>" // EXISTENTIAL / MIXEDIN
- case IMPLCLASS => "<implclass>" // IMPLCLASS / PRESUPER
case _ => super.resolveOverloadedFlag(flag)
}
@@ -3223,7 +3188,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def isAbstractClass = this hasFlag ABSTRACT
override def isCaseClass = this hasFlag CASE
override def isClassLocalToConstructor = this hasFlag INCONSTRUCTOR
- override def isImplClass = this hasFlag IMPLCLASS
override def isModuleClass = this hasFlag MODULE
override def isPackageClass = this hasFlag PACKAGE
override def isTrait = this hasFlag TRAIT
@@ -3241,13 +3205,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// The corresponding interface is the last parent by convention.
private def lastParent = if (tpe.parents.isEmpty) NoSymbol else tpe.parents.last.typeSymbol
- override def toInterface: Symbol = (
- if (isImplClass) {
- if (phase.next.erasedTypes) lastParent
- else owner.info.decl(tpnme.interfaceName(name))
- }
- else super.toInterface
- )
/** Is this class locally defined?
* A class is local, if
@@ -3278,7 +3235,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def existentialBound = GenPolyType(this.typeParams, TypeBounds.upper(this.classBound))
- def primaryConstructorName = if (this hasFlag TRAIT | IMPLCLASS) nme.MIXIN_CONSTRUCTOR else nme.CONSTRUCTOR
+ def primaryConstructorName = if (this hasFlag TRAIT) nme.MIXIN_CONSTRUCTOR else nme.CONSTRUCTOR
override def primaryConstructor = {
val c = info decl primaryConstructorName
@@ -3403,13 +3360,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
}
@@ -3428,12 +3381,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
}
- trait ImplClassSymbol extends ClassSymbol {
- override def sourceModule = companionModule
- // override def isImplClass = true
- override def typeOfThis = thisSym.tpe // don't use the ModuleClassSymbol typeOfThisCache.
- }
-
class PackageClassSymbol protected[Symbols] (owner0: Symbol, pos0: Position, name0: TypeName)
extends ModuleClassSymbol(owner0, pos0, name0) {
override def sourceModule = companionModule
@@ -3445,7 +3392,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
extends ClassSymbol(owner0, pos0, tpnme.REFINE_CLASS_NAME) {
override def name_=(name: Name) {
abort("Cannot set name of RefinementClassSymbol to " + name)
- super.name_=(name)
}
override def isRefinementClass = true
override def isAnonOrRefinementClass = true
@@ -3692,7 +3638,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
assert((prev eq null) || phaseId(validFrom) > phaseId(prev.validFrom), this)
assert(validFrom != NoPeriod, this)
- private def phaseString = "%s: %s".format(phaseOf(validFrom), info)
+ private def phaseString = {
+ val phase = phaseOf(validFrom)
+ s"$phase: ${exitingPhase(phase)(info.toString)}"
+ }
override def toString = toList reverseMap (_.phaseString) mkString ", "
def toList: List[TypeHistory] = this :: ( if (prev eq null) Nil else prev.toList )
diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala
index 201b727ed6..c5038fd1bb 100644
--- a/src/reflect/scala/reflect/internal/TreeGen.scala
+++ b/src/reflect/scala/reflect/internal/TreeGen.scala
@@ -117,6 +117,30 @@ abstract class TreeGen {
case _ => qual
}
+
+
+ // val selType = testedBinder.info
+ //
+ // // See the test for SI-7214 for motivation for dealias. Later `treeCondStrategy#outerTest`
+ // // generates an outer test based on `patType.prefix` with automatically dealises.
+ // // Prefixes can have all kinds of shapes SI-9110
+ // val patPre = expectedTp.dealiasWiden.prefix
+ // val selPre = selType.dealiasWiden.prefix
+ //
+ // // Optimization: which prefixes can we disqualify from the need for an outer reference check?
+ // // - classes in static owners do not get outer pointers
+ // // - if the prefixes are statically known to be equal, the type system ensures an outer test is redundant
+ // !((patPre eq NoPrefix) || (selPre eq NoPrefix)
+ // || patPre.typeSymbol.isPackageClass
+ // || selPre =:= patPre)
+
+ def mkAttributedQualifierIfPossible(prefix: Type): Option[Tree] = prefix match {
+ case NoType | NoPrefix | ErrorType => None
+ case TypeRef(_, sym, _) if sym.isModule || sym.isClass || sym.isType => None
+ case pre => Some(mkAttributedQualifier(prefix))
+ }
+
+
/** Builds a reference to given symbol with given stable prefix. */
def mkAttributedRef(pre: Type, sym: Symbol): RefTree = {
val qual = mkAttributedQualifier(pre)
@@ -129,7 +153,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 +224,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
@@ -277,13 +310,16 @@ abstract class TreeGen {
/** Builds a tuple */
def mkTuple(elems: List[Tree], flattenUnary: Boolean = true): Tree = elems match {
case Nil =>
- Literal(Constant(()))
+ mkLiteralUnit
case tree :: Nil if flattenUnary =>
tree
case _ =>
Apply(scalaDot(TupleClass(elems.length).name.toTermName), elems)
}
+ def mkLiteralUnit: Literal = Literal(Constant(()))
+ def mkUnitBlock(expr: Tree): Block = Block(List(expr), mkLiteralUnit)
+
def mkTupleType(elems: List[Tree], flattenUnary: Boolean = true): Tree = elems match {
case Nil =>
scalaDot(tpnme.Unit)
@@ -362,7 +398,7 @@ abstract class TreeGen {
if (body forall treeInfo.isInterfaceMember) None
else Some(
atPos(wrappingPos(superPos, lvdefs)) (
- DefDef(NoMods, nme.MIXIN_CONSTRUCTOR, Nil, ListOfNil, TypeTree(), Block(lvdefs, Literal(Constant(()))))))
+ DefDef(NoMods, nme.MIXIN_CONSTRUCTOR, Nil, ListOfNil, TypeTree(), Block(lvdefs, mkLiteralUnit))))
}
else {
// convert (implicit ... ) to ()(implicit ... ) if it's the only parameter section
@@ -376,7 +412,7 @@ abstract class TreeGen {
// therefore here we emit a dummy which gets populated when the template is named and typechecked
Some(
atPos(wrappingPos(superPos, lvdefs ::: vparamss1.flatten).makeTransparent) (
- DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(Constant(()))))))
+ DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), mkLiteralUnit))))
}
}
constr foreach (ensureNonOverlapping(_, parents ::: gvdefs, focus = false))
@@ -448,7 +484,7 @@ abstract class TreeGen {
* written by end user. It's important to distinguish the two so that
* quasiquotes can strip synthetic ones away.
*/
- def mkSyntheticUnit() = Literal(Constant(())).updateAttachment(SyntheticUnitAttachment)
+ def mkSyntheticUnit() = mkLiteralUnit.updateAttachment(SyntheticUnitAttachment)
/** Create block of statements `stats` */
def mkBlock(stats: List[Tree], doFlatten: Boolean = true): Tree =
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index 4657fa0000..86b70643c9 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -18,7 +18,7 @@ abstract class TreeInfo {
val global: SymbolTable
import global._
- import definitions.{ isTupleSymbol, isVarArgsList, isCastSymbol, ThrowableClass, TupleClass, uncheckedStableClass, isBlackboxMacroBundleType, isWhiteboxContextType }
+ import definitions.{ isVarArgsList, isCastSymbol, ThrowableClass, uncheckedStableClass, isBlackboxMacroBundleType, isWhiteboxContextType }
/* Does not seem to be used. Not sure what it does anyway.
def isOwnerDefinition(tree: Tree): Boolean = tree match {
@@ -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..cba34aa220 100644
--- a/src/reflect/scala/reflect/internal/Trees.scala
+++ b/src/reflect/scala/reflect/internal/Trees.scala
@@ -8,7 +8,7 @@ package reflect
package internal
import Flags._
-import scala.collection.{ mutable, immutable }
+import scala.collection.mutable
import scala.reflect.macros.Attachments
import util.Statistics
@@ -1161,6 +1161,10 @@ trait Trees extends api.Trees {
def Super(sym: Symbol, mix: TypeName): Tree =
Super(This(sym), mix)
+ /** Selection of a method in an arbitrary ancestor */
+ def SuperSelect(clazz: Symbol, sym: Symbol): Tree =
+ Select(Super(clazz, tpnme.EMPTY), sym)
+
def This(sym: Symbol): Tree =
This(sym.name.toTypeName) setSymbol sym
@@ -1468,8 +1472,10 @@ trait Trees extends api.Trees {
class ChangeOwnerTraverser(val oldowner: Symbol, val newowner: Symbol) extends Traverser {
final def change(sym: Symbol) = {
- if (sym != NoSymbol && sym.owner == oldowner)
+ if (sym != NoSymbol && sym.owner == oldowner) {
sym.owner = newowner
+ if (sym.isModule) sym.moduleClass.owner = newowner
+ }
}
override def traverse(tree: Tree) {
tree match {
@@ -1617,21 +1623,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..de82a6a0b2 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -7,7 +7,7 @@ package scala
package reflect
package internal
-import scala.collection.{ mutable, immutable, generic }
+import scala.collection.{ mutable, immutable }
import scala.ref.WeakReference
import mutable.ListBuffer
import Flags._
@@ -462,7 +462,7 @@ trait Types
* the empty list for all other types */
def boundSyms: immutable.Set[Symbol] = emptySymbolSet
- /** Replace formal type parameter symbols with actual type arguments.
+ /** Replace formal type parameter symbols with actual type arguments. ErrorType on arity mismatch.
*
* Amounts to substitution except for higher-kinded types. (See overridden method in TypeRef) -- @M
*/
@@ -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)
@@ -1189,7 +1196,6 @@ trait Types
object ThisType extends ThisTypeExtractor {
def apply(sym: Symbol): Type = (
if (!phase.erasedTypes) unique(new UniqueThisType(sym))
- else if (sym.isImplClass) sym.typeOfThis
else sym.tpe_*
)
}
@@ -1207,6 +1213,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 +1357,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 +1616,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
@@ -1843,53 +1866,13 @@ trait Types
override def isHigherKinded = false
override def typeParams = Nil
- override def transform(tp: Type): Type = {
- // This situation arises when a typevar is encountered for which
- // too little information is known to determine its kind, and
- // it later turns out not to have kind *. See SI-4070. Only
- // logging it for now.
- val tparams = sym.typeParams
- if (tparams.size != args.size)
- devWarning(s"$this.transform($tp), but tparams.isEmpty and args=$args")
- def asSeenFromInstantiated(tp: Type) =
- asSeenFromOwner(tp).instantiateTypeParams(tparams, args)
- // If we're called with a poly type, and we were to run the `asSeenFrom`, over the entire
- // type, we can end up with new symbols for the type parameters (clones from TypeMap).
- // The subsequent substitution of type arguments would fail. This problem showed up during
- // the fix for SI-8046, however the solution taken there wasn't quite right, and led to
- // SI-8170.
- //
- // Now, we detect the PolyType before both the ASF *and* the substitution, and just operate
- // on the result type.
- //
- // TODO: Revisit this and explore the questions raised:
- //
- // AM: I like this better than the old code, but is there any way the tparams would need the ASF treatment as well?
- // JZ: I think its largely irrelevant, as they are no longer referred to in the result type.
- // In fact, you can get away with returning a type of kind * here and the sky doesn't fall:
- // `case PolyType(`tparams`, result) => asSeenFromInstantiated(result)`
- // But I thought it was better to retain the kind.
- // AM: I've been experimenting with apply-type-args-then-ASF, but running into cycles.
- // In general, it seems iffy the tparams can never occur in the result
- // then we might as well represent the type as a no-arg typeref.
- // AM: I've also been trying to track down uses of transform (pretty generic name for something that
- // does not seem that widely applicable).
- // It's kind of a helper for computing baseType (since it tries to propagate our type args to some
- // other type, which has to be related to this type for that to make sense).
- //
- tp match {
- case PolyType(`tparams`, result) => PolyType(tparams, asSeenFromInstantiated(result))
- case _ => asSeenFromInstantiated(tp)
- }
- }
-
// note: does not go through typeRef. There's no need to because
// neither `pre` nor `sym` changes. And there's a performance
// advantage to call TypeRef directly.
override def typeConstructor = TypeRef(pre, sym, Nil)
}
- class ModuleTypeRef(pre0: Type, sym0: Symbol) extends NoArgsTypeRef(pre0, sym0) with ClassTypeRef {
+ class ModuleTypeRef(pre0: Type, sym0: Symbol) extends NoArgsTypeRef(pre0, sym0) {
require(sym.isModuleClass, sym)
private[this] var narrowedCache: Type = _
override def narrow = {
@@ -1898,6 +1881,10 @@ trait Types
narrowedCache
}
+ override private[Types] def invalidateTypeRefCaches(): Unit = {
+ super.invalidateTypeRefCaches()
+ narrowedCache = null
+ }
override protected def finishPrefix(rest: String) = objectPrefix + rest
override def directObjectString = super.safeToString
override def toLongString = toString
@@ -1908,12 +1895,12 @@ trait Types
require(sym.isPackageClass, sym)
override protected def finishPrefix(rest: String) = packagePrefix + rest
}
- class RefinementTypeRef(pre0: Type, sym0: Symbol) extends NoArgsTypeRef(pre0, sym0) with ClassTypeRef {
+ class RefinementTypeRef(pre0: Type, sym0: Symbol) extends NoArgsTypeRef(pre0, sym0) {
require(sym.isRefinementClass, sym)
// I think this is okay, but see #1241 (r12414), #2208, and typedTypeConstructor in Typers
override protected def normalizeImpl: Type = sym.info.normalize
- override protected def finishPrefix(rest: String) = "" + thisInfo
+ override protected def finishPrefix(rest: String) = "" + sym.info
}
class NoArgsTypeRef(pre0: Type, sym0: Symbol) extends TypeRef(pre0, sym0, Nil) {
@@ -1924,7 +1911,6 @@ trait Types
// represented as existential types.
override def isHigherKinded = (typeParams ne Nil)
override def typeParams = if (isDefinitionsInitialized) sym.typeParams else sym.unsafeTypeParams
- private def isRaw = !phase.erasedTypes && isRawIfWithoutArgs(sym)
override def instantiateTypeParams(formals: List[Symbol], actuals: List[Type]): Type =
if (isHigherKinded) {
@@ -1937,17 +1923,6 @@ trait Types
else
super.instantiateTypeParams(formals, actuals)
- override def transform(tp: Type): Type = {
- val res = asSeenFromOwner(tp)
- if (isHigherKinded && !isRaw)
- res.instantiateTypeParams(typeParams, dummyArgs)
- else
- res
- }
-
- override def transformInfo(tp: Type): Type =
- appliedType(asSeenFromOwner(tp), dummyArgs)
-
override def narrow =
if (sym.isModuleClass) singleType(pre, sym.sourceModule)
else super.narrow
@@ -1959,65 +1934,75 @@ trait Types
if (isHigherKinded) etaExpand else super.normalizeImpl
}
- trait ClassTypeRef extends TypeRef {
- // !!! There are scaladoc-created symbols arriving which violate this require.
- // require(sym.isClass, sym)
-
- override def baseType(clazz: Symbol): Type =
- 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 synchronized in a multi-threaded
- * usage scenario.
- */
+ /** Syncnote: These are pure caches for performance; no problem to evaluate these
+ * several times. Hence, no need to protected with synchronized in a multi-threaded
+ * usage scenario.
+ */
private var relativeInfoCache: Type = _
- private var relativeInfoPeriod: Period = NoPeriod
+ private var relativeInfoCacheValidForPeriod: Period = NoPeriod
+ private var relativeInfoCacheValidForSymInfo: Type = _
- private[Types] def relativeInfo = /*trace(s"relativeInfo(${safeToString}})")*/{
- if (relativeInfoPeriod != currentPeriod) {
- val memberInfo = pre.memberInfo(sym)
- relativeInfoCache = transformInfo(memberInfo)
- relativeInfoPeriod = currentPeriod
+ override private[Types] def invalidateTypeRefCaches(): Unit = {
+ super.invalidateTypeRefCaches()
+ relativeInfoCache = NoType
+ relativeInfoCacheValidForPeriod = NoPeriod
+ relativeInfoCacheValidForSymInfo = null
+ }
+
+ final override protected def relativeInfo = {
+ val symInfo = sym.info
+ if ((relativeInfoCache eq null) || (relativeInfoCacheValidForSymInfo ne symInfo) || (relativeInfoCacheValidForPeriod != currentPeriod)) {
+ relativeInfoCache = super.relativeInfo
+
+ if (this.isInstanceOf[AbstractTypeRef]) validateRelativeInfo()
+
+ relativeInfoCacheValidForSymInfo = symInfo
+ relativeInfoCacheValidForPeriod = currentPeriod
}
relativeInfoCache
}
- override def baseType(clazz: Symbol): Type =
- if (sym == clazz) this else baseTypeOfNonClassTypeRef(this, clazz)
+ private def validateRelativeInfo(): Unit = relativeInfoCache match {
+ // If a subtyping cycle is not detected here, we'll likely enter an infinite
+ // loop before a sensible error can be issued. SI-5093 is one example.
+ case x: SubType if x.supertype eq this =>
+ relativeInfoCache = null
+ throw new RecoverableCyclicReference(sym)
+ case _ =>
+ }
}
- 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 {
- pendingBaseTypes -= tpe
- }
- } finally {
- basetypeRecursions -= 1
- }
trait AliasTypeRef extends NonClassTypeRef {
require(sym.isAliasType, sym)
override def dealias = if (typeParamsMatchArgs) betaReduce.dealias else super.dealias
override def narrow = normalize.narrow
- override def thisInfo = normalize
override def prefix = if (this ne normalize) normalize.prefix else pre
override def termSymbol = if (this ne normalize) normalize.termSymbol else super.termSymbol
override def typeSymbol = if (this ne normalize) normalize.typeSymbol else sym
+ override protected[Types] def parentsImpl: List[Type] = normalize.parents map relativize
+
+ // `baseClasses` is sensitive to type args when referencing type members
+ // consider `type foo[x] = x`, `typeOf[foo[String]].baseClasses` should be the same as `typeOf[String].baseClasses`,
+ // which would be lost by looking at `sym.info` without propagating args
+ // since classes cannot be overridden, the prefix can be ignored
+ // (in fact, taking the prefix into account by replacing `normalize`
+ // with `relativeInfo` breaks pos/t8177g.scala, which is probably a bug, but a tricky one...
+ override def baseClasses = normalize.baseClasses
+
+ // similar reasoning holds here as for baseClasses
+ // as another example, consider the type alias `Foo` in `class O { o => type Foo = X { val bla: o.Bar }; type Bar }`
+ // o1.Foo and o2.Foo have different decls `val bla: o1.Bar` versus `val bla: o2.Bar`
+ // In principle, you should only call `sym.info.decls` when you know `sym.isClass`,
+ // and you should `relativize` the infos of the resulting members.
+ // The latter is certainly violated in multiple spots in the codebase (the members are usually transformed correctly, though).
+ override def decls: Scope = normalize.decls
+
// beta-reduce, but don't do partial application -- cycles have been checked in typeRef
override protected def normalizeImpl =
if (typeParamsMatchArgs) betaReduce.normalize
@@ -2040,7 +2025,7 @@ trait Types
//
// this crashes pos/depmet_implicit_tpbetareduce.scala
// appliedType(sym.info, typeArgs).asSeenFrom(pre, sym.owner)
- override def betaReduce = transform(sym.info.resultType)
+ override def betaReduce = relativize(sym.info.resultType)
/** SI-3731, SI-8177: when prefix is changed to `newPre`, maintain consistency of prefix and sym
* (where the symbol refers to a declaration "embedded" in the prefix).
@@ -2090,27 +2075,13 @@ trait Types
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 = _
+ override def baseClasses = relativeInfo.baseClasses
+ override def decls = relativeInfo.decls
+ override def bounds = relativeInfo.bounds
+
+ override protected[Types] def baseTypeSeqImpl: BaseTypeSeq = bounds.hi.baseTypeSeq prepend this
+ override protected[Types] def parentsImpl: List[Type] = relativeInfo.parents
- override def thisInfo = {
- val symInfo = sym.info
- if (thisInfoCache == null || (symInfo ne symInfoCache)) {
- symInfoCache = symInfo
- thisInfoCache = transformInfo(symInfo) match {
- // If a subtyping cycle is not detected here, we'll likely enter an infinite
- // loop before a sensible error can be issued. SI-5093 is one example.
- case x: SubType if x.supertype eq this =>
- throw new RecoverableCyclicReference(sym)
- case tp => tp
- }
- }
- thisInfoCache
- }
- override def bounds = thisInfo.bounds
- override protected[Types] def baseTypeSeqImpl: BaseTypeSeq = transform(bounds.hi).baseTypeSeq prepend this
override def kind = "AbstractTypeRef"
}
@@ -2128,9 +2099,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
@@ -2151,11 +2125,91 @@ trait Types
finalizeHash(h, 2)
}
+ // interpret symbol's info in terms of the type's prefix and type args
+ protected def relativeInfo: Type = appliedType(sym.info.asSeenFrom(pre, sym.owner), argsOrDummies)
+
// @M: propagate actual type params (args) to `tp`, by replacing
// formal type parameters with actual ones. If tp is higher kinded,
// the "actual" type arguments are types that simply reference the
// corresponding type parameters (unbound type variables)
- def transform(tp: Type): Type
+ //
+ // NOTE: for performance, as well as correctness, we do not attempt
+ // to reframe trivial types in terms of our prefix and args.
+ // asSeenFrom, by construction, is the identity for trivial types,
+ // and substitution cannot change them either (abstract types are non-trivial, specifically because they may need to be replaced)
+ // For correctness, the result for `tp == NoType` must be `NoType`,
+ // if we don't shield against this, and apply instantiateTypeParams to it,
+ // this would result in an ErrorType, which behaves differently during subtyping
+ // (and thus on recursion, subtyping would go from false -- since a NoType is involved --
+ // to true, as ErrorType is always a sub/super type....)
+ final def relativize(tp: Type): Type =
+ if (tp.isTrivial) tp
+ else if (args.isEmpty && (phase.erasedTypes || !isHigherKinded || isRawIfWithoutArgs(sym))) tp.asSeenFrom(pre, sym.owner)
+ else {
+ // The type params and type args should always match in length,
+ // though a mismatch can arise when a typevar is encountered for which
+ // too little information is known to determine its kind, and
+ // it later turns out not to have kind *. See SI-4070.
+ val formals = sym.typeParams
+
+ // If we're called with a poly type, and we were to run the `asSeenFrom`, over the entire
+ // type, we can end up with new symbols for the type parameters (clones from TypeMap).
+ // The subsequent substitution of type arguments would fail. This problem showed up during
+ // the fix for SI-8046, however the solution taken there wasn't quite right, and led to
+ // SI-8170.
+ //
+ // Now, we detect the PolyType before both the ASF *and* the substitution, and just operate
+ // on the result type.
+ //
+ // TODO: Revisit this and explore the questions raised:
+ //
+ // AM: I like this better than the old code, but is there any way the tparams would need the ASF treatment as well?
+ // JZ: I think its largely irrelevant, as they are no longer referred to in the result type.
+ // In fact, you can get away with returning a type of kind * here and the sky doesn't fall:
+ // `case PolyType(`tparams`, result) => asSeenFromInstantiated(result)`
+ // But I thought it was better to retain the kind.
+ // AM: I've been experimenting with apply-type-args-then-ASF, but running into cycles.
+ // In general, it seems iffy the tparams can never occur in the result
+ // then we might as well represent the type as a no-arg typeref.
+ // AM: I've also been trying to track down uses of transform (pretty generic name for something that
+ // does not seem that widely applicable).
+ // It's kind of a helper for computing baseType (since it tries to propagate our type args to some
+ // other type, which has to be related to this type for that to make sense).
+ //
+ def seenFromOwnerInstantiated(tp: Type): Type =
+ tp.asSeenFrom(pre, sym.owner).instantiateTypeParams(formals, argsOrDummies)
+
+ tp match {
+ case PolyType(`formals`, result) => PolyType(formals, seenFromOwnerInstantiated(result))
+ case _ => seenFromOwnerInstantiated(tp)
+ }
+ }
+
+ private def argsOrDummies = if (args.isEmpty) dummyArgs else args
+
+ final override def baseType(clazz: Symbol): Type =
+ if (clazz eq sym) this
+ // NOTE: this first goes to requested base type, *then* does asSeenFrom prefix & instantiates args
+ else if (sym.isClass) relativize(sym.info.baseType(clazz))
+ else baseTypeOfNonClassTypeRef(clazz)
+
+ // two differences with class type basetype:
+ // (1) first relativize the type, then go to the requested base type
+ // (2) cache for cycle robustness
+ private def baseTypeOfNonClassTypeRef(clazz: Symbol) =
+ try {
+ basetypeRecursions += 1
+ if (basetypeRecursions >= LogPendingBaseTypesThreshold) baseTypeOfNonClassTypeRefLogged(clazz)
+ else relativeInfo.baseType(clazz)
+ } finally basetypeRecursions -= 1
+
+ private def baseTypeOfNonClassTypeRefLogged(clazz: Symbol) =
+ if (pendingBaseTypes add this) try relativeInfo.baseType(clazz) finally { pendingBaseTypes remove this }
+ // TODO: is this optimization for AnyClass worth it? (or is it playing last-ditch cycle defense?)
+ // NOTE: for correctness, it only applies for non-class types
+ // (e.g., a package class should not get AnyTpe as its supertype, ever)
+ else if (clazz eq AnyClass) AnyTpe
+ else NoType
// eta-expand, subtyping relies on eta-expansion of higher-kinded types
protected def normalizeImpl: Type = if (isHigherKinded) etaExpand else super.normalize
@@ -2188,21 +2242,16 @@ trait Types
// (they are allowed to be rebound more liberally)
def coevolveSym(pre1: Type): Symbol = sym
- //@M! use appliedType on the polytype that represents the bounds (or if aliastype, the rhs)
- def transformInfo(tp: Type): Type = appliedType(asSeenFromOwner(tp), args)
-
- def thisInfo = sym.info
def initializedTypeParams = sym.info.typeParams
def typeParamsMatchArgs = sameLength(initializedTypeParams, args)
- def asSeenFromOwner(tp: Type) = tp.asSeenFrom(pre, sym.owner)
- override def baseClasses = thisInfo.baseClasses
+
override def baseTypeSeqDepth = baseTypeSeq.maxDepth
override def prefix = pre
override def termSymbol = super.termSymbol
override def termSymbolDirect = super.termSymbol
override def typeArgs = args
- override def typeOfThis = transform(sym.typeOfThis)
+ override def typeOfThis = relativize(sym.typeOfThis)
override def typeSymbol = sym
override def typeSymbolDirect = sym
@@ -2215,22 +2264,26 @@ trait Types
}
}
- override def decls: Scope = {
- sym.info match {
- case TypeRef(_, sym1, _) =>
- assert(sym1 != sym, this) // @MAT was != typeSymbol
- case _ =>
- }
- thisInfo.decls
- }
+ protected[Types] def parentsImpl: List[Type] = sym.info.parents map relativize
+
+ // Since type parameters cannot occur in super types, no need to relativize before looking at base *classes*.
+ // Similarly, our prefix can occur in super class types, but it cannot influence which classes those types resolve to.
+ // For example, `class Outer { outer => class Inner extends outer.Foo; class Foo }`
+ // `outer`'s value has no impact on which `Foo` is selected, since classes cannot be overridden.
+ // besides being faster, we can't use relativeInfo because it causes cycles
+ override def baseClasses = sym.info.baseClasses
+
+ // in principle, we should use `relativeInfo.decls`, but I believe all uses of `decls` will correctly `relativize` the individual members
+ override def decls: Scope = sym.info.decls
+
protected[Types] def baseTypeSeqImpl: BaseTypeSeq =
if (sym.info.baseTypeSeq exists (_.typeSymbolDirect.isAbstractType))
// SI-8046 base type sequence might have more elements in a subclass, we can't map it element wise.
- transform(sym.info).baseTypeSeq
+ relativize(sym.info).baseTypeSeq
else
// Optimization: no abstract types, we can compute the BTS of this TypeRef as an element-wise map
// of the BTS of the referenced symbol.
- sym.info.baseTypeSeq map transform
+ sym.info.baseTypeSeq map relativize
override def baseTypeSeq: BaseTypeSeq = {
val cache = baseTypeSeqCache
@@ -2261,9 +2314,10 @@ trait Types
)
protected def finishPrefix(rest: String) = (
if (sym.isInitialized && sym.isAnonymousClass && !phase.erasedTypes)
- parentsString(thisInfo.parents) + refinementString
+ parentsString(sym.info.parents) + refinementString
else rest
- )
+ )
+
private def noArgsString = finishPrefix(preString + sym.nameString)
private def tupleTypeString: String = args match {
case Nil => noArgsString
@@ -2325,10 +2379,10 @@ trait Types
// No longer defined as anonymous classes in `object TypeRef` to avoid an unnecessary outer pointer.
private final class AliasArgsTypeRef(pre: Type, sym: Symbol, args: List[Type]) extends ArgsTypeRef(pre, sym, args) with AliasTypeRef
private final class AbstractArgsTypeRef(pre: Type, sym: Symbol, args: List[Type]) extends ArgsTypeRef(pre, sym, args) with AbstractTypeRef
- private final class ClassArgsTypeRef(pre: Type, sym: Symbol, args: List[Type]) extends ArgsTypeRef(pre, sym, args) with ClassTypeRef
+ private final class ClassArgsTypeRef(pre: Type, sym: Symbol, args: List[Type]) extends ArgsTypeRef(pre, sym, args)
private final class AliasNoArgsTypeRef(pre: Type, sym: Symbol) extends NoArgsTypeRef(pre, sym) with AliasTypeRef
private final class AbstractNoArgsTypeRef(pre: Type, sym: Symbol) extends NoArgsTypeRef(pre, sym) with AbstractTypeRef
- private final class ClassNoArgsTypeRef(pre: Type, sym: Symbol) extends NoArgsTypeRef(pre, sym) with ClassTypeRef
+ private final class ClassNoArgsTypeRef(pre: Type, sym: Symbol) extends NoArgsTypeRef(pre, sym)
object TypeRef extends TypeRefExtractor {
def apply(pre: Type, sym: Symbol, args: List[Type]): Type = unique({
@@ -2353,7 +2407,7 @@ trait Types
if (period != currentPeriod) {
tpe.parentsPeriod = currentPeriod
if (!isValidForBaseClasses(period)) {
- tpe.parentsCache = tpe.thisInfo.parents map tpe.transform
+ tpe.parentsCache = tpe.parentsImpl
} else if (tpe.parentsCache == null) { // seems this can happen if things are corrupted enough, see #2641
tpe.parentsCache = List(AnyTpe)
}
@@ -2408,7 +2462,6 @@ trait Types
def isImplicit = (params ne Nil) && params.head.isImplicit
def isJava = false // can we do something like for implicits? I.e. do Java methods without parameters need to be recognized?
- //assert(paramTypes forall (pt => !pt.typeSymbol.isImplClass))//DEBUG
override def paramSectionCount: Int = resultType.paramSectionCount + 1
override def paramss: List[List[Symbol]] = params :: resultType.paramss
@@ -2458,6 +2511,8 @@ trait Types
override def isJava = true
}
+ // TODO: rename so it's more appropriate for the type that is for a method without argument lists
+ // ("nullary" erroneously implies it has an argument list with zero arguments, it actually has zero argument lists)
case class NullaryMethodType(override val resultType: Type) extends Type with NullaryMethodTypeApi {
override def isTrivial = resultType.isTrivial && (resultType eq resultType.withoutAnnotations)
override def prefix: Type = resultType.prefix
@@ -3877,6 +3932,8 @@ trait Types
et.withTypeVars(isConsistent(_, tp2))
case (_, et: ExistentialType) =>
et.withTypeVars(isConsistent(tp1, _))
+ case (_, _) =>
+ throw new MatchError((tp1, tp2))
}
def check(tp1: Type, tp2: Type) = (
@@ -3889,54 +3946,15 @@ trait Types
check(tp1, tp2) && check(tp2, tp1)
}
- /** Does a pattern of type `patType` need an outer test when executed against
- * selector type `selType` in context defined by `currentOwner`?
- */
- def needsOuterTest(patType: Type, selType: Type, currentOwner: Symbol) = {
- def createDummyClone(pre: Type): Type = {
- val dummy = currentOwner.enclClass.newValue(nme.ANYname).setInfo(pre.widen)
- singleType(ThisType(currentOwner.enclClass), dummy)
- }
- def maybeCreateDummyClone(pre: Type, sym: Symbol): Type = pre match {
- case SingleType(pre1, sym1) =>
- if (sym1.isModule && sym1.isStatic) {
- NoType
- } else if (sym1.isModule && sym.owner == sym1.moduleClass) {
- val pre2 = maybeCreateDummyClone(pre1, sym1)
- if (pre2 eq NoType) pre2
- else singleType(pre2, sym1)
- } else {
- createDummyClone(pre)
- }
- case ThisType(clazz) =>
- if (clazz.isModuleClass)
- maybeCreateDummyClone(clazz.typeOfThis, sym)
- else if (sym.owner == clazz && (sym.hasFlag(PRIVATE) || sym.privateWithin == clazz))
- NoType
- else
- createDummyClone(pre)
- case _ =>
- NoType
- }
- // See the test for SI-7214 for motivation for dealias. Later `treeCondStrategy#outerTest`
- // generates an outer test based on `patType.prefix` with automatically dealises.
- patType.dealias match {
- case TypeRef(pre, sym, args) =>
- val pre1 = maybeCreateDummyClone(pre, sym)
- (pre1 ne NoType) && isPopulated(copyTypeRef(patType, pre1, sym, args), selType)
- case _ =>
- false
- }
- }
-
- def normalizePlus(tp: Type) = (
+ def normalizePlus(tp: Type): Type = {
if (isRawType(tp)) rawToExistential(tp)
else tp.normalize match {
- // Unify the two representations of module classes
- case st @ SingleType(_, sym) if sym.isModule => st.underlying.normalize
- case _ => tp.normalize
+ // Unify the representations of module classes
+ case st@SingleType(_, sym) if sym.isModule => st.underlying.normalize
+ case st@ThisType(sym) if sym.isModuleClass => normalizePlus(st.underlying)
+ case _ => tp.normalize
}
- )
+ }
/*
todo: change to:
@@ -4555,6 +4573,21 @@ 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 tr: TypeRef if updatedSyms.contains(tr.sym) => tr.invalidateTypeRefCaches()
+ 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/Variances.scala b/src/reflect/scala/reflect/internal/Variances.scala
index af04f47e0e..8d74065207 100644
--- a/src/reflect/scala/reflect/internal/Variances.scala
+++ b/src/reflect/scala/reflect/internal/Variances.scala
@@ -8,7 +8,7 @@ package reflect
package internal
import Variance._
-import scala.collection.{ mutable, immutable }
+import scala.collection.mutable
import scala.annotation.tailrec
/** See comments at scala.reflect.internal.Variance.
diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
index a9020a3d4c..4bc804445c 100644
--- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
@@ -14,7 +14,7 @@ import java.lang.Double.longBitsToDouble
import Flags._
import PickleFormat._
-import scala.collection.{ mutable, immutable }
+import scala.collection.mutable
import scala.collection.mutable.ListBuffer
import scala.annotation.switch
@@ -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/settings/MutableSettings.scala b/src/reflect/scala/reflect/internal/settings/MutableSettings.scala
index 38893d8db3..e75b3dff3d 100644
--- a/src/reflect/scala/reflect/internal/settings/MutableSettings.scala
+++ b/src/reflect/scala/reflect/internal/settings/MutableSettings.scala
@@ -58,6 +58,7 @@ abstract class MutableSettings extends AbsSettings {
def maxClassfileName: IntSetting
def isScala211: Boolean
+ def isScala212: Boolean
}
object MutableSettings {
diff --git a/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala b/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala
index f9b10c90be..cf274f24bb 100644
--- a/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala
+++ b/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala
@@ -58,7 +58,7 @@ trait TypeComparers {
false
private def equalSymsAndPrefixes(sym1: Symbol, pre1: Type, sym2: Symbol, pre2: Type): Boolean = (
- if (sym1 == sym2)
+ if (sym1 eq sym2)
sym1.hasPackageFlag || sym1.owner.hasPackageFlag || phase.erasedTypes || pre1 =:= pre2
else
(sym1.name == sym2.name) && isUnifiable(pre1, pre2)
@@ -79,7 +79,7 @@ trait TypeComparers {
def isDifferentTypeConstructor(tp1: Type, tp2: Type) = !isSameTypeConstructor(tp1, tp2)
private def isSameTypeConstructor(tr1: TypeRef, tr2: TypeRef): Boolean = (
- (tr1.sym == tr2.sym)
+ (tr1.sym eq tr2.sym)
&& !isDifferentType(tr1.pre, tr2.pre)
)
private def isSameTypeConstructor(tp1: Type, tp2: Type): Boolean = (
@@ -222,7 +222,7 @@ trait TypeComparers {
case SingleType(pre1, sym1) => tp2 match { case SingleType(pre2, sym2) => equalSymsAndPrefixes(sym1, pre1, sym2, pre2) ; case _ => false }
case PolyType(ps1, res1) => tp2 match { case PolyType(ps2, res2) => equalTypeParamsAndResult(ps1, res1, ps2, res2) ; case _ => false }
case ExistentialType(qs1, res1) => tp2 match { case ExistentialType(qs2, res2) => equalTypeParamsAndResult(qs1, res1, qs2, res2) ; case _ => false }
- case ThisType(sym1) => tp2 match { case ThisType(sym2) => sym1 == sym2 ; case _ => false }
+ case ThisType(sym1) => tp2 match { case ThisType(sym2) => sym1 eq sym2 ; case _ => false }
case ConstantType(c1) => tp2 match { case ConstantType(c2) => c1 == c2 ; case _ => false }
case NullaryMethodType(res1) => tp2 match { case NullaryMethodType(res2) => res1 =:= res2 ; case _ => false }
case TypeBounds(lo1, hi1) => tp2 match { case TypeBounds(lo2, hi2) => lo1 =:= lo2 && hi1 =:= hi2 ; case _ => false }
@@ -344,7 +344,7 @@ trait TypeComparers {
// in the same class, and the 'x' in the ThisType has in its override chain
// the 'x' in the SuperType, then the types conform.
private def isThisAndSuperSubtype(tp1: Type, tp2: Type): Boolean = (tp1, tp2) match {
- case (SingleType(ThisType(lpre), v1), SingleType(SuperType(ThisType(rpre), _), v2)) => (lpre == rpre) && (v1.overrideChain contains v2)
+ case (SingleType(ThisType(lpre), v1), SingleType(SuperType(ThisType(rpre), _), v2)) => (lpre eq rpre) && (v1.overrideChain contains v2)
case _ => false
}
@@ -361,8 +361,8 @@ trait TypeComparers {
false
}
- ( tp1.typeSymbol == NothingClass // @M Nothing is subtype of every well-kinded type
- || tp2.typeSymbol == AnyClass // @M Any is supertype of every well-kinded type (@PP: is it? What about continuations plugin?)
+ ( (tp1.typeSymbol eq NothingClass) // @M Nothing is subtype of every well-kinded type
+ || (tp2.typeSymbol eq AnyClass) // @M Any is supertype of every well-kinded type (@PP: is it? What about continuations plugin?)
|| isSub(tp1.normalize, tp2.normalize) && annotationsConform(tp1, tp2) // @M! normalize reduces higher-kinded case to PolyType's
)
}
@@ -394,7 +394,7 @@ trait TypeComparers {
val sym2 = tr2.sym
val pre1 = tr1.pre
val pre2 = tr2.pre
- (((if (sym1 == sym2) phase.erasedTypes || sym1.owner.hasPackageFlag || isSubType(pre1, pre2, depth)
+ (((if (sym1 eq sym2) phase.erasedTypes || sym1.owner.hasPackageFlag || isSubType(pre1, pre2, depth)
else (sym1.name == sym2.name && !sym1.isModuleClass && !sym2.isModuleClass &&
(isUnifiable(pre1, pre2) ||
isSameSpecializedSkolem(sym1, sym2, pre1, pre2) ||
@@ -403,7 +403,9 @@ trait TypeComparers {
||
sym2.isClass && {
val base = tr1 baseType sym2
- (base ne tr1) && isSubType(base, tr2, depth)
+ // During bootstrap, `base eq NoType` occurs about 2.5 times as often as `base ne NoType`.
+ // The extra check seems like a worthwhile optimization (about 2.5M useless calls to isSubtype saved during that run).
+ (base ne tr1) && (base ne NoType) && isSubType(base, tr2, depth)
}
||
thirdTryRef(tr1, tr2))
@@ -463,7 +465,7 @@ trait TypeComparers {
case SingletonClass => tp1.isStable || fourthTry
case _: ClassSymbol => classOnRight
case _: TypeSymbol if sym2.isDeferred => abstractTypeOnRight(tp2.bounds.lo) || fourthTry
- case _: TypeSymbol => retry(tp1.normalize, tp2.normalize)
+ case _: TypeSymbol => retry(normalizePlus(tp1), normalizePlus(tp2))
case _ => fourthTry
}
}
@@ -517,7 +519,7 @@ trait TypeComparers {
* - handle typerefs, refined types, and singleton types.
*/
def fourthTry = {
- def retry(lhs: Type, rhs: Type) = isSubType(lhs, rhs, depth)
+ def retry(lhs: Type, rhs: Type) = ((tp1 ne lhs) || (tp2 ne rhs)) && isSubType(lhs, rhs, depth)
def abstractTypeOnLeft(hi: Type) = isDifferentTypeConstructor(tp1, hi) && retry(hi, tp2)
tp1 match {
@@ -526,22 +528,16 @@ trait TypeComparers {
case TypeRef(_, sym2, _) => sym1 isBottomSubClass sym2
case _ => isSingleType(tp2) && retry(tp1, tp2.widen)
}
- def moduleOnLeft = tp2 match {
- case SingleType(pre2, sym2) => equalSymsAndPrefixes(sym1.sourceModule, pre1, sym2, pre2)
- case _ => false
- }
- def classOnLeft = (
- if (isRawType(tp1)) retry(rawToExistential(tp1), tp2)
- else if (sym1.isModuleClass) moduleOnLeft
- else sym1.isRefinementClass && retry(sym1.info, tp2)
- )
+
sym1 match {
- case NothingClass => true
- case NullClass => nullOnLeft
- case _: ClassSymbol => classOnLeft
- case _: TypeSymbol if sym1.isDeferred => abstractTypeOnLeft(tp1.bounds.hi)
- case _: TypeSymbol => retry(tp1.normalize, tp2.normalize)
- case _ => false
+ case NothingClass => true
+ case NullClass => nullOnLeft
+ case _: ClassSymbol if isRawType(tp1) => retry(normalizePlus(tp1), normalizePlus(tp2))
+ case _: ClassSymbol if sym1.isModuleClass => retry(normalizePlus(tp1), normalizePlus(tp2))
+ case _: ClassSymbol if sym1.isRefinementClass => retry(sym1.info, tp2)
+ case _: TypeSymbol if sym1.isDeferred => abstractTypeOnLeft(tp1.bounds.hi)
+ case _: TypeSymbol => retry(normalizePlus(tp1), normalizePlus(tp2))
+ case _ => false
}
case RefinedType(parents, _) => parents exists (retry(_, tp2))
case _: SingletonType => retry(tp1.underlying, tp2)
diff --git a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
index 804360b677..af5128163b 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..412c49f571 100644
--- a/src/reflect/scala/reflect/internal/transform/Erasure.scala
+++ b/src/reflect/scala/reflect/internal/transform/Erasure.scala
@@ -3,8 +3,6 @@ package reflect
package internal
package transform
-import Flags.{PARAMACCESSOR, METHOD}
-
trait Erasure {
val global: SymbolTable
@@ -114,8 +112,10 @@ trait Erasure {
protected def eraseDerivedValueClassRef(tref: TypeRef): Type = erasedValueClassArg(tref)
def apply(tp: Type): Type = tp match {
- case ConstantType(_) =>
- tp
+ case ConstantType(ct) =>
+ // erase classOf[List[_]] to classOf[List]. special case for classOf[Unit], avoid erasing to classOf[BoxedUnit].
+ if (ct.tag == ClazzTag && ct.typeValue.typeSymbol != UnitClass) ConstantType(Constant(apply(ct.typeValue)))
+ else tp
case st: ThisType if st.sym.isPackageClass =>
tp
case st: SubType =>
@@ -123,7 +123,7 @@ trait Erasure {
case tref @ TypeRef(pre, sym, args) =>
if (sym == ArrayClass)
if (unboundedGenericArrayLevel(tp) == 1) ObjectTpe
- else if (args.head.typeSymbol.isBottomClass) arrayType(ObjectTpe)
+ else if (args.head.typeSymbol.isBottomClass) arrayType(ObjectTpe)
else typeRef(apply(pre), sym, args map applyInArray)
else if (sym == AnyClass || sym == AnyValClass || sym == SingletonClass) ObjectTpe
else if (sym == UnitClass) BoxedUnitTpe
@@ -166,7 +166,7 @@ trait Erasure {
/** The erasure |T| of a type T. This is:
*
- * - For a constant type, itself.
+ * - For a constant type classOf[T], classOf[|T|], unless T is Unit. For any other constant type, itself.
* - For a type-bounds structure, the erasure of its upper bound.
* - For every other singleton type, the erasure of its supertype.
* - For a typeref scala.Array+[T] where T is an abstract type, AnyRef.
@@ -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/transform/Transforms.scala b/src/reflect/scala/reflect/internal/transform/Transforms.scala
index 296ccde443..0d2f355aa5 100644
--- a/src/reflect/scala/reflect/internal/transform/Transforms.scala
+++ b/src/reflect/scala/reflect/internal/transform/Transforms.scala
@@ -23,9 +23,9 @@ trait Transforms { self: SymbolTable =>
}
}
- private val refChecksLazy = new Lazy(new { val global: Transforms.this.type = self } with RefChecks)
- private val uncurryLazy = new Lazy(new { val global: Transforms.this.type = self } with UnCurry)
- private val erasureLazy = new Lazy(new { val global: Transforms.this.type = self } with Erasure)
+ private val refChecksLazy = new Lazy(new { val global: Transforms.this.type = self } with RefChecks)
+ private val uncurryLazy = new Lazy(new { val global: Transforms.this.type = self } with UnCurry)
+ private val erasureLazy = new Lazy(new { val global: Transforms.this.type = self } with Erasure)
private val postErasureLazy = new Lazy(new { val global: Transforms.this.type = self } with PostErasure)
def refChecks = refChecksLazy.force
diff --git a/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala b/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala
index 5cbdb92664..b5030460b8 100644
--- a/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala
+++ b/src/reflect/scala/reflect/internal/util/AbstractFileClassLoader.scala
@@ -5,8 +5,8 @@
package scala
package reflect.internal.util
-import scala.collection.{ mutable, immutable }
-import scala.reflect.io.{ AbstractFile, Streamable }
+import scala.collection.mutable
+import scala.reflect.io.AbstractFile
import java.net.{ URL, URLConnection, URLStreamHandler }
import java.security.cert.Certificate
import java.security.{ ProtectionDomain, CodeSource }
diff --git a/src/reflect/scala/reflect/internal/util/FreshNameCreator.scala b/src/reflect/scala/reflect/internal/util/FreshNameCreator.scala
index 8442c1015f..c69dd23c40 100644
--- a/src/reflect/scala/reflect/internal/util/FreshNameCreator.scala
+++ b/src/reflect/scala/reflect/internal/util/FreshNameCreator.scala
@@ -8,7 +8,6 @@ package util
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.atomic.AtomicLong
-import scala.collection.mutable
import scala.reflect.NameTransformer
class FreshNameCreator(creatorPrefix: String = "") {
diff --git a/src/reflect/scala/reflect/internal/util/Origins.scala b/src/reflect/scala/reflect/internal/util/Origins.scala
index 2eb4fa29d5..4c425457a7 100644
--- a/src/reflect/scala/reflect/internal/util/Origins.scala
+++ b/src/reflect/scala/reflect/internal/util/Origins.scala
@@ -7,7 +7,7 @@ package scala
package reflect
package internal.util
-import scala.collection.{ mutable, immutable }
+import scala.collection.mutable
/** A debugging class for logging from whence a method is being called.
* Say you wanted to discover who was calling phase_= in SymbolTable.
diff --git a/src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala b/src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala
index 41011f6c6b..f3db2017be 100644
--- a/src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala
+++ b/src/reflect/scala/reflect/internal/util/ScalaClassLoader.scala
@@ -6,15 +6,16 @@
package scala
package reflect.internal.util
+import scala.language.implicitConversions
+
import java.lang.{ ClassLoader => JClassLoader }
-import java.lang.reflect.{ Constructor, Modifier, Method }
-import java.io.{ File => JFile }
+import java.lang.reflect.Modifier
import java.net.{ URLClassLoader => JURLClassLoader }
import java.net.URL
-import scala.reflect.runtime.ReflectionUtils.unwrapHandler
+
+import scala.reflect.runtime.ReflectionUtils.{ show, unwrapHandler }
import ScalaClassLoader._
import scala.util.control.Exception.{ catching }
-import scala.language.implicitConversions
import scala.reflect.{ ClassTag, classTag }
trait HasClassPath {
@@ -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()
@@ -111,6 +139,10 @@ object ScalaClassLoader {
classloaderURLs :+= url
super.addURL(url)
}
+ override def close(): Unit = {
+ super.close()
+ classloaderURLs = null
+ }
}
def fromURLs(urls: Seq[URL], parent: ClassLoader = null): URLClassLoader =
diff --git a/src/reflect/scala/reflect/internal/util/TraceSymbolActivity.scala b/src/reflect/scala/reflect/internal/util/TraceSymbolActivity.scala
index e4a6503184..e48c35908f 100644
--- a/src/reflect/scala/reflect/internal/util/TraceSymbolActivity.scala
+++ b/src/reflect/scala/reflect/internal/util/TraceSymbolActivity.scala
@@ -2,8 +2,7 @@ package scala
package reflect.internal
package util
-import scala.collection.{ mutable, immutable }
-import scala.language.postfixOps
+import scala.collection.mutable
trait TraceSymbolActivity {
val global: SymbolTable
diff --git a/src/reflect/scala/reflect/internal/util/WeakHashSet.scala b/src/reflect/scala/reflect/internal/util/WeakHashSet.scala
index 83d2a3453b..412b14d329 100644
--- a/src/reflect/scala/reflect/internal/util/WeakHashSet.scala
+++ b/src/reflect/scala/reflect/internal/util/WeakHashSet.scala
@@ -3,7 +3,6 @@ package reflect.internal.util
import java.lang.ref.{WeakReference, ReferenceQueue}
import scala.annotation.tailrec
-import scala.collection.generic.Clearable
import scala.collection.mutable.{Set => MSet}
/**
@@ -57,9 +56,9 @@ final class WeakHashSet[A <: AnyRef](val initialCapacity: Int, val loadFactor: D
/**
* the limit at which we'll increase the size of the hash table
*/
- var threshhold = computeThreshHold
+ private[this] var threshold = computeThreshold
- private[this] def computeThreshHold: Int = (table.size * loadFactor).ceil.toInt
+ private[this] def computeThreshold: Int = (table.size * loadFactor).ceil.toInt
/**
* find the bucket associated with an element's hash code
@@ -122,7 +121,7 @@ final class WeakHashSet[A <: AnyRef](val initialCapacity: Int, val loadFactor: D
private[this] def resize() {
val oldTable = table
table = new Array[Entry[A]](oldTable.size * 2)
- threshhold = computeThreshHold
+ threshold = computeThreshold
@tailrec
def tableLoop(oldBucket: Int): Unit = if (oldBucket < oldTable.size) {
@@ -177,7 +176,7 @@ final class WeakHashSet[A <: AnyRef](val initialCapacity: Int, val loadFactor: D
def add() = {
table(bucket) = new Entry(elem, hash, oldHead, queue)
count += 1
- if (count > threshhold) resize()
+ if (count > threshold) resize()
elem
}
@@ -207,7 +206,7 @@ final class WeakHashSet[A <: AnyRef](val initialCapacity: Int, val loadFactor: D
def add() {
table(bucket) = new Entry(elem, hash, oldHead, queue)
count += 1
- if (count > threshhold) resize()
+ if (count > threshold) resize()
}
@tailrec
@@ -224,7 +223,7 @@ final class WeakHashSet[A <: AnyRef](val initialCapacity: Int, val loadFactor: D
def +=(elem: A) = this + elem
- // from scala.reflect.interanl.Set
+ // from scala.reflect.internal.Set
override def addEntry(x: A) { this += x }
// remove an element from this set and return this set
@@ -253,7 +252,7 @@ final class WeakHashSet[A <: AnyRef](val initialCapacity: Int, val loadFactor: D
// empty this set
override def clear(): Unit = {
table = new Array[Entry[A]](table.size)
- threshhold = computeThreshHold
+ threshold = computeThreshold
count = 0
// drain the queue - doesn't do anything because we're throwing away all the values anyway
@@ -403,4 +402,4 @@ object WeakHashSet {
val defaultLoadFactor = .75
def apply[A <: AnyRef](initialCapacity: Int = WeakHashSet.defaultInitialCapacity, loadFactor: Double = WeakHashSet.defaultLoadFactor) = new WeakHashSet[A](initialCapacity, defaultLoadFactor)
-} \ No newline at end of file
+}
diff --git a/src/reflect/scala/reflect/internal/util/package.scala b/src/reflect/scala/reflect/internal/util/package.scala
index 3618c150ca..ec5938b902 100644
--- a/src/reflect/scala/reflect/internal/util/package.scala
+++ b/src/reflect/scala/reflect/internal/util/package.scala
@@ -5,7 +5,6 @@ package internal
import scala.language.existentials // SI-6541
package object util {
- import StringOps.longestCommonPrefix
// An allocation-avoiding reusable instance of the so-common List(Nil).
val ListOfNil: List[List[Nothing]] = Nil :: Nil
diff --git a/src/reflect/scala/reflect/io/AbstractFile.scala b/src/reflect/scala/reflect/io/AbstractFile.scala
index bcefcc471f..ee0bc129f8 100644
--- a/src/reflect/scala/reflect/io/AbstractFile.scala
+++ b/src/reflect/scala/reflect/io/AbstractFile.scala
@@ -8,10 +8,9 @@ package scala
package reflect
package io
-import java.io.{ FileOutputStream, IOException, InputStream, OutputStream, BufferedOutputStream, ByteArrayOutputStream }
+import java.io.{ IOException, InputStream, OutputStream, BufferedOutputStream, ByteArrayOutputStream }
import java.io.{ File => JFile }
import java.net.URL
-import scala.collection.mutable.ArrayBuffer
import scala.reflect.internal.util.Statistics
/**
diff --git a/src/reflect/scala/reflect/io/File.scala b/src/reflect/scala/reflect/io/File.scala
index a9c6807e88..206861adb3 100644
--- a/src/reflect/scala/reflect/io/File.scala
+++ b/src/reflect/scala/reflect/io/File.scala
@@ -6,20 +6,16 @@
** |/ **
\* */
-
package scala
package reflect
package io
import java.io.{
- FileInputStream, FileOutputStream, BufferedReader, BufferedWriter, InputStreamReader, OutputStreamWriter,
- BufferedInputStream, BufferedOutputStream, IOException, PrintStream, PrintWriter, Closeable => JCloseable,
- File => JFile
+ FileInputStream, FileOutputStream, BufferedWriter, OutputStreamWriter,
+ BufferedOutputStream, IOException, PrintWriter, File => JFile
}
-import java.nio.channels.{ Channel, FileChannel }
import scala.io.Codec
-import scala.language.{reflectiveCalls, implicitConversions}
/**
* ''Note: This library is considered experimental and should not be used unless you know what you are doing.''
*/
diff --git a/src/reflect/scala/reflect/io/Path.scala b/src/reflect/scala/reflect/io/Path.scala
index 15fce953f2..5f93506015 100644
--- a/src/reflect/scala/reflect/io/Path.scala
+++ b/src/reflect/scala/reflect/io/Path.scala
@@ -7,12 +7,11 @@ package scala
package reflect
package io
-import java.io.{
- FileInputStream, FileOutputStream, BufferedReader, BufferedWriter, InputStreamReader, OutputStreamWriter,
- BufferedInputStream, BufferedOutputStream, RandomAccessFile, File => JFile }
+import scala.language.implicitConversions
+
+import java.io.{ RandomAccessFile, File => JFile }
import java.net.{ URI, URL }
import scala.util.Random.alphanumeric
-import scala.language.implicitConversions
import scala.reflect.internal.util.Statistics
/** An abstraction for filesystem paths. The differences between
diff --git a/src/reflect/scala/reflect/io/PlainFile.scala b/src/reflect/scala/reflect/io/PlainFile.scala
index 8f24d84488..eb0940e703 100644
--- a/src/reflect/scala/reflect/io/PlainFile.scala
+++ b/src/reflect/scala/reflect/io/PlainFile.scala
@@ -7,8 +7,6 @@ package scala
package reflect
package io
-import java.io.{ FileInputStream, FileOutputStream, IOException }
-
/** ''Note: This library is considered experimental and should not be used unless you know what you are doing.'' */
class PlainDirectory(givenPath: Directory) extends PlainFile(givenPath) {
override def isDirectory = true
diff --git a/src/reflect/scala/reflect/io/Streamable.scala b/src/reflect/scala/reflect/io/Streamable.scala
index 99a14d1fb0..bc4031ca9b 100644
--- a/src/reflect/scala/reflect/io/Streamable.scala
+++ b/src/reflect/scala/reflect/io/Streamable.scala
@@ -7,8 +7,8 @@ package scala
package reflect
package io
-import java.net.{ URI, URL }
-import java.io.{ BufferedInputStream, InputStream, PrintStream }
+import java.net.URL
+import java.io.{ BufferedInputStream, InputStream }
import java.io.{ BufferedReader, InputStreamReader, Closeable => JCloseable }
import scala.io.{ Codec, BufferedSource, Source }
import scala.collection.mutable.ArrayBuffer
diff --git a/src/reflect/scala/reflect/io/ZipArchive.scala b/src/reflect/scala/reflect/io/ZipArchive.scala
index 0c63acb86c..262ab22ce9 100644
--- a/src/reflect/scala/reflect/io/ZipArchive.scala
+++ b/src/reflect/scala/reflect/io/ZipArchive.scala
@@ -12,8 +12,8 @@ import java.io.{ IOException, InputStream, ByteArrayInputStream, FilterInputStre
import java.io.{ File => JFile }
import java.util.zip.{ ZipEntry, ZipFile, ZipInputStream }
import java.util.jar.Manifest
-import scala.collection.{ immutable, mutable }
-import scala.collection.convert.WrapAsScala.asScalaIterator
+import scala.collection.mutable
+import scala.collection.JavaConverters._
import scala.annotation.tailrec
/** An abstraction for zip files and streams. Everything is written the way
@@ -238,7 +238,7 @@ final class ManifestResources(val url: URL) extends ZipArchive(null) {
val root = new DirEntry("/")
val dirs = mutable.HashMap[String, DirEntry]("/" -> root)
val manifest = new Manifest(input)
- val iter = manifest.getEntries().keySet().iterator().filter(_.endsWith(".class")).map(new ZipEntry(_))
+ val iter = manifest.getEntries().keySet().iterator().asScala.filter(_.endsWith(".class")).map(new ZipEntry(_))
for (zipEntry <- iter) {
val dir = getDir(dirs, zipEntry)
diff --git a/src/reflect/scala/reflect/macros/Enclosures.scala b/src/reflect/scala/reflect/macros/Enclosures.scala
index 1eb6832b5b..798fed2a15 100644
--- a/src/reflect/scala/reflect/macros/Enclosures.scala
+++ b/src/reflect/scala/reflect/macros/Enclosures.scala
@@ -2,8 +2,6 @@ package scala
package reflect
package macros
-import scala.language.existentials // SI-6541
-
/**
* <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
*
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index 50442519f2..9b0d66f41c 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -2,24 +2,24 @@ package scala
package reflect
package runtime
+import scala.language.existentials
+
import scala.ref.WeakReference
import scala.collection.mutable.WeakHashMap
import java.lang.{Class => jClass, Package => jPackage}
import java.lang.reflect.{
Method => jMethod, Constructor => jConstructor, Field => jField,
- Member => jMember, Type => jType, TypeVariable => jTypeVariable, Array => jArray,
- AccessibleObject => jAccessibleObject,
+ Member => jMember, Type => jType, TypeVariable => jTypeVariable,
GenericDeclaration, GenericArrayType, ParameterizedType, WildcardType, AnnotatedElement }
import java.lang.annotation.{Annotation => jAnnotation}
import java.io.IOException
-import scala.reflect.internal.{ MissingRequirementError, JavaAccFlags, JMethodOrConstructor }
+import scala.reflect.internal.{ MissingRequirementError, JavaAccFlags }
import internal.pickling.ByteCodecs
import internal.pickling.UnPickler
-import scala.collection.mutable.{ HashMap, ListBuffer, ArrayBuffer }
+import scala.collection.mutable.ListBuffer
import internal.Flags._
import ReflectionUtils._
-import scala.language.existentials
import scala.runtime.{ScalaRunTime, BoxesRunTime}
private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse with TwoWayCaches { thisUniverse: SymbolTable =>
@@ -154,7 +154,7 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive
}
def apply(schemaAndValue: (jClass[_], Any)): ClassfileAnnotArg = schemaAndValue match {
case ConstantArg(value) => LiteralAnnotArg(Constant(value))
- case (clazz @ ArrayClass(), value: Array[_]) => ArrayAnnotArg(value map (x => apply(ScalaRunTime.arrayElementClass(clazz) -> x)))
+ case (clazz @ ArrayClass(), value: Array[_]) => ArrayAnnotArg(value map (x => apply(clazz.getComponentType -> x)))
case (AnnotationClass(), value: jAnnotation) => NestedAnnotArg(JavaAnnotationProxy(value))
case _ => UnmappableAnnotArg
}
@@ -475,9 +475,9 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive
}
symbol match {
- case Any_== | Object_== => ScalaRunTime.inlinedEquals(objReceiver, objArg0)
- case Any_!= | Object_!= => !ScalaRunTime.inlinedEquals(objReceiver, objArg0)
- case Any_## | Object_## => ScalaRunTime.hash(objReceiver)
+ case Any_== | Object_== => objReceiver == objArg0
+ case Any_!= | Object_!= => objReceiver != objArg0
+ case Any_## | Object_## => objReceiver.##
case Any_equals => receiver.equals(objArg0)
case Any_hashCode => receiver.hashCode
case Any_toString => receiver.toString
@@ -613,7 +613,7 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive
loadBytes[String]("scala.reflect.ScalaSignature") match {
case Some(ssig) =>
info(s"unpickling Scala $clazz and $module, owner = ${clazz.owner}")
- val bytes = ssig.getBytes
+ val bytes = ssig.getBytes(java.nio.charset.StandardCharsets.UTF_8)
val len = ByteCodecs.decode(bytes)
assignAssociatedFile(clazz, module, jclazz)
unpickler.unpickle(bytes take len, 0, clazz, module, jclazz.getName)
@@ -622,7 +622,7 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive
loadBytes[Array[String]]("scala.reflect.ScalaLongSignature") match {
case Some(slsig) =>
info(s"unpickling Scala $clazz and $module with long Scala signature")
- val encoded = slsig flatMap (_.getBytes)
+ val encoded = slsig flatMap (_.getBytes(java.nio.charset.StandardCharsets.UTF_8))
val len = ByteCodecs.decode(encoded)
val decoded = encoded.take(len)
assignAssociatedFile(clazz, module, jclazz)
@@ -999,9 +999,9 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive
}
val cls =
- if (jclazz.isMemberClass && !nme.isImplClassName(jname))
+ if (jclazz.isMemberClass)
lookupClass
- else if (jclazz.isLocalClass0 || scalacShouldntLoadClass(jname))
+ else if (jclazz.isLocalClass0)
// local classes and implementation classes not preserved by unpickling - treat as Java
//
// upd. but only if they cannot be loaded as top-level classes
@@ -1161,6 +1161,7 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive
propagatePackageBoundary(jmeth.javaFlags, meth)
copyAnnotations(meth, jmeth)
if (jmeth.javaFlags.isVarargs) meth modifyInfo arrayToRepeated
+ if (jmeth.getDefaultValue != null) meth.addAnnotation(AnnotationDefaultAttr)
markAllCompleted(meth)
meth
}
diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
index 7725e4a2f0..d50debd7ee 100644
--- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
+++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
@@ -37,10 +37,13 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.FixedMirrorTreeCreator
this.FixedMirrorTypeCreator
this.CompoundTypeTreeOriginalAttachment
+ this.SAMFunction
this.BackquotedIdentifierAttachment
this.ForAttachment
this.SyntheticUnitAttachment
this.SubpatternsAttachment
+ this.NoInlineCallsiteAttachment
+ this.InlineCallsiteAttachment
this.noPrint
this.typeDebug
this.Range
@@ -264,7 +267,9 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
definitions.IterableClass
definitions.ListClass
definitions.SeqClass
- definitions.StringBuilderClass
+ definitions.JavaStringBuilderClass
+ definitions.JavaStringBufferClass
+ definitions.JavaCharSequenceClass
definitions.TraversableClass
definitions.ListModule
definitions.NilModule
@@ -280,6 +285,9 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
definitions.MethodClass
definitions.EmptyMethodCacheClass
definitions.MethodCacheClass
+ definitions.StructuralCallSite
+ definitions.StructuralCallSite_dummy
+ definitions.SymbolLiteral
definitions.ScalaXmlTopScope
definitions.ScalaXmlPackage
definitions.ReflectPackage
@@ -311,7 +319,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
definitions.QuasiquoteClass_api_unapply
definitions.ScalaSignatureAnnotation
definitions.ScalaLongSignatureAnnotation
- definitions.LambdaMetaFactory
definitions.MethodHandle
definitions.OptionClass
definitions.OptionModule
@@ -369,6 +376,8 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
definitions.BridgeClass
definitions.ElidableMethodClass
definitions.ImplicitNotFoundClass
+ definitions.ImplicitAmbiguousClass
+ definitions.JUnitTestClass
definitions.MigrationAnnotationClass
definitions.ScalaStrictFPAttr
definitions.SwitchClass
@@ -421,6 +430,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
definitions.boxedClass
definitions.refClass
definitions.volatileRefClass
+ definitions.allRefClasses
definitions.UnitClass
definitions.ByteClass
definitions.ShortClass
diff --git a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala
index a278ed3fd7..dd15a09b7e 100644
--- a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala
+++ b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala
@@ -10,7 +10,6 @@ import java.lang.{Class => jClass}
import java.lang.reflect.{ Method, InvocationTargetException, UndeclaredThrowableException }
import scala.reflect.internal.util.AbstractFileClassLoader
import scala.reflect.io._
-import java.io.{File => JFile}
/** A few java-reflection oriented utility functions useful during reflection bootstrapping.
*/
@@ -81,12 +80,6 @@ object ReflectionUtils {
accessor invoke outer
}
- def isTraitImplementation(fileName: String) = fileName endsWith "$class.class"
-
- def scalacShouldntLoadClassfile(fileName: String) = isTraitImplementation(fileName)
-
- def scalacShouldntLoadClass(name: scala.reflect.internal.SymbolTable#Name) = scalacShouldntLoadClassfile(name + ".class")
-
object PrimitiveOrArray {
def unapply(jclazz: jClass[_]) = jclazz.isPrimitive || jclazz.isArray
}
diff --git a/src/reflect/scala/reflect/runtime/Settings.scala b/src/reflect/scala/reflect/runtime/Settings.scala
index 27d574b1de..b1d7fde1b4 100644
--- a/src/reflect/scala/reflect/runtime/Settings.scala
+++ b/src/reflect/scala/reflect/runtime/Settings.scala
@@ -51,4 +51,5 @@ private[reflect] class Settings extends MutableSettings {
val Yrecursion = new IntSetting(0)
val maxClassfileName = new IntSetting(255)
def isScala211 = true
+ def isScala212 = true
}
diff --git a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala
index 9ce6331e33..768a3d5ce5 100644
--- a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala
+++ b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala
@@ -2,10 +2,7 @@ package scala
package reflect
package runtime
-import internal.Flags
-import java.lang.{Class => jClass, Package => jPackage}
import scala.collection.mutable
-import scala.reflect.runtime.ReflectionUtils.scalacShouldntLoadClass
import scala.reflect.internal.Flags._
private[reflect] trait SymbolLoaders { self: SymbolTable =>
@@ -127,7 +124,7 @@ private[reflect] trait SymbolLoaders { self: SymbolTable =>
val e = super.lookupEntry(name)
if (e != null)
e
- else if (scalacShouldntLoadClass(name) || (negatives contains name))
+ else if (negatives contains name)
null
else {
val path =
diff --git a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala
index 4f0c0253e9..313ec89311 100644
--- a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala
+++ b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala
@@ -176,9 +176,6 @@ private[reflect] trait SynchronizedSymbols extends internal.Symbols { self: Symb
override protected def createRefinementClassSymbol(pos: Position, newFlags: Long): RefinementClassSymbol =
new RefinementClassSymbol(this, pos) with SynchronizedClassSymbol initFlags newFlags
- override protected def createImplClassSymbol(name: TypeName, pos: Position, newFlags: Long): ClassSymbol =
- new ClassSymbol(this, pos, name) with ImplClassSymbol with SynchronizedClassSymbol initFlags newFlags
-
override protected def createPackageObjectClassSymbol(pos: Position, newFlags: Long): PackageObjectClassSymbol =
new PackageObjectClassSymbol(this, pos) with SynchronizedClassSymbol initFlags newFlags