Skip to content

Commit 4e33e5a

Browse files
authored
Merge pull request #7925 from dotty-staging/fix-#7853
Fix #7853: Add regression test
2 parents 2aeb5ae + 7128732 commit 4e33e5a

File tree

3 files changed

+85
-0
lines changed

3 files changed

+85
-0
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import scala.deriving._
2+
import scala.compiletime.erasedValue
3+
4+
trait JsonEncoder[T] {
5+
def encode(elem: T): String
6+
}
7+
8+
object JsonEncoder {
9+
import scala.compiletime.{erasedValue, summonFrom}
10+
import compiletime._
11+
import scala.deriving._
12+
13+
inline def encodeElem[T](elem: T): String = summonFrom {
14+
case encoder: JsonEncoder[T] => encoder.encode(elem)
15+
}
16+
17+
inline def encodeElems[Elems <: Tuple](idx: Int)(value: Any): List[String] =
18+
inline erasedValue[Elems] match {
19+
case _: (elem *: elems1) =>
20+
encodeElem[elem](productElement[elem](value, idx)) :: encodeElems[elems1](idx + 1)(value)
21+
case _ => Nil
22+
}
23+
24+
inline def derived[T](implicit ev: Mirror.Of[T]): JsonEncoder[T] = new JsonEncoder[T] {
25+
def encode(value: T): String =
26+
inline ev match {
27+
case m: Mirror.SumOf[T] =>
28+
"not supporting this case yet"
29+
case m: Mirror.ProductOf[T] =>
30+
val elems = encodeElems[m.MirroredElemTypes](0)(value)
31+
val labels = value.asInstanceOf[Product].productElementNames
32+
val keyValues = labels.zip(elems).map((k, v) => s"$k: $v")
33+
"{" + (keyValues).mkString(", ") + "}"
34+
case other =>
35+
throw new RuntimeException("mirror was an invalid value: " + other)
36+
}
37+
}
38+
39+
given listEncoder[T]: (encoder: JsonEncoder[T]) => JsonEncoder[List[T]] {
40+
def encode(list: List[T]) = s"[${ list.map(v => encoder.encode(v)).mkString(", ") }]"
41+
}
42+
43+
given intEncoder: JsonEncoder[Int] {
44+
def encode(value: Int) = value + ""
45+
}
46+
47+
given stringEncoder: JsonEncoder[String] {
48+
def encode(value: String) = value
49+
}
50+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import scala.deriving._
2+
import scala.quoted._
3+
import scala.quoted.matching._
4+
import scala.compiletime.{erasedValue, summonFrom}
5+
import JsonEncoder.{given, _}
6+
7+
object SummonJsonEncoderTest {
8+
9+
inline def encodeAndMessAroundType[T](value: =>T): String = ${ encodeAndMessAroundTypeImpl('value) }
10+
11+
def encodeAndMessAroundTypeImpl[T: Type](value: Expr[T])(given qctx: QuoteContext): Expr[String] = {
12+
import qctx.tasty._
13+
14+
val mirrorExpr = summonExpr[Mirror.Of[T]] match {
15+
case Some(mirror) => mirror
16+
}
17+
18+
'{
19+
given JsonEncoder[T] = JsonEncoder.derived($mirrorExpr)
20+
val encoder = summon[JsonEncoder[T]]
21+
encoder.encode($value)
22+
}
23+
}
24+
}

tests/pos-macros/i7853/Test_3.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import SummonJsonEncoderTest._
2+
3+
case class PersonSimple(name:String, age:Int)
4+
5+
object Test {
6+
val stuff = PersonSimple("Joe", 123)
7+
8+
def main(args: Array[String]):Unit = {
9+
println(SummonJsonEncoderTest.encodeAndMessAroundType(stuff) )
10+
}
11+
}

0 commit comments

Comments
 (0)