Skip to content
This repository has been archived by the owner on Feb 23, 2018. It is now read-only.

Commit

Permalink
AnnotationInfo inertia takes me into continuations.
Browse files Browse the repository at this point in the history
And kept carrying me until I was carried away.  The changes are
mostly of the janitorial variety, just doing my part to make the
interesting logic visible without being buried in low level
compiler plumbing.

Added at least one seriously convenient convenience method:

  tree modifyType fn
  // equivalent to if (tree.tpe == null) tree else tree setType fn(tree.tpe)

This is the analogue to the recently added:

  symbol modifyInfo fn
  // same idea

It's like having our carpets steam cleaned when we can keep pushing
until machinery stays in the machine and the relevant logic stands
gloriously on top. You'll eventually exclaim, "I didn't even know these
carpets were that color!"

git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@26064 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
  • Loading branch information
extempore committed Nov 23, 2011
1 parent ec654a6 commit eb0ba5c
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 164 deletions.
15 changes: 12 additions & 3 deletions src/compiler/scala/reflect/internal/AnnotationInfos.scala
Expand Up @@ -24,6 +24,7 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
def annotations: List[AnnotationInfo] // Annotations on this type.
def setAnnotations(annots: List[AnnotationInfo]): Self // Replace annotations with argument list.
def withAnnotations(annots: List[AnnotationInfo]): Self // Add annotations to this type.
def filterAnnotations(p: AnnotationInfo => Boolean): Self // Retain only annotations meeting the condition.
def withoutAnnotations: Self // Remove all annotations from this type.

/** Symbols of any @throws annotations on this symbol.
Expand All @@ -35,9 +36,8 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
/** Test for, get, or remove an annotation */
def hasAnnotation(cls: Symbol) = annotations exists (_ matches cls)
def getAnnotation(cls: Symbol) = annotations find (_ matches cls)
def removeAnnotation(cls: Symbol): Self =
if (hasAnnotation(cls)) setAnnotations(annotations filterNot (_ matches cls))
else this
def removeAnnotation(cls: Symbol): Self = filterAnnotations(ann => !(ann matches cls))
final def withAnnotation(annot: AnnotationInfo): Self = withAnnotations(List(annot))
}

/** Arguments to classfile annotations (which are written to
Expand Down Expand Up @@ -95,6 +95,9 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>
object NestedAnnotArg extends NestedAnnotArgExtractor

object AnnotationInfo extends AnnotationInfoExtractor {
def marker(atp: Type): AnnotationInfo =
apply(atp, Nil, Nil)

def lazily(lazyInfo: => AnnotationInfo) =
new LazyAnnotationInfo(lazyInfo)

Expand Down Expand Up @@ -233,6 +236,12 @@ trait AnnotationInfos extends api.AnnotationInfos { self: SymbolTable =>

def argAtIndex(index: Int): Option[Tree] =
if (index < args.size) Some(args(index)) else None

override def hashCode = atp.## + args.## + assocs.##
override def equals(other: Any) = other match {
case x: AnnotationInfo => (atp == x.atp) && (args == x.args) && (assocs == x.assocs)
case _ => false
}
}

lazy val classfileAnnotArgManifest: ClassManifest[ClassfileAnnotArg] =
Expand Down
3 changes: 3 additions & 0 deletions src/compiler/scala/reflect/internal/Symbols.scala
Expand Up @@ -1199,6 +1199,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>

def withoutAnnotations: this.type =
setAnnotations(Nil)

def filterAnnotations(p: AnnotationInfo => Boolean): this.type =
setAnnotations(annotations filter p)

def addAnnotation(annot: AnnotationInfo): this.type =
setAnnotations(annot :: annotations)
Expand Down
7 changes: 7 additions & 0 deletions src/compiler/scala/reflect/internal/Trees.scala
Expand Up @@ -101,6 +101,13 @@ trait Trees extends api.Trees { self: SymbolTable =>
class TreeOps(tree: Tree) {
def isErroneous = (tree.tpe ne null) && tree.tpe.isErroneous
def isTyped = (tree.tpe ne null) && !tree.tpe.isErroneous

/** Sets the tree's type to the result of the given function.
* If the type is null, it remains null - the function is not called.
*/
def modifyType(f: Type => Type): Tree =
if (tree.tpe eq null) tree
else tree setType f(tree.tpe)

/** If `pf` is defined for a given subtree, call super.traverse(pf(tree)),
* otherwise super.traverse(tree).
Expand Down
17 changes: 13 additions & 4 deletions src/compiler/scala/reflect/internal/Types.scala
Expand Up @@ -1022,11 +1022,10 @@ trait Types extends api.Types { self: SymbolTable =>
// overrides these.
def annotations: List[AnnotationInfo] = Nil
def withoutAnnotations: Type = this
def filterAnnotations(p: AnnotationInfo => Boolean): Type = this
def setAnnotations(annots: List[AnnotationInfo]): Type = annotatedType(annots, this)
def withAnnotations(annots: List[AnnotationInfo]): Type = annotatedType(annots, this)

final def withAnnotation(annot: AnnotationInfo): Type = withAnnotations(List(annot))

/** Remove any annotations from this type and from any
* types embedded in this type. */
def stripAnnotations = StripAnnotationsMap(this)
Expand Down Expand Up @@ -2715,16 +2714,26 @@ A type's typeSymbol should never be inspected directly.

override def safeToString = annotations.mkString(underlying + " @", " @", "")

override def filterAnnotations(p: AnnotationInfo => Boolean): Type = {
val (yes, no) = annotations partition p
if (yes.isEmpty) underlying
else if (no.isEmpty) this
else copy(annotations = yes)
}
override def setAnnotations(annots: List[AnnotationInfo]): Type =
if (annots.isEmpty) withoutAnnotations
if (annots.isEmpty) underlying
else copy(annotations = annots)

/** Add a number of annotations to this type */
override def withAnnotations(annots: List[AnnotationInfo]): Type =
if (annots.isEmpty) this
else copy(annots ::: this.annotations)

/** Remove any annotations from this type */
/** Remove any annotations from this type.
* TODO - is it allowed to nest AnnotatedTypes? If not then let's enforce
* that at creation. At the moment if they do ever turn up nested this
* recursively calls withoutAnnotations.
*/
override def withoutAnnotations = underlying.withoutAnnotations

/** Set the self symbol */
Expand Down

0 comments on commit eb0ba5c

Please sign in to comment.