summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/ast/TreeGen.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2012-02-22 09:55:41 +0100
committerMartin Odersky <odersky@gmail.com>2012-02-22 09:55:41 +0100
commit3a5c70c0634a5d10cff5c52014661a22278b4245 (patch)
tree77117071877cf92ca14aa6bb5afdca97484543e9 /src/compiler/scala/tools/nsc/ast/TreeGen.scala
parent15c9391d3331bce477a7745cadff5af84587f960 (diff)
downloadscala-3a5c70c0634a5d10cff5c52014661a22278b4245.tar.gz
scala-3a5c70c0634a5d10cff5c52014661a22278b4245.tar.bz2
scala-3a5c70c0634a5d10cff5c52014661a22278b4245.zip
Moved mkCast and derived method from reflect.internal.TreeGen to tools.nsc.ast.TreeGen. Made mkCast generate the "right" version of casts according to current phase.
Diffstat (limited to 'src/compiler/scala/tools/nsc/ast/TreeGen.scala')
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala37
1 files changed, 35 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index 265d017653..4e2c906cde 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -30,7 +30,7 @@ abstract class TreeGen extends reflect.internal.TreeGen {
else
tree
}
-
+
/** Builds a fully attributed wildcard import node.
*/
def mkWildcardImport(pkg: Symbol): Import = {
@@ -98,7 +98,7 @@ abstract class TreeGen extends reflect.internal.TreeGen {
def mkModuleVarDef(accessor: Symbol) = {
val inClass = accessor.owner.isClass
val extraFlags = if (inClass) PrivateLocal | SYNTHETIC else 0
-
+
val mval = (
accessor.owner.newVariable(nme.moduleVarName(accessor.name), accessor.pos.focus, MODULEVAR | extraFlags)
setInfo accessor.tpe.finalResultType
@@ -188,6 +188,20 @@ abstract class TreeGen extends reflect.internal.TreeGen {
)
}
+ /** Cast `tree` to type `pt` by creating
+ * one of the calls of the form
+ *
+ * x.asInstanceOf[`pt`] up to phase uncurry
+ * x.asInstanceOf[`pt`]() if after uncurry but before erasure
+ * x.$asInstanceOf[`pt`]() if at or after erasure
+ */
+ def mkCast(tree: Tree, pt: Type): Tree = {
+ debuglog("casting " + tree + ":" + tree.tpe + " to " + pt + " at phase: " + phase)
+ assert(!tree.tpe.isInstanceOf[MethodType], tree)
+ assert(pt eq pt.normalize, tree +" : "+ debugString(pt) +" ~>"+ debugString(pt.normalize))
+ atPos(tree.pos)(mkAsInstanceOf(tree, pt, any = !phase.next.erasedTypes, wrapInApply = phase.id > currentRun.uncurryPhase.id))
+ }
+
/** Generate a cast for tree Tree representing Array with
* elem type elemtp to expected type pt.
*/
@@ -197,6 +211,25 @@ abstract class TreeGen extends reflect.internal.TreeGen {
else
mkCast(tree, pt)
+ def mkZeroContravariantAfterTyper(tp: Type): Tree = {
+ // contravariant -- for replacing an argument in a method call
+ // must use subtyping, as otherwise we miss types like `Any with Int`
+ val tree =
+ if (NullClass.tpe <:< tp) Literal(Constant(null))
+ else if (UnitClass.tpe <:< tp) Literal(Constant())
+ else if (BooleanClass.tpe <:< tp) Literal(Constant(false))
+ else if (FloatClass.tpe <:< tp) Literal(Constant(0.0f))
+ else if (DoubleClass.tpe <:< tp) Literal(Constant(0.0d))
+ else if (ByteClass.tpe <:< tp) Literal(Constant(0.toByte))
+ else if (ShortClass.tpe <:< tp) Literal(Constant(0.toShort))
+ else if (IntClass.tpe <:< tp) Literal(Constant(0))
+ else if (LongClass.tpe <:< tp) Literal(Constant(0L))
+ else if (CharClass.tpe <:< tp) Literal(Constant(0.toChar))
+ else mkCast(Literal(Constant(null)), tp)
+
+ tree
+ }
+
/** Translate names in Select/Ident nodes to type names.
*/
def convertToTypeName(tree: Tree): Option[RefTree] = tree match {