Add positions to AnnotationInfo for use by IDEs and other tools.

git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@19273 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
milessabin 2009-10-25 17:12:45 +00:00
parent fd3e9a33d6
commit 0e9e3a8368
16 changed files with 49 additions and 41 deletions

View File

@ -171,13 +171,13 @@ abstract class GenJVM extends SubComponent {
parents = definitions.ObjectClass.tpe :: parents;
for (annot <- c.symbol.annotations) annot match {
case AnnotationInfo(tp, _, _) if tp.typeSymbol == SerializableAttr =>
case AnnotationInfo(tp, _, _, _) if tp.typeSymbol == SerializableAttr =>
parents = parents ::: List(definitions.SerializableClass.tpe)
case AnnotationInfo(tp, _, _) if tp.typeSymbol == CloneableAttr =>
case AnnotationInfo(tp, _, _, _) if tp.typeSymbol == CloneableAttr =>
parents = parents ::: List(CloneableClass.tpe)
case AnnotationInfo(tp, Literal(const) :: _, _) if tp.typeSymbol == SerialVersionUID =>
case AnnotationInfo(tp, Literal(const) :: _, _, _) if tp.typeSymbol == SerialVersionUID =>
serialVUID = Some(const.longValue)
case AnnotationInfo(tp, _, _) if tp.typeSymbol == RemoteAttr =>
case AnnotationInfo(tp, _, _, _) if tp.typeSymbol == RemoteAttr =>
parents = parents ::: List(RemoteInterface.tpe)
remoteClass = true
case _ => ()
@ -330,7 +330,7 @@ abstract class GenJVM extends SubComponent {
// put some radom value; the actual number is determined at the end
buf.putShort(0xbaba.toShort)
for (AnnotationInfo(tp, List(exc), _) <- excs.removeDuplicates if tp.typeSymbol == ThrowsAttr) {
for (AnnotationInfo(tp, List(exc), _, _) <- excs.removeDuplicates if tp.typeSymbol == ThrowsAttr) {
val Literal(const) = exc
buf.putShort(
cpool.addClass(
@ -402,7 +402,7 @@ abstract class GenJVM extends SubComponent {
}
def emitAnnotation(annotInfo: AnnotationInfo) {
val AnnotationInfo(typ, args, assocs) = annotInfo
val AnnotationInfo(typ, args, assocs, _) = annotInfo
val jtype = javaType(typ)
buf.putShort(cpool.addUtf8(jtype.getSignature()).toShort)
assert(args.isEmpty, args.toString)
@ -537,9 +537,9 @@ abstract class GenJVM extends SubComponent {
var attributes = 0
f.symbol.annotations foreach { a => a match {
case AnnotationInfo(tp, _, _) if tp.typeSymbol == TransientAtt =>
case AnnotationInfo(tp, _, _, _) if tp.typeSymbol == TransientAtt =>
attributes = attributes | JAccessFlags.ACC_TRANSIENT
case AnnotationInfo(tp, _, _) if tp.typeSymbol == VolatileAttr =>
case AnnotationInfo(tp, _, _, _) if tp.typeSymbol == VolatileAttr =>
attributes = attributes | JAccessFlags.ACC_VOLATILE
case _ => ();
}}
@ -622,7 +622,7 @@ abstract class GenJVM extends SubComponent {
private def addRemoteException(jmethod: JMethod, meth: Symbol) {
def isRemoteThrows(ainfo: AnnotationInfo) = ainfo match {
case AnnotationInfo(tp, List(arg), _) if tp.typeSymbol == ThrowsAttr =>
case AnnotationInfo(tp, List(arg), _, _) if tp.typeSymbol == ThrowsAttr =>
arg match {
case Literal(Constant(tpe: Type)) if tpe.typeSymbol == RemoteException.typeSymbol => true
case _ => false
@ -633,7 +633,7 @@ abstract class GenJVM extends SubComponent {
if (remoteClass ||
(meth.hasAnnotation(RemoteAttr) && jmethod.isPublic())) {
val c = Constant(RemoteException)
val ainfo = AnnotationInfo(ThrowsAttr.tpe, List(Literal(c).setType(c.tpe)), List())
val ainfo = AnnotationInfo(ThrowsAttr.tpe, List(Literal(c).setType(c.tpe)), List(), NoPosition)
if (!meth.annotations.exists(isRemoteThrows)) {
meth.addAnnotation(ainfo)
}
@ -646,7 +646,7 @@ abstract class GenJVM extends SubComponent {
*/
private def splitAnnotations(annotations: List[AnnotationInfo], annotSym: Symbol): (List[AnnotationInfo], List[AnnotationInfo]) = {
annotations.partition { a => a match {
case AnnotationInfo(tp, _, _) if tp.typeSymbol == annotSym => true
case AnnotationInfo(tp, _, _, _) if tp.typeSymbol == annotSym => true
case _ => false
}}
}

View File

@ -1858,7 +1858,7 @@ abstract class GenMSIL extends SubComponent {
mf = mf | (if (sym isFinal) TypeAttributes.Sealed else 0)
sym.annotations foreach { a => a match {
case AnnotationInfo(SerializableAttr, _, _) =>
case AnnotationInfo(SerializableAttr, _, _, _) =>
// TODO: add the Serializable TypeAttribute also if the annotation
// System.SerializableAttribute is present (.net annotation, not scala)
// Best way to do it: compare with
@ -1908,7 +1908,7 @@ abstract class GenMSIL extends SubComponent {
// TODO: add this annotation also if the class has the custom attribute
// System.NotSerializedAttribute
sym.annotations.foreach( a => a match {
case AnnotationInfo(TransientAtt, _, _) =>
case AnnotationInfo(TransientAtt, _, _, _) =>
mf = mf | FieldAttributes.NotSerialized
case _ => ()
})
@ -2123,7 +2123,7 @@ abstract class GenMSIL extends SubComponent {
private def isCloneable(sym: Symbol): Boolean = {
!sym.annotations.forall( a => a match {
case AnnotationInfo(CloneableAttr, _, _) => false
case AnnotationInfo(CloneableAttr, _, _, _) => false
case _ => true
})
}

View File

@ -349,7 +349,7 @@ trait ModelToXML extends ModelExtractor {
def attrsFor(entity: Entity)(implicit from: Frame): NodeSeq = {
def attrFor(attr: AnnotationInfo): Node = {
val buf = new StringBuilder
val AnnotationInfo(tpe, args, nvPairs) = attr
val AnnotationInfo(tpe, args, nvPairs, _) = attr
val name = link(decode(tpe.typeSymbol))
if (!args.isEmpty)
buf.append(args.mkString("(", ",", ")"))

View File

@ -257,6 +257,13 @@ self: scala.tools.nsc.Global =>
if (t.pos includes pos) {
if (!t.pos.isTransparent) last = t
super.traverse(t)
} else if (t.symbol != null) {
for(annot <- t.symbol.annotations if !annot.pos.isTransparent) {
last = Annotated(TypeTree(annot.atp) setPos annot.pos, t)
last.setType(annot.atp)
last.setPos(annot.pos)
traverseTrees(annot.args)
}
}
}
}

View File

@ -75,7 +75,7 @@ trait AnnotationInfos {
* </p>
*/
case class AnnotationInfo(atp: Type, args: List[Tree],
assocs: List[(Name, ClassfileAnnotArg)])
assocs: List[(Name, ClassfileAnnotArg)], pos : Position)
extends AnnotationInfoBase {
// Classfile annot: args empty. Scala annot: assocs empty.
@ -95,7 +95,7 @@ trait AnnotationInfos {
/** Change all ident's with Symbol "from" to instead use symbol "to" */
def substIdentSyms(from: Symbol, to: Symbol) = {
val subs = new TreeSymSubstituter(List(from), List(to))
AnnotationInfo(atp, args.map(subs(_)), assocs)
AnnotationInfo(atp, args.map(subs(_)), assocs, pos)
}
}

View File

@ -116,7 +116,7 @@ trait Symbols {
// see "def typeSig" in Namers
val annots1 = initialize.rawannots map {
case LazyAnnotationInfo(annot) => annot()
case a @ AnnotationInfo(_, _, _) => a
case a @ AnnotationInfo(_, _, _, _) => a
} filter { a => !a.atp.isError }
rawannots = annots1
annots1

View File

@ -2163,7 +2163,7 @@ A type's typeSymbol should never be inspected directly.
// ** Replace formal type parameter symbols with actual type arguments. * /
override def instantiateTypeParams(formals: List[Symbol], actuals: List[Type]) = {
val annotations1 = annotations.map(info => AnnotationInfo(info.atp.instantiateTypeParams(
formals, actuals), info.args, info.assocs))
formals, actuals), info.args, info.assocs, info.pos))
val underlying1 = underlying.instantiateTypeParams(formals, actuals)
if ((annotations1 eq annotations) && (underlying1 eq underlying)) this
else AnnotatedType(annotations1, underlying1, selfsym)
@ -2785,7 +2785,7 @@ A type's typeSymbol should never be inspected directly.
}
def mapOver(annot: AnnotationInfo): Option[AnnotationInfo] = {
val AnnotationInfo(atp, args, assocs) = annot
val AnnotationInfo(atp, args, assocs, pos) = annot
if (dropNonConstraintAnnotations &&
!(atp.typeSymbol isNonBottomSubClass TypeConstraintClass))
@ -2798,7 +2798,7 @@ A type's typeSymbol should never be inspected directly.
if ((args eq args1) && (atp eq atp1))
Some(annot)
else if (args1.length == args.length)
Some(AnnotationInfo(atp1, args1, assocs))
Some(AnnotationInfo(atp1, args1, assocs, pos))
else
None
}

View File

@ -793,7 +793,7 @@ abstract class ClassfileParser {
}
// Attribute on methods of java annotation classes when that method has a default
case nme.AnnotationDefaultATTR =>
sym.addAnnotation(AnnotationInfo(definitions.AnnotationDefaultAttr.tpe, List(), List()))
sym.addAnnotation(AnnotationInfo(definitions.AnnotationDefaultAttr.tpe, List(), List(), NoPosition))
in.skip(attrLen)
// Java annotatinos on classes / methods / fields with RetentionPolicy.RUNTIME
case nme.RuntimeAnnotationATTR =>
@ -863,7 +863,7 @@ abstract class ClassfileParser {
}
}
if (hasError) None
else Some(AnnotationInfo(attrType, List(), nvpairs.toList))
else Some(AnnotationInfo(attrType, List(), nvpairs.toList, NoPosition))
} catch {
case f: FatalError => throw f // don't eat fatal errors, they mean a class was not found
case ex: Throwable =>

View File

@ -468,7 +468,7 @@ abstract class Pickler extends SubComponent {
putAnnotation(annInfo)
}
}
val AnnotationInfo(tpe, args, assocs) = annot
val AnnotationInfo(tpe, args, assocs, _) = annot
putType(tpe)
args foreach putAnnotArg
assocs foreach { asc =>
@ -614,7 +614,7 @@ abstract class Pickler extends SubComponent {
}
// annotations attached to a symbol (i.e. annots on terms)
case (target: Symbol, annot@AnnotationInfo(_, _, _)) =>
case (target: Symbol, annot@AnnotationInfo(_, _, _, _)) =>
writeRef(target)
writeAnnotation(annot)
SYMANNOT
@ -966,7 +966,7 @@ abstract class Pickler extends SubComponent {
MODIFIERS
// annotations on types (not linked to a symbol)
case annot@AnnotationInfo(_, _, _) =>
case annot@AnnotationInfo(_, _, _, _) =>
writeAnnotation(annot)
ANNOTINFO
@ -1072,7 +1072,7 @@ abstract class Pickler extends SubComponent {
printRef(tp)
printRefs(annots)
}
case (target: Symbol, AnnotationInfo(atp, args, Nil)) =>
case (target: Symbol, AnnotationInfo(atp, args, Nil, _)) =>
print("SYMANNOT ")
printRef(target)
printRef(atp)
@ -1081,7 +1081,7 @@ abstract class Pickler extends SubComponent {
print("CHILDREN ")
printRef(target)
for (c <- children) printRef(c.asInstanceOf[Symbol])
case AnnotationInfo(atp, args, Nil) =>
case AnnotationInfo(atp, args, Nil, _) =>
print("ANNOTINFO")
printRef(atp)
for (c <- args) printRef(c)

View File

@ -423,7 +423,7 @@ abstract class UnPickler {
else
args += at(argref, readAnnotArg)
}
AnnotationInfo(atp, args.toList, assocs.toList)
AnnotationInfo(atp, args.toList, assocs.toList, NoPosition)
}

View File

@ -9,7 +9,7 @@ package transform
import symtab._
import Flags._
import scala.tools.nsc.util.Position
import scala.tools.nsc.util.{ Position, NoPosition }
import scala.collection.mutable.{ListBuffer, HashMap}
abstract class CleanUp extends Transform with ast.TreeDSL {
@ -32,10 +32,10 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
private var localTyper: analyzer.Typer = null
private lazy val serializableAnnotation =
AnnotationInfo(SerializableAttr.tpe, Nil, Nil)
AnnotationInfo(SerializableAttr.tpe, Nil, Nil, NoPosition)
private lazy val serialVersionUIDAnnotation = {
val attr = definitions.getClass("scala.SerialVersionUID")
AnnotationInfo(attr.tpe, List(Literal(Constant(0))), List())
AnnotationInfo(attr.tpe, List(Literal(Constant(0))), List(), NoPosition)
}
private object MethodDispatchType extends scala.Enumeration {

View File

@ -611,7 +611,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
.setInfo(IntClass.tpe)
.setFlag(PROTECTED)
atPhase(currentRun.typerPhase) {
sym addAnnotation AnnotationInfo(VolatileAttr.tpe, Nil, Nil)
sym addAnnotation AnnotationInfo(VolatileAttr.tpe, Nil, Nil, NoPosition)
}
clazz.info.decls.enter(sym)
addDef(clazz.pos, VAL(sym) === ZERO)

View File

@ -271,7 +271,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
*/
def concreteTypes(sym: Symbol): List[Type] =
sym.getAnnotation(SpecializedClass) match {
case Some(AnnotationInfo(_, args, _)) =>
case Some(AnnotationInfo(_, args, _, _)) =>
args match {
case Literal(ct) :: _ =>
val tpes = parseTypes(ct.stringValue)

View File

@ -8,7 +8,7 @@ package scala.tools.nsc
package typechecker
import scala.collection.mutable.HashMap
import scala.tools.nsc.util.Position
import scala.tools.nsc.util.{ Position, NoPosition }
import symtab.Flags
import symtab.Flags._
@ -919,7 +919,7 @@ trait Namers { self: Analyzer =>
} else typer.typedType(tpt).tpe
// #2382: return type of default getters are always @uncheckedVariance
if (meth.hasFlag(DEFAULTPARAM))
rt.withAnnotation(AnnotationInfo(definitions.uncheckedVarianceClass.tpe, List(), List()))
rt.withAnnotation(AnnotationInfo(definitions.uncheckedVarianceClass.tpe, List(), List(), NoPosition))
else rt
})
}

View File

@ -9,6 +9,7 @@ package typechecker
import symtab.Flags
import symtab.Flags._
import util.NoPosition
import scala.collection.mutable.ListBuffer
/** <ul>
@ -228,7 +229,7 @@ trait SyntheticMethods extends ast.TreeDSL {
if (clazz hasFlag Flags.CASE) {
val isTop = !(clazz.ancestors exists (_ hasFlag Flags.CASE))
// case classes are implicitly declared serializable
clazz addAnnotation AnnotationInfo(SerializableAttr.tpe, Nil, Nil)
clazz addAnnotation AnnotationInfo(SerializableAttr.tpe, Nil, Nil, NoPosition)
if (isTop) {
// If this case class has fields with less than public visibility, their getter at this

View File

@ -2396,7 +2396,7 @@ trait Typers { self: Analyzer =>
* @param annClass the expected annotation class
*/
def typedAnnotation(ann: Tree, mode: Int = EXPRmode, selfsym: Symbol = NoSymbol, annClass: Symbol = AnnotationClass, requireJava: Boolean = false): AnnotationInfo = {
lazy val annotationError = AnnotationInfo(ErrorType, Nil, Nil)
lazy val annotationError = AnnotationInfo(ErrorType, Nil, Nil, NoPosition)
var hasError: Boolean = false
def error(pos: Position, msg: String) = {
context.error(pos, msg)
@ -2507,13 +2507,13 @@ trait Typers { self: Analyzer =>
}
for (name <- names) {
if (!name.annotations.contains(AnnotationInfo(AnnotationDefaultAttr.tpe, List(), List())) &&
if (!name.annotations.contains(AnnotationInfo(AnnotationDefaultAttr.tpe, List(), List(), NoPosition)) &&
!name.hasFlag(DEFAULTPARAM))
error(ann.pos, "annotation " + annType.typeSymbol.fullNameString + " is missing argument " + name.name)
}
if (hasError) annotationError
else AnnotationInfo(annType, List(), nvPairs map {p => (p._1, p._2.get)})
else AnnotationInfo(annType, List(), nvPairs map {p => (p._1, p._2.get)}, ann.pos)
}
} else if (requireJava) {
error(ann.pos, "nested classfile annotations must be defined in java; found: "+ annType)
@ -2553,7 +2553,7 @@ trait Typers { self: Analyzer =>
def annInfo(t: Tree): AnnotationInfo = t match {
case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) =>
AnnotationInfo(annType, args, List())
AnnotationInfo(annType, args, List(), t.pos)
case Block(stats, expr) =>
context.warning(t.pos, "Usage of named or default arguments transformed this annotation\n"+