Skip to content

Commit 4154d05

Browse files
committed
Replace inheritance with ifdef for version specific Parser
1 parent d82e1bf commit 4154d05

File tree

4 files changed

+168
-177
lines changed

4 files changed

+168
-177
lines changed

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

-79
This file was deleted.

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

-96
This file was deleted.

Base/src/main/scala/Parser.scala

+162-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package name.rayrobdod.stringContextParserCombinator
22

3+
import com.eed3si9n.ifdef.ifdef
34
import scala.collection.immutable.Set
45
import scala.collection.immutable.Seq
56
import scala.reflect.ClassTag
@@ -34,8 +35,8 @@ import name.rayrobdod.stringContextParserCombinator.{Parser => SCPCParser}
3435
* @groupprio Convert 2000
3536
*/
3637
final class Parser[Expr[_], Type[_], A] private[stringContextParserCombinator] (
37-
protected[stringContextParserCombinator] override val impl: internal.Parser[Expr, Type, A]
38-
) extends VersionSpecificParser[Expr, Type, A] {
38+
protected[stringContextParserCombinator] val impl: internal.Parser[Expr, Type, A]
39+
) {
3940

4041
/**
4142
* Returns an Interpolator that interpolates like this parser would
@@ -59,13 +60,109 @@ final class Parser[Expr[_], Type[_], A] private[stringContextParserCombinator] (
5960
this.toInterpolator.interpolate(sc, args)
6061
}
6162

63+
/**
64+
* Parses a StringContext and its arguments into a value
65+
*
66+
* @example
67+
* {{{
68+
* def valueImpl(c:Context)(args:c.Expr[Any]*):c.Expr[Result] = {
69+
* val myParser:Interpolator[Expr[Result]] = ???
70+
* myParser.interpolate(c)("package.ValueStringContext")(args)
71+
* }
72+
*
73+
* implicit final class ValueStringContext(val sc:scala.StringContext) extends AnyVal {
74+
* def value(args:Any*):Result = macro valueImpl
75+
* }
76+
*
77+
* // alternatively
78+
* implicit final class ValueStringContext(val sc:scala.StringContext) {
79+
* object value {
80+
* def apply(args:Any*):Result = macro valueImpl
81+
* }
82+
* }
83+
* }}}
84+
* @group Parse
85+
*/
86+
@ifdef("scalaEpochVersion:2")
87+
final def interpolate(c: scala.reflect.macros.blackbox.Context)(extensionClassName:String)(args:Seq[c.Expr[Any]])(implicit ev:c.Expr[Any] <:< Expr[Any]):A = {
88+
new Interpolator(this.impl).interpolate(c)(extensionClassName)(args)
89+
}
90+
91+
/**
92+
* Parses a StringContext and its arguments into a value
93+
*
94+
* @example
95+
* ```
96+
* def valueImpl(sc:Expr[scala.StringContext],
97+
* args:Expr[Seq[Any]])(using Quotes):Expr[Result] = {
98+
* val myParser:Interpolator[Expr[Result]] = ???
99+
* myParser.interpolate(sc, args)
100+
* }
101+
*
102+
* extension (inline sc:scala.StringContext)
103+
* inline def value(inline args:Any*):Result =
104+
* ${valueImpl('sc, 'args)}
105+
* ```
106+
* @group Parse
107+
*/
108+
@ifdef("scalaBinaryVersion:3")
109+
final def interpolate(sc:scala.quoted.Expr[scala.StringContext], args:scala.quoted.Expr[Seq[Any]])(implicit q:scala.quoted.Quotes, ev:scala.quoted.Expr[Any] <:< Expr[Any]):A = {
110+
new Interpolator(this.impl).interpolate(sc, args)
111+
}
112+
62113
/**
63114
* Extract subexpressions from the given value according to the given StringContext
64115
* @group Parse
65116
*/
66117
def extract(sc:StringContext, value:A)(implicit ev:Id[Any] =:= Expr[Any], ev2:ClassTag[Any] =:= Type[Any]):Option[Seq[Any]] =
67118
this.toExtractor.extract(sc, value)
68119

120+
/**
121+
* Build an extractor that will extract values from a value of type A based on the provided StringContext
122+
* @group Parse
123+
*/
124+
@ifdef("scalaEpochVersion:2")
125+
final def extractor[UnexprA](
126+
c: scala.reflect.macros.blackbox.Context)(
127+
extensionClassName:String)(
128+
value:c.Expr[UnexprA])(
129+
implicit ev:c.Expr[UnexprA] <:< A,
130+
ev2:c.Expr[_] =:= Expr[_],
131+
ev3:c.TypeTag[_] =:= Type[_],
132+
ttUnexprA:c.TypeTag[UnexprA]
133+
):c.Expr[Any] = {
134+
new Extractor(this.impl).extractor(c)(extensionClassName)(value)
135+
}
136+
137+
/**
138+
* Parses a StringContext into an extractor
139+
*
140+
* @example
141+
* ```
142+
* def valueImpl(sc:Expr[scala.StringContext])(using Quotes):Expr[Unapply[Result]] = {
143+
* val myParser:Extractor[Expr[Result]] = ???
144+
* myParser.extractor(sc)
145+
* }
146+
*
147+
* extension (inline sc:scala.StringContext)
148+
* inline def value:Unapply[Result] =
149+
* ${valueImpl('sc)}
150+
* ```
151+
* @group Parse
152+
*/
153+
@ifdef("scalaBinaryVersion:3")
154+
final def extractor[UnexprA](
155+
sc:scala.quoted.Expr[scala.StringContext]
156+
)(implicit
157+
quotes: scala.quoted.Quotes,
158+
typeA: scala.quoted.Type[UnexprA],
159+
exprA: scala.quoted.Expr[UnexprA] <:< A,
160+
exprBool: scala.quoted.Expr[Boolean] =:= Expr[Boolean],
161+
typeBool: scala.quoted.Type[Boolean] =:= Type[Boolean],
162+
):scala.quoted.Expr[Unapply[UnexprA]] = {
163+
new Extractor(this.impl).extractor(sc)
164+
}
165+
69166
/**
70167
* Returns an interpolator which invokes this parser, then modifies a successful result according to fn
71168
* @group Map
@@ -249,6 +346,21 @@ final class Parser[Expr[_], Type[_], A] private[stringContextParserCombinator] (
249346
object Parser
250347
extends VersionSpecificParserModule
251348
{
349+
@ifdef("scalaBinaryVersion:3")
350+
type Parser[A] = SCPCParser[quoted.Expr, quoted.Type, A]
351+
@ifdef("scalaBinaryVersion:3")
352+
type Extractor[A] = SCPCExtractor[quoted.Expr, quoted.Type, A]
353+
@ifdef("scalaBinaryVersion:3")
354+
type Interpolator[A] = SCPCInterpolator[quoted.Expr[Any], A]
355+
356+
/**
357+
* A parser that succeeds iff the next part of the input is an `arg` with the given type, and captures the arg's tree
358+
* @group Arg
359+
*/
360+
@ifdef("scalaBinaryVersion:3")
361+
def ofType[A](implicit typA: scala.quoted.Type[A], quoted: scala.quoted.Quotes): SCPCParser[scala.quoted.Expr, scala.quoted.Type, scala.quoted.Expr[A]] =
362+
new SCPCParser(new internal.OfType[A])
363+
252364
/**
253365
* A parser that acts like the Interpolator when interpolating, and like the Extractor when extracting
254366
* @group Misc
@@ -405,6 +517,54 @@ object Parser
405517
new this.Parser(new internal.OfClass(tpe))
406518
}
407519
}
520+
521+
/**
522+
* Create a Parsers that can parse Exprs belonging to the specified Context
523+
* @group ParserGroup
524+
*/
525+
@ifdef("scalaEpochVersion:2")
526+
def contextParsers(c:scala.reflect.macros.blackbox.Context):Parser.Parsers[c.Expr, c.universe.Liftable, c.TypeTag] = {
527+
new Parser.Parsers[c.Expr, c.universe.Liftable, c.TypeTag]
528+
with ExprIndependentParsers[c.Expr, c.TypeTag] {
529+
override def `lazy`[A](fn:Function0[SCPCParser[c.Expr, c.TypeTag, A]]):SCPCParser[c.Expr, c.TypeTag, A] =
530+
new SCPCParser(internal.DelayedConstruction.parser(() => fn().impl))
531+
532+
override def paired[A](interpolator:Interpolator[A], extractor:Extractor[A]):SCPCParser[c.Expr, c.TypeTag, A] =
533+
new SCPCParser(new internal.Paired(interpolator.impl, extractor.impl))
534+
535+
override def ofType[A](implicit tpe: c.TypeTag[A]): SCPCParser[c.Expr, c.TypeTag, c.Expr[A]] =
536+
new SCPCParser(new internal.OfType[c.type, A](tpe))
537+
}
538+
}
539+
540+
/**
541+
* Create an Parsers that can parse `quoted.Expr`s
542+
* @group ParserGroup
543+
*/
544+
@ifdef("scalaBinaryVersion:3")
545+
def quotedParsers(implicit quotes: scala.quoted.Quotes):Parser.Parsers[scala.quoted.Expr, scala.quoted.ToExpr, scala.quoted.Type] = {
546+
new Parser.Parsers[scala.quoted.Expr, scala.quoted.ToExpr, scala.quoted.Type]
547+
with ExprIndependentParsers[scala.quoted.Expr, scala.quoted.Type] {
548+
override def `lazy`[A](fn:Function0[SCPCParser[scala.quoted.Expr, scala.quoted.Type, A]]):SCPCParser[scala.quoted.Expr, scala.quoted.Type, A] =
549+
new SCPCParser(internal.DelayedConstruction.parser(() => fn().impl))
550+
551+
override def paired[A](interpolator:SCPCInterpolator[scala.quoted.Expr[Any], A], extractor:SCPCExtractor[scala.quoted.Expr, scala.quoted.Type, A]):SCPCParser[scala.quoted.Expr, scala.quoted.Type, A] =
552+
new SCPCParser(new internal.Paired(interpolator.impl, extractor.impl))
553+
554+
override def ofType[A](implicit tpe: scala.quoted.Type[A]): SCPCParser[scala.quoted.Expr, scala.quoted.Type, scala.quoted.Expr[A]] =
555+
new SCPCParser(new internal.OfType[A])
556+
}
557+
}
558+
}
559+
560+
@ifdef("scalaEpochVersion:2")
561+
private[stringContextParserCombinator]
562+
trait VersionSpecificParserModule {
563+
}
564+
565+
@ifdef("scalaBinaryVersion:3")
566+
private[stringContextParserCombinator]
567+
trait VersionSpecificParserModule extends ExprIndependentParsers[scala.quoted.Expr, scala.quoted.Type] {
408568
}
409569

410570
/**

0 commit comments

Comments
 (0)