summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@epfl.ch>2009-12-04 08:23:11 +0000
committerLukas Rytz <lukas.rytz@epfl.ch>2009-12-04 08:23:11 +0000
commit0e9c5b7f850d90117cab870d340c2b46cf73586b (patch)
tree3f8adce1a04efcb641d0eec28502a016dfabf633 /src/compiler
parent7feaefb229d567a5f56e8a29746d49db77f63314 (diff)
downloadscala-0e9c5b7f850d90117cab870d340c2b46cf73586b.tar.gz
scala-0e9c5b7f850d90117cab870d340c2b46cf73586b.tar.bz2
scala-0e9c5b7f850d90117cab870d340c2b46cf73586b.zip
close #2708
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala3
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala11
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala82
3 files changed, 55 insertions, 41 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index dbbb306130..736a11a261 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -624,8 +624,9 @@ trait Trees {
var vparamss1 =
vparamss map (vps => vps.map { vd =>
atPos(vd.pos.focus) {
+ val pa = if (vd.hasFlag(PRIVATE | LOCAL)) OL else PARAMACCESSOR
ValDef(
- Modifiers(vd.mods.flags & (IMPLICIT | DEFAULTPARAM) | PARAM) withAnnotations vd.mods.annotations,
+ Modifiers(vd.mods.flags & (IMPLICIT | DEFAULTPARAM) | PARAM | pa) withAnnotations vd.mods.annotations,
vd.name, vd.tpt.duplicate, vd.rhs.duplicate)
}})
val (edefs, rest) = body span treeInfo.isEarlyDef
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index d10c896bc1..4d1650b0bc 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -121,11 +121,12 @@ trait Definitions {
lazy val TailrecClass = getClass("scala.annotation.tailrec")
lazy val SwitchClass = getClass("scala.annotation.switch")
lazy val ElidableMethodClass = getClass("scala.annotation.elidable")
- 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")
+ lazy val FieldTargetClass = getClass("scala.annotation.target.field")
+ lazy val GetterTargetClass = getClass("scala.annotation.target.getter")
+ lazy val SetterTargetClass = getClass("scala.annotation.target.setter")
+ lazy val BeanGetterTargetClass = getClass("scala.annotation.target.beanGetter")
+ lazy val BeanSetterTargetClass = getClass("scala.annotation.target.beanSetter")
+ lazy val ParamTargetClass = getClass("scala.annotation.target.param")
// fundamental reference classes
lazy val ScalaObjectClass = getClass("scala.ScalaObject")
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 58146ffd80..f5062ba665 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1321,48 +1321,17 @@ trait Typers { self: Analyzer =>
case ValDef(mods, name, tpt, rhs)
if (mods.flags & (PRIVATE | LOCAL)) != (PRIVATE | LOCAL).toLong && !stat.symbol.isModuleVar =>
- /** The annotations amongst `annots` that should go on a member of class
- * `memberClass` (field, getter, setter, beanGetter, beanSetter)
- */
- def memberAnnots(annots: List[AnnotationInfo], memberClass: Symbol) = {
-
- 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 != GetterClass && annClass != SetterClass &&
- annClass != BeanGetterClass && annClass != BeanSetterClass
- }) && 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, memberClass == FieldClass)
- }
-
- 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)
- })
- }
-
val isDeferred = mods hasFlag DEFERRED
val value = stat.symbol
val allAnnots = value.annotations
if (!isDeferred)
- value.setAnnotations(memberAnnots(allAnnots, FieldClass))
+ value.setAnnotations(memberAnnots(allAnnots, FieldTargetClass))
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")
- getter.setAnnotations(memberAnnots(allAnnots, GetterClass))
+ getter.setAnnotations(memberAnnots(allAnnots, GetterTargetClass))
if (value.hasFlag(LAZY)) List(stat)
else {
@@ -1385,7 +1354,7 @@ trait Typers { self: Analyzer =>
}
checkNoEscaping.privates(getter, getterDef.tpt)
def setterDef(setter: Symbol, isBean: Boolean = false): DefDef = {
- setter.setAnnotations(memberAnnots(allAnnots, if (isBean) BeanSetterClass else SetterClass))
+ setter.setAnnotations(memberAnnots(allAnnots, if (isBean) BeanSetterTargetClass else SetterTargetClass))
val result = typed {
atPos(vdef.pos.focus) {
DefDef(
@@ -1417,7 +1386,7 @@ trait Typers { self: Analyzer =>
(if (value.hasAnnotation(BooleanBeanPropertyAttr)) "is" else "get") +
nameSuffix
val beanGetter = value.owner.info.decl(beanGetterName)
- beanGetter.setAnnotations(memberAnnots(allAnnots, BeanGetterClass))
+ beanGetter.setAnnotations(memberAnnots(allAnnots, BeanGetterTargetClass))
if (mods hasFlag MUTABLE) {
val beanSetterName = "set" + nameSuffix
val beanSetter = value.owner.info.decl(beanSetterName)
@@ -1436,6 +1405,38 @@ trait Typers { self: Analyzer =>
List(stat)
}
+ /** The annotations amongst `annots` that should go on a member of class
+ * `memberClass` (field, getter, setter, beanGetter, beanSetter, param)
+ */
+ protected def memberAnnots(annots: List[AnnotationInfo], memberClass: Symbol) = {
+
+ 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, memberClass == FieldTargetClass)
+ }
+
+ 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]) = {
var txt0 = txt
for (tree <- trees) txt0 = enterSym(txt0, tree)
@@ -1726,6 +1727,17 @@ trait Typers { self: Analyzer =>
reenterTypeParams(ddef.tparams)
reenterValueParams(ddef.vparamss)
+
+ // for `val` and `var` parameter, look at `target` meta-annotation
+ if (phase.id <= currentRun.typerPhase.id && meth.isPrimaryConstructor) {
+ for (vparams <- ddef.vparamss; vd <- vparams) {
+ if (vd hasFlag PARAMACCESSOR) {
+ val sym = vd.symbol
+ sym.setAnnotations(memberAnnots(sym.annotations, ParamTargetClass))
+ }
+ }
+ }
+
val tparams1 = ddef.tparams mapConserve typedTypeDef
val vparamss1 = ddef.vparamss mapConserve (_ mapConserve typedValDef)