summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@epfl.ch>2009-09-25 09:20:06 +0000
committerLukas Rytz <lukas.rytz@epfl.ch>2009-09-25 09:20:06 +0000
commita43a29e64351a60fc563f777e5dbb07e001470e7 (patch)
tree0d281fa35b3c97bc6a3ae2f69febe4953f481411 /src
parent026b824ecc441261db79eec45eb0a3d0ebd50e80 (diff)
downloadscala-a43a29e64351a60fc563f777e5dbb07e001470e7.tar.gz
scala-a43a29e64351a60fc563f777e5dbb07e001470e7.tar.bz2
scala-a43a29e64351a60fc563f777e5dbb07e001470e7.zip
copying of field annotations can now be control...
copying of field annotations can now be controlled, annotate the annotation class (works with type aliases). Names & location of the meta-annotations field/getter/setter/beanGetter/beanSetter to be discussed.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala5
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala42
-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
9 files changed, 99 insertions, 13 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index 404ffbafc1..e486b56df6 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -98,6 +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")
// fundamental reference classes
lazy val ScalaObjectClass = getClass("scala.ScalaObject")
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index b6deb501f0..a359ec1c57 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -1949,7 +1949,7 @@ A type's typeSymbol should never be inspected directly.
/** Add a number of annotations to this type */
override def withAnnotations(annots: List[AnnotationInfo]): Type =
- AnnotatedType(annots:::this.annotations, this, selfsym)
+ copy(annots:::this.annotations)
/** Remove any annotations from this type */
override def withoutAnnotations = underlying.withoutAnnotations
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index dd166b3086..6e880c91fc 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -482,8 +482,7 @@ trait Namers { self: Analyzer =>
val getterName = if (hasBoolBP) "is" + beanName
else "get" + beanName
- val getterMods = Modifiers(flags, mods.privateWithin,
- mods.annotations map (_.duplicate))
+ val getterMods = Modifiers(flags, mods.privateWithin, Nil)
val beanGetterDef = atPos(vd.pos.focus) {
DefDef(getterMods, getterName, Nil, List(Nil), tpt.duplicate,
if (mods hasFlag DEFERRED) EmptyTree
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 2408e1b8c9..90e263587c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1260,15 +1260,30 @@ trait Typers { self: Analyzer =>
def addGetterSetter(stat: Tree): List[Tree] = stat match {
case ValDef(mods, name, tpt, rhs)
if (mods.flags & (PRIVATE | LOCAL)) != (PRIVATE | LOCAL).toLong && !stat.symbol.isModuleVar =>
+
+ def memberAnnots(annots: List[AnnotationInfo], memberClass: Symbol) = {
+ annots.filter(ann => ann.atp match {
+ case AnnotatedType(annots, _, _) =>
+ annots.exists(_.atp.typeSymbol == memberClass) ||
+ (memberClass == FieldClass && annots.forall(ann => {
+ val annClass = ann.atp.typeSymbol
+ annClass != GetterClass && annClass != SetterClass &&
+ annClass != BeanGetterClass && annClass != BeanSetterClass
+ }))
+ case _ => memberClass == FieldClass
+ })
+ }
+
val isDeferred = mods hasFlag DEFERRED
val value = stat.symbol
+ val allAnnots = value.annotations
+ value.setAnnotations(memberAnnots(allAnnots, FieldClass))
+
val getter = if (isDeferred) value else value.getter(value.owner)
assert(getter != NoSymbol, stat)
if (getter hasFlag OVERLOADED)
error(getter.pos, getter+" is defined twice")
-
- // todo: potentially dangerous not to duplicate the trees and clone the symbols / types.
- getter.setAnnotations(value.annotations)
+ getter.setAnnotations(memberAnnots(allAnnots, GetterClass))
if (value.hasFlag(LAZY)) List(stat)
else {
@@ -1290,8 +1305,8 @@ trait Typers { self: Analyzer =>
}
}
checkNoEscaping.privates(getter, getterDef.tpt)
- def setterDef(setter: Symbol): DefDef = {
- setter.setAnnotations(value.annotations)
+ def setterDef(setter: Symbol, isBean: Boolean = false): DefDef = {
+ setter.setAnnotations(memberAnnots(allAnnots, if (isBean) BeanSetterClass else SetterClass))
val result = typed {
atPos(vdef.pos.focus) {
DefDef(
@@ -1315,12 +1330,19 @@ trait Typers { self: Analyzer =>
if (mods hasFlag MUTABLE) {
val setter = getter.setter(value.owner)
gs.append(setterDef(setter))
- if (!forMSIL && (value.hasAnnotation(BeanPropertyAttr) ||
- value.hasAnnotation(BooleanBeanPropertyAttr))) {
- val beanSetterName = "set" + name(0).toString.toUpperCase +
- name.subName(1, name.length)
+ }
+ if (!forMSIL && (value.hasAnnotation(BeanPropertyAttr) ||
+ value.hasAnnotation(BooleanBeanPropertyAttr))) {
+ val nameSuffix = name(0).toString.toUpperCase + name.subName(1, name.length)
+ val beanGetterName =
+ (if (value.hasAnnotation(BooleanBeanPropertyAttr)) "is" else "get") +
+ nameSuffix
+ val beanGetter = value.owner.info.decl(beanGetterName)
+ beanGetter.setAnnotations(memberAnnots(allAnnots, BeanGetterClass))
+ if (mods hasFlag MUTABLE) {
+ val beanSetterName = "set" + nameSuffix
val beanSetter = value.owner.info.decl(beanSetterName)
- gs.append(setterDef(beanSetter))
+ gs.append(setterDef(beanSetter, isBean = true))
}
}
if (mods hasFlag DEFERRED) gs.toList else vdef :: gs.toList
diff --git a/src/library/scala/annotation/beanGetter.scala b/src/library/scala/annotation/beanGetter.scala
new file mode 100644
index 0000000000..446db85a4e
--- /dev/null
+++ b/src/library/scala/annotation/beanGetter.scala
@@ -0,0 +1,12 @@
+/* __ *\
+** ________ ___ / / ___ 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
new file mode 100644
index 0000000000..0febc8f05d
--- /dev/null
+++ b/src/library/scala/annotation/beanSetter.scala
@@ -0,0 +1,12 @@
+/* __ *\
+** ________ ___ / / ___ 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
new file mode 100644
index 0000000000..2fd4515235
--- /dev/null
+++ b/src/library/scala/annotation/field.scala
@@ -0,0 +1,12 @@
+/* __ *\
+** ________ ___ / / ___ 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
new file mode 100644
index 0000000000..559c132cc5
--- /dev/null
+++ b/src/library/scala/annotation/getter.scala
@@ -0,0 +1,12 @@
+/* __ *\
+** ________ ___ / / ___ 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
new file mode 100644
index 0000000000..8b5583c825
--- /dev/null
+++ b/src/library/scala/annotation/setter.scala
@@ -0,0 +1,12 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2009, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+package scala.annotation
+
+/** Doc
+ */
+final class setter extends StaticAnnotation