Skip to content

Commit 4ea5fe5

Browse files
committed
[base-3] Rewrite quoted string and splice concatenation to be more amenable to -Xcheck-macros
1 parent 6f858c7 commit 4ea5fe5

File tree

1 file changed

+35
-99
lines changed

1 file changed

+35
-99
lines changed

Base/src/main/scala-3/typeclass/RepeatedImpl.scala

Lines changed: 35 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -13,41 +13,23 @@ private[typeclass]
1313
object RepeatedImpl {
1414
private[typeclass]
1515
final class ConcatenateString(using Quotes) extends Repeated[Expr[String], Expr[String]] {
16-
sealed trait Acc
17-
object AccZero extends Acc
18-
final class AccOne(val elem: Expr[String]) extends Acc
19-
final class AccMany extends Acc {
20-
val builder: Builder[Expr[String], Expr[String]] = List.newBuilder.mapResult(parts =>
21-
'{
22-
${
23-
parts.foldLeft
24-
('{new scala.collection.mutable.StringBuilder})
25-
({(builder, part) => '{$builder.append($part)}})
26-
}
27-
.result
28-
}
29-
)
30-
}
16+
type Acc = List[Expr[String]]
3117

32-
def init():Acc = AccZero
33-
def append(acc:Acc, elem:Expr[String]):Acc = acc match {
34-
case AccZero => new AccOne(elem)
35-
case accOne: AccOne => {
36-
val retval = new AccMany()
37-
retval.builder += accOne.elem
38-
retval.builder += elem
39-
retval
40-
}
41-
case accMany: AccMany => {
42-
accMany.builder += elem
43-
accMany
44-
}
45-
}
18+
def init():Acc = Nil
19+
def append(acc:Acc, elem:Expr[String]):Acc = elem :: acc
4620
def result(acc:Acc):Expr[String] = {
4721
acc match {
48-
case AccZero => Expr[String]("")
49-
case accOne: AccOne => accOne.elem
50-
case accMany: AccMany => accMany.builder.result()
22+
case List() => Expr[String]("")
23+
case List(elem) => elem
24+
case _ =>
25+
'{
26+
${
27+
acc.foldRight
28+
('{new scala.collection.mutable.StringBuilder})
29+
({(part, builder) => '{$builder.append($part)}})
30+
}
31+
.result
32+
}
5133
}
5234
}
5335
}
@@ -60,79 +42,33 @@ object RepeatedImpl {
6042
ifOneSplice: PartialFunction[Expr[Iterable[A]], Expr[Z]]
6143
)(using Quotes, Type[A], Type[Z], Type[Builder[A, Z]],
6244
) extends Repeated[SplicePiece[Expr, A], Expr[Z]] {
63-
sealed trait Acc
64-
object AccZero extends Acc
65-
final class AccOneScalar(val elem: Expr[A]) extends Acc
66-
final class AccOneSplice(val iter: Expr[Iterable[A]]) extends Acc
67-
final class AccMany extends Acc {
68-
val builder: Builder[Expr[Builder[A, Z]] => Expr[_], Expr[Z]] = List.newBuilder.mapResult(parts =>
69-
'{
70-
val accumulator: Builder[A, Z] = ${newAccumulator}
71-
${Expr.block(
72-
parts.map(part => part('accumulator)),
73-
'{accumulator.result()}
74-
)}
75-
}
76-
)
77-
}
45+
type Acc = List[SplicePiece[Expr, A]]
7846

79-
def init():Acc = AccZero
80-
def append(acc:Acc, elem:SplicePiece[Expr, A]):Acc = acc match {
81-
case AccZero =>
82-
elem match {
83-
case _: SplicePiece.Zero[Expr] => AccZero
84-
case elemOne: SplicePiece.One[Expr, A] => new AccOneScalar(elemOne.elem)
85-
case elemMany: SplicePiece.Many[Expr, A] => new AccOneSplice(elemMany.iter)
86-
}
87-
case accOne: AccOneScalar => {
88-
elem match {
89-
case _: SplicePiece.Zero[Expr] => accOne
90-
case elemOne: SplicePiece.One[Expr, A] =>
91-
val retval = new AccMany()
92-
retval.builder += {(acc) => '{$acc.addOne(${accOne.elem})}}
93-
retval.builder += {(acc) => '{$acc.addOne(${elemOne.elem})}}
94-
retval
95-
case elemMany: SplicePiece.Many[Expr, A] =>
96-
val retval = new AccMany()
97-
retval.builder += {(acc) => '{$acc.addOne(${accOne.elem})}}
98-
retval.builder += {(acc) => '{$acc.addAll(${elemMany.iter})}}
99-
retval
100-
}
101-
}
102-
case accOne: AccOneSplice => {
103-
elem match {
104-
case _: SplicePiece.Zero[Expr] => accOne
105-
case elemOne: SplicePiece.One[Expr, A] =>
106-
val retval = new AccMany()
107-
retval.builder += {(acc) => '{$acc.addAll(${accOne.iter})}}
108-
retval.builder += {(acc) => '{$acc.addOne(${elemOne.elem})}}
109-
retval
110-
case elemMany: SplicePiece.Many[Expr, A] =>
111-
val retval = new AccMany()
112-
retval.builder += {(acc) => '{$acc.addAll(${accOne.iter})}}
113-
retval.builder += {(acc) => '{$acc.addAll(${elemMany.iter})}}
114-
retval
115-
}
116-
}
117-
case accMany: AccMany => {
118-
elem match {
119-
case _: SplicePiece.Zero[Expr] =>
120-
// do nothing
121-
case elemOne: SplicePiece.One[Expr, A] =>
122-
accMany.builder += {(acc) => '{$acc.addOne(${elemOne.elem})}}
123-
case elemMany: SplicePiece.Many[Expr, A] =>
124-
accMany.builder += {(acc) => '{$acc.addAll(${elemMany.iter})}}
125-
}
126-
accMany
47+
def init():Acc = Nil
48+
def append(acc:Acc, elem:SplicePiece[Expr, A]):Acc = {
49+
elem match {
50+
case _: SplicePiece.Zero[Expr] => acc
51+
case other => other :: acc
12752
}
12853
}
12954

13055
def result(acc:Acc):Expr[Z] = {
13156
acc match {
132-
case AccZero => ifZero.map(_.apply()).getOrElse('{$newAccumulator.result()})
133-
case accOne: AccOneScalar => ifOneScalar.applyOrElse(accOne.elem, e => '{$newAccumulator.addOne(${e}).result()})
134-
case accOne: AccOneSplice => ifOneSplice.applyOrElse(accOne.iter, es => '{$newAccumulator.addAll(${es}).result()})
135-
case accMany: AccMany => accMany.builder.result()
57+
case Nil => ifZero.map(_.apply()).getOrElse('{$newAccumulator.result()})
58+
case List(SplicePiece.One(elem)) => ifOneScalar.applyOrElse(elem, e => '{$newAccumulator.addOne(${e}).result()})
59+
case List(SplicePiece.Many(iter)) => ifOneSplice.applyOrElse(iter, es => '{$newAccumulator.addAll(${es}).result()})
60+
case _ =>
61+
'{
62+
val accumulator: Builder[A, Z] = ${newAccumulator}
63+
${Expr.block(
64+
acc.reverse.map({
65+
case SplicePiece.Zero() => '{()}
66+
case SplicePiece.One(elem) => '{accumulator.addOne($elem)}
67+
case SplicePiece.Many(iter) => '{accumulator.addAll($iter)}
68+
}),
69+
'{accumulator.result()}
70+
)}
71+
}
13672
}
13773
}
13874
}

0 commit comments

Comments
 (0)