diff options
Diffstat (limited to 'src/reflect/scala')
57 files changed, 695 insertions, 589 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..d2312440cc 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,7 @@ trait Definitions extends api.StandardDefinitions { lazy val BridgeClass = requiredClass[scala.annotation.bridge] lazy val ElidableMethodClass = requiredClass[scala.annotation.elidable] lazy val ImplicitNotFoundClass = requiredClass[scala.annotation.implicitNotFound] + lazy val ImplicitAmbiguousClass = getClassIfDefined("scala.annotation.implicitAmbiguous") lazy val MigrationAnnotationClass = requiredClass[scala.annotation.migration] lazy val ScalaStrictFPAttr = requiredClass[scala.annotation.strictfp] lazy val SwitchClass = requiredClass[scala.annotation.switch] @@ -1393,8 +1442,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 +1566,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..c069e2c198 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,9 @@ trait Erasure { protected def eraseDerivedValueClassRef(tref: TypeRef): Type = erasedValueClassArg(tref) def apply(tp: Type): Type = tp match { - case ConstantType(_) => - tp + case ConstantType(ct) => + if (ct.tag == ClazzTag) ConstantType(Constant(apply(ct.typeValue))) + else tp case st: ThisType if st.sym.isPackageClass => tp case st: SubType => @@ -123,7 +122,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 @@ -282,8 +281,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..42e22fda6f 100644 --- a/src/reflect/scala/reflect/io/ZipArchive.scala +++ b/src/reflect/scala/reflect/io/ZipArchive.scala @@ -12,7 +12,7 @@ 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.mutable import scala.collection.convert.WrapAsScala.asScalaIterator import scala.annotation.tailrec 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..37b07ce775 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 @@ -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..4630597668 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,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.BridgeClass definitions.ElidableMethodClass definitions.ImplicitNotFoundClass + definitions.ImplicitAmbiguousClass definitions.MigrationAnnotationClass definitions.ScalaStrictFPAttr definitions.SwitchClass @@ -421,6 +429,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 |