From 47ff69a513f1fc53c444fc60106798bf1fbe4aaa Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Sun, 9 Jun 2019 20:11:05 +0200 Subject: [PATCH] Add quote ConstSeq extractor --- .../scala/quoted/matching/ConstSeq.scala | 22 ++++++++++++++++ .../quote-matcher-string-interpolator-3.check | 2 ++ .../quoted_1.scala | 26 +++++++++++++++++++ .../quoted_2.scala | 10 +++++++ 4 files changed, 60 insertions(+) create mode 100644 library/src-3.x/scala/quoted/matching/ConstSeq.scala create mode 100644 tests/run-macros/quote-matcher-string-interpolator-3.check create mode 100644 tests/run-macros/quote-matcher-string-interpolator-3/quoted_1.scala create mode 100644 tests/run-macros/quote-matcher-string-interpolator-3/quoted_2.scala diff --git a/library/src-3.x/scala/quoted/matching/ConstSeq.scala b/library/src-3.x/scala/quoted/matching/ConstSeq.scala new file mode 100644 index 000000000000..8e337cc531bf --- /dev/null +++ b/library/src-3.x/scala/quoted/matching/ConstSeq.scala @@ -0,0 +1,22 @@ +package scala.quoted.matching + +import scala.quoted.Expr + +import scala.tasty.Reflection // TODO do not depend on reflection directly + +/** Literal sequence of literal constant value expressions */ +object ConstSeq { + + /** Matches literal sequence of literal constant value expressions */ + def unapply[T](expr: Expr[Seq[T]]) given Reflection: Option[Seq[T]] = expr match { + case ExprSeq(elems) => + elems.foldRight(Option(List.empty[T])) { (elem, acc) => + (elem, acc) match { + case (Const(value), Some(lst)) => Some(value :: lst) + case (_, _) => None + } + } + case _ => None + } + +} diff --git a/tests/run-macros/quote-matcher-string-interpolator-3.check b/tests/run-macros/quote-matcher-string-interpolator-3.check new file mode 100644 index 000000000000..254f890b55ba --- /dev/null +++ b/tests/run-macros/quote-matcher-string-interpolator-3.check @@ -0,0 +1,2 @@ +HELLO WORLD +HELLO World diff --git a/tests/run-macros/quote-matcher-string-interpolator-3/quoted_1.scala b/tests/run-macros/quote-matcher-string-interpolator-3/quoted_1.scala new file mode 100644 index 000000000000..2b98a358cd68 --- /dev/null +++ b/tests/run-macros/quote-matcher-string-interpolator-3/quoted_1.scala @@ -0,0 +1,26 @@ +import scala.quoted._ +import scala.quoted.matching._ + +import scala.tasty.Reflection + +object Macros { + + inline def (self: => StringContext) S(args: => String*): String = ${impl('self, 'args)} + + private def impl(self: Expr[StringContext], args: Expr[Seq[String]]) given Reflection: Expr[String] = { + self match { + case '{ StringContext(${ConstSeq(parts)}: _*) } => + val upprerParts: List[String] = parts.toList.map(_.toUpperCase) + val upprerPartsExpr: Expr[List[String]] = upprerParts.map(_.toExpr).toExprOfList + '{ StringContext($upprerPartsExpr: _*).s($args: _*) } + case _ => + '{ + val parts: Seq[String] = $self.parts + val upprerParts = parts.map(_.toUpperCase) + StringContext(upprerParts: _*).s($args: _*) + } + } + + } + +} diff --git a/tests/run-macros/quote-matcher-string-interpolator-3/quoted_2.scala b/tests/run-macros/quote-matcher-string-interpolator-3/quoted_2.scala new file mode 100644 index 000000000000..7ed4d71a1607 --- /dev/null +++ b/tests/run-macros/quote-matcher-string-interpolator-3/quoted_2.scala @@ -0,0 +1,10 @@ +import Macros._ + +object Test { + + def main(args: Array[String]): Unit = { + println(S"Hello World") + println(S"Hello ${"World"}") + } + +}