Skip to content

Fix #8460: expose children of sealed trait in Reflection #8461

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

Merged
merged 1 commit into from
Mar 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1753,6 +1753,9 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend
case sym if sym.is(Flags.CaseAccessor) => sym.asTerm
}

def Symbol_children(self: Symbol)(using ctx: Context): List[Symbol] =
dotty.tools.dotc.transform.SymUtils(self).children

private def isField(sym: Symbol)(using ctx: Context): Boolean = sym.isTerm && !sym.is(Flags.Method)

def Symbol_of(fullName: String)(using ctx: Context): Symbol =
Expand Down
4 changes: 4 additions & 0 deletions library/src/scala/tasty/Reflection.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2254,6 +2254,10 @@ class Reflection(private[scala] val internal: CompilerInterface) { self =>
/** Shows the tree as fully typed source code */
def showWith(syntaxHighlight: SyntaxHighlight)(using ctx: Context): String =
new SourceCodePrinter[self.type](self)(syntaxHighlight).showSymbol(sym)

/** Case class or case object children of a sealed trait */
def children(using ctx: Context): List[Symbol] =
internal.Symbol_children(sym)
}


Expand Down
3 changes: 3 additions & 0 deletions library/src/scala/tasty/reflect/CompilerInterface.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1350,6 +1350,9 @@ trait CompilerInterface {

def Symbol_noSymbol(using ctx: Context): Symbol

/** Case class or case object children of a sealed trait */
def Symbol_children(self: Symbol)(using ctx: Context): List[Symbol]


///////////
// FLAGS //
Expand Down
48 changes: 48 additions & 0 deletions tests/run-custom-args/tasty-inspector/i8460.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import scala.tasty.Reflection
import scala.tasty.inspector._

// Ambiguous member names
sealed trait Vehicle
case class Truck(numberOfWheels: Int) extends Vehicle
case class Car(numberOfWheels: Int, color: String) extends Vehicle
case class Plane(numberOfEngines: Int) extends Vehicle

// Case object implementation
sealed trait Flavor
case object Vanilla extends Flavor
case object Chocolate extends Flavor
case object Bourbon extends Flavor

object Test {
def main(args: Array[String]): Unit = {

// Tasty Scala Class
val inspect1 = new TestInspector_Children()
inspect1.inspect("", List("Vehicle"))
assert(inspect1.kids == List("Truck","Car","Plane"))

// Java Class
val inspect2 = new TestInspector_Children()
inspect2.inspect("", List("Flavor"))
assert(inspect2.kids == List("Vanilla","Chocolate","Bourbon"))
}
}

class TestInspector_Children() extends TastyInspector:

var kids: List[String] = Nil

protected def processCompilationUnit(reflect: Reflection)(root: reflect.Tree): Unit =
import reflect._
inspectClass(reflect)(root)

private def inspectClass(reflect: Reflection)(tree: reflect.Tree): Unit =
import reflect.{given _, _}
tree match {
case t: reflect.PackageClause =>
t.stats.map( m => inspectClass(reflect)(m) )
case t: reflect.ClassDef =>
kids = t.symbol.children.map(_.fullName)

case x =>
}