diff options
author | Martin Odersky <odersky@gmail.com> | 2012-02-22 09:55:41 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2012-02-22 09:55:41 +0100 |
commit | 3a5c70c0634a5d10cff5c52014661a22278b4245 (patch) | |
tree | 77117071877cf92ca14aa6bb5afdca97484543e9 /src/compiler | |
parent | 15c9391d3331bce477a7745cadff5af84587f960 (diff) | |
download | scala-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')
-rw-r--r-- | src/compiler/scala/reflect/internal/TreeGen.scala | 35 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/TreeGen.scala | 37 |
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 { |