1

I want to access documentation comments from a Scala compiler plugin running after typer stage.

scala.tools.nsc.Global extends DocComments, so I assumed it would be as simple as calling global.cookedDocComment(symbol) but it returns empty string even for symbols which have comments.

Then I looked at where the docComments map gets updated: the primary location is in the interactive compiler's

private def forceDocComment(sym: Symbol, unit: RichCompilationUnit) {
  unit.body foreachPartial {
    case DocDef(comment, defn) if defn.symbol == sym =>
      fillDocComment(defn.symbol, comment) // <- updates the map
      EmptyTree
    case _: ValOrDefDef =>
      EmptyTree
  }
}

So I tried to add the following traverser:

object FindCommentsTraverser extends Traverser {
  override def traverse(tree: Tree): Unit = tree match {
    case DocDef(comment, definition) =>
      fillDocComment(definition.symbol, comment)
    case _ => super.traverse(tree)
  }
}

val unit: global.CompilationUnit = ...
FindCommentsTraverser.traverse(unit.body)

I can verify the traverser is called, but it never encounters a DocDef.

EDIT: I have a partial workaround (the comments explain why it's only partial and I still very much want a better alternative):

object FindCommentsTraverser extends Traverser {
  override def traverse(tree: Tree): Unit = tree match {
    case DocDef(comment, definition) =>
      super.traverse(tree)
      // FIXME definition.symbol is NoSymbol
//        fillDocComment(definition.symbol, comment)

      // For now work around by searching for name
      val name = definition match {
        case named: NameTree => named.name.toString
      }
      symbolMap.valuesIterator.find {
        sym => sym.nameString == name
      }.foreach {
        sym => fillDocComment(sym, comment)
      }
    case _ => super.traverse(tree)
  }
}

val analyzer = new ScaladocSyntaxAnalyzer[global.type](global) {
  override val runsAfter: List[String] = Nil
  override val runsRightAfter: Option[String] = None
}
val parser = new analyzer.ScaladocUnitParser(context.unit, Nil)
val treeWithDocs = parser.parse()
FindCommentsTraverser.traverse(treeWithDocs)

where symbolMap is part of my plugin.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487

0 Answers0