forked from scala/scala3
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathArrayConstructors.scala
59 lines (48 loc) · 2.1 KB
/
ArrayConstructors.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package dotty.tools.dotc
package transform
import core.*
import MegaPhase.*
import Contexts.*
import Symbols.*
import Types.*
import StdNames.*
import dotty.tools.dotc.ast.tpd
import scala.collection.immutable.::
/** This phase rewrites calls to array constructors to newArray method in Dotty.runtime.Arrays module.
*
* It assummes that generic arrays have already been handled by typer(see Applications.convertNewGenericArray).
* Additionally it optimizes calls to scala.Array.ofDim functions by replacing them with calls to newArray with specific dimensions
*/
class ArrayConstructors extends MiniPhase {
import ast.tpd.*
override def phaseName: String = ArrayConstructors.name
override def description: String = ArrayConstructors.description
override def transformApply(tree: tpd.Apply)(using Context): tpd.Tree = {
def expand(elemType: Type, dims: List[Tree]) =
val elemTypeNonVoid =
if elemType.isValueSubType(defn.UnitType) then defn.BoxedUnitClass.typeRef
else elemType
tpd.newArray(elemTypeNonVoid, tree.tpe, tree.span, JavaSeqLiteral(dims, TypeTree(defn.IntClass.typeRef)))
if (tree.fun.symbol eq defn.ArrayConstructor) {
val TypeApply(tycon, targ :: Nil) = tree.fun: @unchecked
expand(targ.tpe, tree.args)
}
else if ((tree.fun.symbol.maybeOwner eq defn.ArrayModuleClass) && (tree.fun.symbol.name eq nme.ofDim) && !tree.tpe.isInstanceOf[MethodicType]) {
val Apply(Apply(TypeApply(_, List(tp)), _), _) = tree: @unchecked
val cs = tp.tpe.classSymbol
tree.fun match {
case Apply(TypeApply(t: Ident, targ), dims)
if !TypeErasure.isGeneric(targ.head.tpe) && !cs.isDerivedValueClass =>
expand(targ.head.tpe, dims)
case Apply(TypeApply(t: Select, targ), dims)
if !TypeErasure.isGeneric(targ.head.tpe) && !cs.isDerivedValueClass =>
Block(t.qualifier :: Nil, expand(targ.head.tpe, dims))
case _ => tree
}
}
else tree
}
}
object ArrayConstructors:
val name: String = "arrayConstructors"
val description: String = "intercept creation of (non-generic) arrays and intrinsify"