summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTiark Rompf <tiark.rompf@epfl.ch>2009-02-23 15:35:27 +0000
committerTiark Rompf <tiark.rompf@epfl.ch>2009-02-23 15:35:27 +0000
commitae4e5376d5547d86f302ffdcc4cf8ad223ea5908 (patch)
treebaebb1e58bbae3b060a686b68d61d3257573b7bf /src
parentc4c651969c1c72a38c7bbd33c2cad2bc7a1f65cb (diff)
downloadscala-ae4e5376d5547d86f302ffdcc4cf8ad223ea5908.tar.gz
scala-ae4e5376d5547d86f302ffdcc4cf8ad223ea5908.tar.bz2
scala-ae4e5376d5547d86f302ffdcc4cf8ad223ea5908.zip
added a hook for annotation checkers in Typers....
added a hook for annotation checkers in Typers.adapt
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/AnnotationCheckers.scala28
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala7
2 files changed, 33 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/AnnotationCheckers.scala b/src/compiler/scala/tools/nsc/symtab/AnnotationCheckers.scala
index 9765eb192e..735943b4ad 100644
--- a/src/compiler/scala/tools/nsc/symtab/AnnotationCheckers.scala
+++ b/src/compiler/scala/tools/nsc/symtab/AnnotationCheckers.scala
@@ -23,6 +23,18 @@ trait AnnotationCheckers {
/** Modify the type that has thus far been inferred
* for a tree. All this should do is add annotations. */
def addAnnotations(tree: Tree, tpe: Type): Type = tpe
+
+ /** Decide whether this annotation checker can adapt a tree
+ * that has an annotated type to the given type tp, taking
+ * into account the given mode (see method adapt in trait Typers).*/
+ def canAdaptAnnotations(tree: Tree, mode: Int, pt: Type): Boolean = false
+
+ /** Adapt a tree that has an annotated type to the given type tp,
+ * taking into account the given mode (see method adapt in trait Typers).
+ * An implementation cannot rely on canAdaptAnnotations being called
+ * before. If the implementing class cannot do the adaptiong, it
+ * should return the tree unchanged.*/
+ def adaptAnnotations(tree: Tree, mode: Int, pt: Type): Tree = tree
}
/** The list of annotation checkers that have been registered */
@@ -57,4 +69,20 @@ trait AnnotationCheckers {
annotationCheckers.foldLeft(tpe)((tpe, checker) =>
checker.addAnnotations(tree, tpe))
}
+
+ /** Find out whether any annotation checker can adapt a tree
+ * to a given type. Called by Typers.adapt. */
+ def canAdaptAnnotations(tree: Tree, mode: Int, pt: Type): Boolean = {
+ annotationCheckers.foldLeft(false)((res, checker) =>
+ res || checker.canAdaptAnnotations(tree, mode, pt))
+ }
+
+ /** Let registered annotation checkers adapt a tree
+ * to a given type (called by Typers.adapt). Annotation checkers
+ * that cannot do the adaption should pass the tree through
+ * unchanged. */
+ def adaptAnnotations(tree: Tree, mode: Int, pt: Type): Tree = {
+ annotationCheckers.foldLeft(tree)((tree, checker) =>
+ checker.adaptAnnotations(tree, mode, pt))
+ }
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 5e876cc8e7..876431703d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -647,6 +647,7 @@ trait Typers { self: Analyzer =>
/** Perform the following adaptations of expression, pattern or type `tree' wrt to
* given mode `mode' and given prototype `pt':
+ * (-1) For expressions with annotated types, let AnnotationCheckers decide what to do
* (0) Convert expressions with constant types to literals
* (1) Resolve overloading, unless mode contains FUNmode
* (2) Apply parameterless functions
@@ -680,6 +681,8 @@ trait Typers { self: Analyzer =>
* If all this fails, error
*/
protected def adapt(tree: Tree, mode: Int, pt: Type): Tree = tree.tpe match {
+ case atp @ AnnotatedType(_, _, _) if canAdaptAnnotations(tree, mode, pt) => // (-1)
+ adaptAnnotations(tree, mode, pt)
case ct @ ConstantType(value) if ((mode & (TYPEmode | FUNmode)) == 0 && (ct <:< pt) && !inIDE) => // (0)
copy.Literal(tree, value)
case OverloadedType(pre, alts) if ((mode & FUNmode) == 0) => // (1)
@@ -2466,7 +2469,7 @@ trait Typers { self: Analyzer =>
val cond1 = checkDead(typed(cond, BooleanClass.tpe))
if (elsep.isEmpty) { // in the future, should be unecessary
val thenp1 = typed(thenp, UnitClass.tpe)
- copy.If(tree, cond1, thenp1, elsep) setType UnitClass.tpe
+ copy.If(tree, cond1, thenp1, elsep) setType thenp1.tpe
} else {
val thenp1 = typed(thenp, pt)
val elsep1 = typed(elsep, pt)
@@ -3811,7 +3814,7 @@ trait Typers { self: Analyzer =>
case RefinedType(ps, _) =>
for (p <- ps) getParts(p, s)
case AnnotatedType(_, t, _) =>
- getParts(t, s)
+ getParts(t, s)
case _ =>
}
}