aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-08-03 20:50:37 +0200
committerMartin Odersky <odersky@gmail.com>2014-08-03 21:02:11 +0200
commite25232d5b4fdc1ae7bc5a44ad06e31a00699dbaf (patch)
tree26c3ce90d09933debc6a991d10e708cc65a84157 /src/dotty/tools/dotc
parent168e4f18f0b2f8ac0e3d7ef5128797303dec6a44 (diff)
downloaddotty-e25232d5b4fdc1ae7bc5a44ad06e31a00699dbaf.tar.gz
dotty-e25232d5b4fdc1ae7bc5a44ad06e31a00699dbaf.tar.bz2
dotty-e25232d5b4fdc1ae7bc5a44ad06e31a00699dbaf.zip
Annotation decorators for symbols
Added decorators for symbols that can query specific annotations and annotation arguments (for now, -deprecated and -migration are added)
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r--src/dotty/tools/dotc/ast/TreeInfo.scala12
-rw-r--r--src/dotty/tools/dotc/core/Annotations.scala33
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala9
3 files changed, 45 insertions, 9 deletions
diff --git a/src/dotty/tools/dotc/ast/TreeInfo.scala b/src/dotty/tools/dotc/ast/TreeInfo.scala
index cc3e53abc..174de4d46 100644
--- a/src/dotty/tools/dotc/ast/TreeInfo.scala
+++ b/src/dotty/tools/dotc/ast/TreeInfo.scala
@@ -103,11 +103,19 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
/** The number of arguments in an application */
def numArgs(tree: Tree): Int = unsplice(tree) match {
case Apply(fn, args) => numArgs(fn) + args.length
- case TypeApply(fn, args) => numArgs(fn)
- case Block(stats, expr) => numArgs(expr)
+ case TypeApply(fn, _) => numArgs(fn)
+ case Block(_, expr) => numArgs(expr)
case _ => 0
}
+ /** The (last) list of arguments of an application */
+ def arguments(tree: Tree): List[Tree] = unsplice(tree) match {
+ case Apply(_, args) => args
+ case TypeApply(fn, _) => arguments(fn)
+ case Block(_, expr) => arguments(expr)
+ case _ => Nil
+ }
+
/** Is tree a self constructor call this(...)? I.e. a call to a constructor of the
* same object?
*/
diff --git a/src/dotty/tools/dotc/core/Annotations.scala b/src/dotty/tools/dotc/core/Annotations.scala
index b4b7ebd24..f67381ddc 100644
--- a/src/dotty/tools/dotc/core/Annotations.scala
+++ b/src/dotty/tools/dotc/core/Annotations.scala
@@ -2,6 +2,7 @@ package dotty.tools.dotc
package core
import Symbols._, Types._, util.Positions._, Contexts._, Constants._, ast.tpd._
+import config.ScalaVersion
object Annotations {
@@ -15,6 +16,14 @@ object Annotations {
def derivedAnnotation(tree: Tree)(implicit ctx: Context) =
if (tree eq this.tree) this else Annotation(tree)
+
+ def arguments(implicit ctx: Context) = ast.tpd.arguments(tree)
+ def argument(i: Int)(implicit ctx: Context): Option[Tree] = {
+ val args = arguments
+ if (i < args.length) Some(args(i)) else None
+ }
+ def argumentConstant(i: Int)(implicit ctx: Context): Option[Constant] =
+ for (ConstantType(c) <- argument(i) map (_.tpe)) yield c
}
case class ConcreteAnnotation(t: Tree) extends Annotation {
@@ -69,4 +78,28 @@ object Annotations {
val tref = cls.typeRef
Annotation(defn.ThrowsAnnot.typeRef.appliedTo(tref), Ident(tref))
}
+
+ /** A decorator that provides queries for specific annotations
+ * of a symbol.
+ */
+ implicit class AnnotInfo(val sym: Symbol) extends AnyVal {
+
+ def isDeprecated(implicit ctx: Context) =
+ sym.hasAnnotation(defn.DeprecatedAnnot)
+
+ def deprecationMessage(implicit ctx: Context) =
+ for (annot <- sym.getAnnotation(defn.DeprecatedAnnot);
+ arg <- annot.argumentConstant(0))
+ yield arg.stringValue
+
+ def migrationVersion(implicit ctx: Context) =
+ for (annot <- sym.getAnnotation(defn.MigrationAnnot);
+ arg <- annot.argumentConstant(1))
+ yield ScalaVersion.parse(arg.stringValue)
+
+ def migrationMessage(implicit ctx: Context) =
+ for (annot <- sym.getAnnotation(defn.MigrationAnnot);
+ arg <- annot.argumentConstant(0))
+ yield ScalaVersion.parse(arg.stringValue)
+ }
} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 91a8e4345..fcc01503f 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -200,14 +200,9 @@ object SymDenotations {
dropOtherAnnotations(annotations, cls).nonEmpty
/** Optionally, the arguments of the first annotation matching the given class symbol */
- final def getAnnotationArgs(cls: Symbol)(implicit ctx: Context): Option[List[tpd.Tree]] =
+ final def getAnnotation(cls: Symbol)(implicit ctx: Context): Option[Annotation] =
dropOtherAnnotations(annotations, cls) match {
- case annot :: _ =>
- Some(
- annot.tree match {
- case Trees.Apply(_, args) => args
- case _ => Nil
- })
+ case annot :: _ => Some(annot)
case nil => None
}