Skip to content

Commit 539d8ca

Browse files
Merge pull request #6478 from dotty-staging/add-regression-test
Add regression test
2 parents 6238938 + 79f32d4 commit 539d8ca

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import scala.quoted._
2+
import scala.quoted.autolift._
3+
import scala.quoted.matching._
4+
import scala.tasty.Reflection
5+
6+
import scala.language.implicitConversions
7+
8+
object Foo {
9+
implicit object StringContextOps {
10+
inline def (ctx: => StringContext) foo (args: => Any*): String = ${ Macro.foo('ctx, 'args) }
11+
}
12+
}
13+
14+
15+
object TestFooErrors { // Defined in tests
16+
implicit object StringContextOps {
17+
inline def (ctx: => StringContext) foo (args: => Any*): List[(Int, Int, Int, String)] = ${ Macro.fooErrors('ctx, 'args) }
18+
}
19+
}
20+
21+
object Macro {
22+
23+
def foo(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]]) given (reflect: Reflection): Expr[String] = {
24+
(sc, argsExpr) match {
25+
case ('{ StringContext(${ExprSeq(parts)}: _*) }, ExprSeq(args)) =>
26+
val reporter = new Reporter {
27+
def errorOnPart(msg: String, partIdx: Int): Unit = {
28+
import reflect._
29+
error(msg, parts(partIdx).unseal.pos)
30+
}
31+
}
32+
fooCore(parts, args, reporter)
33+
}
34+
}
35+
36+
def fooErrors(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]]) given (reflect: Reflection): Expr[List[(Int, Int, Int, String)]] = {
37+
(sc, argsExpr) match {
38+
case ('{ StringContext(${ExprSeq(parts)}: _*) }, ExprSeq(args)) =>
39+
val errors = List.newBuilder[Expr[(Int, Int, Int, String)]]
40+
val reporter = new Reporter {
41+
def errorOnPart(msg: String, partIdx: Int): Unit = {
42+
import reflect._
43+
val pos = parts(partIdx).unseal.pos
44+
errors += '{ Tuple4($partIdx, ${pos.start}, ${pos.end}, $msg) }
45+
}
46+
}
47+
fooCore(parts, args, reporter) // Discard result
48+
errors.result().toExprOfList
49+
}
50+
51+
52+
}
53+
54+
55+
private def fooCore(parts: Seq[Expr[String]], args: Seq[Expr[Any]], reporter: Reporter) given Reflection: Expr[String] = {
56+
for ((part, idx) <- parts.zipWithIndex) {
57+
val Const(v: String) = part
58+
if (v.contains("#"))
59+
reporter.errorOnPart("Cannot use #", idx)
60+
}
61+
62+
'{ StringContext(${parts.toList.toExprOfList}: _*).s(${args.toList.toExprOfList}: _*) }
63+
}
64+
65+
66+
trait Reporter {
67+
def errorOnPart(msg: String, partIdx: Int): Unit
68+
}
69+
70+
71+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
object Test {
3+
4+
def main(args: Array[String]): Unit = {
5+
posTests()
6+
negTests()
7+
}
8+
9+
def posTests() = {
10+
import Foo._
11+
assertEquals(foo"abc${"123"}def", "abc123def")
12+
}
13+
14+
def negTests() = {
15+
import TestFooErrors._
16+
assertEquals(foo"a#c${"123"}def", List((0, 256, 259, "Cannot use #")))
17+
assertEquals(foo"abc${"123"}#ef", List((1, 342, 345, "Cannot use #")))
18+
assertEquals(foo"a#c${"123"}#ef", List((0, 406, 409, "Cannot use #"), (1, 417, 420, "Cannot use #")))
19+
}
20+
21+
def assertEquals(actual: Any, expected: Any): Unit = {
22+
assert(actual == expected, s"actual: $actual\nbut expected: $expected")
23+
}
24+
}

0 commit comments

Comments
 (0)