summaryrefslogtreecommitdiff
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
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.
-rw-r--r--src/compiler/scala/reflect/internal/TreeGen.scala35
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala37
2 files changed, 35 insertions, 37 deletions
diff --git a/src/compiler/scala/reflect/internal/TreeGen.scala b/src/compiler/scala/reflect/internal/TreeGen.scala
index def1350187..3b3c7f6298 100644
--- a/src/compiler/scala/reflect/internal/TreeGen.scala
+++ b/src/compiler/scala/reflect/internal/TreeGen.scala
@@ -148,22 +148,6 @@ abstract class TreeGen {
None
}
- /** Cast `tree` to type `pt` */
- 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.typeSymbol.isPackageClass && !pt.typeSymbol.isPackageObjectClass, pt)
- // called during (at least): typer, uncurry, explicitouter, cleanup.
- // TODO: figure out the truth table for any/wrapInApply
- // - the `any` flag seems to relate to erasure's adaptMember: "x.asInstanceOf[T] becomes x.$asInstanceOf[T]",
- // where asInstanceOf is Any_asInstanceOf and $asInstanceOf is Object_asInstanceOf
- // erasure will only unbox the value in a tree made by mkCast if `any && wrapInApply`
- // - the `wrapInApply` flag need not be true if the tree will be adapted to have the empty argument list added before it gets to erasure
- // in fact, I think it should be false for trees that will be type checked during typer
- assert(pt eq pt.normalize, tree +" : "+ debugString(pt) +" ~>"+ debugString(pt.normalize))
- atPos(tree.pos)(mkAsInstanceOf(tree, pt, any = false, wrapInApply = true))
- }
-
/** Builds a reference with stable type to given symbol */
def mkAttributedStableRef(pre: Type, sym: Symbol): Tree =
stabilize(mkAttributedRef(pre, sym))
@@ -265,25 +249,6 @@ abstract class TreeGen {
tree setType tp
}
- 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
- }
-
/** Builds a tuple */
def mkTuple(elems: List[Tree]): Tree =
if (elems.isEmpty) Literal(Constant())
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 {