diff options
Diffstat (limited to 'src/reflect')
-rw-r--r-- | src/reflect/scala/reflect/api/ImplicitTags.scala | 108 | ||||
-rw-r--r-- | src/reflect/scala/reflect/api/Symbols.scala | 2 | ||||
-rw-r--r-- | src/reflect/scala/reflect/api/Types.scala | 107 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Flags.scala | 2 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Symbols.scala | 133 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Types.scala | 2 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/util/Statistics.scala | 2 |
7 files changed, 193 insertions, 163 deletions
diff --git a/src/reflect/scala/reflect/api/ImplicitTags.scala b/src/reflect/scala/reflect/api/ImplicitTags.scala new file mode 100644 index 0000000000..3f377d6cff --- /dev/null +++ b/src/reflect/scala/reflect/api/ImplicitTags.scala @@ -0,0 +1,108 @@ +package scala.reflect +package api + +trait ImplicitTags { + self: Types => + + /** A tag that preserves the identity of the `Type` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val TypeTagg: ClassTag[Type] + + /** A tag that preserves the identity of the `SingletonType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val SingletonTypeTag: ClassTag[SingletonType] + + /** A tag that preserves the identity of the `ThisType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val ThisTypeTag: ClassTag[ThisType] + + /** A tag that preserves the identity of the `SingleType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val SingleTypeTag: ClassTag[SingleType] + + /** A tag that preserves the identity of the `SuperType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val SuperTypeTag: ClassTag[SuperType] + + /** A tag that preserves the identity of the `ConstantType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val ConstantTypeTag: ClassTag[ConstantType] + + /** A tag that preserves the identity of the `TypeRef` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val TypeRefTag: ClassTag[TypeRef] + + /** A tag that preserves the identity of the `CompoundType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val CompoundTypeTag: ClassTag[CompoundType] + + /** A tag that preserves the identity of the `RefinedType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val RefinedTypeTag: ClassTag[RefinedType] + + /** A tag that preserves the identity of the `ClassInfoType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val ClassInfoTypeTag: ClassTag[ClassInfoType] + + /** A tag that preserves the identity of the `MethodType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val MethodTypeTag: ClassTag[MethodType] + + /** A tag that preserves the identity of the `NullaryMethodType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val NullaryMethodTypeTag: ClassTag[NullaryMethodType] + + /** A tag that preserves the identity of the `PolyType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val PolyTypeTag: ClassTag[PolyType] + + /** A tag that preserves the identity of the `ExistentialType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val ExistentialTypeTag: ClassTag[ExistentialType] + + /** A tag that preserves the identity of the `AnnotatedType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val AnnotatedTypeTag: ClassTag[AnnotatedType] + + /** A tag that preserves the identity of the `TypeBounds` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val TypeBoundsTag: ClassTag[TypeBounds] + + /** A tag that preserves the identity of the `BoundedWildcardType` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + * @group Tags + */ + implicit val BoundedWildcardTypeTag: ClassTag[BoundedWildcardType] +} diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala index a4a4277239..dbad3dd478 100644 --- a/src/reflect/scala/reflect/api/Symbols.scala +++ b/src/reflect/scala/reflect/api/Symbols.scala @@ -946,7 +946,7 @@ trait Symbols { self: Universe => def knownDirectSubclasses: Set[Symbol] /** The list of all base classes of this type (including its own typeSymbol) - * in reverse linearization order, starting with the class itself and ending + * in linearization order, starting with the class itself and ending * in class Any. * * @group Class diff --git a/src/reflect/scala/reflect/api/Types.scala b/src/reflect/scala/reflect/api/Types.scala index 143438b8f5..e5140f23e5 100644 --- a/src/reflect/scala/reflect/api/Types.scala +++ b/src/reflect/scala/reflect/api/Types.scala @@ -50,7 +50,8 @@ package api * * @contentDiagram hideNodes "*Api" */ -trait Types { self: Universe => +trait Types extends ImplicitTags { + self: Universe => /** The type of Scala types, and also Scala type signatures. * (No difference is internally made between the two). @@ -59,12 +60,6 @@ trait Types { self: Universe => */ type Type >: Null <: TypeApi - /** A tag that preserves the identity of the `Type` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val TypeTagg: ClassTag[Type] - /** This constant is used as a special value that indicates that no meaningful type exists. * @group Types */ @@ -149,7 +144,7 @@ trait Types { self: Universe => def =:= (that: Type): Boolean /** The list of all base classes of this type (including its own typeSymbol) - * in reverse linearization order, starting with the class itself and ending + * in linearization order, starting with the class itself and ending * in class Any. */ def baseClasses: List[Symbol] @@ -256,12 +251,6 @@ trait Types { self: Universe => */ type SingletonType >: Null <: Type - /** A tag that preserves the identity of the `SingletonType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val SingletonTypeTag: ClassTag[SingletonType] - /** A singleton type that describes types of the form on the left with the * corresponding `ThisType` representation to the right: * {{{ @@ -272,12 +261,6 @@ trait Types { self: Universe => */ type ThisType >: Null <: AnyRef with SingletonType with ThisTypeApi - /** A tag that preserves the identity of the `ThisType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val ThisTypeTag: ClassTag[ThisType] - /** The constructor/extractor for `ThisType` instances. * @group Extractors */ @@ -316,12 +299,6 @@ trait Types { self: Universe => */ type SingleType >: Null <: AnyRef with SingletonType with SingleTypeApi - /** A tag that preserves the identity of the `SingleType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val SingleTypeTag: ClassTag[SingleType] - /** The constructor/extractor for `SingleType` instances. * @group Extractors */ @@ -361,12 +338,6 @@ trait Types { self: Universe => */ type SuperType >: Null <: AnyRef with SingletonType with SuperTypeApi - /** A tag that preserves the identity of the `SuperType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val SuperTypeTag: ClassTag[SuperType] - /** The constructor/extractor for `SuperType` instances. * @group Extractors */ @@ -406,12 +377,6 @@ trait Types { self: Universe => */ type ConstantType >: Null <: AnyRef with SingletonType with ConstantTypeApi - /** A tag that preserves the identity of the `ConstantType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val ConstantTypeTag: ClassTag[ConstantType] - /** The constructor/extractor for `ConstantType` instances. * @group Extractors */ @@ -450,12 +415,6 @@ trait Types { self: Universe => */ type TypeRef >: Null <: AnyRef with Type with TypeRefApi - /** A tag that preserves the identity of the `TypeRef` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val TypeRefTag: ClassTag[TypeRef] - /** The constructor/extractor for `TypeRef` instances. * @group Extractors */ @@ -497,12 +456,6 @@ trait Types { self: Universe => */ type CompoundType >: Null <: AnyRef with Type - /** A tag that preserves the identity of the `CompoundType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val CompoundTypeTag: ClassTag[CompoundType] - /** The `RefinedType` type defines types of any of the forms on the left, * with their RefinedType representations to the right. * {{{ @@ -515,12 +468,6 @@ trait Types { self: Universe => */ type RefinedType >: Null <: AnyRef with CompoundType with RefinedTypeApi - /** A tag that preserves the identity of the `RefinedType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val RefinedTypeTag: ClassTag[RefinedType] - /** The constructor/extractor for `RefinedType` instances. * @group Extractors */ @@ -567,12 +514,6 @@ trait Types { self: Universe => */ type ClassInfoType >: Null <: AnyRef with CompoundType with ClassInfoTypeApi - /** A tag that preserves the identity of the `ClassInfoType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val ClassInfoTypeTag: ClassTag[ClassInfoType] - /** The constructor/extractor for `ClassInfoType` instances. * @group Extractors */ @@ -610,12 +551,6 @@ trait Types { self: Universe => */ type MethodType >: Null <: AnyRef with Type with MethodTypeApi - /** A tag that preserves the identity of the `MethodType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val MethodTypeTag: ClassTag[MethodType] - /** The constructor/extractor for `MethodType` instances. * @group Extractors */ @@ -660,12 +595,6 @@ trait Types { self: Universe => */ type NullaryMethodType >: Null <: AnyRef with Type with NullaryMethodTypeApi - /** A tag that preserves the identity of the `NullaryMethodType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val NullaryMethodTypeTag: ClassTag[NullaryMethodType] - /** The constructor/extractor for `NullaryMethodType` instances. * @group Extractors */ @@ -696,12 +625,6 @@ trait Types { self: Universe => */ type PolyType >: Null <: AnyRef with Type with PolyTypeApi - /** A tag that preserves the identity of the `PolyType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val PolyTypeTag: ClassTag[PolyType] - /** The constructor/extractor for `PolyType` instances. * @group Extractors */ @@ -736,12 +659,6 @@ trait Types { self: Universe => */ type ExistentialType >: Null <: AnyRef with Type with ExistentialTypeApi - /** A tag that preserves the identity of the `ExistentialType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val ExistentialTypeTag: ClassTag[ExistentialType] - /** The constructor/extractor for `ExistentialType` instances. * @group Extractors */ @@ -777,12 +694,6 @@ trait Types { self: Universe => */ type AnnotatedType >: Null <: AnyRef with Type with AnnotatedTypeApi - /** A tag that preserves the identity of the `AnnotatedType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val AnnotatedTypeTag: ClassTag[AnnotatedType] - /** The constructor/extractor for `AnnotatedType` instances. * @group Extractors */ @@ -828,12 +739,6 @@ trait Types { self: Universe => */ type TypeBounds >: Null <: AnyRef with Type with TypeBoundsApi - /** A tag that preserves the identity of the `TypeBounds` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val TypeBoundsTag: ClassTag[TypeBounds] - /** The constructor/extractor for `TypeBounds` instances. * @group Extractors */ @@ -885,12 +790,6 @@ trait Types { self: Universe => */ type BoundedWildcardType >: Null <: AnyRef with Type with BoundedWildcardTypeApi - /** A tag that preserves the identity of the `BoundedWildcardType` abstract type from erasure. - * Can be used for pattern matching, instance tests, serialization and likes. - * @group Tags - */ - implicit val BoundedWildcardTypeTag: ClassTag[BoundedWildcardType] - /** The constructor/extractor for `BoundedWildcardType` instances. * @group Extractors */ diff --git a/src/reflect/scala/reflect/internal/Flags.scala b/src/reflect/scala/reflect/internal/Flags.scala index 45c5279574..06f6c46fc3 100644 --- a/src/reflect/scala/reflect/internal/Flags.scala +++ b/src/reflect/scala/reflect/internal/Flags.scala @@ -287,7 +287,7 @@ class Flags extends ModifierFlags { * from Modifiers. Others which may be applied at creation time are: * SYNTHETIC. */ - final val ValueParameterFlags = BYNAMEPARAM | IMPLICIT | DEFAULTPARAM | STABLE + final val ValueParameterFlags = BYNAMEPARAM | IMPLICIT | DEFAULTPARAM | STABLE | SYNTHETIC final val BeanPropertyFlags = DEFERRED | OVERRIDE | STATIC final val VarianceFlags = COVARIANT | CONTRAVARIANT diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 4f6dab3e7c..fbf14e8156 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -853,12 +853,13 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Is this a term symbol only defined in a refinement (so that it needs * to be accessed by reflection)? */ - def isOnlyRefinementMember: Boolean = + def isOnlyRefinementMember: Boolean = ( isTerm && // type members are not affected owner.isRefinementClass && // owner must be a refinement class (owner.info decl name) == this && // symbol must be explicitly declared in the refinement (not synthesized from glb) - allOverriddenSymbols.isEmpty && // symbol must not override a symbol in a base class + !isOverridingSymbol && // symbol must not override a symbol in a base class !isConstant // symbol must not be a constant. Question: Can we exclude @inline methods as well? + ) final def isStructuralRefinementMember = owner.isStructuralRefinement && isPossibleInRefinement && isPublic final def isPossibleInRefinement = !isConstructor && !isOverridingSymbol @@ -960,14 +961,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => def ownerChain: List[Symbol] = this :: owner.ownerChain def originalOwnerChain: List[Symbol] = this :: originalOwner.getOrElse(this, rawowner).originalOwnerChain - // All the symbols overridden by this symbol and this symbol at the head, - // or Nil if this is NoSymbol. - def overrideChain = ( - if (this eq NoSymbol) Nil - else if (!owner.isClass) this :: Nil - else this :: allOverriddenSymbols - ) - // Non-classes skip self and return rest of owner chain; overridden in ClassSymbol. def enclClassChain: List[Symbol] = owner.enclClassChain @@ -2070,81 +2063,111 @@ trait Symbols extends api.Symbols { self: SymbolTable => * @param ofclazz The class containing the symbol's definition * @param site The base type from which member types are computed */ - final def matchingSymbol(ofclazz: Symbol, site: Type): Symbol = { - //OPT cut down on #closures by special casing non-overloaded case - // was: ofclazz.info.nonPrivateDecl(name) filter (sym => - // !sym.isTerm || (site.memberType(this) matches site.memberType(sym))) - val result = ofclazz.info.nonPrivateDecl(name) - def qualifies(sym: Symbol) = !sym.isTerm || (site.memberType(this) matches site.memberType(sym)) - if ((result eq NoSymbol) || !result.isOverloaded && qualifies(result)) result - else result filter qualifies - } + final def matchingSymbol(ofclazz: Symbol, site: Type): Symbol = + matchingSymbolInternal(site, ofclazz.info nonPrivateDecl name) /** The non-private member of `site` whose type and name match the type of this symbol. */ final def matchingSymbol(site: Type, admit: Long = 0L): Symbol = - site.nonPrivateMemberAdmitting(name, admit).filter(sym => - !sym.isTerm || (site.memberType(this) matches site.memberType(sym))) + matchingSymbolInternal(site, site.nonPrivateMemberAdmitting(name, admit)) - /** The symbol, in class `ofclazz`, that is overridden by this symbol. + private def matchingSymbolInternal(site: Type, candidate: Symbol): Symbol = { + def qualifies(sym: Symbol) = !sym.isTerm || ((site memberType this) matches (site memberType sym)) + //OPT cut down on #closures by special casing non-overloaded case + if (candidate.isOverloaded) candidate filter qualifies + else if (qualifies(candidate)) candidate + else NoSymbol + } + + /** The symbol, in class `baseClass`, that is overridden by this symbol. * - * @param ofclazz is a base class of this symbol's owner. + * @param baseClass is a base class of this symbol's owner. */ - final def overriddenSymbol(ofclazz: Symbol): Symbol = - if (isClassConstructor) NoSymbol else matchingSymbol(ofclazz, owner.thisType) + final def overriddenSymbol(baseClass: Symbol): Symbol = ( + // concrete always overrides abstract, so don't let an abstract definition + // claim to be overriding an inherited concrete one. + matchingInheritedSymbolIn(baseClass) filter (res => res.isDeferred || !this.isDeferred) + ) + + private def matchingInheritedSymbolIn(baseClass: Symbol): Symbol = + if (canMatchInheritedSymbols) matchingSymbol(baseClass, owner.thisType) else NoSymbol /** The symbol overriding this symbol in given subclass `ofclazz`. * * @param ofclazz is a subclass of this symbol's owner */ - final def overridingSymbol(ofclazz: Symbol): Symbol = - if (isClassConstructor) NoSymbol else matchingSymbol(ofclazz, ofclazz.thisType) + final def overridingSymbol(ofclazz: Symbol): Symbol = ( + if (canMatchInheritedSymbols) + matchingSymbol(ofclazz, ofclazz.thisType) + else + NoSymbol + ) - /** Returns all symbols overriden by this symbol. */ - final def allOverriddenSymbols: List[Symbol] = ( - if ((this eq NoSymbol) || !owner.isClass) Nil - else { - def loop(xs: List[Symbol]): List[Symbol] = xs match { - case Nil => Nil - case x :: xs => - overriddenSymbol(x) match { - case NoSymbol => loop(xs) - case sym => sym :: loop(xs) - } - } - loop(owner.ancestors) - } + /** If false, this symbol cannot possibly participate in an override, + * either as overrider or overridee. For internal use; you should consult + * with isOverridingSymbol. This is used by isOverridingSymbol to escape + * the recursive knot. + */ + private def canMatchInheritedSymbols = ( + (this ne NoSymbol) + && owner.isClass + && !this.isClass + && !this.isConstructor + ) + + // All the symbols overridden by this symbol and this symbol at the head, + // or Nil if this is NoSymbol. + def overrideChain = ( + if (this eq NoSymbol) Nil + else if (isOverridingSymbol) this :: allOverriddenSymbols + else this :: Nil ) + /** Returns all symbols overridden by this symbol. */ + final def allOverriddenSymbols: List[Symbol] = { + def loop(xs: List[Symbol]): List[Symbol] = xs match { + case Nil => Nil + case x :: xs => + overriddenSymbol(x) match { + case NoSymbol => loop(xs) + case sym => sym :: loop(xs) + } + } + if (isOverridingSymbol) loop(owner.ancestors) else Nil + } + /** Equivalent to allOverriddenSymbols.nonEmpty, but more efficient. */ - // !!! When if ever will this answer differ from .isOverride? - // How/where is the OVERRIDE flag managed, as compared to how checks - // based on type membership will evaluate? - def isOverridingSymbol = owner.isClass && ( - owner.ancestors exists (cls => matchingSymbol(cls, owner.thisType) != NoSymbol) + lazy val isOverridingSymbol = ( + canMatchInheritedSymbols + && owner.ancestors.exists(base => overriddenSymbol(base) != NoSymbol) ) + /** Equivalent to allOverriddenSymbols.head (or NoSymbol if no overrides) but more efficient. */ def nextOverriddenSymbol: Symbol = { - if ((this ne NoSymbol) && owner.isClass) owner.ancestors foreach { base => - val sym = overriddenSymbol(base) - if (sym != NoSymbol) - return sym + @tailrec def loop(bases: List[Symbol]): Symbol = bases match { + case Nil => NoSymbol + case base :: rest => + val sym = overriddenSymbol(base) + if (sym == NoSymbol) loop(rest) else sym } - NoSymbol + if (isOverridingSymbol) loop(owner.ancestors) else NoSymbol } /** Returns all symbols overridden by this symbol, plus all matching symbols * defined in parents of the selftype. */ - final def extendedOverriddenSymbols: List[Symbol] = - if (!owner.isClass) Nil - else owner.thisSym.ancestors map overriddenSymbol filter (_ != NoSymbol) + final def extendedOverriddenSymbols: List[Symbol] = ( + if (canMatchInheritedSymbols) + owner.thisSym.ancestors map overriddenSymbol filter (_ != NoSymbol) + else + Nil + ) /** The symbol accessed by a super in the definition of this symbol when * seen from class `base`. This symbol is always concrete. * pre: `this.owner` is in the base class sequence of `base`. */ final def superSymbol(base: Symbol): Symbol = { - var bcs = base.info.baseClasses.dropWhile(owner != _).tail + var bcs = base.info.baseClasses dropWhile (owner != _) drop 1 var sym: Symbol = NoSymbol while (!bcs.isEmpty && sym == NoSymbol) { if (!bcs.head.isImplClass) diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index ce7fae8628..5cb6f78874 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -372,7 +372,7 @@ trait Types extends api.Types { self: SymbolTable => * This is assessed to be the case if the class is final, * and all type parameters (if any) are invariant. */ - def isFinalType = typeSymbol.hasOnlyBottomSubclasses + def isFinalType = typeSymbol.hasOnlyBottomSubclasses && prefix.isStable /** Is this type completed (i.e. not a lazy type)? */ def isComplete: Boolean = true diff --git a/src/reflect/scala/reflect/internal/util/Statistics.scala b/src/reflect/scala/reflect/internal/util/Statistics.scala index b078b7d4f9..0fa798058d 100644 --- a/src/reflect/scala/reflect/internal/util/Statistics.scala +++ b/src/reflect/scala/reflect/internal/util/Statistics.scala @@ -109,7 +109,7 @@ quant) * Quantities with non-empty prefix are printed in the statistics info. */ trait Quantity { - if (prefix.nonEmpty) { + if (enabled && prefix.nonEmpty) { val key = s"${if (underlying != this) underlying.prefix else ""}/$prefix" qs(key) = this } |