-
Notifications
You must be signed in to change notification settings - Fork 66
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
Suggestion: Surface - get list of derived classes #3428
Comments
Listing derived classes of a sealed trait is interesting. I also have some use cases, but mostly for testing purpose. I'd like to see how complex your implementation is before deciding to support it in airframe-surface. In JVM world, I would use just Java reflection as in airframe/airframe-log/.jvm/src/main/scala/wvlet/log/io/Resource.scala Lines 378 to 382 in 75cd4b3
which is simpler to use and does not need to generate a lot of code at compile time.
|
Checking my source code it seems my Scala 2 version is not producing private def listDerivedClasses(t: Type): Set[Type] = {
def recurse(tpe: Type): Set[Type] = {
if (tpe.typeSymbol.isAbstract && tpe.typeSymbol.isClass && tpe.typeSymbol.asClass.isSealed) {
val subclasses = tpe.typeSymbol.asClass.knownDirectSubclasses.map(sym => sym.asType.typeSignature)
subclasses.flatMap(recurse)
} else {
Set(tpe)
}
}
recurse(t)
}
def listDerivedClasses[T: TypeTag]: Set[TypeDesc] = {
listDerivedClasses(implicitly[TypeTag[T]].tpe)
} Here is Scala 3 version, which produces list of
|
I think the trouble with such solutions is a maintenance burden - you need to update the list each time the list of subclasses changes. It may be easy to do, but it may be easy to forget to do so. However, as I said, I personally have no need for such function at this moment, therefore I will not press to implement it. |
I use Surface to inspect ASTs in my application. There is one feature which I currently have to implement on my own, and that is getting all derived classes of a
sealed trait
/class
. I have an implementation for Scala 2 usingTypeTags
and for Scala 3 using a macro.Given Surface seems to be used to implement codecs and codec libraries often offer a similar functionality, would such a function be in a scope of the surface library?
The declaration could be
def Surface.derivedClasses[T]: Seq[Surface]
.If this is welcome, I can try preparing a PR.
I am not sure if providing methods is also desired. In my current use I do not need it.
I am afraid a separate function would be necessary for this. I would be nice to forward necessary information in
Surface
implementations, so that it a methoddef methodsOf: Seq[MethodSurface]
could be implement directly in theSurface
trait, but while this would be straightforward in Scala 2 usingTypeTag
, I do not see how this could be done in Scala 3 (something like inline type alias would be necessary to pass [A]).A simple alternative would be to provide a separate function as:
def Surface.derivedClassesWithMethods[T]: Seq[(Surface, Seq[MethodSurface])]
.... or perhaps somebody can suggest something better.
The text was updated successfully, but these errors were encountered: