diff --git a/library/src-bootstrapped/scala/quoted/Expr.scala b/library/src-bootstrapped/scala/quoted/Expr.scala index 386d286c6493..e2c84686817f 100644 --- a/library/src-bootstrapped/scala/quoted/Expr.scala +++ b/library/src-bootstrapped/scala/quoted/Expr.scala @@ -114,6 +114,25 @@ object Expr { def ofList[T](xs: Seq[Expr[T]])(using Type[T], QuoteContext): Expr[List[T]] = if (xs.isEmpty) Expr(Nil) else '{ List(${Varargs(xs)}: _*) } + /** Lifts the Map the values of which are expressions into an expression of Map. */ + def ofMapValues[K: Type: Liftable, V: Type](m: Map[K, Expr[V]])( + using QuoteContext): Expr[Map[K, V]] = + ofMapKeyValues(m.map { case (k, v) => (Expr(k), v) }) + + /** Lifts the Map the keys of which are expressions into an expression of Map. */ + def ofMapKeys[K: Type, V: Type: Liftable](m: Map[Expr[K], V])( + using QuoteContext): Expr[Map[K, V]] = + ofMapKeyValues(m.map { case (k, v) => (k, Expr(v)) }) + + /** Lifts the Map the keys and values of which are expressions into an expression of Map. */ + def ofMapKeyValues[K: Type, V: Type](m: Map[Expr[K], Expr[V]])( + using QuoteContext): Expr[Map[K, V]] = + val listOfExprs: List[Expr[(K, V)]] = + m.iterator.map((k, v) => '{ ($k, $v) }).toList + val exprOfList: Expr[List[(K, V)]] = Expr.ofList(listOfExprs) + '{ Map.from($exprOfList) } + end ofMapKeyValues + /** Lifts this sequence of expressions into an expression of a tuple * * Transforms a sequence of expression diff --git a/tests/run-macros/expr-ofMap.check b/tests/run-macros/expr-ofMap.check new file mode 100644 index 000000000000..e9f0b258e7a6 --- /dev/null +++ b/tests/run-macros/expr-ofMap.check @@ -0,0 +1,3 @@ +List((a,b), (foo,bar)) +List((a,b), (foo,bar)) +List((a,b), (foo,bar)) diff --git a/tests/run-macros/expr-ofMap/Macro_1.scala b/tests/run-macros/expr-ofMap/Macro_1.scala new file mode 100644 index 000000000000..3eb5930694c6 --- /dev/null +++ b/tests/run-macros/expr-ofMap/Macro_1.scala @@ -0,0 +1,22 @@ +import scala.quoted._ + +inline def ofMapKeyValues: Map[String, String] = ${ ofMapKeyValuesImpl } +private def ofMapKeyValuesImpl(using QuoteContext): Expr[Map[String, String]] = + Expr.ofMapKeyValues(Map( + '{ "foo" } -> '{ "bar" }, + '{ "a" } -> '{ "b" } + )) + +inline def ofMapKeys: Map[String, String] = ${ ofMapKeysImpl } +private def ofMapKeysImpl(using QuoteContext): Expr[Map[String, String]] = + Expr.ofMapKeys(Map( + '{ "foo" } -> "bar", + '{ "a" } -> "b" + )) + +inline def ofMapValues: Map[String, String] = ${ ofMapValuesImpl } +private def ofMapValuesImpl(using QuoteContext): Expr[Map[String, String]] = + Expr.ofMapValues(Map( + "foo" -> '{ "bar" }, + "a" -> '{ "b" } + )) diff --git a/tests/run-macros/expr-ofMap/Test_2.scala b/tests/run-macros/expr-ofMap/Test_2.scala new file mode 100644 index 000000000000..40c1fe68b9f5 --- /dev/null +++ b/tests/run-macros/expr-ofMap/Test_2.scala @@ -0,0 +1,4 @@ +@main def Test = + println(ofMapKeyValues.toList.sortBy(_._1)) + println(ofMapKeys.toList.sortBy(_._1)) + println(ofMapValues.toList.sortBy(_._1))