diff options
Diffstat (limited to 'src/reflect')
15 files changed, 82 insertions, 55 deletions
diff --git a/src/reflect/scala/reflect/internal/AnnotationInfos.scala b/src/reflect/scala/reflect/internal/AnnotationInfos.scala index b923541b56..c0772c8cc0 100644 --- a/src/reflect/scala/reflect/internal/AnnotationInfos.scala +++ b/src/reflect/scala/reflect/internal/AnnotationInfos.scala @@ -30,12 +30,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 +169,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 +416,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/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 5ce5c39145..35b08e72c4 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -518,7 +518,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 diff --git a/src/reflect/scala/reflect/internal/Internals.scala b/src/reflect/scala/reflect/internal/Internals.scala index ad4cec5b4d..acf000ebc5 100644 --- a/src/reflect/scala/reflect/internal/Internals.scala +++ b/src/reflect/scala/reflect/internal/Internals.scala @@ -60,19 +60,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 +158,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/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/StdAttachments.scala b/src/reflect/scala/reflect/internal/StdAttachments.scala index cca33253be..8358c1295c 100644 --- a/src/reflect/scala/reflect/internal/StdAttachments.scala +++ b/src/reflect/scala/reflect/internal/StdAttachments.scala @@ -52,4 +52,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/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 3d87035f88..14afd0d42d 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -2964,7 +2964,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]) diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala index 49554d6d0f..d63c23b992 100644 --- a/src/reflect/scala/reflect/internal/Trees.scala +++ b/src/reflect/scala/reflect/internal/Trees.scala @@ -1468,8 +1468,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 { diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 33592bbd86..5b23bbf144 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -2496,6 +2496,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 @@ -3938,7 +3940,8 @@ trait Types def maybeCreateDummyClone(pre: Type, sym: Symbol): Type = pre match { case SingleType(pre1, sym1) => if (sym1.isModule && sym1.isStatic) { - NoType + if (sym.owner == sym1 || sym.isJavaDefined || sym.owner.sourceModule.isStaticModule) NoType + else pre } else if (sym1.isModule && sym.owner == sym1.moduleClass) { val pre2 = maybeCreateDummyClone(pre1, sym1) if (pre2 eq NoType) pre2 diff --git a/src/reflect/scala/reflect/internal/Variances.scala b/src/reflect/scala/reflect/internal/Variances.scala index ef22df3f2e..af04f47e0e 100644 --- a/src/reflect/scala/reflect/internal/Variances.scala +++ b/src/reflect/scala/reflect/internal/Variances.scala @@ -122,15 +122,21 @@ trait Variances { * same is true of the parameters (ValDefs) unless we are inside a * refinement, in which case they are checked from here. */ - def apply(tp: Type): Type = tp match { - case _ if isUncheckedVariance(tp) => tp - case _ if resultTypeOnly(tp) => this(tp.resultType) - case TypeRef(_, sym, _) if sym.isAliasType => this(tp.normalize) - case TypeRef(_, sym, _) if !sym.variance.isInvariant => checkVarianceOfSymbol(sym) ; mapOver(tp) - case RefinedType(_, _) => withinRefinement(mapOver(tp)) - case ClassInfoType(parents, _, _) => parents foreach this ; tp - case mt @ MethodType(_, result) => flipped(mt.paramTypes foreach this) ; this(result) - case _ => mapOver(tp) + def apply(tp: Type): Type = { + tp match { + case _ if isUncheckedVariance(tp) => + case _ if resultTypeOnly(tp) => this(tp.resultType) + case TypeRef(_, sym, _) if sym.isAliasType => this(tp.normalize) + case TypeRef(_, sym, _) if !sym.variance.isInvariant => checkVarianceOfSymbol(sym) ; mapOver(tp) + case RefinedType(_, _) => withinRefinement(mapOver(tp)) + case ClassInfoType(parents, _, _) => parents foreach this + case mt @ MethodType(_, result) => flipped(mt.paramTypes foreach this) ; this(result) + case _ => mapOver(tp) + } + // We're using TypeMap here for type traversal only. To avoid wasteful symbol + // cloning during the recursion, it is important to return the input `tp`, rather + // than the result of the pattern match above, which normalizes types. + tp } def validateDefinition(base: Symbol) { val saved = this.base diff --git a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala index 28a7fb37a6..af5128163b 100644 --- a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala +++ b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala @@ -1001,10 +1001,20 @@ private[internal] trait TypeMaps { class ContainsCollector(sym: Symbol) extends TypeCollector(false) { def traverse(tp: Type) { if (!result) { - tp.normalize match { - case TypeRef(_, sym1, _) if (sym == sym1) => result = true - case SingleType(_, sym1) if (sym == sym1) => result = true - case _ => mapOver(tp) + tp match { + case _: ExistentialType => + // ExistentialType#normalize internally calls contains, which leads to exponential performance + // for types like: `A[_ <: B[_ <: ... ]]`. Example: pos/existential-contains.scala. + // + // We can just map over the components and wait until we see the underlying type before we call + // normalize. + mapOver(tp) + case _ => + tp.normalize match { + case TypeRef(_, sym1, _) if (sym == sym1) => result = true + case SingleType(_, sym1) if (sym == sym1) => result = true + case _ => mapOver(tp) + } } } } diff --git a/src/reflect/scala/reflect/internal/util/WeakHashSet.scala b/src/reflect/scala/reflect/internal/util/WeakHashSet.scala index 3a7a7626fb..83d2a3453b 100644 --- a/src/reflect/scala/reflect/internal/util/WeakHashSet.scala +++ b/src/reflect/scala/reflect/internal/util/WeakHashSet.scala @@ -41,7 +41,7 @@ final class WeakHashSet[A <: AnyRef](val initialCapacity: Int, val loadFactor: D * power of two equal to or greater than the specified initial capacity */ private def computeCapacity = { - if (initialCapacity < 0) throw new IllegalArgumentException("initial capacity cannot be less than 0"); + if (initialCapacity < 0) throw new IllegalArgumentException("initial capacity cannot be less than 0") var candidate = 1 while (candidate < initialCapacity) { candidate *= 2 @@ -372,13 +372,13 @@ final class WeakHashSet[A <: AnyRef](val initialCapacity: Int, val loadFactor: D * Number of buckets that hold collisions. Useful for diagnosing performance issues. */ def collisionBucketsCount: Int = - (table filter (entry => entry != null && entry.tail != null)).size + (table count (entry => entry != null && entry.tail != null)) /** * Number of buckets that are occupied in this hash table. */ def fullBucketsCount: Int = - (table filter (entry => entry != null)).size + (table count (entry => entry != null)) /** * Number of buckets in the table diff --git a/src/reflect/scala/reflect/macros/Attachments.scala b/src/reflect/scala/reflect/macros/Attachments.scala index b5c340645a..0b5360c004 100644 --- a/src/reflect/scala/reflect/macros/Attachments.scala +++ b/src/reflect/scala/reflect/macros/Attachments.scala @@ -39,7 +39,7 @@ abstract class Attachments { self => /** An underlying payload of the given class type `T`. */ def get[T: ClassTag]: Option[T] = - (all filter matchesTag[T]).headOption.asInstanceOf[Option[T]] + (all find matchesTag[T]).asInstanceOf[Option[T]] /** Check underlying payload contains an instance of type `T`. */ def contains[T: ClassTag]: Boolean = diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala index 1e9a4fe8a5..a9b91b5ec3 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala @@ -41,6 +41,8 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => this.ForAttachment this.SyntheticUnitAttachment this.SubpatternsAttachment + this.NoInlineCallsiteAttachment + this.InlineCallsiteAttachment this.noPrint this.typeDebug this.Range @@ -311,7 +313,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.QuasiquoteClass_api_unapply definitions.ScalaSignatureAnnotation definitions.ScalaLongSignatureAnnotation - definitions.LambdaMetaFactory definitions.MethodHandle definitions.OptionClass definitions.OptionModule diff --git a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala index a4bd698068..a278ed3fd7 100644 --- a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala +++ b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala @@ -72,7 +72,7 @@ object ReflectionUtils { def singletonAccessor(clazz: Class[_]): Option[Method] = if (clazz == null) None else { - val declaredAccessor = clazz.getDeclaredMethods.filter(_.getName == accessorName).headOption + val declaredAccessor = clazz.getDeclaredMethods.find(_.getName == accessorName) declaredAccessor orElse singletonAccessor(clazz.getSuperclass) } @@ -92,7 +92,7 @@ object ReflectionUtils { } class EnclosedIn[T](enclosure: jClass[_] => T) { - def unapply(jclazz: jClass[_]): Option[T] = if (enclosure(jclazz) != null) Some(enclosure(jclazz)) else None + def unapply(jclazz: jClass[_]): Option[T] = Option(enclosure(jclazz)) } object EnclosedInMethod extends EnclosedIn(_.getEnclosingMethod) diff --git a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala index 4a8585d616..f0d96e0fd6 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala +++ b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala @@ -15,7 +15,7 @@ private[reflect] trait SynchronizedOps extends internal.SymbolTable override protected def newBaseTypeSeq(parents: List[Type], elems: Array[Type]) = // only need to synchronize BaseTypeSeqs if they contain refined types - if (elems.filter(_.isInstanceOf[RefinedType]).nonEmpty) new BaseTypeSeq(parents, elems) with SynchronizedBaseTypeSeq + if (elems.exists(_.isInstanceOf[RefinedType])) new BaseTypeSeq(parents, elems) with SynchronizedBaseTypeSeq else new BaseTypeSeq(parents, elems) trait SynchronizedBaseTypeSeq extends BaseTypeSeq { @@ -31,7 +31,7 @@ private[reflect] trait SynchronizedOps extends internal.SymbolTable override def lateMap(f: Type => Type): BaseTypeSeq = // only need to synchronize BaseTypeSeqs if they contain refined types - if (map(f).toList.filter(_.isInstanceOf[RefinedType]).nonEmpty) new MappedBaseTypeSeq(this, f) with SynchronizedBaseTypeSeq + if (map(f).toList.exists(_.isInstanceOf[RefinedType])) new MappedBaseTypeSeq(this, f) with SynchronizedBaseTypeSeq else new MappedBaseTypeSeq(this, f) } |