-
-
Notifications
You must be signed in to change notification settings - Fork 140
For information / discussion: Add support for Scala 3 enums #1176
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,12 +4,11 @@ | |
|
|
||
| package play.api.libs.json | ||
|
|
||
| import scala.deriving.Mirror | ||
| import scala.util.Try as TryResult | ||
| import scala.util.Success as TrySuccess | ||
| import scala.util.Failure as TryFailure | ||
|
|
||
| import scala.deriving.Mirror.ProductOf | ||
|
|
||
| import scala.quoted.Expr | ||
| import scala.quoted.Quotes | ||
| import scala.quoted.Type | ||
|
|
@@ -43,51 +42,27 @@ private[json] trait QuotesHelper { | |
| * Class `Lorem` is listed through `SubFoo`, | ||
| * but `SubFoo` itself is not returned. | ||
| */ | ||
| final def knownSubclasses(tpr: TypeRepr): Option[List[TypeRepr]] = | ||
| tpr.classSymbol.flatMap { cls => | ||
| @annotation.tailrec | ||
| def subclasses( | ||
| children: List[Tree], | ||
| out: List[TypeRepr] | ||
| ): List[TypeRepr] = { | ||
| val childTpr = children.headOption.collect { | ||
| case tpd: Typed => | ||
| tpd.tpt.tpe | ||
|
|
||
| case vd: ValDef => | ||
| vd.tpt.tpe | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know what to do here to get the singleton |
||
|
|
||
| case cd: ClassDef => | ||
| cd.constructor.returnTpt.tpe | ||
|
|
||
| } | ||
|
|
||
| childTpr match { | ||
| case Some(child) => { | ||
| val tpeSym = child.typeSymbol | ||
|
|
||
| if (tpeSym.flags.is(Flags.Abstract) && | ||
| tpeSym.flags.is(Flags.Sealed) && | ||
| !(child <:< anyValTpe)) || | ||
| (tpeSym.flags.is(Flags.Sealed) && | ||
| tpeSym.flags.is(Flags.Trait)) | ||
| then { | ||
| // Ignore sub-trait itself, but check the sub-sub-classes | ||
| subclasses(tpeSym.children.map(_.tree) ::: children.tail, out) | ||
| } else { | ||
| subclasses(children.tail, child :: out) | ||
| } | ||
| final def knownSubclasses(tpr: TypeRepr): Option[List[TypeRepr]] = { | ||
| def gatherNestedSubtypes[Parent: Type, Elems: Type](using Quotes): List[TypeRepr] = | ||
| Type.of[Elems] match { | ||
| case '[elem *: elems] => | ||
| Expr.summon[Mirror.Of[elem]] match { | ||
| case Some('{ $sum: Mirror.SumOf[elem] { type MirroredElemTypes = elementTypes } }) => | ||
| gatherNestedSubtypes[elem, elementTypes] ++ gatherNestedSubtypes[Parent, elems] | ||
| case _ => | ||
| TypeRepr.of[elem] :: gatherNestedSubtypes[Parent, elems] | ||
| } | ||
|
|
||
| case _ => | ||
| out.reverse | ||
| } | ||
| case '[EmptyTuple] => Nil | ||
| } | ||
|
|
||
| val types = subclasses(cls.children.map(_.tree), Nil) | ||
|
|
||
| if types.isEmpty then None else Some(types) | ||
| tpr.asType match { | ||
| case '[t] => | ||
| Expr.summon[Mirror.Of[t]].collect { | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that a less WIP implementation of this should probably use |
||
| case '{ $sum: Mirror.SumOf[t] { type MirroredElemTypes = elementTypes } } => | ||
| gatherNestedSubtypes[t, elementTypes] | ||
| } | ||
| } | ||
| } | ||
|
|
||
| @annotation.tailrec | ||
| private def withElems[U <: Product]( | ||
|
|
||
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.
By using the
termSymbolwe get the fully qualified name of theenumcaserather than the name of theenumas our type discriminator.