Skip to content

Commit a7fccd4

Browse files
authored
Merge pull request #11034 from dotty-staging/add-interpreter-regression-test
Add regression test
2 parents 64a089f + 706fb1b commit a7fccd4

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Some(BYTE)
2+
Some(INT)
3+
Some(OPTION[INT])
4+
Some(OPTION[OPTION[INT]])
5+
Some(MAP[INT,INT])
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
2+
trait Schema[T]
3+
trait SchemaType[T] extends Schema[T]
4+
5+
object Schema {
6+
given intSchema: SchemaType[Int] = new SchemaType { override def toString = "INT" }
7+
given byteSchema: SchemaType[Byte] = new SchemaType { override def toString = "BYTE" }
8+
given optionSchema[T](using t: Schema[T]): Schema[Option[T]] = new Schema { override def toString = s"OPTION[$t]" }
9+
given mapSchema[K, V](using k: Schema[K], v: Schema[V]): Schema[Map[K, V]] = new Schema { override def toString = s"MAP[$k,$v]" }
10+
}
11+
12+
/** Intereter for Schema.
13+
* Assumes that all instances of schema come from `object Schema`
14+
*/
15+
object SchemaInterpreter {
16+
import scala.quoted._
17+
18+
def interpretSchemaType[T: Type](schema: Expr[SchemaType[T]])(using Quotes): Option[SchemaType[T]] =
19+
schema match {
20+
case '{ Schema.intSchema } => Some(Schema.intSchema.asInstanceOf[SchemaType[T]])
21+
case '{ Schema.byteSchema } => Some(Schema.byteSchema.asInstanceOf[SchemaType[T]])
22+
case _ => None
23+
}
24+
25+
def interpretSchema[T: Type](schemaExpr: Expr[Schema[T]])(using Quotes): Option[Schema[T]] =
26+
schemaExpr match {
27+
case '{ $typeSchemaExpr: SchemaType[T] } =>
28+
interpretSchemaType(typeSchemaExpr)
29+
case '{ Schema.optionSchema[t](using $tSchemaExpr) } =>
30+
for tSchema <- interpretSchema(tSchemaExpr)
31+
yield Schema.optionSchema(using tSchema).asInstanceOf[Schema[T]]
32+
case '{ Schema.mapSchema[k, v](using $kSchemaExpr, $vSchemaExpr) } =>
33+
for kSchema <- interpretSchema(kSchemaExpr)
34+
vSchema <- interpretSchema(vSchemaExpr)
35+
yield Schema.mapSchema(using kSchema, vSchema).asInstanceOf[Schema[T]]
36+
case _ =>
37+
None // could also hangle with `quotes.reflect.{error, throwError}`
38+
}
39+
}
40+
41+
object Macro {
42+
import scala.quoted._
43+
44+
inline def useSchema[T](using inline schema: Schema[T]): String =
45+
${ useSchemaExpr[T]('schema) }
46+
47+
private def useSchemaExpr[T: Type](schemaExpr: Expr[Schema[T]])(using Quotes): Expr[String] = {
48+
val schemaOpt: Option[Schema[T]] = SchemaInterpreter.interpretSchema(schemaExpr)
49+
Expr(schemaOpt.toString)
50+
}
51+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import Macro.useSchema
2+
3+
@main def Test: Unit = {
4+
println(useSchema[Byte])
5+
println(useSchema[Int])
6+
println(useSchema[Option[Int]])
7+
println(useSchema[Option[Option[Int]]])
8+
println(useSchema[Map[Int, Int]])
9+
}

0 commit comments

Comments
 (0)