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:
parent
fd3e9a33d6
commit
0e9e3a8368
|
@ -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
|
||||
}}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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("(", ",", ")"))
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 =>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"+
|
||||
|
|
Loading…
Reference in New Issue