Skip to content

Commit d82e1bf

Browse files
committed
Replace inheritance with ifdef for version specific Extractor
1 parent c4ab99f commit d82e1bf

File tree

5 files changed

+255
-262
lines changed

5 files changed

+255
-262
lines changed

Base/src/main/scala-2/VersionSpecificExtractor.scala

-98
This file was deleted.

Base/src/main/scala-3/InterpolatorImpl.scala

+75
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package name.rayrobdod.stringContextParserCombinator
22

3+
import scala.annotation.nowarn
34
import scala.quoted.*
5+
import name.rayrobdod.stringContextParserCombinator.{Unapply => SCUnapply}
46

57
// scala 2 reads the `'{Some($value}` as an unclosed character literal
68
// and ifdef is insufficient to hide that construct from the scala 2 compiler
@@ -13,4 +15,77 @@ object InterpolatorImpl {
1315
case _ => scala.quoted.quotes.reflect.report.errorAndAbort(s"Do not know how to process this tree", sc)
1416
}
1517
}
18+
19+
def unapplyExprToExpr[UnexprA](expr: UnapplyExpr[quoted.Expr, quoted.Type, quoted.Expr[UnexprA]])(using Type[UnexprA], Quotes): Expr[SCUnapply[UnexprA]] = {
20+
val conditionFn:quoted.Expr[UnexprA] => quoted.Expr[Boolean] = expr.condition
21+
22+
expr.parts match {
23+
case Nil =>
24+
'{((a:UnexprA) => ${conditionFn('a)}):Unapply.Zero[UnexprA]}
25+
case (part: UnapplyExpr.Part[quoted.Expr, quoted.Type, quoted.Expr[UnexprA], z]) :: Nil =>
26+
@nowarn("msg=unused local definition") given quoted.Type[z] = part.typ
27+
'{((a:UnexprA) => Option.when[z](${conditionFn('a)})(${part.value('a)})):Unapply.Fixed[UnexprA, z]}
28+
case _ =>
29+
import quotes.reflect._
30+
val unexpraTypeTree = TypeTree.of[UnexprA]
31+
32+
val tupleTypeConstructorSymbol = defn.TupleClass(expr.parts.size)
33+
val tupleTypeConstructorTree = TypeIdent(tupleTypeConstructorSymbol)
34+
val tupleTypeTree = Applied(tupleTypeConstructorTree, expr.parts.map(part => TypeTree.of(using part.typ)))
35+
val optionTupleTypeTree = Applied(TypeIdent(defn.OptionClass), List(tupleTypeTree))
36+
37+
val tupleModule = tupleTypeConstructorSymbol.companionModule
38+
val tupleConstructorTree = Ref(tupleModule)
39+
40+
val unapplyTypeConstructorTree = TypeIdent(Symbol.requiredClass("name.rayrobdod.stringContextParserCombinator.Unapply.Fixed"))
41+
42+
val anonfunType = MethodType(
43+
List("a"))(
44+
{(_:MethodType) => List(unexpraTypeTree.tpe)},
45+
{(_:MethodType) => optionTupleTypeTree.tpe},
46+
)
47+
val anonfunSymbol = Symbol.newMethod(
48+
Symbol.spliceOwner,
49+
"$anonfun",
50+
anonfunType
51+
)
52+
53+
Block(
54+
List(
55+
DefDef(
56+
anonfunSymbol,
57+
{paramss =>
58+
val param = paramss(0)(0).asExprOf[UnexprA]
59+
val condition = conditionFn(param).asTerm
60+
val optionModule = defn.OptionClass.companionModule
61+
62+
val partsTuple = {
63+
val typeArgs = expr.parts.map(part => TypeTree.of(using part.typ))
64+
val valueArgs = expr.parts.map(part => part.value(param).asTerm)
65+
66+
tupleConstructorTree
67+
.select(tupleModule.methodMember("apply")(0))
68+
.appliedToTypeTrees(typeArgs)
69+
.appliedToArgs(valueArgs)
70+
}
71+
72+
Option(
73+
Ref(optionModule)
74+
.select(optionModule.methodMember("when")(0))
75+
.appliedToType(tupleTypeTree.tpe)
76+
.appliedToArgss(
77+
List(List(condition), List(partsTuple))
78+
)
79+
)
80+
}
81+
),
82+
),
83+
Closure(
84+
Ref(anonfunSymbol),
85+
Option(AppliedType(unapplyTypeConstructorTree.tpe, List(unexpraTypeTree.tpe, tupleTypeTree.tpe)))
86+
)
87+
)
88+
.asExprOf[SCUnapply[UnexprA]]
89+
}
90+
}
1691
}

Base/src/main/scala-3/VersionSpecificExtractor.scala

-162
This file was deleted.

0 commit comments

Comments
 (0)