Skip to content

Commit 7cdecc6

Browse files
committed
Fix macros with Module and inner classes parameters
1 parent 88bc6bd commit 7cdecc6

File tree

4 files changed

+63
-28
lines changed

4 files changed

+63
-28
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: 43 additions & 22 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
@@ -170,28 +170,49 @@ object Splicer {
170170

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

tests/pos/macro-with-array/Macro_1.scala

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
object Macro {
33

4+
inline def foo0(i: Int): Unit = ~{ '() }
45
inline def foo1(arr: Array[Boolean]): Unit = ~{ '() }
56
inline def foo2(arr: Array[Byte]): Unit = ~{ '() }
67
inline def foo3(arr: Array[Short]): Unit = ~{ '() }
@@ -19,7 +20,15 @@ object Macro {
1920
inline def foo16(arr: Array[AnyVal]): Unit = ~{ '() }
2021
inline def foo17(arr: Array[AnyRef]): Unit = ~{ '() }
2122
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 = ~{ '() }
2227

28+
class Bar
29+
object Baz
2330
}
2431

25-
class Foo
32+
class Foo {
33+
class A
34+
}

tests/pos/macro-with-array/Test_2.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
object PowerInlined1 {
2+
Macro.foo0(2)
23
Macro.foo1(Array.empty)
34
Macro.foo2(Array.empty)
45
Macro.foo3(Array.empty)
@@ -17,4 +18,8 @@ object PowerInlined1 {
1718
Macro.foo16(Array.empty)
1819
Macro.foo17(Array.empty)
1920
Macro.foo18(Array.empty)
21+
Macro.foo19(Array.empty)
22+
Macro.foo20(Array.empty)
23+
Macro.foo21(Array.empty)
24+
Macro.foo22(Array.empty)
2025
}

0 commit comments

Comments
 (0)