diff options
author | Tiark Rompf <tiark.rompf@epfl.ch> | 2009-02-23 15:35:27 +0000 |
---|---|---|
committer | Tiark Rompf <tiark.rompf@epfl.ch> | 2009-02-23 15:35:27 +0000 |
commit | ae4e5376d5547d86f302ffdcc4cf8ad223ea5908 (patch) | |
tree | baebb1e58bbae3b060a686b68d61d3257573b7bf /src | |
parent | c4c651969c1c72a38c7bbd33c2cad2bc7a1f65cb (diff) | |
download | scala-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.scala | 28 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 7 |
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 _ => } } |