diff options
author | Martin Odersky <odersky@gmail.com> | 2007-03-06 17:43:03 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2007-03-06 17:43:03 +0000 |
commit | 4ba667134f2a190087675c625fa9d91607fe3231 (patch) | |
tree | fcc9c8b09d6fbefc550eb834158b5e6ff3bec1d5 | |
parent | 70e2162afee52f9e52e652e55a5ab3bbdc550214 (diff) | |
download | scala-4ba667134f2a190087675c625fa9d91607fe3231.tar.gz scala-4ba667134f2a190087675c625fa9d91607fe3231.tar.bz2 scala-4ba667134f2a190087675c625fa9d91607fe3231.zip |
modified annotated types scheme
22 files changed, 145 insertions, 185 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala index 7abb358c45..308fefba31 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala @@ -356,12 +356,9 @@ abstract class TreeBrowsers { case TypeTree() => ("TypeTree", EMPTY) - case Annotated(constr, elements, arg) => + case Annotated(annot, arg) => ("Annotated", EMPTY) - case AttributedTypeTree(attribs, tpt) => - ("AttributedTypeTree", EMPTY) - case SingletonTypeTree(ref) => ("SingletonType", EMPTY) @@ -506,8 +503,8 @@ abstract class TreeBrowsers { case TypeTree() => Nil - case Annotated(constr, elements, arg) => - constr :: elements ::: List(arg) + case Annotated(annot, arg) => + annot.constr :: annot.elements ::: List(arg) case SingletonTypeTree(ref) => List(ref) @@ -660,9 +657,9 @@ abstract class TreeBrowsers { toDocument(result) :: ")") ) - case AttributedType(attribs, tp) => + case AnnotatedType(attribs, tp) => Document.group( - Document.nest(4, "AttributedType(" :/: + Document.nest(4, "AnnotatedType(" :/: attribs.mkString("[", ",", "]") :/: "," :/: toDocument(tp) :: ")") ) diff --git a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala index 28634815a6..280b005a2c 100644 --- a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala +++ b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala @@ -104,14 +104,14 @@ abstract class TreePrinters { if (s.length() != 0) print(s + " ") } - def printAnnotations(tree: Tree): unit = { - val attrs = tree.symbol.attributes - if (!attrs.isEmpty) - attrs foreach { attr => print("@"+attr+" ") } + def printAnnotations(tree: Tree) { + val annots = tree.symbol.attributes + if (!annots.isEmpty) + annots foreach { annot => print("@"+annot+" ") } else { - val attrs = tree.asInstanceOf[MemberDef].mods.attributes - if (!attrs.isEmpty) - attrs foreach { attr => print("@"+attr+" ") } + val annots = tree.asInstanceOf[MemberDef].mods.annotations + if (!annots.isEmpty) + annots foreach { annot => print("@"+annot+" ") } } } @@ -298,18 +298,8 @@ abstract class TreePrinters { tree.tpe.toString() ) - case AttributedTypeTree(attribs, tree) => - for(val attrib <- attribs) { - print("[") - print(attrib) - print("]") - } - if(!attribs.isEmpty) - print(" ") - print(tree) - - case Annotated(Apply(Select(New(tpt), nme.CONSTRUCTOR), args), elements, tree) => - def printAttr() { + case Annotated(Annotation(Apply(Select(New(tpt), nme.CONSTRUCTOR), args), elements), tree) => + def printAnnot() { print("@"); print(tpt) if (!args.isEmpty) printRow(args, "(", ",", ")") @@ -317,8 +307,8 @@ abstract class TreePrinters { print((for (val Assign(name, value) <- elements) yield "val " + name + " = " + value). mkString("{", ",", "}")) } - if (tree.isType) { printAttr(); print(" "); print(tree) } - else { print(tree); print(": "); printAttr() } + if (tree.isType) { printAnnot(); print(" "); print(tree) } + else { print(tree); print(": "); printAnnot() } case SingletonTypeTree(ref) => print(ref); print(".type") diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 0eac9da0c7..7054c695ea 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -17,7 +17,7 @@ trait Trees requires Global { //statistics var nodeCount = 0 - case class Modifiers(flags: int, privateWithin: Name, attributes: List[Annotation]) { + case class Modifiers(flags: int, privateWithin: Name, annotations: List[Annotation]) { def isCovariant = hasFlag(COVARIANT ) def isContravariant = hasFlag(CONTRAVARIANT) def isPrivate = hasFlag(PRIVATE ) @@ -38,21 +38,21 @@ trait Trees requires Global { def & (flag: Int): Modifiers = { val flags1 = flags & flag if (flags1 == flags) this - else Modifiers(flags1, privateWithin, attributes) + else Modifiers(flags1, privateWithin, annotations) } def &~ (flag: Int): Modifiers = { val flags1 = flags & (~flag) if (flags1 == flags) this - else Modifiers(flags1, privateWithin, attributes) + else Modifiers(flags1, privateWithin, annotations) } def | (flag: int): Modifiers = { val flags1 = flags | flag if (flags1 == flags) this - else Modifiers(flags1, privateWithin, attributes) + else Modifiers(flags1, privateWithin, annotations) } - def withAnnotations(attrs: List[Annotation]) = - if (attrs.isEmpty) this - else Modifiers(flags, privateWithin, attributes ::: attrs) + def withAnnotations(annots: List[Annotation]) = + if (annots.isEmpty) this + else Modifiers(flags, privateWithin, annotations ::: annots) } def Modifiers(flags: int, privateWithin: Name): Modifiers = Modifiers(flags, privateWithin, List()) @@ -138,9 +138,6 @@ trait Trees requires Global { if (hasSymbol) symbol = tree.symbol this } - - def withAttributes(attribs: List[Tree]) = - AttributedTypeTree(attribs, this) } trait SymTree extends Tree { @@ -444,7 +441,7 @@ trait Trees requires Global { /** Add constructor to template */ var vparamss1 = vparamss map (.map (vd => { - val ret = ValDef(Modifiers(vd.mods.flags & IMPLICIT | PARAM) withAnnotations vd.mods.attributes, + val ret = ValDef(Modifiers(vd.mods.flags & IMPLICIT | PARAM) withAnnotations vd.mods.annotations, vd.name, vd.tpt.duplicate, EmptyTree).setPos(vd.pos) if (false/*inIDE*/ && vd.symbol != NoSymbol) ret.symbol = vd.symbol @@ -670,17 +667,10 @@ trait Trees requires Global { // def TypeTree(tp: Type, tree : Tree): TypeTree = TypeTree(tree) setType tp /** A tree that has anP attribute attached to it */ - case class Annotated(constr: Tree, elements: List[Tree], arg: Tree) extends Tree { + case class Annotated(annot: Annotation, arg: Tree) extends Tree { override def isType = arg.isType } - /** A type tree that has attributes attached to it */ - case class AttributedTypeTree(attribs: List[Tree], tpt: Tree) - extends TypTree { - override def withAttributes(attribs: List[Tree]) = - AttributedTypeTree(attribs:::this.attribs, this) - } - /** Singleton type, eliminated by RefCheck */ case class SingletonTypeTree(ref: Tree) extends TypTree @@ -743,8 +733,7 @@ trait Trees requires Global { case Ident(name) => case Literal(value) => case TypeTree() => (introduced by refcheck) - case Annotated(constr, elements, arg) => (eliminated by typer) - case AttributedTypeTree(attribs, tpt) => (eliminated by uncurry) + case Annotated(annot, arg) => (eliminated by typer) case SingletonTypeTree(ref) => (eliminated by uncurry) case SelectFromTypeTree(qualifier, selector) => (eliminated by uncurry) case CompoundTypeTree(templ: Template) => (eliminated by uncurry) @@ -791,8 +780,7 @@ trait Trees requires Global { def Ident(tree: Tree, name: Name): Ident def Literal(tree: Tree, value: Constant): Literal def TypeTree(tree: Tree): TypeTree - def Annotated(tree: Tree, constr: Tree, elements: List[Tree], arg: Tree): Annotated - def AttributedTypeTree(tree: Tree, attribs: List[Tree], tpt: Tree): AttributedTypeTree + def Annotated(tree: Tree, annot: Annotation, arg: Tree): Annotated def SingletonTypeTree(tree: Tree, ref: Tree): SingletonTypeTree def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name): SelectFromTypeTree def CompoundTypeTree(tree: Tree, templ: Template): CompoundTypeTree @@ -820,7 +808,7 @@ trait Trees requires Global { def Import(tree: Tree, expr: Tree, selectors: List[(Name, Name)]) = new Import(expr, selectors).copyAttrs(tree) def Annotation(tree: Tree, constr: Tree, elements: List[Tree]) = - new Annotation(constr, elements) + new Annotation(constr, elements).copyAttrs(tree) def DocDef(tree: Tree, comment: String, definition: Tree) = new DocDef(comment, definition).copyAttrs(tree) def Template(tree: Tree, parents: List[Tree], body: List[Tree]) = @@ -877,10 +865,8 @@ trait Trees requires Global { new Literal(value).copyAttrs(tree) def TypeTree(tree: Tree) = new TypeTree().copyAttrs(tree) - def Annotated(tree: Tree, constr: Tree, elements: List[Tree], arg: Tree) = - new Annotated(constr, elements, arg) - def AttributedTypeTree(tree: Tree, attribs: List[Tree], tpt: Tree) = - new AttributedTypeTree(attribs, tpt) + def Annotated(tree: Tree, annot: Annotation, arg: Tree) = + new Annotated(annot, arg).copyAttrs(tree) def SingletonTypeTree(tree: Tree, ref: Tree) = new SingletonTypeTree(ref).copyAttrs(tree) def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name) = @@ -1085,15 +1071,10 @@ trait Trees requires Global { case t @ TypeTree() => t case _ => copy.TypeTree(tree) } - def Annotated(tree: Tree, constr: Tree, elements: List[Tree], arg: Tree) = tree match { - case t @ Annotated(constr0, elements0, arg0) - if (constr0==constr) && (elements0==elements) && (arg0==arg) => t - case _ => copy.Annotated(tree, constr, elements, arg) - } - def AttributedTypeTree(tree: Tree, attribs: List[Tree], tpt: Tree) = tree match { - case t @ AttributedTypeTree(attribs0, tpt0) - if (attribs0==attribs) && (tpt0==tpt) => t - case _ => copy.AttributedTypeTree(tree, attribs, tpt) + def Annotated(tree: Tree, annot: Annotation, arg: Tree) = tree match { + case t @ Annotated(annot0, arg0) + if (annot0==annot) => t + case _ => copy.Annotated(tree, annot, arg) } def SingletonTypeTree(tree: Tree, ref: Tree) = tree match { case t @ SingletonTypeTree(ref0) @@ -1227,10 +1208,8 @@ trait Trees requires Global { copy.Literal(tree, value) case TypeTree() => copy.TypeTree(tree) - case Annotated(constr, elements, arg) => - copy.Annotated(tree, transform(constr), transformTrees(elements), transform(arg)) - case AttributedTypeTree(attribs, tpt) => - copy.AttributedTypeTree(tree, transformTrees(attribs), transform(tpt)) + case Annotated(annot, arg) => + copy.Annotated(tree, transform(annot).asInstanceOf[Annotation], transform(arg)) case SingletonTypeTree(ref) => copy.SingletonTypeTree(tree, transform(ref)) case SelectFromTypeTree(qualifier, selector) => @@ -1315,8 +1294,8 @@ trait Trees requires Global { traverse(expr) case Annotation(constr, elements) => traverse(constr); traverseTrees(elements) - case Annotated(constr, elements, arg) => - traverse(constr); traverseTrees(elements); traverse(arg) + case Annotated(annot, arg) => + traverse(annot); traverse(arg) case DocDef(comment, definition) => traverse(definition) case Template(parents, body) => @@ -1375,8 +1354,6 @@ trait Trees requires Global { ; case TypeTree() => ; - case AttributedTypeTree(attribs, tpt) => - traverseTrees(attribs); traverse(tpt) case SingletonTypeTree(ref) => traverse(ref) case SelectFromTypeTree(qualifier, selector) => diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 6f4247b49e..71522aae4e 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -669,8 +669,7 @@ trait Parsers requires SyntaxAnalyzer { * | `(' ArgTypePats [`,'] `)' */ def annotType(isPattern: boolean): Tree = { - val annots = if (settings.Xplugtypes.value) typeAttributes() - else annotations() + val annots = annotations() val pos = in.currentPos var t: Tree = if (in.token == LPAREN) { @@ -701,8 +700,7 @@ trait Parsers requires SyntaxAnalyzer { } else done=true } - if (settings.Xplugtypes.value) t.withAttributes(annots) - else (t /: annots) (makeAnnotated) + (t /: annots) (makeAnnotated) } /** TypeArgs ::= `[' ArgType {`,' ArgType} `]' diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index e6efb6e76a..0604f8e59f 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -103,9 +103,7 @@ abstract class TreeBuilder { case _ => t } - def makeAnnotated(t: Tree, attr: Tree): Tree = attr match { - case Annotation(constr, elements) => Annotated(constr, elements, t) setPos attr.pos - } + def makeAnnotated(t: Tree, annot: Annotation): Tree = Annotated(annot, t) setPos annot.pos def makeSelfDef(name: Name, tpt: Tree): ValDef = ValDef(Modifiers(PRIVATE), name, tpt, EmptyTree) @@ -371,7 +369,7 @@ abstract class TreeBuilder { makeVisitor(cases, checkExhaustive, "x$") private def makeUnsealed(expr: Tree): Tree = - Annotated(New(scalaDot(definitions.UnsealedClass.name), List(List())), List(), expr) + Annotated(Annotation(New(scalaDot(definitions.UnsealedClass.name), List(List())), List()), expr) /** Create visitor <x => x match cases> */ def makeVisitor(cases: List[CaseDef], checkExhaustive: boolean, prefix: String): Tree = { diff --git a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala index 0946d75672..81739a95af 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/TypeKinds.scala @@ -398,7 +398,7 @@ trait TypeKinds requires ICodes { REFERENCE(sym) } - case AttributedType(attribs, tp) => + case AnnotatedType(attribs, tp) => toTypeKind(tp) case _ => diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index dc0127bb37..f18c958b5e 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -149,13 +149,13 @@ abstract class GenJVM extends SubComponent { if (!forCLDC) for (val attr <- c.symbol.attributes) attr match { - case AttrInfo(SerializableAttr, _, _) => + case AnnotationInfo(SerializableAttr, _, _) => parents = parents ::: List(definitions.SerializableClass.tpe) - case AttrInfo(CloneableAttr, _, _) => + case AnnotationInfo(CloneableAttr, _, _) => parents = parents ::: List(CloneableClass.tpe) - case AttrInfo(SerialVersionUID, value :: _, _) => + case AnnotationInfo(SerialVersionUID, value :: _, _) => serialVUID = Some(value.longValue) - case AttrInfo(RemoteAttr, _, _) => + case AnnotationInfo(RemoteAttr, _, _) => parents = parents ::: List(RemoteInterface.tpe) remoteClass = true case _ => () @@ -204,7 +204,7 @@ abstract class GenJVM extends SubComponent { def addExceptionsAttribute(sym: Symbol): Unit = { val (excs, others) = sym.attributes.partition((a => a match { - case AttrInfo(ThrowsAttr, _, _) => true + case AnnotationInfo(ThrowsAttr, _, _) => true case _ => false })) if (excs isEmpty) return; @@ -217,7 +217,7 @@ abstract class GenJVM extends SubComponent { // put some radom value; the actual number is determined at the end buf.putShort(0xbaba.toShort) - for (val AttrInfo(ThrowsAttr, List(exc), _) <- excs.removeDuplicates) { + for (val AnnotationInfo(ThrowsAttr, List(exc), _) <- excs.removeDuplicates) { buf.putShort(cpool.addClass(javaName(exc.typeValue.symbol)).shortValue) nattr = nattr + 1 } @@ -227,7 +227,7 @@ abstract class GenJVM extends SubComponent { addAttribute(jmethod, nme.ExceptionsATTR, buf) } - private def emitAttributes(buf: ByteBuffer, attributes: List[AttrInfo]): Int = { + private def emitAttributes(buf: ByteBuffer, attributes: List[AnnotationInfo[Constant]]): Int = { val cpool = jclass.getConstantPool() def emitElement(const: Constant): Unit = const.tag match { @@ -278,7 +278,7 @@ abstract class GenJVM extends SubComponent { // put some radom value; the actual number of annotations is determined at the end buf.putShort(0xbaba.toShort) - for (val AttrInfo(typ, consts, nvPairs) <- attributes; + for (val AnnotationInfo(typ, consts, nvPairs) <- attributes; typ.symbol isNonBottomSubClass definitions.ClassfileAnnotationClass) { nattr = nattr + 1 val jtype = javaType(typ) @@ -300,7 +300,7 @@ abstract class GenJVM extends SubComponent { nattr } - def addAnnotations(jmember: JMember, attributes: List[AttrInfo]): Unit = { + def addAnnotations(jmember: JMember, attributes: List[AnnotationInfo[Constant]]): Unit = { if (attributes.isEmpty) return val buf: ByteBuffer = ByteBuffer.allocate(2048) @@ -310,9 +310,9 @@ abstract class GenJVM extends SubComponent { addAttribute(jmember, nme.RuntimeAnnotationATTR, buf) } - def addParamAnnotations(pattrss: List[List[AttrInfo]]): Unit = { + def addParamAnnotations(pattrss: List[List[AnnotationInfo[Constant]]]): Unit = { val attributes = for (val attrs <- pattrss) yield - for (val attr @ AttrInfo(tpe, _, _) <- attrs; + for (val attr @ AnnotationInfo(tpe, _, _) <- attrs; tpe.symbol isNonBottomSubClass definitions.ClassfileAnnotationClass) yield attr; if (attributes.forall(.isEmpty)) return; @@ -373,9 +373,9 @@ abstract class GenJVM extends SubComponent { var attributes = 0 f.symbol.attributes foreach { a => a match { - case AttrInfo(TransientAtt, _, _) => + case AnnotationInfo(TransientAtt, _, _) => attributes = attributes | JAccessFlags.ACC_TRANSIENT - case AttrInfo(VolatileAttr, _, _) => + case AnnotationInfo(VolatileAttr, _, _) => attributes = attributes | JAccessFlags.ACC_VOLATILE case _ => (); }} @@ -414,11 +414,11 @@ abstract class GenJVM extends SubComponent { jmethod.addAttribute(fjbgContext.JOtherAttribute(jclass, jmethod, "Bridge", new Array[Byte](0))) if ((remoteClass || - (m.symbol.attributes contains AttrInfo(RemoteAttr, Nil, Nil))) && + (m.symbol.attributes contains AnnotationInfo(RemoteAttr, Nil, Nil))) && jmethod.isPublic() && !forCLDC) { m.symbol.attributes = - AttrInfo(ThrowsAttr, List(Constant(RemoteException)), List()) :: m.symbol.attributes; + AnnotationInfo(ThrowsAttr, List(Constant(RemoteException)), List()) :: m.symbol.attributes; } if (!jmethod.isAbstract()) { diff --git a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala index 553669d162..1a21da8c98 100644 --- a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala +++ b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala @@ -293,12 +293,12 @@ abstract class GenMSIL extends SubComponent { log("Could not find pickle information for " + sym) } - def addAttributes(member: ICustomAttributeSetter, attributes: List[AttrInfo]): Unit = { + def addAttributes(member: ICustomAttributeSetter, attributes: List[AnnotationInfo[Constant]]): Unit = { return // FIXME if (settings.debug.value) log("creating attributes: " + attributes + " for member : " + member) - for(val AttrInfo(typ, consts, nvPairs) <- attributes /* !typ.symbol.hasFlag(Flags.JAVA) */ ) { + for(val AnnotationInfo(typ, consts, nvPairs) <- attributes /* !typ.symbol.hasFlag(Flags.JAVA) */ ) { // assert(consts.length <= 1, // "too many constant arguments for attribute; "+consts.toString()) @@ -310,7 +310,7 @@ abstract class GenMSIL extends SubComponent { // val attrType: MsilType = getType(typ.symbol) // Problem / TODO: i have no idea which constructor is used. This - // information should be available in AttrInfo. + // information should be available in AnnotationInfo. attrType.CreateType() // else, GetConstructors can't be used val constr: ConstructorInfo = attrType.GetConstructors()(0) // prevent a second call of CreateType, only needed because there's no @@ -1808,7 +1808,7 @@ abstract class GenMSIL extends SubComponent { mf = mf | (if (sym isFinal) TypeAttributes.Sealed else 0) sym.attributes foreach { a => a match { - case AttrInfo(SerializableAttr, _, _) => + case AnnotationInfo(SerializableAttr, _, _) => // TODO: add the Serializable TypeAttribute also if the attribute // System.SerializableAttribute is present (.net attribute, not scala) // Best way to do it: compare with @@ -1859,7 +1859,7 @@ abstract class GenMSIL extends SubComponent { // TODO: add this attribute also if the class has the custom attribute // System.NotSerializedAttribute sym.attributes.foreach( a => a match { - case AttrInfo(TransientAtt, _, _) => + case AnnotationInfo(TransientAtt, _, _) => mf = mf | FieldAttributes.NotSerialized case _ => () }) @@ -2067,7 +2067,7 @@ abstract class GenMSIL extends SubComponent { private def isCloneable(sym: Symbol): Boolean = { !sym.attributes.forall( a => a match { - case AttrInfo(CloneableAttr, _, _) => false + case AnnotationInfo(CloneableAttr, _, _) => false case _ => true }) } diff --git a/src/compiler/scala/tools/nsc/doc/DocGenerator.scala b/src/compiler/scala/tools/nsc/doc/DocGenerator.scala index bca2419ec7..b492574cd6 100644 --- a/src/compiler/scala/tools/nsc/doc/DocGenerator.scala +++ b/src/compiler/scala/tools/nsc/doc/DocGenerator.scala @@ -330,9 +330,9 @@ abstract class DocGenerator extends Models { if (tree.symbol.attributes.isEmpty || tree.symbol.hasFlag(Flags.CASE)) NodeSeq.Empty else { - def attrFor(attr: AttrInfo): Node = { + def attrFor(attr: AnnotationInfo[Constant]): Node = { val buf = new StringBuilder - val AttrInfo(tpe, args, nvPairs) = attr + val AnnotationInfo(tpe, args, nvPairs) = attr val name = aref(urlFor(tpe.symbol), contentFrame, tpe.toString) if (!args.isEmpty) buf.append(args.map(.escapedStringValue).mkString("(", ",", ")")) diff --git a/src/compiler/scala/tools/nsc/models/SemanticTokens.scala b/src/compiler/scala/tools/nsc/models/SemanticTokens.scala index a61e9ae549..0702498396 100644 --- a/src/compiler/scala/tools/nsc/models/SemanticTokens.scala +++ b/src/compiler/scala/tools/nsc/models/SemanticTokens.scala @@ -478,7 +478,6 @@ class SemanticTokens(val compiler: Global) { case tree: Import => build(tree.expr) case tree: AppliedTypeTree => ; case tree: Annotated => ; - case tree: AttributedTypeTree => ; case tree: SingletonTypeTree => ; case tree: Super => ; case tree: Literal => ; diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index 417ab89308..7011f7d809 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -77,7 +77,7 @@ trait Symbols requires SymbolTable { else -1 } - var attributes: List[AttrInfo] = List() + var attributes: List[AnnotationInfo[Constant]] = List() var privateWithin: Symbol = _ @@ -151,7 +151,7 @@ trait Symbols requires SymbolTable { final def newAnonymousFunctionClass(pos: PositionType) = { val anonfun = newClass(pos, nme.ANON_FUN_NAME.toTypeName) anonfun.attributes = - AttrInfo(definitions.SerializableAttr.tpe, List(), List()) :: anonfun.attributes + AnnotationInfo(definitions.SerializableAttr.tpe, List(), List()) :: anonfun.attributes anonfun } final def newRefinementClass(pos: PositionType) = @@ -536,7 +536,7 @@ trait Symbols requires SymbolTable { rawInfo.load(this); rawInfo.typeParams } - def getAttributes(clazz: Symbol): List[AttrInfo] = + def getAttributes(clazz: Symbol): List[AnnotationInfo[Constant]] = attributes.filter(.atp.symbol.isNonBottomSubClass(clazz)) /** Reset symbol to initial state @@ -1315,7 +1315,7 @@ trait Symbols requires SymbolTable { def cloneSymbolImpl(owner: Symbol): Symbol = throw new Error() } - case class AttrInfo(atp: Type, args: List[Constant], assocs: List[(Name, Constant)]) { + case class AnnotationInfo[+T](atp: Type, args: List[T], assocs: List[(Name, T)]) { override def toString: String = atp + (if (args.isEmpty) "" diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index ffca860e18..70c1521953 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -29,7 +29,7 @@ import Flags._ case OverloadedType(pre, tparams, alts) => case AntiPolyType(pre: Type, targs) => case TypeVar(_, _) => - case AttributedType(attribs, tp) => + case AnnotatedType(attribs, tp) => */ trait Types requires SymbolTable { @@ -486,13 +486,13 @@ trait Types requires SymbolTable { } /** Add an attribute to this type */ - def withAttribute(attrib: Any) = withAttributes(List(attrib)) + def withAttribute(attrib: AnnotationInfo[Any]) = withAttributes(List(attrib)) /** Add a number of attributes to this type */ - def withAttributes(attribs: List[Any]): Type = + def withAttributes(attribs: List[AnnotationInfo[Any]]): Type = attribs match { case Nil => this - case _ => AttributedType(attribs, this) + case _ => AnnotatedType(attribs, this) } /** Remove any attributes from this type */ @@ -1212,7 +1212,7 @@ trait Types requires SymbolTable { * to the core compiler, but can be observed by type-system plugins. The * core compiler does take care to propagate attributes and to save them * in the symbol tables of object files. */ - case class AttributedType(attributes: List[Any], tp: Type) extends Type { + case class AnnotatedType(attributes: List[AnnotationInfo[Any]], tp: Type) extends Type { override def toString(): String = { val attString = if(attributes.isEmpty) @@ -1225,8 +1225,8 @@ trait Types requires SymbolTable { /** Add a number of attributes to this type */ - override def withAttributes(attribs: List[Any]): Type = - AttributedType(attribs:::this.attributes, this) + override def withAttributes(attribs: List[AnnotationInfo[Any]]): Type = + AnnotatedType(attribs:::this.attributes, this) /** Remove any attributes from this type */ override def withoutAttributes = tp.withoutAttributes @@ -1621,12 +1621,12 @@ trait Types requires SymbolTable { case TypeVar(_, constr) => if (constr.inst != NoType) this(constr.inst) else tp - case AttributedType(attribs, atp) => + case AnnotatedType(attribs, atp) => val atp1 = this(atp) if(atp1 eq atp) tp else - AttributedType(attribs, atp1) + AnnotatedType(attribs, atp1) case _ => tp // throw new Error("mapOver inapplicable for " + tp); @@ -1935,7 +1935,7 @@ trait Types requires SymbolTable { case TypeBounds(_, _) => mapOver(tp) case MethodType(_, _) => mapOver(tp) case TypeVar(_, _) => mapOver(tp) - case AttributedType(_,_) => mapOver(tp) + case AnnotatedType(_,_) => mapOver(tp) case _ => tp } } @@ -2076,9 +2076,9 @@ trait Types requires SymbolTable { case (_, TypeVar(_, constr2)) => if (constr2.inst != NoType) tp1 =:= constr2.inst else constr2 instantiate (wildcardToTypeVarMap(tp1)) - case (AttributedType(_,atp), _) => + case (AnnotatedType(_,atp), _) => isSameType(atp, tp2) - case (_, AttributedType(_,atp)) => + case (_, AnnotatedType(_,atp)) => isSameType(tp1, atp) case _ => if (tp1.isStable && tp2.isStable) { @@ -2194,9 +2194,9 @@ trait Types requires SymbolTable { case (TypeVar(_, constr1), _) => if (constr1.inst != NoType) constr1.inst <:< tp2 else { constr1.hibounds = tp2 :: constr1.hibounds; true } - case (AttributedType(_,atp1), _) => + case (AnnotatedType(_,atp1), _) => atp1 <:< tp2 - case (_, AttributedType(_,atp2)) => + case (_, AnnotatedType(_,atp2)) => tp1 <:< atp2 case (_, TypeRef(pre2, sym2, args2)) if sym2.isAbstractType && !(tp2 =:= tp2.bounds.lo) && (tp1 <:< tp2.bounds.lo) => diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 4022c475d2..319ea13a35 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -651,7 +651,7 @@ abstract class ClassfileParser { } case nme.AnnotationDefaultATTR => sym.attributes = - AttrInfo(definitions.AnnotationDefaultAttr.tpe, List(), List()) :: sym.attributes + AnnotationInfo(definitions.AnnotationDefaultAttr.tpe, List(), List()) :: sym.attributes in.skip(attrLen) case nme.RuntimeAnnotationATTR => parseAnnotations(attrLen) @@ -702,7 +702,7 @@ abstract class ClassfileParser { val name = pool.getName(in.nextChar) nvpairs += (name, parseTaggedConstant) } - sym.attributes = AttrInfo(attrType, List(), nvpairs.toList) :: sym.attributes + sym.attributes = AnnotationInfo(attrType, List(), nvpairs.toList) :: sym.attributes } } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index 5dc137e102..c40cbba935 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -149,7 +149,7 @@ abstract class Pickler extends SubComponent { putType(restpe); putTypes(formals) case PolyType(tparams, restpe) => putType(restpe); putSymbols(tparams) - case AttributedType(attribs, tp) => + case AnnotatedType(attribs, tp) => putType(tp) // the attributes should be stored, but it is not yet // decided how to handle that. case _ => @@ -173,7 +173,7 @@ abstract class Pickler extends SubComponent { children foreach putSymbol } - private def putAnnotation(sym: Symbol, attr: AttrInfo): unit = { + private def putAnnotation(sym: Symbol, attr: AnnotationInfo[Constant]): unit = { assert(putEntry((sym, attr))) putType(attr.atp) for (val c <- attr.args) putConstant(c) @@ -277,13 +277,13 @@ abstract class Pickler extends SubComponent { else if (c.tag == StringTag) writeRef(newTermName(c.stringValue)) else if (c.tag == ClassTag) writeRef(c.typeValue) LITERAL + c.tag - case AttributedType(attribs, tp) => + case AnnotatedType(attribs, tp) => writeBody(tp) // obviously, this should be improved - case (target: Symbol, attr @ AttrInfo(atp, args, assocs)) => + case (target: Symbol, attr @ AnnotationInfo(atp, args, assocs)) => writeRef(target) writeRef(atp) - for (val c <- args) writeRef(c) - for (val (name, c) <- assocs) { writeRef(name); writeRef(c) } + for (val c <- args) writeRef(c.asInstanceOf[Constant]) + for (val (name, c) <- assocs) { writeRef(name); writeRef(c.asInstanceOf[Constant]) } ATTRIBUTE case (target: Symbol, children: List[_]) => writeRef(target) diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala index a338824c8b..70fcc5e7d7 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala @@ -294,7 +294,7 @@ abstract class UnPickler { if (isNameEntry(argref)) assocs += (at(argref, readName), readConstantRef()) else args += at(argref, readConstant) } - val attr = AttrInfo(attrType, args.toList, assocs.toList) + val attr = AnnotationInfo(attrType, args.toList, assocs.toList) target.attributes = attr :: target.attributes } else if (tag == CHILDREN) { while (readIndex != end) target addChild readSymbolRef() diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index de5e99c91e..15197b413e 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -493,14 +493,14 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter val ncases = transformCaseDefs(cases) var checkExhaustive = true - def isUnsealedAttribute(tpe: Type) = tpe match { - case AttributedType(List(AttrInfo(atp, _, _)), _) if atp.symbol == UnsealedClass => + def isUnsealedAnnotation(tpe: Type) = tpe match { + case AnnotatedType(List(AnnotationInfo(atp, _, _)), _) if atp.symbol == UnsealedClass => true case _ => false } nselector match { - case Typed(nselector1, tpt) if isUnsealedAttribute(tpt.tpe) => + case Typed(nselector1, tpt) if isUnsealedAnnotation(tpt.tpe) => nselector = nselector1 checkExhaustive = false case _ => diff --git a/src/compiler/scala/tools/nsc/transform/LiftCode.scala b/src/compiler/scala/tools/nsc/transform/LiftCode.scala index bec7141751..f5426083dd 100644 --- a/src/compiler/scala/tools/nsc/transform/LiftCode.scala +++ b/src/compiler/scala/tools/nsc/transform/LiftCode.scala @@ -213,7 +213,7 @@ abstract class LiftCode extends Transform { if (_log_reify_type_) Console.println("cannot handle MethodType "+tp); null case PolyType(tparams, result) => if (_log_reify_type_) Console.println("cannot handle PolyType "+tp); null; - case AttributedType(attribs, tp) => + case AnnotatedType(attribs, tp) => reify(tp) case _ => null diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 6a877e9f50..e265d2e9c5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -570,14 +570,14 @@ trait Namers requires Analyzer { val sym: Symbol = tree.symbol tree match { case defn: MemberDef => - val annots = for { - val Annotation(constr, elements) <- defn.mods.attributes - val ainfo = typer.typedAnnotation(constr, elements) + val ainfos = for { + val annot <- defn.mods.annotations + val ainfo = typer.typedAnnotation(annot, typer.getConstant) !ainfo.atp.isError } yield ainfo - if (!annots.isEmpty) { + if (!ainfos.isEmpty) { val annotated = if (sym.isModule) sym.moduleClass else sym - annotated.attributes = annots + annotated.attributes = ainfos } case _ => } diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 68c8bebcfa..4f1a9388b7 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -373,7 +373,7 @@ abstract class RefChecks extends InfoTransform { validateVariance(result, variance) case PolyType(tparams, result) => validateVariance(result, variance) - case AttributedType(attribs, tp) => + case AnnotatedType(attribs, tp) => validateVariance(tp, variance) } diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala index 9c4dca6e59..420230a48d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala @@ -210,7 +210,7 @@ trait SyntheticMethods requires Analyzer { if (clazz hasFlag CASE) { // case classes are implicitly declared serializable - clazz.attributes = AttrInfo(SerializableAttr.tpe, List(), List()) :: clazz.attributes + clazz.attributes = AnnotationInfo(SerializableAttr.tpe, List(), List()) :: clazz.attributes for (val stat <- templ.body) { if (stat.isDef && stat.symbol.isMethod && stat.symbol.hasFlag(CASEACCESSOR) && !isPublic(stat.symbol)) { diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 1ebb6cb451..c439f19dbd 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -910,7 +910,7 @@ trait Typers requires Analyzer { else typed(atPos(vdef.pos)(Select(This(value.owner), value)), EXPRmode, value.tpe)) result.tpt.asInstanceOf[TypeTree] setOriginal tpt /* setPos tpt.pos */ checkNoEscaping.privates(getter, result.tpt) - copy.DefDef(result, result.mods withAnnotations mods.attributes, result.name, + copy.DefDef(result, result.mods withAnnotations mods.annotations, result.name, result.tparams, result.vparamss, result.tpt, result.rhs) //todo: withAnnotations is probably unnecessary } @@ -924,7 +924,7 @@ trait Typers requires Analyzer { else typed(Assign(Select(This(value.owner), value), Ident(vparamss.head.head))))) - copy.DefDef(result, result.mods withAnnotations mods.attributes, result.name, + copy.DefDef(result, result.mods withAnnotations mods.annotations, result.name, result.tparams, result.vparamss, result.tpt, result.rhs) } val gs = if (mods hasFlag MUTABLE) List(getterDef, setterDef) @@ -934,8 +934,8 @@ trait Typers requires Analyzer { case DocDef(comment, defn) => addGetterSetter(defn) map (stat => DocDef(comment, stat)) - case Annotated(constr, elements, defn) => - addGetterSetter(defn) map (stat => Annotated(constr, elements, stat)) + case Annotated(annot, defn) => + addGetterSetter(defn) map (stat => Annotated(annot, stat)) case _ => List(stat) @@ -1566,25 +1566,26 @@ trait Typers requires Analyzer { } } - def typedAnnotation(constr: Tree, elements: List[Tree]): AttrInfo = { + def getConstant(tree: Tree): Constant = tree match { + case Literal(value) => value + case arg => error(arg.pos, "attribute argument needs to be a constant; found: "+arg); Constant(null) + } + + def typedAnnotation[T](annot: Annotation, reify: Tree => T): AnnotationInfo[T] = { var attrError: Boolean = false; def error(pos: PositionType, msg: String): Null = { context.error(pos, msg) attrError = true null } - def getConstant(tree: Tree): Constant = tree match { - case Literal(value) => value - case arg => error(arg.pos, "attribute argument needs to be a constant; found: "+arg) - } - typed(constr, EXPRmode | CONSTmode, AnnotationClass.tpe) match { + typed(annot.constr, EXPRmode | CONSTmode, AnnotationClass.tpe) match { case t @ Apply(Select(New(tpt), nme.CONSTRUCTOR), args) => if (t.isErroneous) { - AttrInfo(ErrorType, List(), List()) + AnnotationInfo[T](ErrorType, List(), List()) } else { val annType = tpt.tpe - val constrArgs = args map getConstant + val constrArgs = args map reify val attrScope = annType.decls .filter(sym => sym.isMethod && !sym.isConstructor && sym.hasFlag(JAVA)) val names = new collection.mutable.HashSet[Symbol] @@ -1592,7 +1593,7 @@ trait Typers requires Analyzer { if (args.length == 1) { names.retain(sym => sym.name != nme.value) } - val nvPairs = elements map { + val nvPairs = annot.elements map { case Assign(ntree @ Ident(name), rhs) => { val sym = attrScope.lookup(name); if (sym == NoSymbol) { @@ -1601,20 +1602,20 @@ trait Typers requires Analyzer { error(ntree.pos, "duplicate value for element " + name) } else { names -= sym - (sym.name, getConstant(typed(rhs, EXPRmode | CONSTmode, sym.tpe.resultType))) + (sym.name, reify(typed(rhs, EXPRmode | CONSTmode, sym.tpe.resultType))) } } } for (val name <- names) { - if (!name.attributes.contains(AttrInfo(AnnotationDefaultAttr.tpe, List(), List()))) { - error(constr.pos, "attribute " + annType.symbol.fullNameString + " is missing element " + name.name) + if (!name.attributes.contains(AnnotationInfo(AnnotationDefaultAttr.tpe, List(), List()))) { + error(annot.constr.pos, "attribute " + annType.symbol.fullNameString + " is missing element " + name.name) } } if (annType.symbol.hasFlag(JAVA) && settings.target.value == "jvm-1.4") { - context.unit.warning (constr.pos, "Java annotation will not be emitted in classfile unless you use the '-target:jvm-1.5' option") + context.unit.warning (annot.constr.pos, "Java annotation will not be emitted in classfile unless you use the '-target:jvm-1.5' option") } - if (attrError) AttrInfo(ErrorType, List(), List()) - else AttrInfo(annType, constrArgs, nvPairs) + if (attrError) AnnotationInfo(ErrorType, List(), List()) + else AnnotationInfo(annType, constrArgs, nvPairs) } } } @@ -1974,22 +1975,27 @@ trait Typers requires Analyzer { if (comments ne null) comments(defn.symbol) = comment ret - case Annotated(constr, elements, arg) => - val attrInfo = typedAnnotation(constr, elements) + case Annotated(annot, arg) => val arg1 = typed(arg, mode, pt) - def attrType = - TypeTree(arg1.tpe.withAttribute(attrInfo)) setOriginal tree - arg1 match { - case _: DefTree => - if (!attrInfo.atp.isError) { - val attributed = - if (arg1.symbol.isModule) arg1.symbol.moduleClass else arg1.symbol - attributed.attributes = attrInfo :: attributed.attributes - } - arg1 - case _ => - if (arg1.isType) attrType - else Typed(arg1, attrType) setPos tree.pos setType attrType.tpe + def annotTypeTree(ainfo: AnnotationInfo[Any]): Tree = + TypeTree(arg1.tpe.withAttribute(ainfo)) setOriginal tree + if (arg1.isType) { + val annotInfo = typedAnnotation(annot, identity[Tree]) + annotTypeTree(annotInfo) + } else { + val annotInfo = typedAnnotation(annot, getConstant) + arg1 match { + case _: DefTree => + if (!annotInfo.atp.isError) { + val attributed = + if (arg1.symbol.isModule) arg1.symbol.moduleClass else arg1.symbol + attributed.attributes = annotInfo :: attributed.attributes + } + arg1 + case _ => + val atpt = annotTypeTree(annotInfo) + Typed(arg1, atpt) setPos tree.pos setType atpt.tpe + } } case tree @ Block(_, _) => @@ -2330,11 +2336,6 @@ trait Typers requires Analyzer { if (value.tag == UnitTag) UnitClass.tpe else mkConstantType(value)) - case AttributedTypeTree(attribs, tpt) => - attribs.foreach(t => typed(t, EXPRmode, WildcardType)) - val tptTyped = typed1(tpt, mode, pt) - tptTyped setType (tptTyped.tpe.withAttributes(attribs)) - case SingletonTypeTree(ref) => val ref1 = checkStable(typed(ref, EXPRmode | QUALmode, AnyRefClass.tpe)) tree setType ref1.tpe.resultType diff --git a/src/compiler/scala/tools/nsc/typechecker/Variances.scala b/src/compiler/scala/tools/nsc/typechecker/Variances.scala index 1e112d320f..582cd028c5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Variances.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Variances.scala @@ -79,7 +79,7 @@ trait Variances { flip(varianceInTypes(formals)(tparam)) & varianceInType(restpe)(tparam) case PolyType(tparams, restpe) => flip(varianceInSyms(tparams)(tparam)) & varianceInType(restpe)(tparam) - case AttributedType(attribs, tp) => + case AnnotatedType(attribs, tp) => varianceInType(tp)(tparam) } } |