summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Typers.scala
diff options
context:
space:
mode:
authorLex Spoon <lex@lexspoon.org>2007-05-21 15:49:37 +0000
committerLex Spoon <lex@lexspoon.org>2007-05-21 15:49:37 +0000
commitfe55fa336be15afe509fbc7096e8cf51026cbfd9 (patch)
tree6d47073ccecfaacf588e017e22551c92a3d055d0 /src/compiler/scala/tools/nsc/typechecker/Typers.scala
parent22a8618b48e945323723755525bbdeb97c63da3e (diff)
downloadscala-fe55fa336be15afe509fbc7096e8cf51026cbfd9.tar.gz
scala-fe55fa336be15afe509fbc7096e8cf51026cbfd9.tar.bz2
scala-fe55fa336be15afe509fbc7096e8cf51026cbfd9.zip
Annotations clean up, including:
- AnnotationInfo has no type parameter. It always has a parse tree, and sometimes has a constant. - SymbolReifier is separated from LiftCode for independent use - reification into reflect.* structures handles more cases - unreify is added, for enough cases that annotations work
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Typers.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala67
1 files changed, 32 insertions, 35 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index b1e81f6ad4..411662c96e 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -110,11 +110,6 @@ trait Typers requires Analyzer {
*/
val LHSmode = 0x400
- /** The mode <code>CONSTmode</code> is set when expressions should evaluate
- * to constant sused for attribute arguments.
- */
- val CONSTmode = 0x800
-
/** The mode <code>REGPATmode</code> is set when regular expression patterns
* are allowed.
*/
@@ -129,7 +124,7 @@ trait Typers requires Analyzer {
*/
val HKmode = 0x4000 // @M: could also use POLYmode | TAPPmode
- private val stickyModes: int = EXPRmode | PATTERNmode | TYPEmode | CONSTmode | ALTmode
+ private val stickyModes: int = EXPRmode | PATTERNmode | TYPEmode | ALTmode
private def funMode(mode: int) = mode & (stickyModes | SCCmode) | FUNmode | POLYmode
@@ -1536,21 +1531,7 @@ trait Typers requires Analyzer {
if (fun.symbol == List_apply && args.isEmpty) {
atPos(tree.pos) { gen.mkNil setType restpe }
- } else if ((mode & CONSTmode) != 0 &&
- fun.symbol.owner == definitions.ArrayModule.tpe.symbol &&
- fun.symbol.name == nme.apply) {
- val elems = new Array[Constant](args2.length)
- var i = 0;
- for (val arg <- args2) arg match {
- case Literal(value) =>
- elems(i) = value
- i = i + 1
- case _ => errorTree(arg, "constant required")
- }
- val arrayConst = new ArrayConstant(elems, restpe)
- Literal(arrayConst) setType mkConstantType(arrayConst)
- }
- else
+ } else
constfold(copy.Apply(tree, fun, args2).setType(ifPatternSkipFormals(restpe)))
} else {
assert((mode & PATTERNmode) == 0); // this case cannot arise for patterns
@@ -1645,26 +1626,37 @@ trait Typers requires Analyzer {
}
}
- def getConstant(tree: Tree): Constant = tree match {
- case Literal(value) => value
- case arg => error(arg.pos, "attribute argument needs to be a constant; found: "+arg); Constant(null)
- }
-
- def typedAnnotation[T](annot: Annotation, reify: Tree => T): AnnotationInfo[T] = {
+ def typedAnnotation(annot: Annotation): AnnotationInfo = {
var attrError: Boolean = false;
def error(pos: Position, msg: String): Null = {
context.error(pos, msg)
attrError = true
null
}
- typed(annot.constr, EXPRmode | CONSTmode, AnnotationClass.tpe) match {
+ def needConst(tr: Tree) {
+ error(tr.pos, "attribute argument needs to be a constant; found: "+tr)
+ }
+
+ typed(annot.constr, EXPRmode, AnnotationClass.tpe) match {
case t @ Apply(Select(New(tpt), nme.CONSTRUCTOR), args) =>
if (t.isErroneous) {
- AnnotationInfo[T](ErrorType, List(), List())
+ AnnotationInfo(ErrorType, List(), List())
}
else {
val annType = tpt.tpe
- val constrArgs = args map reify
+
+ val needsConstant =
+ (!settings.Xplugtypes.value ||
+ annType <:< ClassfileAnnotationClass.tpe)
+
+ def annotArg(tree: Tree): AnnotationArgument = {
+ val arg = new AnnotationArgument(liftcode.reify(tree))
+ if(needsConstant && !arg.isConstant)
+ needConst(tree)
+ arg
+ }
+ val constrArgs = args map annotArg
+
val attrScope = annType.decls
.filter(sym => sym.isMethod && !sym.isConstructor && sym.hasFlag(JAVA))
val names = new collection.mutable.HashSet[Symbol]
@@ -1681,7 +1673,10 @@ trait Typers requires Analyzer {
error(ntree.pos, "duplicate value for element " + name)
} else {
names -= sym
- (sym.name, reify(typed(rhs, EXPRmode | CONSTmode, sym.tpe.resultType)))
+ val annArg =
+ annotArg(
+ typed(rhs, EXPRmode, sym.tpe.resultType))
+ (sym.name, annArg)
}
}
}
@@ -1716,14 +1711,16 @@ trait Typers requires Analyzer {
case _ => NoType
}
- def typedAnnotated(annot: Annotation, arg1: Tree) = {
- def annotTypeTree(ainfo: AnnotationInfo[Any]): Tree =
+ def typedAnnotated(annot: Annotation, arg1: Tree): Tree = {
+ def annotTypeTree(ainfo: AnnotationInfo): Tree =
TypeTree(arg1.tpe.withAttribute(ainfo)) setOriginal tree
+
if (arg1.isType) {
- val annotInfo = typedAnnotation(annot, liftcode.reify)
+ val annotInfo = typedAnnotation(annot)
if (settings.Xplugtypes.value) annotTypeTree(annotInfo) else arg1
} else {
- val annotInfo = typedAnnotation(annot, getConstant)
+ val annotInfo = typedAnnotation(annot)
+
arg1 match {
case _: DefTree =>
if (!annotInfo.atp.isError) {