diff options
author | Lukas Rytz <lukas.rytz@epfl.ch> | 2009-09-25 09:20:06 +0000 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@epfl.ch> | 2009-09-25 09:20:06 +0000 |
commit | a43a29e64351a60fc563f777e5dbb07e001470e7 (patch) | |
tree | 0d281fa35b3c97bc6a3ae2f69febe4953f481411 | |
parent | 026b824ecc441261db79eec45eb0a3d0ebd50e80 (diff) | |
download | scala-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.
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Definitions.scala | 5 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Types.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Namers.scala | 3 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 42 | ||||
-rw-r--r-- | src/library/scala/annotation/beanGetter.scala | 12 | ||||
-rw-r--r-- | src/library/scala/annotation/beanSetter.scala | 12 | ||||
-rw-r--r-- | src/library/scala/annotation/field.scala | 12 | ||||
-rw-r--r-- | src/library/scala/annotation/getter.scala | 12 | ||||
-rw-r--r-- | src/library/scala/annotation/setter.scala | 12 |
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 |