How to extract comments in scala 3 source files by using a tasty inspector

46 Views Asked by At

Say I am parsing the tasty file of some scala source file like this source file:

/** Some comments
  */
trait LsFunctions:
...

I would like to extract the "Some comments" comment and ideally associate it with trait LsFunctions.

At the moment my code looks like this:

import codegen.tastyextractor.model.{EMethod, EPackage, EParam, EType}
import dotty.tools.dotc.ast.Trees.*

import scala.quoted.*
import scala.tasty.inspector.*

class StructureExtractorInspector extends Inspector:
  override def inspect(using Quotes)(tastys: List[Tasty[quotes.type]]): Unit =
    for tasty <- tastys do
      val ctx                                      = scala.quoted.quotes.asInstanceOf[scala.quoted.runtime.impl.QuotesImpl].ctx
      given dotty.tools.dotc.core.Contexts.Context = ctx
      tasty.ast match {
        case PackageDef(pid, stats) =>
          val types = stats.collect { case TypeDef(typeName, Template(constr, parentsOrDerived, self, preBody: List[_])) =>
...

But I can't find any method or so that can give me the comments. Running scalac with tasty-inspector I see that the tasty file retains the comments.

1

There are 1 best solutions below

0
kostas.kougios On

I used the link provided by Gaston in the comments above and copied some code and finally managed to extract the comments from the tasty files. Here is the solution for reference. In my case I had to use several TreeAccumulators but a simplified version of my code is below:

import scala.quoted.*
import scala.tasty.inspector.*

// something to collect the results including the scalaDocs
case class EType(name: String, scalaDocs: Option[String])

class StructureExtractorInspector extends Inspector:

  override def inspect(using Quotes)(tastys: List[Tasty[quotes.type]]): Unit =
    import quotes.reflect.*


    object TypeTraverser extends TreeAccumulator[List[EType]]:
      def foldTree(existing: List[EType], tree: Tree)(owner: Symbol): List[EType] =
        val r = tree match
          case c: ClassDef =>
            val t = EType(c.name, c.symbol.docstring)
            List(t)
          case _           =>
            Nil
        foldOverTree(existing ++ r, tree)(owner)
    end TypeTraverser

    for tasty <- tastys do
      val tree = tasty.ast
      val results = TypeTraverser.foldTree(Nil, tree)(tree.symbol)
      ... do something with the results ...

and finally to run it:

val inspector = new StructureExtractorInspector
TastyInspector.inspectAllTastyFiles(Nil, jars, Nil)(inspector)