summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@epfl.ch>2009-09-29 19:00:05 +0000
committerLukas Rytz <lukas.rytz@epfl.ch>2009-09-29 19:00:05 +0000
commit0d724fbb3e193b46fef840d12258eab26ed206f2 (patch)
tree80ead17bfb5369212d90b78682145256cac1edc0
parent2a91d630e70d1c9ff349d7e57d7e084780cf11fb (diff)
downloadscala-0d724fbb3e193b46fef840d12258eab26ed206f2.tar.gz
scala-0d724fbb3e193b46fef840d12258eab26ed206f2.tar.bz2
scala-0d724fbb3e193b46fef840d12258eab26ed206f2.zip
improved annotations copying (documentation, mo...
improved annotations copying (documentation, moved meta-annotations, added tests)
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala3
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala10
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala3
-rw-r--r--src/library/scala/annotation/beanGetter.scala12
-rw-r--r--src/library/scala/annotation/beanSetter.scala12
-rw-r--r--src/library/scala/annotation/field.scala12
-rw-r--r--src/library/scala/annotation/getter.scala12
-rw-r--r--src/library/scala/annotation/setter.scala12
-rw-r--r--src/library/scala/annotation/target/beanGetter.scala42
-rw-r--r--src/library/scala/annotation/target/beanSetter.scala42
-rw-r--r--src/library/scala/annotation/target/field.scala42
-rw-r--r--src/library/scala/annotation/target/getter.scala42
-rw-r--r--src/library/scala/annotation/target/setter.scala42
-rw-r--r--test/files/jvm/annotations.check12
-rw-r--r--test/files/jvm/annotations.scala11
16 files changed, 244 insertions, 67 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
index 4956ca1074..346fce3395 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala
@@ -450,6 +450,9 @@ trait TypeKinds { self: ICodes =>
case ExistentialType(tparams, t) =>
toTypeKind(t)
+ case AnnotatedType(_, t, _) =>
+ toTypeKind(t)
+
//case WildcardType => // bq: useful hack when wildcard types come here
// REFERENCE(definitions.ObjectClass)
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index e486b56df6..71e9725944 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -98,11 +98,11 @@ trait Definitions {
lazy val SwitchClass = getClass("scala.annotation.switch")
lazy val ExperimentalClass = getClass("scala.annotation.experimental")
lazy val ElidableMethodClass = getClass("scala.annotation.elidable")
- lazy val FieldClass = getClass("scala.annotation.field")
- lazy val GetterClass = getClass("scala.annotation.getter")
- lazy val SetterClass = getClass("scala.annotation.setter")
- lazy val BeanGetterClass = getClass("scala.annotation.beanGetter")
- lazy val BeanSetterClass = getClass("scala.annotation.beanSetter")
+ lazy val FieldClass = getClass("scala.annotation.target.field")
+ lazy val GetterClass = getClass("scala.annotation.target.getter")
+ lazy val SetterClass = getClass("scala.annotation.target.setter")
+ lazy val BeanGetterClass = getClass("scala.annotation.target.beanGetter")
+ lazy val BeanSetterClass = getClass("scala.annotation.target.beanSetter")
// fundamental reference classes
lazy val ScalaObjectClass = getClass("scala.ScalaObject")
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 6e880c91fc..e84a1dd4d4 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -1106,7 +1106,7 @@ trait Namers { self: Analyzer =>
val annotated = if (sym.isModule) sym.moduleClass else sym
// typeSig might be called multiple times, e.g. on a ValDef: val, getter, setter
// parse the annotations only once.
- if (annotated.rawAnnotations.isEmpty) tree match {
+ if (!annotated.isInitialized) tree match {
case defn: MemberDef =>
val ainfos = defn.mods.annotations filter { _ != null } map { ann =>
// need to be lazy, #1782
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index d9d9bda13f..a552c2ef7c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1293,7 +1293,8 @@ trait Typers { self: Analyzer =>
val isDeferred = mods hasFlag DEFERRED
val value = stat.symbol
val allAnnots = value.annotations
- value.setAnnotations(memberAnnots(allAnnots, FieldClass))
+ if (!isDeferred)
+ value.setAnnotations(memberAnnots(allAnnots, FieldClass))
val getter = if (isDeferred) value else value.getter(value.owner)
assert(getter != NoSymbol, stat)
diff --git a/src/library/scala/annotation/beanGetter.scala b/src/library/scala/annotation/beanGetter.scala
deleted file mode 100644
index 446db85a4e..0000000000
--- a/src/library/scala/annotation/beanGetter.scala
+++ /dev/null
@@ -1,12 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2009, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-package scala.annotation
-
-/** Doc
- */
-final class beanGetter extends StaticAnnotation
diff --git a/src/library/scala/annotation/beanSetter.scala b/src/library/scala/annotation/beanSetter.scala
deleted file mode 100644
index 0febc8f05d..0000000000
--- a/src/library/scala/annotation/beanSetter.scala
+++ /dev/null
@@ -1,12 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2009, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-package scala.annotation
-
-/** Doc
- */
-final class beanSetter extends StaticAnnotation
diff --git a/src/library/scala/annotation/field.scala b/src/library/scala/annotation/field.scala
deleted file mode 100644
index 2fd4515235..0000000000
--- a/src/library/scala/annotation/field.scala
+++ /dev/null
@@ -1,12 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2009, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-package scala.annotation
-
-/** Doc
- */
-final class field extends StaticAnnotation
diff --git a/src/library/scala/annotation/getter.scala b/src/library/scala/annotation/getter.scala
deleted file mode 100644
index 559c132cc5..0000000000
--- a/src/library/scala/annotation/getter.scala
+++ /dev/null
@@ -1,12 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2009, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-package scala.annotation
-
-/** Doc
- */
-final class getter extends StaticAnnotation
diff --git a/src/library/scala/annotation/setter.scala b/src/library/scala/annotation/setter.scala
deleted file mode 100644
index 8b5583c825..0000000000
--- a/src/library/scala/annotation/setter.scala
+++ /dev/null
@@ -1,12 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2009, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-package scala.annotation
-
-/** Doc
- */
-final class setter extends StaticAnnotation
diff --git a/src/library/scala/annotation/target/beanGetter.scala b/src/library/scala/annotation/target/beanGetter.scala
new file mode 100644
index 0000000000..2490dd871e
--- /dev/null
+++ b/src/library/scala/annotation/target/beanGetter.scala
@@ -0,0 +1,42 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2009, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+package scala.annotation.target
+
+/**
+ * For every field of a class, the Scala compiler generates up to four
+ * synthetic accessors: getter, setter, bean getter and bean setter.
+ * The meta-annotations in package {{{scala.annotation.target}}} are
+ * used to control to which of the above members the annotations on
+ * the field are copied. By default, field annotations are only added
+ * to the actual field, but not to any of the accessors. By annotating
+ * the annotation type with one or several of the meta-annotations this
+ * behavior can be changed.
+ *
+ * In the following example, the annotation {{{@Id}}} will be added
+ * to the bean getter {{{getX}}}
+ *
+ * {{{
+ * import javax.persistence.Id
+ * class A {
+ * @(Id @beanGetter) @BeanProperty val x = 0
+ * }
+ * }}}
+ *
+ * The syntax can be improved using a type alias:
+ *
+ * {{{
+ * object myAnnotations {
+ * type Id = javax.persistence.Id @beanGetter
+ * }
+ * import myAnnotations.Id
+ * class A {
+ * @Id @BeanProperty val x = 0
+ * }
+ * }}}
+ */
+final class beanGetter extends StaticAnnotation
diff --git a/src/library/scala/annotation/target/beanSetter.scala b/src/library/scala/annotation/target/beanSetter.scala
new file mode 100644
index 0000000000..57c62ee764
--- /dev/null
+++ b/src/library/scala/annotation/target/beanSetter.scala
@@ -0,0 +1,42 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2009, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+package scala.annotation.target
+
+/**
+ * For every field of a class, the Scala compiler generates up to four
+ * synthetic accessors: getter, setter, bean getter and bean setter.
+ * The meta-annotations in package {{{scala.annotation.target}}} are
+ * used to control to which of the above members the annotations on
+ * the field are copied. By default, field annotations are only added
+ * to the actual field, but not to any of the accessors. By annotating
+ * the annotation type with one or several of the meta-annotations this
+ * behavior can be changed.
+ *
+ * In the following example, the annotation {{{@Id}}} will be added
+ * to the bean getter {{{getX}}}
+ *
+ * {{{
+ * import javax.persistence.Id
+ * class A {
+ * @(Id @beanGetter) @BeanProperty val x = 0
+ * }
+ * }}}
+ *
+ * The syntax can be improved using a type alias:
+ *
+ * {{{
+ * object myAnnotations {
+ * type Id = javax.persistence.Id @beanGetter
+ * }
+ * import myAnnotations.Id
+ * class A {
+ * @Id @BeanProperty val x = 0
+ * }
+ * }}}
+ */
+final class beanSetter extends StaticAnnotation
diff --git a/src/library/scala/annotation/target/field.scala b/src/library/scala/annotation/target/field.scala
new file mode 100644
index 0000000000..5d0277fade
--- /dev/null
+++ b/src/library/scala/annotation/target/field.scala
@@ -0,0 +1,42 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2009, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+package scala.annotation.target
+
+/**
+ * For every field of a class, the Scala compiler generates up to four
+ * synthetic accessors: getter, setter, bean getter and bean setter.
+ * The meta-annotations in package {{{scala.annotation.target}}} are
+ * used to control to which of the above members the annotations on
+ * the field are copied. By default, field annotations are only added
+ * to the actual field, but not to any of the accessors. By annotating
+ * the annotation type with one or several of the meta-annotations this
+ * behavior can be changed.
+ *
+ * In the following example, the annotation {{{@Id}}} will be added
+ * to the bean getter {{{getX}}}
+ *
+ * {{{
+ * import javax.persistence.Id
+ * class A {
+ * @(Id @beanGetter) @BeanProperty val x = 0
+ * }
+ * }}}
+ *
+ * The syntax can be improved using a type alias:
+ *
+ * {{{
+ * object myAnnotations {
+ * type Id = javax.persistence.Id @beanGetter
+ * }
+ * import myAnnotations.Id
+ * class A {
+ * @Id @BeanProperty val x = 0
+ * }
+ * }}}
+ */
+final class field extends StaticAnnotation
diff --git a/src/library/scala/annotation/target/getter.scala b/src/library/scala/annotation/target/getter.scala
new file mode 100644
index 0000000000..ed9ed89f07
--- /dev/null
+++ b/src/library/scala/annotation/target/getter.scala
@@ -0,0 +1,42 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2009, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+package scala.annotation.target
+
+/**
+ * For every field of a class, the Scala compiler generates up to four
+ * synthetic accessors: getter, setter, bean getter and bean setter.
+ * The meta-annotations in package {{{scala.annotation.target}}} are
+ * used to control to which of the above members the annotations on
+ * the field are copied. By default, field annotations are only added
+ * to the actual field, but not to any of the accessors. By annotating
+ * the annotation type with one or several of the meta-annotations this
+ * behavior can be changed.
+ *
+ * In the following example, the annotation {{{@Id}}} will be added
+ * to the bean getter {{{getX}}}
+ *
+ * {{{
+ * import javax.persistence.Id
+ * class A {
+ * @(Id @beanGetter) @BeanProperty val x = 0
+ * }
+ * }}}
+ *
+ * The syntax can be improved using a type alias:
+ *
+ * {{{
+ * object myAnnotations {
+ * type Id = javax.persistence.Id @beanGetter
+ * }
+ * import myAnnotations.Id
+ * class A {
+ * @Id @BeanProperty val x = 0
+ * }
+ * }}}
+ */
+final class getter extends StaticAnnotation
diff --git a/src/library/scala/annotation/target/setter.scala b/src/library/scala/annotation/target/setter.scala
new file mode 100644
index 0000000000..e4eae905b7
--- /dev/null
+++ b/src/library/scala/annotation/target/setter.scala
@@ -0,0 +1,42 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2009, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+package scala.annotation.target
+
+/**
+ * For every field of a class, the Scala compiler generates up to four
+ * synthetic accessors: getter, setter, bean getter and bean setter.
+ * The meta-annotations in package {{{scala.annotation.target}}} are
+ * used to control to which of the above members the annotations on
+ * the field are copied. By default, field annotations are only added
+ * to the actual field, but not to any of the accessors. By annotating
+ * the annotation type with one or several of the meta-annotations this
+ * behavior can be changed.
+ *
+ * In the following example, the annotation {{{@Id}}} will be added
+ * to the bean getter {{{getX}}}
+ *
+ * {{{
+ * import javax.persistence.Id
+ * class A {
+ * @(Id @beanGetter) @BeanProperty val x = 0
+ * }
+ * }}}
+ *
+ * The syntax can be improved using a type alias:
+ *
+ * {{{
+ * object myAnnotations {
+ * type Id = javax.persistence.Id @beanGetter
+ * }
+ * import myAnnotations.Id
+ * class A {
+ * @Id @BeanProperty val x = 0
+ * }
+ * }}}
+ */
+final class setter extends StaticAnnotation
diff --git a/test/files/jvm/annotations.check b/test/files/jvm/annotations.check
index 214c60d06f..0194a7f77d 100644
--- a/test/files/jvm/annotations.check
+++ b/test/files/jvm/annotations.check
@@ -25,5 +25,17 @@ public Test4$Foo7()
@test.SourceAnnotation(mails={bill.gates@bloodsuckers.com}, value=constructor val)
private final int Test4$Foo8.n
+@test.SourceAnnotation(mails={bill.gates@bloodsuckers.com}, value=http://eppli.com)
+private int Test4$Foo9.z
+
+@test.SourceAnnotation(mails={bill.gates@bloodsuckers.com}, value=http://apple.com)
+public int Test4$Foo9.x()
+
+@test.SourceAnnotation(mails={bill.gates@bloodsuckers.com}, value=http://eppli.com)
+public int Test4$Foo9.getZ()
+
+@test.SourceAnnotation(mails={bill.gates@bloodsuckers.com}, value=http://uppla.com)
+public void Test4$Foo9.setY(int)
+
0
99
diff --git a/test/files/jvm/annotations.scala b/test/files/jvm/annotations.scala
index ec3841b958..902ea87a90 100644
--- a/test/files/jvm/annotations.scala
+++ b/test/files/jvm/annotations.scala
@@ -93,6 +93,15 @@ object Test4 {
def this() = this("")
}
class Foo8(@SourceAnnotation("constructor val") val n: Int) {}
+ class Foo9 {
+ import scala.annotation.target._
+ import scala.reflect.BeanProperty
+ @(SourceAnnotation @getter)("http://apple.com") val x = 0
+ @BeanProperty @(SourceAnnotation @beanSetter)("http://uppla.com") var y = 0
+
+ type myAnn = SourceAnnotation @beanGetter @field
+ @BeanProperty @myAnn("http://eppli.com") var z = 0
+ }
def run {
import java.lang.annotation.Annotation
import java.lang.reflect.AnnotatedElement
@@ -121,6 +130,8 @@ object Test4 {
classOf[Foo7].getDeclaredConstructors foreach printSourceAnnotations
classOf[Foo8].getDeclaredFields foreach printSourceAnnotations
classOf[Foo8].getDeclaredMethods foreach printSourceAnnotations
+ classOf[Foo9].getDeclaredFields foreach printSourceAnnotations
+ classOf[Foo9].getDeclaredMethods foreach printSourceAnnotations
}
}