diff options
author | Lex Spoon <lex@lexspoon.org> | 2007-10-10 01:07:30 +0000 |
---|---|---|
committer | Lex Spoon <lex@lexspoon.org> | 2007-10-10 01:07:30 +0000 |
commit | ab093d847caf4d0d014628df1af5e9b611dd1fea (patch) | |
tree | 29bcfa974d0c852f3e407900464e8b7ac5c782a8 | |
parent | 515ab49a70bd897a541acbe975a5fe25a24ff61f (diff) | |
download | scala-ab093d847caf4d0d014628df1af5e9b611dd1fea.tar.gz scala-ab093d847caf4d0d014628df1af5e9b611dd1fea.tar.bz2 scala-ab093d847caf4d0d014628df1af5e9b611dd1fea.zip |
Annotations with embedded annotations are now
parsed but quietly discarded (trac issue #14)
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Constants.scala | 9 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala | 53 |
2 files changed, 51 insertions, 11 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Constants.scala b/src/compiler/scala/tools/nsc/symtab/Constants.scala index b4c7eca43c..ec6f5dbc8c 100644 --- a/src/compiler/scala/tools/nsc/symtab/Constants.scala +++ b/src/compiler/scala/tools/nsc/symtab/Constants.scala @@ -31,6 +31,7 @@ trait Constants { final val ClassTag = LITERALclass - LITERAL final val EnumTag = ClassTag + 1 final val ArrayTag = EnumTag + 1 + final val AnnotationTag = ArrayTag + 1 def isNumeric(tag: Int) = ByteTag <= tag && tag <= DoubleTag @@ -67,6 +68,7 @@ trait Constants { case NullTag => AllRefClass.tpe case ClassTag => Predef_classOfType(value.asInstanceOf[Type]) case EnumTag => symbolValue.owner.linkedClassOfClass.tpe + case AnnotationTag => AnnotationClass.tpe // what should it be? } /** We need the equals method to take account of tags as well as values. @@ -232,4 +234,11 @@ trait Constants { extends Constant(arrayValue) { override def toString() = arrayValue.mkString("Constant(", "," , ")") } + + /** A place-holder for annotation constants. The contents of + * the constant are not read. */ + class AnnotationConstant() + extends Constant(null) { + override val tag = AnnotationTag + } } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 66ef759e79..fe448dcc76 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -680,21 +680,52 @@ abstract class ClassfileParser { } new ArrayConstant(arr.toArray, appliedType(definitions.ArrayClass.typeConstructor, List(arr(0).tpe))) + case ANNOTATION_TAG => + parseAnnotation(index) // skip it + new AnnotationConstant() } } + + /** Parse and return a single annotation. If it is malformed, + * throw an exception. If it contains a nested annotation, + * return None. + */ + def parseAnnotation(attrNameIndex: Char): Option[AnnotationInfo] = { + val attrType = pool.getType(attrNameIndex) + val nargs = in.nextChar + val nvpairs = new ListBuffer[(Name,AnnotationArgument)] + var nestedAnnot = false // if a nested annotation is seen, + // then skip this annotation + for (i <- 0 until nargs) { + val name = pool.getName(in.nextChar) + val argConst = parseTaggedConstant + if (argConst.tag == AnnotationTag) + nestedAnnot = true + else + nvpairs += ((name, new AnnotationArgument(argConst))) + } + + if (nestedAnnot) + None + else + Some(AnnotationInfo(attrType, List(), nvpairs.toList)) + } + + /** Parse a sequence of annotations and attach them to the + * current symbol sym. + */ def parseAnnotations(len: Int) { val nAttr = in.nextChar - for (n <- 0 until nAttr) { - val attrNameIndex = in.nextChar - val attrType = pool.getType(attrNameIndex) - val nargs = in.nextChar - val nvpairs = new ListBuffer[(Name,AnnotationArgument)] - for (i <- 0 until nargs) { - val name = pool.getName(in.nextChar) - nvpairs += ((name, new AnnotationArgument(parseTaggedConstant))) - } - sym.attributes = AnnotationInfo(attrType, List(), nvpairs.toList) :: sym.attributes - } + for (n <- 0 until nAttr) + parseAnnotation(in.nextChar) match { + case None => + if (settings.debug.value) + global.inform("dropping annotation on " + + sym + + " that has a nested annotation") + case Some(annot) => + sym.attributes = annot :: sym.attributes + } } def parseInnerClasses() { |