Skip to content

Commit c5ba46b

Browse files
committed
Replace inheritance with ifdef for version specific Optionally
1 parent 5ff22b2 commit c5ba46b

File tree

5 files changed

+115
-117
lines changed

5 files changed

+115
-117
lines changed

Base/src/main/scala-2/typeclass/VersionSpecificOptionally.scala

Lines changed: 0 additions & 76 deletions
This file was deleted.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package name.rayrobdod.stringContextParserCombinator
2+
package typeclass
3+
4+
import scala.quoted.*
5+
6+
// scala 2 reads the `'{Some($value}` as an unclosed character literal
7+
// and ifdef is insufficient to hide that construct from the scala 2 compiler
8+
9+
private[typeclass]
10+
object OptionallyImpl {
11+
private[typeclass]
12+
implicit def quotedToExprOption[A](using Quotes, Type[A]):BiOptionally[Expr, Expr[A], Expr[Option[A]]] =
13+
BiOptionally.apply(
14+
Expr(None),
15+
value => '{Some($value)},
16+
value => '{$value.isEmpty},
17+
PartialExprFunction(
18+
value => '{$value.nonEmpty},
19+
value => '{$value.get},
20+
),
21+
)
22+
}

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

Lines changed: 0 additions & 37 deletions
This file was deleted.

Base/src/main/scala/typeclass/Optionally.scala

Lines changed: 89 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package name.rayrobdod.stringContextParserCombinator
22
package typeclass
33

4+
import com.eed3si9n.ifdef.ifdef
5+
46
/**
57
* Describes how to represent an optional value
68
*
@@ -113,7 +115,7 @@ private[typeclass] trait LowPrioOptionally {
113115
* Predefined implicit implementations of ContraOptionally
114116
* and methods to create new ContraOptionally
115117
*/
116-
object ContraOptionally extends VersionSpecificContraOptionally with LowPrioContraOptionally {
118+
object ContraOptionally extends LowPrioContraOptionally {
117119
/**
118120
* Constructs an `ContraOptionally` from a set of functions corresponding to each of ContraOptionally's methods
119121
*/
@@ -129,17 +131,43 @@ object ContraOptionally extends VersionSpecificContraOptionally with LowPrioCont
129131
}
130132

131133
implicit def idUnit:ContraOptionally[Id, Unit, Unit] = BiOptionally.idUnit
134+
135+
@ifdef("scalaEpochVersion:2")
136+
trait ContraOptionallys[Expr[_], Type[_]] extends LowPrioContraOptionallys[Expr, Type] {
137+
implicit def unit:ContraOptionally[Expr, Unit, Unit]
138+
}
139+
@ifdef("scalaEpochVersion:2")
140+
trait LowPrioContraOptionallys[Expr[_], Type[_]] {
141+
implicit def toExprOption[A](implicit typA:Type[A]):ContraOptionally[Expr, Expr[A], Expr[Option[A]]]
142+
}
143+
144+
@ifdef("scalaEpochVersion:2")
145+
def forContext(c:scala.reflect.macros.blackbox.Context):ContraOptionallys[c.Expr, c.TypeTag] = {
146+
new ContraOptionallys[c.Expr, c.TypeTag] {
147+
private[this] val backing = BiOptionally.forContext(c)
148+
149+
override def unit:ContraOptionally[c.Expr, Unit, Unit] = backing.unit
150+
override def toExprOption[A](implicit typA:c.TypeTag[A]):ContraOptionally[c.Expr, c.Expr[A], c.Expr[Option[A]]] = backing.toExprOption[A]
151+
}
152+
}
153+
154+
@ifdef("scalaBinaryVersion:3")
155+
implicit def quotedUnit(implicit quotes: scala.quoted.Quotes):BiOptionally[scala.quoted.Expr, Unit, Unit] = BiOptionally.quotedUnit
156+
132157
}
133158

134-
private[typeclass] trait LowPrioContraOptionally extends VersionSpecificLowPrioContraOptionally {
159+
private[typeclass] trait LowPrioContraOptionally {
135160
implicit def idToOption[A]:ContraOptionally[Id, A, Option[A]] = BiOptionally.idToOption
161+
162+
@ifdef("scalaBinaryVersion:3")
163+
implicit def quotedToExprOption[A](implicit quotes: scala.quoted.Quotes, typA: scala.quoted.Type[A]):BiOptionally[scala.quoted.Expr, scala.quoted.Expr[A], scala.quoted.Expr[Option[A]]] = BiOptionally.quotedToExprOption
136164
}
137165

138166
/**
139167
* Predefined implicit implementations of BiOptionally
140168
* and methods to create new BiOptionally
141169
*/
142-
object BiOptionally extends VersionSpecificBiOptionally with LowPrioBiOptionally {
170+
object BiOptionally extends LowPrioBiOptionally {
143171
/**
144172
* Constructs an `BiOptionally` from a set of functions corresponding to each of BiOptionally's methods
145173
*/
@@ -164,9 +192,62 @@ object BiOptionally extends VersionSpecificBiOptionally with LowPrioBiOptionally
164192
_ => true,
165193
PartialExprFunction.identity[Id, Unit](true)
166194
)
195+
196+
@ifdef("scalaEpochVersion:2")
197+
trait BiOptionallys[Expr[_], Type[_]] extends LowPrioBiOptionallys[Expr, Type] {
198+
implicit def unit:BiOptionally[Expr, Unit, Unit]
199+
}
200+
@ifdef("scalaEpochVersion:2")
201+
trait LowPrioBiOptionallys[Expr[_], Type[_]] {
202+
implicit def toExprOption[A](implicit typA:Type[A]):BiOptionally[Expr, Expr[A], Expr[Option[A]]]
203+
}
204+
205+
@ifdef("scalaEpochVersion:2")
206+
def forContext(c:scala.reflect.macros.blackbox.Context):BiOptionallys[c.Expr, c.TypeTag] = {
207+
new BiOptionallys[c.Expr, c.TypeTag] {
208+
private[this] val exprTrue = c.Expr[Boolean](c.universe.Literal(c.universe.Constant(true)))
209+
private[this] def select[A, Z](qualifier:c.Expr[A], name:String)(implicit typZ:c.TypeTag[Z]):c.Expr[Z] = {
210+
c.Expr[Z](c.universe.Select(qualifier.tree, c.universe.TermName(name)))
211+
}
212+
private[this] def selectTermNames[Z](root:String, names:String*)(implicit typZ:c.TypeTag[Z]):c.Expr[Z] = {
213+
val rootTree = c.universe.Ident(c.universe.TermName(root))
214+
val namesTree = names.foldLeft[c.universe.Tree](rootTree)({(folding, name) => c.universe.Select(folding, c.universe.TermName(name))})
215+
c.Expr[Z](namesTree)
216+
}
217+
218+
override def unit:BiOptionally[c.Expr, Unit, Unit] = BiOptionally.apply(
219+
(),
220+
_ => (),
221+
_ => exprTrue,
222+
PartialExprFunction.identity(exprTrue)
223+
)
224+
225+
override def toExprOption[A](implicit typA:c.TypeTag[A]):BiOptionally[c.Expr, c.Expr[A], c.Expr[Option[A]]] = BiOptionally.apply(
226+
selectTermNames[Option[A]]("_root_", "scala", "None"),
227+
value => {
228+
val rootTree = c.universe.Ident(c.universe.TermName("_root_"))
229+
val namesTree = List("scala", "Some", "apply").foldLeft[c.universe.Tree](rootTree)({(folding, name) => c.universe.Select(folding, c.universe.TermName(name))})
230+
c.Expr[Option[A]](c.universe.Apply(namesTree, List(value.tree)))
231+
},
232+
value => select[Option[A], Boolean](value, "isEmpty"),
233+
PartialExprFunction(
234+
value => select[Option[A], Boolean](value, "nonEmpty"),
235+
value => select[Option[A], A](value, "get")
236+
)
237+
)
238+
}
239+
}
240+
241+
@ifdef("scalaBinaryVersion:3")
242+
implicit def quotedUnit(implicit quotes: scala.quoted.Quotes):BiOptionally[scala.quoted.Expr, Unit, Unit] = BiOptionally.apply(
243+
(),
244+
_ => (),
245+
_ => scala.quoted.Expr(true),
246+
PartialExprFunction.identity(scala.quoted.Expr(true)),
247+
)
167248
}
168249

169-
private[typeclass] trait LowPrioBiOptionally extends VersionSpecificLowPrioBiOptionally {
250+
private[typeclass] trait LowPrioBiOptionally {
170251
implicit def idToOption[A]:BiOptionally[Id, A, Option[A]] = BiOptionally.apply[Id, A, Option[A]](
171252
None,
172253
Some.apply _,
@@ -176,4 +257,8 @@ private[typeclass] trait LowPrioBiOptionally extends VersionSpecificLowPrioBiOpt
176257
_.get
177258
)
178259
)
260+
261+
@ifdef("scalaBinaryVersion:3")
262+
implicit def quotedToExprOption[A](implicit quotes: scala.quoted.Quotes, typ: scala.quoted.Type[A]):BiOptionally[scala.quoted.Expr, scala.quoted.Expr[A], scala.quoted.Expr[Option[A]]] =
263+
OptionallyImpl.quotedToExprOption[A]
179264
}

CHANGES.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## [Unreleased](https://github.com/rayrobdod/string-context-parser-combinator/compare/0.1.1...HEAD)
44
* Improve performance of `codePointWhere` and `charWhere` if default error message is not needed
5+
* Flatten typeclass's companion's inheritance hierarchy
6+
* Include pages for the companion's scala-2 `Context` inner classes in scala-2 docs
7+
(was previously not included since, despite being visible via inheritance, class was still an inner class of a package-private trait)
8+
* Use `ifdef` annotation instead of inheritance for scala-version-specific methods
59

610
## [0.1.1](https://github.com/rayrobdod/string-context-parser-combinator/compare/0.1.0...0.1.1) – 2025-02-04
711
* Add symbolic operators to Parser, Extractor and Interpolator

0 commit comments

Comments
 (0)