From 3a5c70c0634a5d10cff5c52014661a22278b4245 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 22 Feb 2012 09:55:41 +0100 Subject: 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. --- src/compiler/scala/tools/nsc/ast/TreeGen.scala | 37 ++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) (limited to 'src/compiler/scala/tools/nsc/ast/TreeGen.scala') 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 { -- cgit v1.2.3