From 3a502e53a91f0083388e848e78bb61f60101c1fa Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 18 Mar 2020 18:32:33 +0100 Subject: [PATCH] Add string interpolator `apply` macro prototype This is just an example of how to encode String interpolator macros that used an object with and `apply` and `unapply` in the extension class. --- .../xml-interpolation-5/Macros_1.scala | 34 +++++++++++++++++++ .../xml-interpolation-5/Test_2.scala | 11 ++++++ .../xml-interpolation-6/Macros_1.scala | 34 +++++++++++++++++++ .../xml-interpolation-6/Test_2.scala | 11 ++++++ .../xml-interpolation-7/Macros_1.scala | 34 +++++++++++++++++++ .../xml-interpolation-7/Test_2.scala | 12 +++++++ 6 files changed, 136 insertions(+) create mode 100644 tests/run-macros/xml-interpolation-5/Macros_1.scala create mode 100644 tests/run-macros/xml-interpolation-5/Test_2.scala create mode 100644 tests/run-macros/xml-interpolation-6/Macros_1.scala create mode 100644 tests/run-macros/xml-interpolation-6/Test_2.scala create mode 100644 tests/run-macros/xml-interpolation-7/Macros_1.scala create mode 100644 tests/run-macros/xml-interpolation-7/Test_2.scala diff --git a/tests/run-macros/xml-interpolation-5/Macros_1.scala b/tests/run-macros/xml-interpolation-5/Macros_1.scala new file mode 100644 index 000000000000..df83b4f18839 --- /dev/null +++ b/tests/run-macros/xml-interpolation-5/Macros_1.scala @@ -0,0 +1,34 @@ +import scala.quoted._ +import scala.quoted.autolift + +import scala.language.implicitConversions + +case class Xml(parts: String, args: List[Any]) + +object XmlQuote { + + // Encoding for + // + // implicit class SCOps(s: StringContext) { + // object xml { + // def apply(exprs: Any*) = ... + // def unapplySeq(...) = ... + // } + // } + object SCOps { + opaque type StringContext = scala.StringContext + def apply(sc: scala.StringContext): StringContext = sc + } + inline def (inline ctx: StringContext).xml <: SCOps.StringContext = SCOps(ctx) + inline def (inline ctx: SCOps.StringContext).apply(inline args: Any*): Xml = + ${XmlQuote.impl('ctx, 'args)} + // inline def (inline ctx: SCOps.StringContext).unapplySeq(...): Xml = ... + + + def impl(receiver: Expr[SCOps.StringContext], args: Expr[Seq[Any]])(using QuoteContext): Expr[Xml] = { + val string = receiver match { + case '{ SCOps(${Unlifted(sc)}) } => sc.parts.mkString("??") + } + '{new Xml(${string}, $args.toList)} + } +} diff --git a/tests/run-macros/xml-interpolation-5/Test_2.scala b/tests/run-macros/xml-interpolation-5/Test_2.scala new file mode 100644 index 000000000000..37549d857ddb --- /dev/null +++ b/tests/run-macros/xml-interpolation-5/Test_2.scala @@ -0,0 +1,11 @@ +import XmlQuote._ + +object Test { + def main(args: Array[String]): Unit = { + + assert(xml"Hello World!" == Xml("Hello World!", Nil)) + + val name = new Object{} + assert(xml"Hello $name!" == Xml("Hello ??!", List(name))) + } +} diff --git a/tests/run-macros/xml-interpolation-6/Macros_1.scala b/tests/run-macros/xml-interpolation-6/Macros_1.scala new file mode 100644 index 000000000000..b6913f3b8ce1 --- /dev/null +++ b/tests/run-macros/xml-interpolation-6/Macros_1.scala @@ -0,0 +1,34 @@ +import scala.quoted._ +import scala.quoted.autolift + +import scala.language.implicitConversions + +case class Xml(parts: String, args: List[Any]) + +object XmlQuote { + + // Encoding for + // + // implicit class SCOps(s: StringContext) { + // object xml { + // def apply(exprs: Any*) = ... + // def unapplySeq(...) = ... + // } + // } + object SCOps { + opaque type StringContext = scala.StringContext + def apply(sc: scala.StringContext): StringContext = sc + } + inline def (inline ctx: StringContext).xml: SCOps.StringContext = SCOps(ctx) + inline def (inline ctx: SCOps.StringContext).apply(inline args: Any*): Xml = + ${XmlQuote.impl('ctx, 'args)} + // inline def (inline ctx: SCOps.StringContext).unapplySeq(...): Xml = ... + + + def impl(receiver: Expr[SCOps.StringContext], args: Expr[Seq[Any]])(using QuoteContext): Expr[Xml] = { + val string = receiver match { + case '{ SCOps(${Unlifted(sc)}): SCOps.StringContext } => sc.parts.mkString("??") + } + '{new Xml(${string}, $args.toList)} + } +} diff --git a/tests/run-macros/xml-interpolation-6/Test_2.scala b/tests/run-macros/xml-interpolation-6/Test_2.scala new file mode 100644 index 000000000000..37549d857ddb --- /dev/null +++ b/tests/run-macros/xml-interpolation-6/Test_2.scala @@ -0,0 +1,11 @@ +import XmlQuote._ + +object Test { + def main(args: Array[String]): Unit = { + + assert(xml"Hello World!" == Xml("Hello World!", Nil)) + + val name = new Object{} + assert(xml"Hello $name!" == Xml("Hello ??!", List(name))) + } +} diff --git a/tests/run-macros/xml-interpolation-7/Macros_1.scala b/tests/run-macros/xml-interpolation-7/Macros_1.scala new file mode 100644 index 000000000000..1f753c7e47ee --- /dev/null +++ b/tests/run-macros/xml-interpolation-7/Macros_1.scala @@ -0,0 +1,34 @@ +import scala.quoted._ +import scala.quoted.autolift + +import scala.language.implicitConversions + +case class Xml(parts: String, args: List[Any]) + +object XmlQuote { + + // Encoding for + // + // implicit class SCOps(s: StringContext) { + // object xml { + // def apply(exprs: Any*) = ... + // def unapplySeq(...) = ... + // } + // } + object XMLOps { + opaque type StringContext = scala.StringContext + def (ctx: scala.StringContext).xml: StringContext = ctx + } + + inline def (inline ctx: XMLOps.StringContext).apply(inline args: Any*): Xml = + ${XmlQuote.impl('ctx, 'args)} + // inline def (inline ctx: SCOps.StringContext).unapplySeq(...): Xml = ... + + + def impl(receiver: Expr[XMLOps.StringContext], args: Expr[Seq[Any]])(using QuoteContext): Expr[Xml] = { + val string = receiver match { + case '{ XMLOps.xml(${Unlifted(sc)}) } => sc.parts.mkString("??") + } + '{new Xml(${string}, $args.toList)} + } +} diff --git a/tests/run-macros/xml-interpolation-7/Test_2.scala b/tests/run-macros/xml-interpolation-7/Test_2.scala new file mode 100644 index 000000000000..367ead05b0a8 --- /dev/null +++ b/tests/run-macros/xml-interpolation-7/Test_2.scala @@ -0,0 +1,12 @@ +import XmlQuote._ + +object Test { + def main(args: Array[String]): Unit = { + import XMLOps.xml + + assert(xml"Hello World!" == Xml("Hello World!", Nil)) + + val name = new Object{} + assert(xml"Hello $name!" == Xml("Hello ??!", List(name))) + } +}