From 4d03782d909f5309f6f4418d4cbaad7f192cc660 Mon Sep 17 00:00:00 2001 From: Raymond Dodge Date: Mon, 18 Nov 2024 17:19:30 -0500 Subject: [PATCH] Make using lifted more uniform across scala versions Specifically, make both versions of LiftFunction and LiftedInterpolator have the same type parameters so cross-compiled dependencies can share sources when passing around values of those types --- .../main/scala-2/VersionSpecificInterpolator.scala | 10 +++++----- Base/src/main/scala-2/internal/Lifted.scala | 2 +- Base/src/main/scala-2/package.scala | 4 +++- .../main/scala-3/VersionSpecificInterpolator.scala | 13 +++++++------ Base/src/main/scala-3/internal/Lifted.scala | 4 ++-- Base/src/main/scala-3/package.scala | 6 +++--- JsonParser/src/main/scala-2/MacroImpl.scala | 4 ++-- JsonParser/src/main/scala-3/MacroImpl.scala | 6 +++--- 8 files changed, 26 insertions(+), 23 deletions(-) diff --git a/Base/src/main/scala-2/VersionSpecificInterpolator.scala b/Base/src/main/scala-2/VersionSpecificInterpolator.scala index 6dfd488..001fef0 100644 --- a/Base/src/main/scala-2/VersionSpecificInterpolator.scala +++ b/Base/src/main/scala-2/VersionSpecificInterpolator.scala @@ -83,17 +83,17 @@ trait VersionSpecificInterpolatorModule { * Create a Interpolators that can parse Exprs belonging to the specified Context * @group InterpolatorGroup */ - def contextInterpolators(c:Context):Interpolator.Interpolators[c.Expr, c.universe.Liftable, c.TypeTag] with LiftedInterpolator[c.type] = { + def contextInterpolators(c:Context):Interpolator.Interpolators[c.Expr, c.universe.Liftable, c.TypeTag] with LiftedInterpolator[c.Expr, c.TypeTag] = { new Interpolator.Interpolators[c.Expr, c.universe.Liftable, c.TypeTag] with ExprIndependentInterpolators[c.Expr[Any]] - with LiftedInterpolator[c.type] { + with LiftedInterpolator[c.Expr, c.TypeTag] { override def `lazy`[A](fn:Function0[Interpolator[A]]):Interpolator[A] = new Interpolator[A](internal.DelayedConstruction.interpolator(fn)) override def ofType[A](implicit tpe: c.TypeTag[A]): Interpolator[c.Expr[A]] = new Interpolator[c.Expr[A]](new internal.OfType[c.type, A](tpe)) - override def lifted[Lifter[_], Z](lift:LiftFunction[c.type, Lifter, Z], description:String)(implicit lifterTypeTag:c.TypeTag[Lifter[_]]):Interpolator[Z] = + override def lifted[Lifter[_], Z](lift:LiftFunction[c.Expr, c.TypeTag, Lifter, Z], description:String)(implicit lifterTypeTag:c.TypeTag[Lifter[_]]):Interpolator[Z] = new Interpolator[Z](internal.Lifted(c)(lift, ExpectingDescription(description))) } } @@ -102,13 +102,13 @@ trait VersionSpecificInterpolatorModule { * * @group InterpolatorGroup */ - trait LiftedInterpolator[C <: Context with Singleton] { + trait LiftedInterpolator[Expr[+_], Type[_]] { /** * A parser that succeeds if the next part of the in put is an `arg` and Lifter parameterized on `arg`'s type can be implicitly summoned * * The implicitly summoned value and the `arg` value are passed to `lift`; the returned value is returned by this parser * @group Arg */ - def lifted[Lifter[_], Z](lift:LiftFunction[C, Lifter, Z], description:String)(implicit lifterTypeTag:C#TypeTag[Lifter[_]]):SCInterpolator[C#Expr[Any], Z] + def lifted[Lifter[_], Z](lift:LiftFunction[Expr, Type, Lifter, Z], description:String)(implicit lifterTypeTag:Type[Lifter[_]]):SCInterpolator[Expr[Any], Z] } } diff --git a/Base/src/main/scala-2/internal/Lifted.scala b/Base/src/main/scala-2/internal/Lifted.scala index 66a52c8..89e1477 100644 --- a/Base/src/main/scala-2/internal/Lifted.scala +++ b/Base/src/main/scala-2/internal/Lifted.scala @@ -7,7 +7,7 @@ private[stringContextParserCombinator] object Lifted { def apply[Lifter[_], Z]( c:Context)( - lift:LiftFunction[c.type, Lifter, Z], + lift:LiftFunction[c.Expr, c.TypeTag, Lifter, Z], description:ExpectingDescription )(implicit lifterTypeTag:c.TypeTag[Lifter[_]] ):Interpolator[c.Expr[_], Z] = { diff --git a/Base/src/main/scala-2/package.scala b/Base/src/main/scala-2/package.scala index 50f8bf9..d9446c3 100644 --- a/Base/src/main/scala-2/package.scala +++ b/Base/src/main/scala-2/package.scala @@ -83,5 +83,7 @@ package object stringContextParserCombinator { package stringContextParserCombinator { /** Support for Interpolator.contextInterpolators.lifted; represents a macro-level function that combines a CC[A] and an A. */ - trait LiftFunction[U <: Context with Singleton, -CC[_], +Z] {def apply[A](lifter:U#Expr[CC[A]], elem:U#Expr[A]):Z} + trait LiftFunction[Expr[+_], Type[_], -CC[_], +Z] { + def apply[A](lifter:Expr[CC[A]], elem:Expr[A]):Z + } } diff --git a/Base/src/main/scala-3/VersionSpecificInterpolator.scala b/Base/src/main/scala-3/VersionSpecificInterpolator.scala index ea0f847..f43fd72 100644 --- a/Base/src/main/scala-3/VersionSpecificInterpolator.scala +++ b/Base/src/main/scala-3/VersionSpecificInterpolator.scala @@ -68,7 +68,7 @@ trait VersionSpecificInterpolatorModule extends ExprIndependentInterpolators[Any * The implicitly summoned value and the `arg` value are passed to `lift`; the returned value is returned by this parser * @group Arg */ - def lifted[Lifter[_], Z](lift:LiftFunction[Lifter, Z], description:String)(using Quotes, Type[Lifter]):SCInterpolator[Expr[Any], Z] = + def lifted[Lifter[_], Z](lift:LiftFunction[Expr, Type, Lifter, Z], description:String)(using Quotes, Type[Lifter]):SCInterpolator[Expr[Any], Z] = new SCInterpolator(internal.Lifted(lift, ExpectingDescription(description))) @@ -76,17 +76,18 @@ trait VersionSpecificInterpolatorModule extends ExprIndependentInterpolators[Any * Create an Interpolators that can parse `quoted.Expr`s * @group InterpolatorGroup */ - def quotedInterpolators(using Quotes):Interpolator.Interpolators[quoted.Expr, quoted.ToExpr, quoted.Type] & LiftedInterpolator = { + def quotedInterpolators(using Quotes):Interpolator.Interpolators[quoted.Expr, quoted.ToExpr, quoted.Type] & LiftedInterpolator[quoted.Expr, quoted.Type] = { new Interpolator.Interpolators[quoted.Expr, quoted.ToExpr, quoted.Type] with ExprIndependentInterpolators[quoted.Expr[Any]] - with LiftedInterpolator { + with LiftedInterpolator[quoted.Expr, quoted.Type] + { override def `lazy`[A](fn:Function0[SCInterpolator[quoted.Expr[Any], A]]):SCInterpolator[quoted.Expr[Any], A] = new SCInterpolator(internal.DelayedConstruction.interpolator(fn)) override def ofType[A](implicit tpe: Type[A]): SCInterpolator[Expr[Any], Expr[A]] = new SCInterpolator(new internal.OfType[A]) - override def lifted[Lifter[_], Z](lift:LiftFunction[Lifter, Z], description:String)(using quoted.Type[Lifter]):SCInterpolator[Expr[Any], Z] = + override def lifted[Lifter[_], Z](lift:LiftFunction[quoted.Expr, quoted.Type, Lifter, Z], description:String)(using quoted.Type[Lifter]):SCInterpolator[Expr[Any], Z] = new SCInterpolator(internal.Lifted(lift, ExpectingDescription(description))) } } @@ -95,13 +96,13 @@ trait VersionSpecificInterpolatorModule extends ExprIndependentInterpolators[Any * * @group InterpolatorGroup */ - trait LiftedInterpolator { + trait LiftedInterpolator[Expr[+_], Type[_ <: AnyKind]] { /** * A parser that succeeds if the next part of the in put is an `arg` and Lifter parameterized on `arg`'s type can be implicitly summoned * * The implicitly summoned value and the `arg` value are passed to `lift`; the returned value is returned by this parser * @group Arg */ - def lifted[Lifter[_], Z](lift:LiftFunction[Lifter, Z], description:String)(using quoted.Type[Lifter]):SCInterpolator[Expr[Any], Z] + def lifted[Lifter[_], Z](lift:LiftFunction[Expr, Type, Lifter, Z], description:String)(using Type[Lifter]):SCInterpolator[Expr[Any], Z] } } diff --git a/Base/src/main/scala-3/internal/Lifted.scala b/Base/src/main/scala-3/internal/Lifted.scala index 7c8bcc5..896efb0 100644 --- a/Base/src/main/scala-3/internal/Lifted.scala +++ b/Base/src/main/scala-3/internal/Lifted.scala @@ -13,11 +13,11 @@ object Lifted { def transpose:Option[MyTuple[A, Lifter]] = lifter.map(x => MyTuple(value, x)) } private final class MyTuple[A : Type, Lifter[_]](value:Expr[A], lifter:Expr[Lifter[A]]) { - def liftApply[Z](lift:LiftFunction[Lifter, Z])(using Quotes):Z = lift.apply[A](lifter, value) + def liftApply[Z](lift:LiftFunction[Expr, Type, Lifter, Z])(using Quotes):Z = lift.apply[A](lifter, value) } def apply[Lifter[_], Z]( - lift:LiftFunction[Lifter, Z], + lift:LiftFunction[Expr, Type, Lifter, Z], description:ExpectingDescription, )(using Type[Lifter], diff --git a/Base/src/main/scala-3/package.scala b/Base/src/main/scala-3/package.scala index fc18263..c0f9211 100644 --- a/Base/src/main/scala-3/package.scala +++ b/Base/src/main/scala-3/package.scala @@ -1,9 +1,7 @@ package name.rayrobdod import scala.language.higherKinds -import scala.quoted.Expr import scala.quoted.Quotes -import scala.quoted.Type /** * A library for implementing custom string interpolation implementations using Parser Combinators @@ -28,7 +26,9 @@ package object stringContextParserCombinator { package stringContextParserCombinator { /** Support for [[Interpolator.lifted]]; represents a macro-level function that combines a CC[A] and an A. */ - trait LiftFunction[-CC[_], +Z] {def apply[A](lifter:Expr[CC[A]], elem:Expr[A])(using Type[A], Quotes):Z} + trait LiftFunction[Expr[+_], Type[_], -CC[_], +Z] { + def apply[A](lifter:Expr[CC[A]], elem:Expr[A])(using Type[A], Quotes):Z + } /** An identity context - for parsing outside of a macro */ type Id[+A] = A /** An identity function for lifting into the identity context */ diff --git a/JsonParser/src/main/scala-2/MacroImpl.scala b/JsonParser/src/main/scala-2/MacroImpl.scala index 4e78072..b827ac1 100644 --- a/JsonParser/src/main/scala-2/MacroImpl.scala +++ b/JsonParser/src/main/scala-2/MacroImpl.scala @@ -6,8 +6,8 @@ import org.json4s._ import name.rayrobdod.stringContextParserCombinator._ final class MacroImpl(val c:Context {type PrefixType = JsonStringContext}) { - private[this] def myLiftFunction[Z, Lifter[A] <: Lift[A, Z]]:LiftFunction[c.type, Lifter, c.Expr[Z]] = { - new LiftFunction[c.type, Lifter, c.Expr[Z]] { + private[this] def myLiftFunction[Z, Lifter[A] <: Lift[A, Z]]:LiftFunction[c.Expr, c.TypeTag, Lifter, c.Expr[Z]] = { + new LiftFunction[c.Expr, c.TypeTag, Lifter, c.Expr[Z]] { def apply[A](lifter:c.Expr[Lifter[A]], a:c.Expr[A]):c.Expr[Z] = { c.Expr( c.universe.Apply( diff --git a/JsonParser/src/main/scala-3/MacroImpl.scala b/JsonParser/src/main/scala-3/MacroImpl.scala index 745c8f8..0e52f56 100644 --- a/JsonParser/src/main/scala-3/MacroImpl.scala +++ b/JsonParser/src/main/scala-3/MacroImpl.scala @@ -8,8 +8,8 @@ import name.rayrobdod.stringContextParserCombinator._ object MacroImpl { import scala.language.higherKinds - private def myLiftFunction[Z : Type, Lifter[A] <: Lift[A, Z] : Type]:LiftFunction[Lifter, Expr[Z]] = { - new LiftFunction[Lifter, Expr[Z]] { + private def myLiftFunction[Z : Type, Lifter[A] <: Lift[A, Z] : Type]:LiftFunction[Expr, Type, Lifter, Expr[Z]] = { + new LiftFunction[Expr, Type, Lifter, Expr[Z]] { def apply[A](lifter:Expr[Lifter[A]], a:Expr[A])(using Type[A], Quotes):Expr[Z] = lifter match { // Lifter being a Lift.jvalue implies that A =:= Z case '{ Lift.jvalue } => a.asExprOf[Z] @@ -27,7 +27,7 @@ object MacroImpl { * (i.e. `Lift.string.apply("abcd").values`). * This will bypass that wrapping, at least for the built-in `Lift.string`. */ - private object stringLiftFunction extends LiftFunction[Lift.String, Expr[String]] { + private object stringLiftFunction extends LiftFunction[Expr, Type, Lift.String, Expr[String]] { def apply[A](lifter:Expr[Lift.String[A]], a:Expr[A])(using Type[A], Quotes):Expr[String] = lifter match { // Lifter being a Lift.jvalue implies that A =:= Z, and for Lift.String, Z =:= JString case '{ Lift.jvalue } => '{ ${a.asExprOf[JString]}.values }