summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-10-10 06:24:46 +0000
committerPaul Phillips <paulp@improving.org>2011-10-10 06:24:46 +0000
commit4e86106b5b0637aa88de2e3d5a8751d918e4c069 (patch)
treefd4fc08760ffd102b590f670720c8846e41fb15e
parent1706358bdcf0492b82e87c8f34e9b7120348df8b (diff)
downloadscala-4e86106b5b0637aa88de2e3d5a8751d918e4c069.tar.gz
scala-4e86106b5b0637aa88de2e3d5a8751d918e4c069.tar.bz2
scala-4e86106b5b0637aa88de2e3d5a8751d918e4c069.zip
Moved meta annotations to annotation.meta, plus.
It took me a long time to find a trivial error while adjusting the annotation packages, so I spent even longer trying to make sure next time it would take me less time. It's the usual business of eliminating duplication and unnecessary indirection. Behavioral note: there was no consistency or deducible reasoning regarding when annotation checks would be performed against the typeSymbol directly (thus excluding annotation subclasses) or when they would do a subclass check. I saw no reason it shouldn't always be a subclass check; if the annotation isn't supposed to be subclassed it should be final, and if it is, then the subclasses had probably better not stop exhibiting the behavior of the base class. Example: this now draws deprecated warnings, but did not before. class bippy extends deprecated("hi mom", "burma shave") @bippy def f = 5 (The deprecation message isn't printed so we're not there yet, but closer.) There is some new internal documentation on annotations, sadly lacking in my famous ascii diagrams, and some new conveniences. Review by rytz.
-rw-r--r--lib/scala-compiler.jar.desired.sha12
-rw-r--r--lib/scala-library-src.jar.desired.sha12
-rw-r--r--lib/scala-library.jar.desired.sha12
-rw-r--r--src/compiler/scala/reflect/internal/AnnotationInfos.scala75
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala95
-rw-r--r--src/compiler/scala/reflect/internal/StdNames.scala7
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala29
-rw-r--r--src/compiler/scala/reflect/internal/Trees.scala8
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala63
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala123
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala4
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala8
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/CleanUp.scala13
-rw-r--r--src/compiler/scala/tools/nsc/transform/LazyVals.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala6
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala19
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala41
-rw-r--r--src/library/scala/annotation/meta/beanGetter.scala (renamed from src/library/scala/beans/meta/beanGetter.scala)4
-rw-r--r--src/library/scala/annotation/meta/beanSetter.scala (renamed from src/library/scala/beans/meta/beanSetter.scala)4
-rw-r--r--src/library/scala/annotation/meta/field.scala (renamed from src/library/scala/beans/meta/field.scala)4
-rw-r--r--src/library/scala/annotation/meta/getter.scala (renamed from src/library/scala/beans/meta/getter.scala)4
-rw-r--r--src/library/scala/annotation/meta/package.scala (renamed from src/library/scala/beans/meta/package.scala)4
-rw-r--r--src/library/scala/annotation/meta/param.scala (renamed from src/library/scala/beans/meta/param.scala)4
-rw-r--r--src/library/scala/annotation/meta/setter.scala (renamed from src/library/scala/beans/meta/setter.scala)4
-rw-r--r--src/library/scala/annotation/target/package.scala24
-rw-r--r--src/library/scala/beans/BeanProperty.scala4
-rw-r--r--src/library/scala/beans/BooleanBeanProperty.scala4
-rw-r--r--src/library/scala/deprecated.scala2
-rw-r--r--src/library/scala/deprecatedName.scala2
-rw-r--r--src/library/scala/transient.scala2
-rw-r--r--src/library/scala/volatile.scala2
-rw-r--r--test/files/jvm/annotations.scala8
-rw-r--r--test/files/pos/annotations.scala2
37 files changed, 318 insertions, 267 deletions
diff --git a/lib/scala-compiler.jar.desired.sha1 b/lib/scala-compiler.jar.desired.sha1
index b523db5638..b676b3fe8c 100644
--- a/lib/scala-compiler.jar.desired.sha1
+++ b/lib/scala-compiler.jar.desired.sha1
@@ -1 +1 @@
-14a0987b7538c3aadcfa9160965076dfe118ec0d ?scala-compiler.jar
+4d0cb32fa024710769b5ee51106c3e9ea29ade7d ?scala-compiler.jar
diff --git a/lib/scala-library-src.jar.desired.sha1 b/lib/scala-library-src.jar.desired.sha1
index 299e06422e..f011801242 100644
--- a/lib/scala-library-src.jar.desired.sha1
+++ b/lib/scala-library-src.jar.desired.sha1
@@ -1 +1 @@
-6207899bfc2c03c7c9d014e332475eb313062e3c ?scala-library-src.jar
+14b578464704bac38ef517eb6914994d8c412aa4 ?scala-library-src.jar
diff --git a/lib/scala-library.jar.desired.sha1 b/lib/scala-library.jar.desired.sha1
index 32ae1abf35..63d7b7196b 100644
--- a/lib/scala-library.jar.desired.sha1
+++ b/lib/scala-library.jar.desired.sha1
@@ -1 +1 @@
-f374329f89c77e8205a377060b21cf97ace5ac9b ?scala-library.jar
+199221beaa29c95057822c294596ede424f42f37 ?scala-library.jar
diff --git a/src/compiler/scala/reflect/internal/AnnotationInfos.scala b/src/compiler/scala/reflect/internal/AnnotationInfos.scala
index dcabdf0a27..57722593d4 100644
--- a/src/compiler/scala/reflect/internal/AnnotationInfos.scala
+++ b/src/compiler/scala/reflect/internal/AnnotationInfos.scala
@@ -11,6 +11,34 @@ import pickling.ByteCodecs
/** AnnotationInfo and its helpers */
trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
+ import definitions.{ ThrowsClass, isMetaAnnotation }
+
+ // Common annotation code between Symbol and Type.
+ // For methods altering the annotation list, on Symbol it mutates
+ // the Symbol's field directly. For Type, a new AnnotatedType is
+ // created which wraps the original type.
+ trait Annotatable[Self] {
+ self: Self =>
+
+ /** The annotations on this type. */
+ def annotations: List[AnnotationInfo] // Annotations on this type.
+ def setAnnotations(annots: List[AnnotationInfo]): Self // Replace annotations with argument list.
+ def withAnnotations(annots: List[AnnotationInfo]): Self // Add annotations to this type.
+ def withoutAnnotations: Self // Remove all annotations from this type.
+
+ /** Symbols of any @throws annotations on this symbol.
+ */
+ def throwsAnnotations() = annotations collect {
+ case AnnotationInfo(tp, Literal(Constant(tpe: Type)) :: Nil, _) if tp.typeSymbol == ThrowsClass => tpe.typeSymbol
+ }
+
+ /** Test for, get, or remove an annotation */
+ def hasAnnotation(cls: Symbol) = annotations exists (_ matches cls)
+ def getAnnotation(cls: Symbol) = annotations find (_ matches cls)
+ def removeAnnotation(cls: Symbol): Self =
+ if (hasAnnotation(cls)) setAnnotations(annotations filterNot (_ matches cls))
+ else this
+ }
/** Arguments to classfile annotations (which are written to
* bytecode as java annotations) are either:
@@ -90,7 +118,7 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
extends AnnotationInfoBase {
// Classfile annot: args empty. Scala annot: assocs empty.
- assert(args.isEmpty || assocs.isEmpty)
+ assert(args.isEmpty || assocs.isEmpty, atp)
private var rawpos: Position = NoPosition
def pos = rawpos
@@ -99,7 +127,45 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
this
}
- lazy val isTrivial: Boolean = atp.isTrivial && !(args exists (_.exists(_.isInstanceOf[This]))) // see annotationArgRewriter
+ /** Annotations annotating annotations are confusing so I drew
+ * an example. Given the following code:
+ *
+ * class A {
+ * @(deprecated @setter) @(inline @getter)
+ * var x: Int = 0
+ * }
+ *
+ * For the setter `x_=` in A, annotations contains one AnnotationInfo =
+ * List(deprecated @setter)
+ * The single AnnotationInfo in that list, i.e. `@(deprecated @setter)`, has metaAnnotations =
+ * List(setter)
+ *
+ * Similarly, the getter `x` in A has an @inline annotation, which has
+ * metaAnnotations = List(getter).
+ */
+ def symbol = atp.typeSymbol
+
+ /** These are meta-annotations attached at the use site; they
+ * only apply to this annotation usage. For instance, in
+ * `@(deprecated @setter @field) val ...`
+ * metaAnnotations = List(setter, field).
+ */
+ def metaAnnotations: List[AnnotationInfo] = atp match {
+ case AnnotatedType(metas, _, _) => metas
+ case _ => Nil
+ }
+
+ /** The default kind of members to which this annotation is attached.
+ * For instance, for scala.deprecated defaultTargets =
+ * List(getter, setter, beanGetter, beanSetter).
+ */
+ def defaultTargets = symbol.annotations map (_.symbol) filter isMetaAnnotation
+ // Test whether the typeSymbol of atp conforms to the given class.
+ def matches(clazz: Symbol) = symbol isNonBottomSubClass clazz
+ // All subtrees of all args are considered.
+ def hasArgWhich(p: Tree => Boolean) = args exists (_ exists p)
+
+ lazy val isTrivial: Boolean = atp.isTrivial && !hasArgWhich(_.isInstanceOf[This]) // see annotationArgRewriter
override def toString: String = atp +
(if (!args.isEmpty) args.mkString("(", ", ", ")") else "") +
@@ -109,8 +175,7 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
def isErroneous = atp.isErroneous || args.exists(_.isErroneous)
/** Check whether any of the arguments mention a symbol */
- def refsSymbol(sym: Symbol) =
- args.exists(_.exists(_.symbol == sym))
+ def refsSymbol(sym: Symbol) = hasArgWhich(_.symbol == sym)
/** Change all ident's with Symbol "from" to instead use symbol "to" */
def substIdentSyms(from: Symbol, to: Symbol) = {
@@ -145,4 +210,6 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
*/
case class LazyAnnotationInfo(annot: () => AnnotationInfo)
extends AnnotationInfoBase
+
+ object UnmappableAnnotation extends AnnotationInfo(NoType, Nil, Nil)
}
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index e3b149e0d6..d816ba247d 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -183,30 +183,6 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val ThrowableClass = getClass(sn.Throwable)
lazy val UninitializedErrorClass = getClass("scala.UninitializedFieldError")
- // annotations
- lazy val AnnotationClass = getClass("scala.annotation.Annotation")
- lazy val ClassfileAnnotationClass = getClass("scala.annotation.ClassfileAnnotation")
- lazy val StaticAnnotationClass = getClass("scala.annotation.StaticAnnotation")
- lazy val uncheckedStableClass = getClass("scala.annotation.unchecked.uncheckedStable")
- lazy val uncheckedVarianceClass = getClass("scala.annotation.unchecked.uncheckedVariance")
- lazy val UncheckedClass = getClass("scala.unchecked")
- lazy val ThrowsClass = getClass("scala.throws")
- lazy val TailrecClass = getClass("scala.annotation.tailrec")
- lazy val SwitchClass = getClass("scala.annotation.switch")
- lazy val ElidableMethodClass = getClass("scala.annotation.elidable")
- lazy val ImplicitNotFoundClass = getClass("scala.annotation.implicitNotFound")
- lazy val VarargsClass = getClass("scala.annotation.varargs")
- lazy val FieldTargetClass = getClass("scala.beans.meta.field")
- lazy val GetterTargetClass = getClass("scala.beans.meta.getter")
- lazy val SetterTargetClass = getClass("scala.beans.meta.setter")
- lazy val BeanGetterTargetClass = getClass("scala.beans.meta.beanGetter")
- lazy val BeanSetterTargetClass = getClass("scala.beans.meta.beanSetter")
- lazy val ParamTargetClass = getClass("scala.beans.meta.param")
- lazy val ScalaInlineClass = getClass("scala.inline")
- lazy val ScalaNoInlineClass = getClass("scala.noinline")
- lazy val SpecializedClass = getClass("scala.specialized")
- lazy val BridgeClass = getClass("scala.annotation.bridge")
-
// fundamental reference classes
lazy val ScalaObjectClass = getMember(ScalaPackageClass, tpnme.ScalaObject)
lazy val PartialFunctionClass = getClass("scala.PartialFunction")
@@ -256,6 +232,8 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val ArrowAssocClass = getClass("scala.Predef.ArrowAssoc")
lazy val StringAdd_+ = getMember(StringAddClass, nme.PLUS)
lazy val NotNullClass = getClass("scala.NotNull")
+ lazy val ScalaNumberClass = getClass("scala.math.ScalaNumber")
+ lazy val TraitSetterAnnotationClass = getClass("scala.runtime.TraitSetter")
lazy val DelayedInitClass = getClass("scala.DelayedInit")
def delayedInitMethod = getMember(DelayedInitClass, nme.delayedInit)
// a dummy value that communicates that a delayedInit call is compiler-generated
@@ -606,22 +584,59 @@ trait Definitions extends reflect.api.StandardDefinitions {
def BoxedUnit_UNIT = getMember(BoxedUnitModule, "UNIT")
def BoxedUnit_TYPE = getMember(BoxedUnitModule, "TYPE")
- // special attributes
- lazy val BeanPropertyAttr: Symbol = getClass(sn.BeanProperty)
- lazy val BooleanBeanPropertyAttr: Symbol = getClass(sn.BooleanBeanProperty)
- lazy val CloneableAttr: Symbol = getClass("scala.cloneable")
- lazy val DeprecatedAttr: Symbol = getClass("scala.deprecated")
- lazy val DeprecatedNameAttr: Symbol = getClass("scala.deprecatedName")
- lazy val MigrationAnnotationClass: Symbol = getClass("scala.annotation.migration")
- lazy val NativeAttr: Symbol = getClass("scala.native")
- lazy val RemoteAttr: Symbol = getClass("scala.remote")
- lazy val ScalaNumberClass: Symbol = getClass("scala.math.ScalaNumber")
- lazy val ScalaStrictFPAttr: Symbol = getClass("scala.annotation.strictfp")
- lazy val SerialVersionUIDAttr: Symbol = getClass("scala.SerialVersionUID")
- lazy val SerializableAttr: Symbol = getClass("scala.annotation.serializable") // @serializable is deprecated
- lazy val TraitSetterAnnotationClass: Symbol = getClass("scala.runtime.TraitSetter")
- lazy val TransientAttr: Symbol = getClass("scala.transient")
- lazy val VolatileAttr: Symbol = getClass("scala.volatile")
+ // Annotation base classes
+ lazy val AnnotationClass = getClass("scala.annotation.Annotation")
+ lazy val ClassfileAnnotationClass = getClass("scala.annotation.ClassfileAnnotation")
+ lazy val StaticAnnotationClass = getClass("scala.annotation.StaticAnnotation")
+
+ // Annotations
+ lazy val BridgeClass = getClass("scala.annotation.bridge")
+ lazy val ElidableMethodClass = getClass("scala.annotation.elidable")
+ lazy val ImplicitNotFoundClass = getClass("scala.annotation.implicitNotFound")
+ lazy val MigrationAnnotationClass = getClass("scala.annotation.migration")
+ lazy val ScalaStrictFPAttr = getClass("scala.annotation.strictfp")
+ lazy val SerializableAttr = getClass("scala.annotation.serializable") // @serializable is deprecated
+ lazy val SwitchClass = getClass("scala.annotation.switch")
+ lazy val TailrecClass = getClass("scala.annotation.tailrec")
+ lazy val VarargsClass = getClass("scala.annotation.varargs")
+ lazy val uncheckedStableClass = getClass("scala.annotation.unchecked.uncheckedStable")
+ lazy val uncheckedVarianceClass = getClass("scala.annotation.unchecked.uncheckedVariance")
+
+ lazy val BeanPropertyAttr = getClass(sn.BeanProperty)
+ lazy val BooleanBeanPropertyAttr = getClass(sn.BooleanBeanProperty)
+ lazy val CloneableAttr = getClass("scala.cloneable")
+ lazy val DeprecatedAttr = getClass("scala.deprecated")
+ lazy val DeprecatedNameAttr = getClass("scala.deprecatedName")
+ lazy val NativeAttr = getClass("scala.native")
+ lazy val RemoteAttr = getClass("scala.remote")
+ lazy val ScalaInlineClass = getClass("scala.inline")
+ lazy val ScalaNoInlineClass = getClass("scala.noinline")
+ lazy val SerialVersionUIDAttr = getClass("scala.SerialVersionUID")
+ lazy val SpecializedClass = getClass("scala.specialized")
+ lazy val ThrowsClass = getClass("scala.throws")
+ lazy val TransientAttr = getClass("scala.transient")
+ lazy val UncheckedClass = getClass("scala.unchecked")
+ lazy val VolatileAttr = getClass("scala.volatile")
+
+ // Meta-annotations
+ lazy val BeanGetterTargetClass = getMetaAnnotation("beanGetter")
+ lazy val BeanSetterTargetClass = getMetaAnnotation("beanSetter")
+ lazy val FieldTargetClass = getMetaAnnotation("field")
+ lazy val GetterTargetClass = getMetaAnnotation("getter")
+ lazy val ParamTargetClass = getMetaAnnotation("param")
+ lazy val SetterTargetClass = getMetaAnnotation("setter")
+
+ private def getMetaAnnotation(name: String) = getClass("scala.annotation.meta." + name)
+ def isMetaAnnotation(sym: Symbol): Boolean = metaAnnotations(sym) || (
+ // Trying to allow for deprecated locations
+ sym.isAliasType && isMetaAnnotation(sym.info.typeSymbol)
+ )
+
+ lazy val metaAnnotations = Set(
+ FieldTargetClass, ParamTargetClass,
+ GetterTargetClass, SetterTargetClass,
+ BeanGetterTargetClass, BeanSetterTargetClass
+ )
lazy val AnnotationDefaultAttr: Symbol = {
val attr = newClass(RuntimePackageClass, tpnme.AnnotationDefaultATTR, List(AnnotationClass.typeConstructor))
diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala
index eca2fd7807..9e40b11fc8 100644
--- a/src/compiler/scala/reflect/internal/StdNames.scala
+++ b/src/compiler/scala/reflect/internal/StdNames.scala
@@ -146,7 +146,12 @@ trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: Sy
final val String: NameType = "String"
final val Throwable: NameType = "Throwable"
- // Annotation types
+ // Annotation simple names, used in Namer
+ final val BeanPropertyAnnot: NameType = "BeanProperty"
+ final val BooleanBeanPropertyAnnot: NameType = "BooleanBeanProperty"
+ final val bridgeAnnot: NameType = "bridge"
+
+ // Classfile Attributes
final val AnnotationDefaultATTR: NameType = "AnnotationDefault"
final val BridgeATTR: NameType = "Bridge"
final val ClassfileAnnotationATTR: NameType = "RuntimeInvisibleAnnotations" // RetentionPolicy.CLASS. Currently not used (Apr 2009).
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index 533a343589..db17306768 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -42,7 +42,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
val originalOwner = perRunCaches.newMap[Symbol, Symbol]()
/** The class for all symbols */
- abstract class Symbol(initOwner: Symbol, initPos: Position, initName: Name) extends AbsSymbol with HasFlags {
+ abstract class Symbol(initOwner: Symbol, initPos: Position, initName: Name)
+ extends AbsSymbol
+ with HasFlags
+ with Annotatable[Symbol] {
type FlagsType = Long
type AccessBoundaryType = Symbol
@@ -1166,25 +1169,25 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
annots1
}
- def setAnnotations(annots: List[AnnotationInfoBase]): this.type = {
+ def setRawAnnotations(annots: List[AnnotationInfoBase]): this.type = {
this.rawannots = annots
this
}
+ def setAnnotations(annots: List[AnnotationInfo]): this.type =
+ setRawAnnotations(annots)
- def addAnnotation(annot: AnnotationInfo) {
- setAnnotations(annot :: this.rawannots)
- }
+ def withAnnotations(annots: List[AnnotationInfo]): this.type =
+ setRawAnnotations(annots ::: rawannots)
- /** Does this symbol have an annotation of the given class? */
- def hasAnnotation(cls: Symbol) =
- getAnnotation(cls).isDefined
+ def withoutAnnotations: this.type =
+ setRawAnnotations(Nil)
- def getAnnotation(cls: Symbol): Option[AnnotationInfo] =
- annotations find (_.atp.typeSymbol == cls)
+ def addAnnotation(annot: AnnotationInfo): this.type =
+ setRawAnnotations(annot :: rawannots)
- /** Remove all annotations matching the given class. */
- def removeAnnotation(cls: Symbol): Unit =
- setAnnotations(annotations filterNot (_.atp.typeSymbol == cls))
+ // Convenience for the overwhelmingly common case
+ def addAnnotation(sym: Symbol, args: Tree*): this.type =
+ addAnnotation(AnnotationInfo(sym.tpe, args.toList, Nil))
// ------ comparisons ----------------------------------------------------------------
diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala
index f9ca57fadc..d4e2550698 100644
--- a/src/compiler/scala/reflect/internal/Trees.scala
+++ b/src/compiler/scala/reflect/internal/Trees.scala
@@ -35,6 +35,14 @@ trait Trees extends api.Trees { self: SymbolTable =>
type AccessBoundaryType = Name
type AnnotationType = Tree
+ def hasAnnotationNamed(name: TypeName) = {
+ annotations exists {
+ case Apply(Select(New(Ident(`name`)), _), _) => true
+ case Apply(Select(New(Select(_, `name`)), _), _) => true
+ case _ => false
+ }
+ }
+
def hasAccessBoundary = privateWithin != tpnme.EMPTY
def hasAllFlags(mask: Long): Boolean = (flags & mask) == mask
def hasFlag(flag: Long) = (flag & flags) != 0L
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index 1e0a265f4b..e85dc6de95 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -234,11 +234,9 @@ trait Types extends api.Types { self: SymbolTable =>
super.tpe_=(NoType)
override def tpe_=(t: Type) = if (t != NoType) throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for <empty>")
}
- object UnmappableAnnotation extends AnnotationInfo(NoType, Nil, Nil)
/** The base class for all types */
- abstract class Type extends AbsType {
-
+ abstract class Type extends AbsType with Annotatable[Type] {
/** Types for which asSeenFrom always is the identity, no matter what
* prefix or owner.
*/
@@ -1000,24 +998,14 @@ trait Types extends api.Types { self: SymbolTable =>
skolems
}
- /** Return the annotations on this type. */
+ // Implementation of Annotatable for all types but AnnotatedType, which
+ // overrides these.
def annotations: List[AnnotationInfo] = Nil
+ def withoutAnnotations: Type = this
+ def setAnnotations(annots: List[AnnotationInfo]): Type = annotatedType(annots, this)
+ def withAnnotations(annots: List[AnnotationInfo]): Type = annotatedType(annots, this)
- /** Test for the presence of an annotation */
- def hasAnnotation(clazz: Symbol) = annotations exists { _.atp.typeSymbol == clazz }
-
- /** Add an annotation to this type */
- def withAnnotation(annot: AnnotationInfo) = withAnnotations(List(annot))
-
- /** Add a number of annotations to this type */
- def withAnnotations(annots: List[AnnotationInfo]): Type =
- annots match {
- case Nil => this
- case _ => AnnotatedType(annots, this, NoSymbol)
- }
-
- /** Remove any annotations from this type */
- def withoutAnnotations = this
+ final def withAnnotation(annot: AnnotationInfo): Type = withAnnotations(List(annot))
/** Remove any annotations from this type and from any
* types embedded in this type. */
@@ -2653,35 +2641,31 @@ A type's typeSymbol should never be inspected directly.
override val selfsym: Symbol)
extends RewrappingTypeProxy {
- assert(!annotations.isEmpty)
+ assert(!annotations.isEmpty, "" + underlying)
- override protected def rewrap(tp: Type) = AnnotatedType(annotations, tp, selfsym)
+ override protected def rewrap(tp: Type) = copy(underlying = tp)
override def isTrivial: Boolean = isTrivial0
- private lazy val isTrivial0 = underlying.isTrivial && (annotations forall (_.isTrivial))
+ private lazy val isTrivial0 = underlying.isTrivial && annotations.forall(_.isTrivial)
- override def safeToString: String = {
- val attString =
- if (annotations.isEmpty)
- ""
- else
- annotations.mkString(" @", " @", "")
+ override def safeToString = annotations.mkString(underlying + " @", " @", "")
- underlying + attString
- }
+ override def setAnnotations(annots: List[AnnotationInfo]): Type =
+ if (annots.isEmpty) withoutAnnotations
+ else copy(annotations = annots)
/** Add a number of annotations to this type */
override def withAnnotations(annots: List[AnnotationInfo]): Type =
- copy(annots:::this.annotations)
+ if (annots.isEmpty) this
+ else copy(annots ::: this.annotations)
/** Remove any annotations from this type */
override def withoutAnnotations = underlying.withoutAnnotations
/** Set the self symbol */
- override def withSelfsym(sym: Symbol) =
- AnnotatedType(annotations, underlying, sym)
+ override def withSelfsym(sym: Symbol) = copy(selfsym = sym)
- /** Drop the annotations on the bounds, unless but the low and high
+ /** Drop the annotations on the bounds, unless the low and high
* bounds are exactly tp.
*/
override def bounds: TypeBounds = underlying.bounds match {
@@ -2711,7 +2695,14 @@ A type's typeSymbol should never be inspected directly.
override def kind = "AnnotatedType"
}
- object AnnotatedType extends AnnotatedTypeExtractor
+ /** Creator for AnnotatedTypes. It returns the underlying type if annotations.isEmpty
+ * rather than walking into the assertion.
+ */
+ def annotatedType(annots: List[AnnotationInfo], underlying: Type, selfsym: Symbol = NoSymbol): Type =
+ if (annots.isEmpty) underlying
+ else AnnotatedType(annots, underlying, selfsym)
+
+ object AnnotatedType extends AnnotatedTypeExtractor { }
/** A class representing types with a name. When an application uses
* named arguments, the named argument types for calling isApplicable
@@ -3241,7 +3232,7 @@ A type's typeSymbol should never be inspected directly.
trait KeepOnlyTypeConstraints extends AnnotationFilter {
// filter keeps only type constraint annotations
- def keepAnnotation(annot: AnnotationInfo) = annot.atp.typeSymbol isNonBottomSubClass TypeConstraintClass
+ def keepAnnotation(annot: AnnotationInfo) = annot matches TypeConstraintClass
}
/** A prototype for mapping a function over all possible types
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index bec488ab72..033b049a92 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -71,7 +71,7 @@ abstract class TreeGen extends reflect.internal.TreeGen {
setFlag (MODULEVAR)
)
- mval.addAnnotation(AnnotationInfo(VolatileAttr.tpe, Nil, Nil))
+ mval addAnnotation VolatileAttr
if (mval.owner.isClass) {
mval setFlag (PrivateLocal | SYNTHETIC)
mval.owner.info.decls.enter(mval)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index 7f1dc1fbcd..8408965afe 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -185,6 +185,12 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
val BeanDisplayNameAttr = definitions.getClass("scala.beans.BeanDisplayName")
val BeanDescriptionAttr = definitions.getClass("scala.beans.BeanDescription")
+ lazy val annotationInterfaces = List(
+ SerializableAttr -> SerializableClass.tpe,
+ CloneableAttr -> CloneableClass.tpe,
+ RemoteAttr -> RemoteInterface.tpe
+ )
+
lazy val CloneableClass = definitions.getClass("java.lang.Cloneable")
lazy val RemoteInterface = definitions.getClass("java.rmi.Remote")
lazy val RemoteException = definitions.getClass("java.rmi.RemoteException").tpe
@@ -204,6 +210,12 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
var jmethod: JMethod = _
// var jcode: JExtendedCode = _
+ def isParcelableClass = isAndroidParcelableClass(clasz.symbol)
+ def isRemoteClass = clasz.symbol hasAnnotation RemoteAttr
+ def serialVUID = clasz.symbol getAnnotation SerialVersionUIDAttr collect {
+ case AnnotationInfo(_, Literal(const) :: _, _) => const.longValue
+ }
+
val fjbgContext = new FJBGContext(49, 0)
val emitSource = debugLevel >= 1
@@ -298,47 +310,32 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
None
}
- var serialVUID: Option[Long] = None
- var isRemoteClass: Boolean = false
- var isParcelableClass = false
-
private var innerClassBuffer = mutable.LinkedHashSet[Symbol]()
def genClass(c: IClass) {
clasz = c
innerClassBuffer.clear()
- var parents = c.symbol.info.parents
- var ifaces = JClass.NO_INTERFACES
val name = javaName(c.symbol)
- serialVUID = None
- isRemoteClass = false
- isParcelableClass = isAndroidParcelableClass(c.symbol)
-
- if (parents.isEmpty)
- parents = List(ObjectClass.tpe)
-
- for (annot <- c.symbol.annotations) annot match {
- case AnnotationInfo(tp, _, _) if tp.typeSymbol == SerializableAttr =>
- parents :+= SerializableClass.tpe
- case AnnotationInfo(tp, _, _) if tp.typeSymbol == CloneableAttr =>
- parents :+= CloneableClass.tpe
- case AnnotationInfo(tp, Literal(const) :: _, _) if tp.typeSymbol == SerialVersionUIDAttr =>
- serialVUID = Some(const.longValue)
- case AnnotationInfo(tp, _, _) if tp.typeSymbol == RemoteAttr =>
- parents :+= RemoteInterface.tpe
- isRemoteClass = true
- case _ =>
+ val parents = {
+ val parents0 = c.symbol.info.parents match {
+ case Nil => List(ObjectClass.tpe)
+ case ps => ps
+ }
+ val newInterfaces = annotationInterfaces collect {
+ case (annot, tpe) if c.symbol hasAnnotation annot => tpe
+ }
+ parents0 ++ newInterfaces distinct
+ }
+ val superClass :: superInterfaces = parents
+ val ifaces = superInterfaces match {
+ case Nil => JClass.NO_INTERFACES
+ case _ => mkArray(superInterfaces map (x => javaName(x.typeSymbol)))
}
-
- parents = parents.distinct
-
- if (parents.tail.nonEmpty)
- ifaces = mkArray(parents drop 1 map (x => javaName(x.typeSymbol)))
jclass = fjbgContext.JClass(javaFlags(c.symbol),
name,
- javaName(parents(0).typeSymbol),
+ javaName(superClass.typeSymbol),
ifaces,
c.cunit.source.toString)
@@ -394,7 +391,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
val ssa = scalaSignatureAddingMarker(jclass, c.symbol)
addGenericSignature(jclass, c.symbol, c.symbol.owner)
addAnnotations(jclass, c.symbol.annotations ++ ssa)
-
addEnclosingMethodAttribute(jclass, c.symbol)
emitClass(jclass, c.symbol)
@@ -438,7 +434,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
* @author Ross Judson (ross.judson@soletta.com)
*/
def genBeanInfoClass(c: IClass) {
- val description = c.symbol.annotations.find(_.atp.typeSymbol == BeanDescriptionAttr)
+ val description = c.symbol getAnnotation BeanDescriptionAttr
// informProgress(description.toString)
val beanInfoClass = fjbgContext.JClass(javaFlags(c.symbol),
@@ -532,8 +528,8 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
* .initialize: if 'annot' is read from pickle, atp might be un-initialized
*/
private def shouldEmitAnnotation(annot: AnnotationInfo) =
- annot.atp.typeSymbol.initialize.isJavaDefined &&
- annot.atp.typeSymbol.isNonBottomSubClass(ClassfileAnnotationClass) &&
+ annot.symbol.initialize.isJavaDefined &&
+ annot.matches(ClassfileAnnotationClass) &&
annot.args.isEmpty
private def emitJavaAnnotations(cpool: JConstantPool, buf: ByteBuffer, annotations: List[AnnotationInfo]): Int = {
@@ -699,7 +695,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
}
def addAnnotations(jmember: JMember, annotations: List[AnnotationInfo]) {
- if (annotations.exists(_.atp.typeSymbol == definitions.DeprecatedAttr)) {
+ if (annotations exists (_ matches definitions.DeprecatedAttr)) {
val attr = jmember.getContext().JOtherAttribute(
jmember.getJClass(), jmember, tpnme.DeprecatedATTR.toString,
new Array[Byte](0), 0)
@@ -798,21 +794,11 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
def genField(f: IField) {
debuglog("Adding field: " + f.symbol.fullName)
-
- val attributes = f.symbol.annotations.map(_.atp.typeSymbol).foldLeft(0) {
- case (res, TransientAttr) => res | ACC_TRANSIENT
- case (res, VolatileAttr) => res | ACC_VOLATILE
- case (res, _) => res
- }
-
- var flags = javaFlags(f.symbol)
- if (!f.symbol.isMutable)
- flags |= ACC_FINAL
-
- val jfield =
- jclass.addNewField(flags | attributes,
- javaName(f.symbol),
- javaType(f.symbol.tpe))
+ val jfield = jclass.addNewField(
+ javaFlags(f.symbol) | javaFieldFlags(f.symbol),
+ javaName(f.symbol),
+ javaType(f.symbol.tpe)
+ )
addGenericSignature(jfield, f.symbol, clasz.symbol)
addAnnotations(jfield, f.symbol.annotations)
@@ -896,27 +882,20 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
}
}
+ /** Adds a @remote annotation, actual use unknown.
+ */
private def addRemoteException(jmethod: JMethod, meth: Symbol) {
- def isRemoteThrows(ainfo: AnnotationInfo) = ainfo match {
- case AnnotationInfo(tp, List(arg), _) if tp.typeSymbol == ThrowsClass =>
- arg match {
- case Literal(Constant(tpe: Type)) if tpe.typeSymbol == RemoteException.typeSymbol => true
- case _ => false
- }
- case _ => false
- }
-
- if (isRemoteClass ||
- (meth.hasAnnotation(RemoteAttr) && jmethod.isPublic)) {
- val c = Constant(RemoteException)
- val ainfo = AnnotationInfo(ThrowsClass.tpe, List(Literal(c).setType(c.tpe)), List())
- if (!meth.annotations.exists(isRemoteThrows)) {
- meth addAnnotation ainfo
- }
+ val needsAnnotation = (
+ !(meth.throwsAnnotations contains RemoteException)
+ && (isRemoteClass || (meth hasAnnotation RemoteAttr) && jmethod.isPublic)
+ )
+ if (needsAnnotation) {
+ val c = Constant(RemoteException)
+ val arg = Literal(c) setType c.tpe
+ meth.addAnnotation(ThrowsClass, arg)
}
}
-
/** Return a pair of lists of annotations, first one containing all
* annotations for the given symbol, and the rest.
*/
@@ -1897,6 +1876,8 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
}}).reverse
}
+ private def mkFlags(args: Int*) = args.foldLeft(0)(_ | _)
+
/**
* Return the Java modifiers for the given symbol.
* Java modifiers for classes:
@@ -1914,7 +1895,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
* and they would fail verification after lifted.
*/
def javaFlags(sym: Symbol): Int = {
- def mkFlags(args: Int*) = args.foldLeft(0)(_ | _)
// constructors of module classes should be private
// PP: why are they only being marked private at this stage and not earlier?
val privateFlag =
@@ -1942,6 +1922,13 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
if (sym.isVarargsMethod) ACC_VARARGS else 0
)
}
+ def javaFieldFlags(sym: Symbol) = {
+ mkFlags(
+ if (sym hasAnnotation TransientAttr) ACC_TRANSIENT else 0,
+ if (sym hasAnnotation VolatileAttr) ACC_VOLATILE else 0,
+ if (sym.isMutable) 0 else ACC_FINAL
+ )
+ }
def isTopLevelModule(sym: Symbol): Boolean =
atPhase (currentRun.picklerPhase.next) {
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
index d735044e07..1efcbeac29 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
@@ -421,10 +421,10 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
/** */
def makeAnnotation(annot: AnnotationInfo): Annotation = {
- val aSym = annot.atp.typeSymbol
+ val aSym = annot.symbol
new EntityImpl(aSym, makeTemplate(aSym.owner)) with Annotation {
lazy val annotationClass =
- makeTemplate(annot.atp.typeSymbol)
+ makeTemplate(annot.symbol)
val arguments = { // lazy
def noParams = annot.args map { _ => None }
val params: List[Option[ValueParam]] = annotationClass match {
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 3697bbe120..fc150d3361 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -871,7 +871,7 @@ abstract class ClassfileParser {
in.skip(attrLen)
case tpnme.DeprecatedATTR =>
val arg = Literal(Constant("see corresponding Javadoc for more information."))
- sym addAnnotation AnnotationInfo(definitions.DeprecatedAttr.tpe, List(arg, Literal(Constant(""))), Nil)
+ sym.addAnnotation(definitions.DeprecatedAttr, arg, Literal(Constant("")))
in.skip(attrLen)
case tpnme.ConstantValueATTR =>
val c = pool.getConstant(in.nextChar)
@@ -892,7 +892,7 @@ abstract class ClassfileParser {
this.hasMeta = true
// Attribute on methods of java annotation classes when that method has a default
case tpnme.AnnotationDefaultATTR =>
- sym.addAnnotation(AnnotationInfo(definitions.AnnotationDefaultAttr.tpe, List(), List()))
+ sym.addAnnotation(definitions.AnnotationDefaultAttr)
in.skip(attrLen)
// Java annotations on classes / methods / fields with RetentionPolicy.RUNTIME
case tpnme.RuntimeAnnotationATTR =>
@@ -1036,9 +1036,7 @@ abstract class ClassfileParser {
val nClasses = in.nextChar
for (n <- 0 until nClasses) {
val cls = pool.getClassSymbol(in.nextChar.toInt)
- sym.addAnnotation(AnnotationInfo(definitions.ThrowsClass.tpe,
- Literal(Constant(cls.tpe)) :: Nil,
- Nil))
+ sym.addAnnotation(definitions.ThrowsClass, Literal(Constant(cls.tpe)))
}
}
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
index 12a17abe91..89a770310f 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
@@ -108,7 +108,7 @@ abstract class Pickler extends SubComponent {
private def staticAnnotations(annots: List[AnnotationInfo]) =
annots filter(ann =>
- ann.atp.typeSymbol isNonBottomSubClass definitions.StaticAnnotationClass)
+ ann.symbol isNonBottomSubClass definitions.StaticAnnotationClass)
// Phase 1 methods: Populate entries/index ------------------------------------
diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
index f31d853967..9c851019a9 100644
--- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala
+++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
@@ -114,12 +114,15 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
/* ### CREATING THE METHOD CACHE ### */
def addStaticVariableToClass(forName: String, forType: Type, forInit: Tree, isFinal: Boolean): Symbol = {
- val varSym = currentClass.newVariable(ad.pos, mkTerm(forName))
- .setFlag(PRIVATE | STATIC | SYNTHETIC)
- .setInfo(forType)
- if (isFinal) varSym setFlag FINAL else varSym addAnnotation AnnotationInfo(VolatileAttr.tpe, Nil, Nil)
- currentClass.info.decls enter varSym
+ val varSym = (
+ currentClass.newVariable(ad.pos, mkTerm(forName))
+ setFlag (PRIVATE | STATIC | SYNTHETIC)
+ setInfo (forType)
+ )
+ if (isFinal) varSym setFlag FINAL
+ else varSym.addAnnotation(VolatileAttr)
+ currentClass.info.decls enter varSym
val varDef = typedPos( VAL(varSym) === forInit )
newStaticMembers append transform(varDef)
diff --git a/src/compiler/scala/tools/nsc/transform/LazyVals.scala b/src/compiler/scala/tools/nsc/transform/LazyVals.scala
index 857966fadd..c3aae2b65e 100644
--- a/src/compiler/scala/tools/nsc/transform/LazyVals.scala
+++ b/src/compiler/scala/tools/nsc/transform/LazyVals.scala
@@ -248,7 +248,7 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD
else {
val sym = meth.newVariable(meth.pos, nme.bitmapName(n)).setInfo(IntClass.tpe)
atPhase(currentRun.typerPhase) {
- sym addAnnotation AnnotationInfo(VolatileAttr.tpe, Nil, Nil)
+ sym addAnnotation VolatileAttr
}
bitmaps(meth) = (sym :: bmps).reverse
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index 885a15c419..8dbc34d9d1 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -519,7 +519,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
}
} else {
if (currentOwner.isTrait && sym.isSetter && !atPhase(currentRun.picklerPhase)(sym.isDeferred)) {
- sym.addAnnotation(AnnotationInfo(TraitSetterAnnotationClass.tpe, List(), List()))
+ sym.addAnnotation(TraitSetterAnnotationClass)
}
tree
}
@@ -705,13 +705,13 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
def createBitmap: Symbol = {
val sym = clazz0.newVariable(clazz0.pos, bitmapName).setInfo(IntClass.tpe)
atPhase(currentRun.typerPhase) {
- sym addAnnotation AnnotationInfo(VolatileAttr.tpe, Nil, Nil)
+ sym addAnnotation VolatileAttr
}
// What's going on here, why is setFlag called three times?
bitmapOperation(
field,
- { sym.addAnnotation(AnnotationInfo(TransientAttr.tpe, Nil, Nil)); sym.setFlag(PrivateLocal) },
+ { sym.addAnnotation(TransientAttr); sym.setFlag(PrivateLocal) },
sym setFlag PrivateLocal,
sym setFlag (if (checkinitField) PrivateLocal else PROTECTED)
)
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index c9cc8e46a8..0f07ac0641 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -987,7 +987,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
*/
private def subst(env: TypeEnv, tpe: Type): Type = {
class FullTypeMap(from: List[Symbol], to: List[Type]) extends SubstTypeMap(from, to) with AnnotationFilter {
- def keepAnnotation(annot: AnnotationInfo) = annot.atp.typeSymbol != uncheckedVarianceClass
+ def keepAnnotation(annot: AnnotationInfo) = !(annot matches uncheckedVarianceClass)
override def mapOver(tp: Type): Type = tp match {
case ClassInfoType(parents, decls, clazz) =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 5073cd02ae..b25c52b324 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -558,7 +558,7 @@ trait Namers { self: Analyzer =>
finishWith(tparams)
case DefDef(mods, name, tparams, _, _, _) =>
tree.symbol = enterNewMethod(tree, name, mods.flags, mods, tree.pos)
- if (mods.annotations.exists(ann => isAnn(ann, "bridge")))
+ if (mods hasAnnotationNamed tpnme.bridgeAnnot)
tree.symbol setFlag BRIDGE
finishWith(tparams)
case TypeDef(mods, name, tparams, _) =>
@@ -602,18 +602,11 @@ trait Namers { self: Analyzer =>
def enterAccessorMethod(tree: Tree, name: Name, flags: Long, mods: Modifiers): TermSymbol =
enterNewMethod(tree, name, flags, mods, tree.pos.focus)
- def isAnn(ann: Tree, demand: String) = ann match {
- case Apply(Select(New(Ident(name)), _), _) =>
- name.toString == demand
- case Apply(Select(New(Select(pre, name)), _), _) =>
- name.toString == demand
- case _ => false
- }
-
private def addBeanGetterSetter(vd: ValDef, getter: Symbol) {
val ValDef(mods, name, tpt, _) = vd
- val hasBP = mods.annotations.exists(isAnn(_, "BeanProperty"))
- val hasBoolBP = mods.annotations.exists(isAnn(_, "BooleanBeanProperty"))
+ val hasBP = mods hasAnnotationNamed tpnme.BeanPropertyAnnot
+ val hasBoolBP = mods hasAnnotationNamed tpnme.BooleanBeanPropertyAnnot
+
if ((hasBP || hasBoolBP) && !forMSIL) {
if (!name(0).isLetter)
context.error(vd.pos, "`BeanProperty' annotation can be applied "+
@@ -1266,9 +1259,9 @@ trait Namers { self: Analyzer =>
LazyAnnotationInfo(() => typer.typedAnnotation(ann))
}
if (!ainfos.isEmpty)
- annotated.setAnnotations(ainfos)
+ annotated.setRawAnnotations(ainfos)
if (annotated.isTypeSkolem)
- annotated.deSkolemize.setAnnotations(ainfos)
+ annotated.deSkolemize.setRawAnnotations(ainfos)
case _ =>
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index b3e1e3feb8..ca90bb8e6b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -869,7 +869,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
validateVariances(tparams map (_.info), variance)
validateVariance(result, variance)
case AnnotatedType(annots, tp, selfsym) =>
- if (!(annots exists (_.atp.typeSymbol.isNonBottomSubClass(uncheckedVarianceClass))))
+ if (!annots.exists(_ matches uncheckedVarianceClass))
validateVariance(tp, variance)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 676ad34592..d01cd829ac 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1490,36 +1490,21 @@ trait Typers extends Modes with Adaptations {
/**
* The annotations amongst `annots` that should go on a member of class
- * `memberClass` (field, getter, setter, beanGetter, beanSetter, param)
- * If 'keepClean' is true, annotations without any meta-annotation are kept
+ * `annotKind` (one of: field, getter, setter, beanGetter, beanSetter, param)
+ * If 'keepClean' is true, annotations without any meta-annotations are kept.
*/
- protected def memberAnnots(annots: List[AnnotationInfo], memberClass: Symbol, keepClean: Boolean = false) = {
-
- def hasMatching(metaAnnots: List[AnnotationInfo], orElse: => Boolean) = {
- // either one of the meta-annotations matches the `memberClass`
- metaAnnots.exists(_.atp.typeSymbol == memberClass) ||
- // else, if there is no `target` meta-annotation at all, use the default case
- (metaAnnots.forall(ann => {
- val annClass = ann.atp.typeSymbol
- annClass != FieldTargetClass && annClass != GetterTargetClass &&
- annClass != SetterTargetClass && annClass != BeanGetterTargetClass &&
- annClass != BeanSetterTargetClass && annClass != ParamTargetClass
- }) && orElse)
- }
-
- // there was no meta-annotation on `ann`. Look if the class annotations of
- // `ann` has a `target` annotation, otherwise put `ann` only on fields.
- def noMetaAnnot(ann: AnnotationInfo) = {
- hasMatching(ann.atp.typeSymbol.annotations, keepClean)
+ protected def memberAnnots(annots: List[AnnotationInfo], annotKind: Symbol, keepClean: Boolean = false) = {
+ annots filter { ann =>
+ // There are no meta-annotation arguments attached to `ann`
+ if (ann.metaAnnotations.isEmpty) {
+ // A meta-annotation matching `annotKind` exists on `ann`'s definition.
+ (ann.defaultTargets contains annotKind) ||
+ // `ann`'s definition has no meta-annotations, and `keepClean` is true.
+ (ann.defaultTargets.isEmpty && keepClean)
+ }
+ // There are meta-annotation arguments, and one of them matches `annotKind`
+ else ann.metaAnnotations exists (_ matches annotKind)
}
-
- annots.filter(ann => ann.atp match {
- // the annotation type has meta-annotations, e.g. @(foo @getter)
- case AnnotatedType(metaAnnots, _, _) =>
- hasMatching(metaAnnots, noMetaAnnot(ann))
- // there are no meta-annotations, e.g. @foo
- case _ => noMetaAnnot(ann)
- })
}
protected def enterSyms(txt: Context, trees: List[Tree]) = {
diff --git a/src/library/scala/beans/meta/beanGetter.scala b/src/library/scala/annotation/meta/beanGetter.scala
index 3eb2dcbda3..040a3f415a 100644
--- a/src/library/scala/beans/meta/beanGetter.scala
+++ b/src/library/scala/annotation/meta/beanGetter.scala
@@ -5,9 +5,9 @@
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
-package scala.beans.meta
+package scala.annotation.meta
/**
- * Consult the documentation in package [[scala.beans.meta]].
+ * Consult the documentation in package [[scala.annotation.meta]].
*/
final class beanGetter extends annotation.StaticAnnotation
diff --git a/src/library/scala/beans/meta/beanSetter.scala b/src/library/scala/annotation/meta/beanSetter.scala
index 8c61acfe6d..45ea063169 100644
--- a/src/library/scala/beans/meta/beanSetter.scala
+++ b/src/library/scala/annotation/meta/beanSetter.scala
@@ -5,9 +5,9 @@
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
-package scala.beans.meta
+package scala.annotation.meta
/**
- * Consult the documentation in package [[scala.beans.meta]].
+ * Consult the documentation in package [[scala.annotation.meta]].
*/
final class beanSetter extends annotation.StaticAnnotation
diff --git a/src/library/scala/beans/meta/field.scala b/src/library/scala/annotation/meta/field.scala
index 135b2e590c..78f4a98544 100644
--- a/src/library/scala/beans/meta/field.scala
+++ b/src/library/scala/annotation/meta/field.scala
@@ -5,9 +5,9 @@
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
-package scala.beans.meta
+package scala.annotation.meta
/**
- * Consult the documentation in package [[scala.beans.meta]].
+ * Consult the documentation in package [[scala.annotation.meta]].
*/
final class field extends annotation.StaticAnnotation
diff --git a/src/library/scala/beans/meta/getter.scala b/src/library/scala/annotation/meta/getter.scala
index 18afa8e324..07e4512f00 100644
--- a/src/library/scala/beans/meta/getter.scala
+++ b/src/library/scala/annotation/meta/getter.scala
@@ -5,9 +5,9 @@
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
-package scala.beans.meta
+package scala.annotation.meta
/**
- * Consult the documentation in package [[scala.beans.meta]].
+ * Consult the documentation in package [[scala.annotation.meta]].
*/
final class getter extends annotation.StaticAnnotation
diff --git a/src/library/scala/beans/meta/package.scala b/src/library/scala/annotation/meta/package.scala
index c7b7b425e1..2d18ae5dd7 100644
--- a/src/library/scala/beans/meta/package.scala
+++ b/src/library/scala/annotation/meta/package.scala
@@ -1,4 +1,4 @@
-package scala.beans
+package scala.annotation
/**
* When defining a field, the Scala compiler creates up to four accessors
@@ -18,7 +18,7 @@ package scala.beans
* end up on the parameter, not on any other entity. Annotations on fields
* by default only end up on the field.
*
- * The meta-annotations in package `scala.beans.meta` are used
+ * The meta-annotations in package `scala.annotation.meta` are used
* to control where annotations on fields and class parameters are copied.
* This is done by annotating either the annotation type or the annotation
* class with one or several of the meta-annotations in this package.
diff --git a/src/library/scala/beans/meta/param.scala b/src/library/scala/annotation/meta/param.scala
index 45c3e3e00f..d9ebcc76d3 100644
--- a/src/library/scala/beans/meta/param.scala
+++ b/src/library/scala/annotation/meta/param.scala
@@ -5,9 +5,9 @@
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
-package scala.beans.meta
+package scala.annotation.meta
/**
- * Consult the documentation in package [[scala.beans.meta]].
+ * Consult the documentation in package [[scala.annotation.meta]].
*/
final class param extends annotation.StaticAnnotation
diff --git a/src/library/scala/beans/meta/setter.scala b/src/library/scala/annotation/meta/setter.scala
index 5a23b7b53d..c27cee2985 100644
--- a/src/library/scala/beans/meta/setter.scala
+++ b/src/library/scala/annotation/meta/setter.scala
@@ -5,9 +5,9 @@
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
-package scala.beans.meta
+package scala.annotation.meta
/**
- * Consult the documentation in package [[scala.beans.meta]].
+ * Consult the documentation in package [[scala.annotation.meta]].
*/
final class setter extends annotation.StaticAnnotation
diff --git a/src/library/scala/annotation/target/package.scala b/src/library/scala/annotation/target/package.scala
index 3aff964c7b..8563bf698e 100644
--- a/src/library/scala/annotation/target/package.scala
+++ b/src/library/scala/annotation/target/package.scala
@@ -9,21 +9,21 @@
package scala.annotation
package object target {
- @deprecated("Use `@scala.beans.meta.beanGetter` instead", "2.10.0")
- type beanGetter = scala.beans.meta.beanGetter
+ @deprecated("Use `@scala.annotation.meta.beanGetter` instead", "2.10.0")
+ type beanGetter = scala.annotation.meta.beanGetter
- @deprecated("Use `@scala.beans.meta.beanSetter` instead", "2.10.0")
- type beanSetter = scala.beans.meta.beanSetter
+ @deprecated("Use `@scala.annotation.meta.beanSetter` instead", "2.10.0")
+ type beanSetter = scala.annotation.meta.beanSetter
- @deprecated("Use `@scala.beans.meta.field` instead", "2.10.0")
- type field = scala.beans.meta.field
+ @deprecated("Use `@scala.annotation.meta.field` instead", "2.10.0")
+ type field = scala.annotation.meta.field
- @deprecated("Use `@scala.beans.meta.getter` instead", "2.10.0")
- type getter = scala.beans.meta.getter
+ @deprecated("Use `@scala.annotation.meta.getter` instead", "2.10.0")
+ type getter = scala.annotation.meta.getter
- @deprecated("Use `@scala.beans.meta.param` instead", "2.10.0")
- type param = scala.beans.meta.param
+ @deprecated("Use `@scala.annotation.meta.param` instead", "2.10.0")
+ type param = scala.annotation.meta.param
- @deprecated("Use `@scala.beans.meta.setter` instead", "2.10.0")
- type setter = scala.beans.meta.setter
+ @deprecated("Use `@scala.annotation.meta.setter` instead", "2.10.0")
+ type setter = scala.annotation.meta.setter
}
diff --git a/src/library/scala/beans/BeanProperty.scala b/src/library/scala/beans/BeanProperty.scala
index f5708a0ab0..4a2fb716c7 100644
--- a/src/library/scala/beans/BeanProperty.scala
+++ b/src/library/scala/beans/BeanProperty.scala
@@ -8,8 +8,6 @@
package scala.beans
-import meta._
-
/** When attached to a field, this annotation adds a setter and a getter
* method following the Java Bean convention. For example:
* {{{
@@ -24,5 +22,5 @@ import meta._
* For fields of type `Boolean`, if you need a getter named `isStatus`,
* use the `scala.beans.BooleanBeanProperty` annotation instead.
*/
-@field
+@scala.annotation.meta.field
class BeanProperty extends annotation.StaticAnnotation
diff --git a/src/library/scala/beans/BooleanBeanProperty.scala b/src/library/scala/beans/BooleanBeanProperty.scala
index 2215177a80..1c85a88c84 100644
--- a/src/library/scala/beans/BooleanBeanProperty.scala
+++ b/src/library/scala/beans/BooleanBeanProperty.scala
@@ -8,11 +8,9 @@
package scala.beans
-import meta._
-
/** This annotation has the same functionality as
* `scala.beans.BeanProperty`, but the generated Bean getter will be
* named `isFieldName` instead of `getFieldName`.
*/
-@field
+@scala.annotation.meta.field
class BooleanBeanProperty extends annotation.StaticAnnotation
diff --git a/src/library/scala/deprecated.scala b/src/library/scala/deprecated.scala
index 12c36da8d3..111affc904 100644
--- a/src/library/scala/deprecated.scala
+++ b/src/library/scala/deprecated.scala
@@ -8,7 +8,7 @@
package scala
-import beans.meta._
+import annotation.meta._
/** An annotation that designates that a definition is deprecated.
* Access to the member then generates a deprecated warning.
diff --git a/src/library/scala/deprecatedName.scala b/src/library/scala/deprecatedName.scala
index 53f26573c0..cc36be6775 100644
--- a/src/library/scala/deprecatedName.scala
+++ b/src/library/scala/deprecatedName.scala
@@ -8,7 +8,7 @@
package scala
-import beans.meta._
+import annotation.meta._
/**
* An annotation that designates the name of the parameter to which it is
diff --git a/src/library/scala/transient.scala b/src/library/scala/transient.scala
index fd3c824e81..3dcff0664c 100644
--- a/src/library/scala/transient.scala
+++ b/src/library/scala/transient.scala
@@ -10,7 +10,7 @@
package scala
-import beans.meta._
+import annotation.meta._
@field
class transient extends annotation.StaticAnnotation
diff --git a/src/library/scala/volatile.scala b/src/library/scala/volatile.scala
index a45bdf8d14..88726d9336 100644
--- a/src/library/scala/volatile.scala
+++ b/src/library/scala/volatile.scala
@@ -10,7 +10,7 @@
package scala
-import beans.meta._
+import annotation.meta._
@field
class volatile extends annotation.StaticAnnotation
diff --git a/test/files/jvm/annotations.scala b/test/files/jvm/annotations.scala
index a0b087a8db..b1c3c8ba40 100644
--- a/test/files/jvm/annotations.scala
+++ b/test/files/jvm/annotations.scala
@@ -94,7 +94,7 @@ object Test4 {
}
class Foo8(@SourceAnnotation("constructor val") val n: Int) {}
class Foo9 {
- import scala.beans.meta._
+ import scala.annotation.meta._
import scala.beans.BeanProperty
@(SourceAnnotation @getter)("http://apple.com") val x = 0
@BeanProperty @(SourceAnnotation @beanSetter)("http://uppla.com") var y = 0
@@ -103,8 +103,8 @@ object Test4 {
@BeanProperty @myAnn("http://eppli.com") var z = 0
}
class Foo10(@SourceAnnotation("on param 1") val name: String)
- class Foo11(@(SourceAnnotation @scala.beans.meta.field)("on param 2") val name: String)
- class Foo12(@(SourceAnnotation @scala.beans.meta.setter)("on param 3") var name: String)
+ class Foo11(@(SourceAnnotation @scala.annotation.meta.field)("on param 2") val name: String)
+ class Foo12(@(SourceAnnotation @scala.annotation.meta.setter)("on param 3") var name: String)
def run {
import java.lang.annotation.Annotation
import java.lang.reflect.AnnotatedElement
@@ -183,7 +183,7 @@ object Test5 {
object Test6 {
import scala.beans.BeanProperty
- import scala.reflect.BooleanBeanProperty
+ import scala.beans.BooleanBeanProperty
class C(@BeanProperty var text: String)
class D(@BooleanBeanProperty var prop: Boolean) {
@BeanProperty val m: Int = if (prop) 1 else 2
diff --git a/test/files/pos/annotations.scala b/test/files/pos/annotations.scala
index 1cae262bb0..4e5fddda39 100644
--- a/test/files/pos/annotations.scala
+++ b/test/files/pos/annotations.scala
@@ -79,7 +79,7 @@ class C extends T with BeanF {
trait T {
@scala.beans.BeanProperty var f = "nei"
- @scala.reflect.BooleanBeanProperty var g = false
+ @scala.beans.BooleanBeanProperty var g = false
}
trait BeanF {