Scaladocを実行時に読み取れるようにするコンパイラプラグイン

ScalaベースのフレームワークでクラスのメタデータからSwaggerなどを生成できるものがあるのですが、専用のアノテーションやオブジェクトを使って情報を記述しておく必要があり、特にパラメータの説明などはScaladocに書いたものをそのまま使えればいいのに、と思うことがありました。

そこで試しにScaladocとして記述したコメントを実行時にリフレクションで取得できるようにするコンパイラプラグインを作ってみました。

github.com

プロジェクトに以下の設定を追加しておくと使えるようになります。

libraryDependencies += "com.github.takezoe" %% "runtime-scaladoc-reader" % "1.0.1"

addCompilerPlugin("com.github.takezoe" %% "runtime-scaladoc-reader" % "1.0.1")

このコンパイラプラグインコンパイル時にScaladocの内容を@Scaladocアノテーションとしてクラスに埋め込みます。たとえば以下のようなクラスがあるとします。

package com.github.takezoe

/**
 * Hello, World!
 */
class HelloWorld {
  ...
}

このクラスから、実行時に以下のようにしてリフレクションでアノテーションを取得することでScaladocコメントを取り出すことができます。

import com.github.takezoe.HelloWorld
import com.github.takezoe.scaladoc.Scaladoc

val clazz = classOf[HelloWorld]
val scaladoc = clazz.getAnnotation(classOf[Scaladoc])

if(scaladoc != null){
  val comment: String = scaladoc.value()
  println(comment)
}

ClassだけでなくMethodFieldからも同じようにしてScaladocを取得できます。

ただし、/**から*/までがそのまま入っているので、実際にデータとして使うにはさらにScaladocをパースしてコメント記号を取り除いたりScaladocタグを抽出したりする必要がありますね。手軽に使えるScaladocパーサがあるとよいのですが…。