|
| 1 | +package dotty.tools.dotc |
| 2 | +package transform |
| 3 | + |
| 4 | +import core._ |
| 5 | +import Types._ |
| 6 | +import dotty.tools.dotc.transform.TreeTransforms._ |
| 7 | +import Contexts.Context |
| 8 | +import Symbols._ |
| 9 | +import Phases._ |
| 10 | +import Decorators._ |
| 11 | + |
| 12 | +/** A transformer that eliminates SeqLiteral's, transforming `SeqLiteral(elems)` to an operation |
| 13 | + * equivalent to |
| 14 | + * |
| 15 | + * JavaSeqLiteral(elems).toSeq |
| 16 | + * |
| 17 | + * Instead of `toSeq`, which takes an implicit, the appropriate "wrapArray" method |
| 18 | + * is called directly. The reason for this step is that JavaSeqLiterals, being arrays |
| 19 | + * keep a precise type after erasure, whereas SeqLiterals only get the erased type `Seq`, |
| 20 | + */ |
| 21 | +class SeqLiterals extends MiniPhaseTransform { thisTransformer => |
| 22 | + import ast.tpd._ |
| 23 | + |
| 24 | + override def phaseName = "seqLiterals" |
| 25 | + override def treeTransformPhase = thisTransformer.next |
| 26 | + override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[PatternMatcher]) |
| 27 | + |
| 28 | + override def checkPostCondition(tree: Tree)(implicit ctx: Context): Unit = tree match { |
| 29 | + case tpd: SeqLiteral => assert(tpd.isInstanceOf[JavaSeqLiteral]) |
| 30 | + case _ => |
| 31 | + } |
| 32 | + |
| 33 | + override def transformSeqLiteral(tree: SeqLiteral)(implicit ctx: Context, info: TransformerInfo): Tree = tree match { |
| 34 | + case tree: JavaSeqLiteral => tree |
| 35 | + case _ => |
| 36 | + val arr = JavaSeqLiteral(tree.elems) |
| 37 | + //println(i"trans seq $tree, arr = $arr: ${arr.tpe} ${arr.tpe.elemType}") |
| 38 | + val elemtp = arr.tpe.elemType.bounds.hi |
| 39 | + val elemCls = elemtp.classSymbol |
| 40 | + val (wrapMethStr, targs) = |
| 41 | + if (elemCls.isPrimitiveValueClass) (s"wrap${elemCls.name}Array", Nil) |
| 42 | + else if (elemtp derivesFrom defn.ObjectClass) ("wrapRefArray", elemtp :: Nil) |
| 43 | + else ("genericWrapArray", elemtp :: Nil) |
| 44 | + ref(defn.ScalaPredefModule) |
| 45 | + .select(wrapMethStr.toTermName) |
| 46 | + .appliedToTypes(targs) |
| 47 | + .appliedTo(arr) |
| 48 | + } |
| 49 | +} |
0 commit comments