-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added apply methods to import selectors in Quotes #21225 #22457
base: main
Are you sure you want to change the base?
Conversation
@@ -2621,6 +2624,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => | |||
|
|||
/** Methods of the module object `val GivenSelector` */ | |||
trait GivenSelectorModule { this: GivenSelector.type => | |||
@experimental def apply(bound: Option[TypeTree]): GivenSelector |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@experimental def apply(bound: Option[TypeTree]): GivenSelector | |
@experimental def apply(bound: Option[TypeRepr]): GivenSelector |
I would suggest internally wrapping the type in TypeTree with the default span
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be inconsistent with unapply
and the .bound
accessor method. Is that a problem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TypeTree
makes more sense to me too
Thank you for submitting! The PR looks good, and in my opinion the use case is valid. I would only suggest adding a test, at least for GivenSelector and OmitSelector - I don't really know how we could test others. Here's what I came up with, based on the snippets submitted in #21225: //> using options -experimental
import scala.quoted.*
trait Codec[-T] { def print(): Unit }
object Codec {
inline def derivedWithDeps[T](deps: Any): Codec[T] = ${derivedWithDepsImpl[T]('deps)}
private def derivedWithDepsImpl[T](deps: Expr[Any])(using q: Quotes)(using Type[T]): Expr[Codec[T]] = {
import q.reflect.*
val givenSelector: Selector = GivenSelector(None)
val theImport = Import(deps.asTerm, List(givenSelector))
Block(List(theImport), '{scala.compiletime.summonInline[Codec[T]]}.asTerm).asExprOf[Codec[T]]
/* import deps.given
* summonInline[Codec[T]]
*/
}
inline def derivedWithDepsWithNamedOmitted[T](deps: Any): Codec[T] = ${derivedWithDepsWithNamedOmittedImpl[T]('deps)}
private def derivedWithDepsWithNamedOmittedImpl[T](deps: Expr[Any])(using q: Quotes)(using Type[T]): Expr[Codec[T]] = {
import q.reflect.*
val givenSelector: Selector = GivenSelector(None)
val omitSelector: Selector = OmitSelector("named")
val theImport = Import(deps.asTerm, List(givenSelector, omitSelector))
Block(List(theImport), '{scala.compiletime.summonInline[Codec[T]]}.asTerm).asExprOf[Codec[T]]
/* import deps.{given, named => _}
* summonInline[Codec[T]]
*/
}
} In //> using options -experimental
import scala.quoted.*
sealed trait Foo
case class Bar() extends Foo
object CustomCodecs {
given named: Codec[Bar] = new Codec[Bar]{ def print(): Unit = println("bar codec")}
given Codec[Foo] = new Codec[Foo]{ def print(): Unit = println("foo codec") }
}
@main def Test =
Codec.derivedWithDeps[Bar](CustomCodecs).print()
Codec.derivedWithDepsWithNamedOmitted[Bar](CustomCodecs).print() In
Sorry about the long wait, let me know if you have the time to add those, alternatively I can take this over. |
This comment was marked as outdated.
This comment was marked as outdated.
@jchyb added tests as you suggested |
Fixes #21225