aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-02-11 14:53:24 +0100
committerMartin Odersky <odersky@gmail.com>2013-02-11 14:53:24 +0100
commit48076bb9c287d82a1259885dccfa424df16fe912 (patch)
tree34e0d3b9dd3e3ab1d8e083da5ad48ae2db860b10 /src/dotty/tools/dotc/core
parent952d4a29c3e55d44defa70ab15f0137a51320de2 (diff)
downloaddotty-48076bb9c287d82a1259885dccfa424df16fe912.tar.gz
dotty-48076bb9c287d82a1259885dccfa424df16fe912.tar.bz2
dotty-48076bb9c287d82a1259885dccfa424df16fe912.zip
Treating all annotations as wrappers over trees.
Diffstat (limited to 'src/dotty/tools/dotc/core')
-rw-r--r--src/dotty/tools/dotc/core/Annotations.scala20
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala12
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala8
-rw-r--r--src/dotty/tools/dotc/core/pickling/UnPickler.scala95
4 files changed, 71 insertions, 64 deletions
diff --git a/src/dotty/tools/dotc/core/Annotations.scala b/src/dotty/tools/dotc/core/Annotations.scala
index 8aead084d..1bd6fc31f 100644
--- a/src/dotty/tools/dotc/core/Annotations.scala
+++ b/src/dotty/tools/dotc/core/Annotations.scala
@@ -1,24 +1,28 @@
package dotty.tools.dotc.core
-import Symbols._
+import Symbols._, Trees._, Types._, Positions._, Contexts._
object Annotations {
abstract class Annotation {
- def matches(cls: Symbol) = ???
+ def tree: TypedTree
+ def symbol(implicit ctx: Context): Symbol = tree.tpe.typeSymbol
+ def matches(cls: Symbol)(implicit ctx: Context): Boolean = symbol.isNonBottomSubClass(cls)
def appliesToModule: Boolean = ???
}
- abstract class InternalAnnotation extends Annotation {
+ case class ConcreteAnnotation(val tree: TypedTree) extends Annotation
- }
+ object Annotation {
- case class Alias(sym: Symbol) extends InternalAnnotation {
+ def apply(cls: ClassSymbol, args: List[TypedTree])(implicit ctx: Context): Annotation =
+ ConcreteAnnotation(makeTypedTree.New(cls.typeConstructor, args))
- }
+ def makeAlias(sym: TermSymbol)(implicit ctx: Context) =
+ apply(defn.AliasAnnot, List(makeTypedTree.Ident(TermRef(sym.owner.thisType, sym))))
- case class Child(child: ClassSymbol) extends InternalAnnotation {
+ def makeChild(sym: ClassSymbol)(implicit ctx: Context) =
+ apply(defn.ChildAnnot, List(makeTypedTree.Ident(TypeRef(sym.owner.thisType, sym))))
}
-
} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala
index b399a77c4..3e5e8b8af 100644
--- a/src/dotty/tools/dotc/core/Definitions.scala
+++ b/src/dotty/tools/dotc/core/Definitions.scala
@@ -113,11 +113,12 @@ class Definitions(implicit ctx: Context) {
lazy val SymbolClass = requiredClass("scala.Symbol")
lazy val StringClass = requiredClass("java.lang.String")
lazy val ClassClass = requiredClass("java.lang.Class")
- //def Class_getMethod = getMemberMethod(ClassClass, nme.getMethod_)
+ //def Class_getMethod = getMemberMethod(ClassClass, nme.getMethod_)
lazy val DynamicClass = requiredClass("scala.Dynamic")
- lazy val BoxedNumberClass = requiredClass("java.lang.Number")
- lazy val JavaSerializableClass = requiredClass("java.lang.Serializable")
- lazy val ComparableClass = requiredClass("java.lang.Comparable")
+ lazy val BoxedNumberClass = requiredClass("java.lang.Number")
+ lazy val JavaSerializableClass = requiredClass("java.lang.Serializable")
+ lazy val ComparableClass = requiredClass("java.lang.Comparable")
+ lazy val AnnotationClass = requiredClass("scala.annotation.Annotation")
lazy val AnyType = AnyClass.typeConstructor
lazy val AnyValType = AnyValClass.typeConstructor
@@ -129,6 +130,9 @@ class Definitions(implicit ctx: Context) {
lazy val SeqType = SeqClass.typeConstructor
lazy val ArrayType = ArrayClass.typeConstructor
+ lazy val AliasAnnot = requiredClass("dotty.annotation.internal.Alias")
+ lazy val ChildAnnot = requiredClass("dotty.annotation.internal.Alias")
+
def ClassType(arg: Type)(implicit ctx: Context) = {
val ctype = ClassClass.typeConstructor
if (ctx.phase.erasedTypes) ctype else ctype.appliedTo(arg)
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index a53ac374f..979e2130f 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -95,18 +95,14 @@ object SymDenotations {
private[core] def annotations_=(annots: List[Annotation]): Unit = { _annotations = annots }
/** Does this denotation have an annotation matching the given class symbol? */
- def hasAnnotation(cls: Symbol) = dropOtherAnnotations(annotations, cls).nonEmpty
+ def hasAnnotation(cls: Symbol)(implicit ctx: Context) = dropOtherAnnotations(annotations, cls).nonEmpty
/** Add given annotation to the annotations of this denotation */
final def addAnnotation(annot: Annotation): Unit = annotations =
annot :: annotations
- /** Record that the denoting symbol is an alias of given `alias` symbol */
- final def setAlias(alias: Symbol)(implicit ctx: Context): Unit =
- addAnnotation(Alias(alias))
-
@tailrec
- private def dropOtherAnnotations(anns: List[Annotation], cls: Symbol): List[Annotation] = anns match {
+ private def dropOtherAnnotations(anns: List[Annotation], cls: Symbol)(implicit ctx: Context): List[Annotation] = anns match {
case ann :: rest => if (ann matches cls) anns else dropOtherAnnotations(rest, cls)
case Nil => Nil
}
diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
index ed97217f3..0183718e4 100644
--- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala
+++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
@@ -9,6 +9,7 @@ import java.lang.Double.longBitsToDouble
import Contexts._, Symbols._, Types._, Scopes._, SymDenotations._, Names._
import StdNames._, Denotations._, NameOps._, Flags._, Constants._, Annotations._
+import Trees._
import scala.reflect.internal.pickling.PickleFormat._
import scala.collection.{ mutable, immutable }
import scala.collection.mutable.ListBuffer
@@ -62,6 +63,8 @@ abstract class UnPickler {
/** A map from refinement classes to their associated refinement types */
private val refinementTypes = mutable.HashMap[Symbol, RefinedType]()
+ private val mk = makeTypedTree
+
//println("unpickled " + classRoot + ":" + classRoot.rawInfo + ", " + moduleRoot + ":" + moduleRoot.rawInfo);//debug
// Laboriously unrolled for performance.
@@ -473,19 +476,10 @@ abstract class UnPickler {
val boundSyms = until(end, readSymbolRef)
elimExistentials(boundSyms, restpe)
case ANNOTATEDtpe =>
- ???
- /*
- var typeRef = readNat()
- val selfsym = if (isSymbolRef(typeRef)) {
- val s = at(typeRef, readSymbol)
- typeRef = readNat()
- s
- } else NoSymbol // selfsym can go.
- val tp = at(typeRef, () => readType(forceProperType)) // NMT_TRANSITION
+ val tp = readTypeRef()
+ // no annotation self type is supported, so no test whether this is a symbol ref
val annots = until(end, readAnnotationRef)
- if (selfsym == NoSymbol) AnnotatedType(annots, tp, selfsym)
- else tp
- */
+ AnnotatedType(annots, tp)
case _ =>
noSuchTypeTag(tag, end)
}
@@ -527,7 +521,7 @@ abstract class UnPickler {
val end = readNat() + readIndex
val target = readSymbolRef()
while (readIndex != end)
- target.addAnnotation(Child(readSymbolRef().asClass))
+ target.addAnnotation(Annotation.makeChild(readSymbolRef().asClass))
}
/* Read a reference to a pickled item */
@@ -552,76 +546,85 @@ abstract class UnPickler {
protected def readTypeNameRef(): TypeName = readNameRef().toTypeName
protected def readTermNameRef(): TermName = readNameRef().toTermName
- protected def readSymbolAnnotation(): Unit = ???
- protected def readAnnotationRef(): Annotation = ??? // at(readNat(), readAnnotation)
+ protected def readAnnotationRef(): Annotation = at(readNat(), readAnnotation)
+
// protected def readModifiersRef(): Modifiers = at(readNat(), readModifiers)
-// protected def readTreeRef(): Tree = at(readNat(), readTree)
-/*
+ protected def readTreeRef(): TypedTree = at(readNat(), readTree)
+
+ protected def readTree(): TypedTree = ???
+
/** Read an annotation argument, which is pickled either
* as a Constant or a Tree.
*/
- protected def readAnnotArg(i: Int): Tree = bytes(index(i)) match {
+ protected def readAnnotArg(i: Int): TypedTree = bytes(index(i)) match {
case TREE => at(i, readTree)
- case _ =>
- val const = at(i, readConstant)
- Literal(const) setType const.tpe
+ case _ => mk.Literal(at(i, readConstant))
}
/** Read a ClassfileAnnotArg (argument to a classfile annotation)
*/
- private def readArrayAnnot() = {
+ private def readArrayAnnotArg(): TypedTree = {
readByte() // skip the `annotargarray` tag
val end = readNat() + readIndex
- until(end, () => readClassfileAnnotArg(readNat())).toArray(JavaArgumentTag)
+ // array elements are trees representing instances of scala.annotation.Annotation
+ mk.ArrayValue(
+ mk.TypeTree(defn.AnnotationClass.typeConstructor),
+ until(end, () => readClassfileAnnotArg(readNat())))
}
- protected def readClassfileAnnotArg(i: Int): ClassfileAnnotArg = bytes(index(i)) match {
- case ANNOTINFO => NestedAnnotArg(at(i, readAnnotation))
- case ANNOTARGARRAY => at(i, () => ArrayAnnotArg(readArrayAnnot()))
- case _ => LiteralAnnotArg(at(i, readConstant))
+
+ private def readAnnotInfoArg(): TypedTree = {
+ readByte() // skip the `annotinfo` tag
+ val end = readNat() + readIndex
+ readAnnotationContents(end)
+ }
+
+ protected def readClassfileAnnotArg(i: Int): TypedTree = bytes(index(i)) match {
+ case ANNOTINFO => at(i, readAnnotInfoArg)
+ case ANNOTARGARRAY => at(i, readArrayAnnotArg)
+ case _ => readAnnotArg(i)
}
- /** Read an AnnotationInfo. Not to be called directly, use
- * readAnnotation or readSymbolAnnotation
+ /** Read an annotation's contents. Not to be called directly, use
+ * readAnnotation, readSymbolAnnotation, or readAnnotInfoArg
*/
- protected def readAnnotationInfo(end: Int): AnnotationInfo = {
+ protected def readAnnotationContents(end: Int): TypedTree = {
val atp = readTypeRef()
- val args = new ListBuffer[Tree]
- val assocs = new ListBuffer[(Name, ClassfileAnnotArg)]
+ val args = new ListBuffer[TypedTree]
while (readIndex != end) {
val argref = readNat()
- if (isNameEntry(argref)) {
- val name = at(argref, readName)
- val arg = readClassfileAnnotArg(readNat())
- assocs += ((name, arg))
+ args += {
+ if (isNameEntry(argref)) {
+ val name = at(argref, readName)
+ val arg = readClassfileAnnotArg(readNat())
+ mk.NamedArg(name, arg)
+ } else readAnnotArg(argref)
}
- else
- args += readAnnotArg(argref)
}
- AnnotationInfo(atp, args.toList, assocs.toList)
+ mk.New(atp, args.toList)
}
/** Read an annotation and as a side effect store it into
* the symbol it requests. Called at top-level, for all
* (symbol, annotInfo) entries. */
- protected def readSymbolAnnotation() {
+ protected def readSymbolAnnotation(): Unit = {
val tag = readByte()
if (tag != SYMANNOT)
errorBadSignature("symbol annotation expected ("+ tag +")")
val end = readNat() + readIndex
val target = readSymbolRef()
- target.addAnnotation(readAnnotationInfo(end))
+ target.addAnnotation(ConcreteAnnotation(readAnnotationContents(end)))
}
/** Read an annotation and return it. Used when unpickling
* an ANNOTATED(WSELF)tpe or a NestedAnnotArg */
- protected def readAnnotation(): AnnotationInfo = {
+ protected def readAnnotation(): Annotation = {
val tag = readByte()
if (tag != ANNOTINFO)
errorBadSignature("annotation expected (" + tag + ")")
val end = readNat() + readIndex
- readAnnotationInfo(end)
+ ConcreteAnnotation(readAnnotationContents(end))
}
-
+/*
/* Read an abstract syntax tree */
protected def readTree(): Tree = {
val outerTag = readByte()
@@ -960,8 +963,8 @@ abstract class UnPickler {
def disambiguate(alt: Symbol) =
denot.info =:= denot.owner.thisType.memberInfo(alt)
if (j >= 0) {
- val alias = at(j, readDisambiguatedSymbol(disambiguate))
- denot.setAlias(alias)
+ val alias = at(j, readDisambiguatedSymbol(disambiguate)).asTerm
+ denot.addAnnotation(Annotation.makeAlias(alias))
}
} catch {
case e: MissingRequirementError => throw toTypeError(e)