Skip to content

Commit ba2eafc

Browse files
Merge pull request #4567 from dotty-staging/fix-macro-array-params
Fix macros with array parameters
2 parents 0f69a36 + 7cdecc6 commit ba2eafc

File tree

4 files changed

+108
-11
lines changed

4 files changed

+108
-11
lines changed

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,7 +1137,7 @@ class Definitions {
11371137

11381138
// private val unboxedTypeRef = mutable.Map[TypeName, TypeRef]()
11391139
// private val javaTypeToValueTypeRef = mutable.Map[Class[_], TypeRef]()
1140-
private val valueTypeNamesToJavaType = mutable.Map[TypeName, Class[_]]()
1140+
// private val valueTypeNamesToJavaType = mutable.Map[TypeName, Class[_]]()
11411141

11421142
private def valueTypeRef(name: String, boxed: TypeRef, jtype: Class[_], enc: Int, tag: Name): TypeRef = {
11431143
val vcls = ctx.requiredClassRef(name)
@@ -1146,7 +1146,7 @@ class Definitions {
11461146
typeTags(vcls.name) = tag
11471147
// unboxedTypeRef(boxed.name) = vcls
11481148
// javaTypeToValueTypeRef(jtype) = vcls
1149-
valueTypeNamesToJavaType(vcls.name) = jtype
1149+
// valueTypeNamesToJavaType(vcls.name) = jtype
11501150
vcls
11511151
}
11521152

@@ -1156,9 +1156,9 @@ class Definitions {
11561156
/** The JVM tag for `tp` if it's a primitive, `java.lang.Object` otherwise. */
11571157
def typeTag(tp: Type)(implicit ctx: Context): Name = typeTags(scalaClassName(tp))
11581158

1159-
/** The `Class[_]` of a primitive value type name */
1160-
def valueTypeNameToJavaType(name: TypeName)(implicit ctx: Context): Option[Class[_]] =
1161-
valueTypeNamesToJavaType.get(if (name.firstPart eq nme.scala_) name.lastPart.toTypeName else name)
1159+
// /** The `Class[_]` of a primitive value type name */
1160+
// def valueTypeNameToJavaType(name: TypeName)(implicit ctx: Context): Option[Class[_]] =
1161+
// valueTypeNamesToJavaType.get(if (name.firstPart eq nme.scala_) name.lastPart.toTypeName else name)
11621162

11631163
type PrimitiveClassEnc = Int
11641164

compiler/src/dotty/tools/dotc/transform/Splicer.scala

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package transform
33

44
import java.io.{PrintWriter, StringWriter}
55
import java.lang.reflect.Method
6-
import java.net.URLClassLoader
76

87
import dotty.tools.dotc.ast.tpd
98
import dotty.tools.dotc.core.Contexts._
@@ -14,6 +13,7 @@ import dotty.tools.dotc.core.Names.Name
1413
import dotty.tools.dotc.core.quoted._
1514
import dotty.tools.dotc.core.Types._
1615
import dotty.tools.dotc.core.Symbols._
16+
import dotty.tools.dotc.core.TypeErasure
1717

1818
import scala.util.control.NonFatal
1919
import dotty.tools.dotc.util.Positions.Position
@@ -172,11 +172,49 @@ object Splicer {
172172

173173
/** List of classes of the parameters of the signature of `sym` */
174174
private def paramsSig(sym: Symbol): List[Class[_]] = {
175-
sym.signature.paramsSig.map { param =>
176-
defn.valueTypeNameToJavaType(param) match {
177-
case Some(clazz) => clazz
178-
case None => classLoader.loadClass(param.toString)
179-
}
175+
TypeErasure.erasure(sym.info) match {
176+
case meth: MethodType =>
177+
meth.paramInfos.map { param =>
178+
def arrayDepth(tpe: Type, depth: Int): (Type, Int) = tpe match {
179+
case JavaArrayType(elemType) => arrayDepth(elemType, depth + 1)
180+
case _ => (tpe, depth)
181+
}
182+
def javaArraySig(tpe: Type): String = {
183+
val (elemType, depth) = arrayDepth(tpe, 0)
184+
val sym = elemType.classSymbol
185+
val suffix =
186+
if (sym == defn.BooleanClass) "Z"
187+
else if (sym == defn.ByteClass) "B"
188+
else if (sym == defn.ShortClass) "S"
189+
else if (sym == defn.IntClass) "I"
190+
else if (sym == defn.LongClass) "J"
191+
else if (sym == defn.FloatClass) "F"
192+
else if (sym == defn.DoubleClass) "D"
193+
else if (sym == defn.CharClass) "C"
194+
else "L" + javaSig(elemType) + ";"
195+
("[" * depth) + suffix
196+
}
197+
def javaSig(tpe: Type): String = tpe match {
198+
case tpe: JavaArrayType => javaArraySig(tpe)
199+
case _ =>
200+
// Take the flatten name of the class and the full package name
201+
val pack = tpe.classSymbol.topLevelClass.owner
202+
val packageName = if (pack == defn.EmptyPackageClass) "" else pack.fullName + "."
203+
packageName + tpe.classSymbol.fullNameSeparated(FlatName).toString
204+
}
205+
206+
val sym = param.classSymbol
207+
if (sym == defn.BooleanClass) classOf[Boolean]
208+
else if (sym == defn.ByteClass) classOf[Byte]
209+
else if (sym == defn.CharClass) classOf[Char]
210+
else if (sym == defn.ShortClass) classOf[Short]
211+
else if (sym == defn.IntClass) classOf[Int]
212+
else if (sym == defn.LongClass) classOf[Long]
213+
else if (sym == defn.FloatClass) classOf[Float]
214+
else if (sym == defn.DoubleClass) classOf[Double]
215+
else java.lang.Class.forName(javaSig(param), false, classLoader)
216+
}
217+
case _ => Nil
180218
}
181219
}
182220

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
2+
object Macro {
3+
4+
inline def foo0(i: Int): Unit = ~{ '() }
5+
inline def foo1(arr: Array[Boolean]): Unit = ~{ '() }
6+
inline def foo2(arr: Array[Byte]): Unit = ~{ '() }
7+
inline def foo3(arr: Array[Short]): Unit = ~{ '() }
8+
inline def foo4(arr: Array[Int]): Unit = ~{ '() }
9+
inline def foo5(arr: Array[Long]): Unit = ~{ '() }
10+
inline def foo6(arr: Array[Float]): Unit = ~{ '() }
11+
inline def foo7(arr: Array[Double]): Unit = ~{ '() }
12+
inline def foo8(arr: Array[Char]): Unit = ~{ '() }
13+
inline def foo9(arr: Array[Object]): Unit = ~{ '() }
14+
inline def foo10(arr: Array[String]): Unit = ~{ '() }
15+
inline def foo11[T](arr: Array[T]): Unit = ~{ '() }
16+
inline def foo12(arr: Array[Array[Int]]): Unit = ~{ '() }
17+
inline def foo13(arr: Array[Array[String]]): Unit = ~{ '() }
18+
inline def foo14(arr: Array[Array[Array[Int]]]): Unit = ~{ '() }
19+
inline def foo15(arr: Array[Any]): Unit = ~{ '() }
20+
inline def foo16(arr: Array[AnyVal]): Unit = ~{ '() }
21+
inline def foo17(arr: Array[AnyRef]): Unit = ~{ '() }
22+
inline def foo18(arr: Array[Foo]): Unit = ~{ '() }
23+
inline def foo19(arr: Array[Macro.type]): Unit = ~{ '() }
24+
inline def foo20(arr: Array[Bar]): Unit = ~{ '() }
25+
inline def foo21(arr: Array[Baz.type]): Unit = ~{ '() }
26+
inline def foo22(arr: Array[Foo#A]): Unit = ~{ '() }
27+
28+
class Bar
29+
object Baz
30+
}
31+
32+
class Foo {
33+
class A
34+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
object PowerInlined1 {
2+
Macro.foo0(2)
3+
Macro.foo1(Array.empty)
4+
Macro.foo2(Array.empty)
5+
Macro.foo3(Array.empty)
6+
Macro.foo4(Array.empty)
7+
Macro.foo5(Array.empty)
8+
Macro.foo6(Array.empty)
9+
Macro.foo7(Array.empty)
10+
Macro.foo8(Array.empty)
11+
Macro.foo9(Array.empty)
12+
Macro.foo10(Array.empty)
13+
Macro.foo11[String](Array.empty)
14+
Macro.foo12(Array.empty)
15+
Macro.foo13(Array.empty)
16+
Macro.foo14(Array.empty)
17+
Macro.foo15(Array.empty)
18+
Macro.foo16(Array.empty)
19+
Macro.foo17(Array.empty)
20+
Macro.foo18(Array.empty)
21+
Macro.foo19(Array.empty)
22+
Macro.foo20(Array.empty)
23+
Macro.foo21(Array.empty)
24+
Macro.foo22(Array.empty)
25+
}

0 commit comments

Comments
 (0)