環境
OS
Windows 10
Kotlin
Kotlin version 1.2.10
Gradle
Gradle 4.4
KDoc とは
- Kotlin のソースコード上に書いたドキュメンテーションコメントから生成された API ドキュメント(またその仕組みのこと)
- Kotlin 版 Javadoc
- Javadoc と同じようなところもあれば、全然違うところもある
Hello World
フォルダ構成
|-build.gradle
|
`-src/main/kotlin/
`-sample/kdoc/
`-Hello.kt
build.gradle
buildscript {
ext {
kotlin_version = '1.2.10'
}
repositories {
mavenCentral() // kotlin 用
jcenter() // dokka 用
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.15"
}
}
apply plugin: 'kotlin'
apply plugin: 'org.jetbrains.dokka'
Hello.kt
package sample.kdoc
/**
* クラスの説明.
*/
class TopLevelClass {
/**
* コンパニオンオブジェクトの説明.
*/
companion object {
/**
* コンパニオンオブジェクトのプロパティの説明.
*/
val value = "test"
}
/**
* プロパティの説明.
*/
var value: String? = null
/**
* メソッドの説明.
*
* @args arg 引数の説明
* @return return 戻り値の説明
*/
fun method(arg: String = "default") = "method"
}
/**
* トップレベルの関数の説明.
*/
fun topLevelFunction() {
}
/**
* トップレベルのプロパティの説明.
*/
val topLevelProperty = "test"
ドキュメント生成
$ gradle dokka
出力結果
出力先フォルダ
|-build.gradle
|-src/
| :
`-build/
|-dokka/
: |-style.css
`-kdoc/
|-index.html
|-index-outline.html
|-sample.kdoc/
: |-index.html
:
index.html
sample.kdoc/index.html
説明
build.gradle
buildscript {
...
repositories {
...
jcenter() // dokka 用
}
dependencies {
...
classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.15"
}
}
...
apply plugin: 'org.jetbrains.dokka'
- KDoc の出力には、 Dokka というツールを使用する
- Ant, Maven, Gradle のプラグインとして組み込んで利用することができる
- jar ファイルを直接利用してコマンドラインで生成することも可能
- ここでは、 Gradle を使った場合を前提にする
- Dokka プラグインを追加すると
dokka
というドキュメントを生成するタスクが追加される - デフォルトでは、
build/dokka
の下に簡素な HTML 形式で出力される
出力形式を変更する
Javadoc 形式
build.gradle
...
dokka {
outputFormat = 'javadoc'
}
出力結果
説明
-
dokka.outputFormat
で出力形式を指定できる -
javadoc
を指定すると、本家 Javadoc 形式で出力される - Kotlin 独自の言語仕様(プロパティやトップレベルの関数など)は、 Java から見たときの形式に置き換えられる
- つまり、 Java から Kotlin のコードを使うときに見ると有用な形式になってる
Markdown 形式
build.gradle
...
dokka {
outputFormat = 'markdown'
}
出力結果
フォルダ構成
`-build/dokka/kdoc/
|-alltypes/
| :
|-sample.kdoc
|-index.md
`-package-list
index.md
[kdoc](.)
### Packages
| [sample.kdoc](sample.kdoc/index.md) | |
### Index
[All Types](alltypes/index.md)
説明
-
outputFormat
にmarkdown
を選択すると、出力が Markdown 形式のテキストファイルになる - これをそのまま GitHub などの Markdown ファイルをプレビューしてくれるサービスに上げれば、ドキュメントの公開ができる
-
outputFormat
をgfm
にすると、 GitHub Flavored Markdown 形式の Markdown が出力される- 実際にリポジトリにコミットして GitHub にあげると こんな感じ になる
基本文法
Hello.kt
package sample.kdoc
/**
* 最初の空行までは
* 概要として扱われる.
*
* ## 見出し
* クラス名とかは `<h1>` で出力されるので、見出しを使うならレベル2からにしたほうが良さげ.
*
* Markdown が普通に書ける.
*
* 空行を入れると、段落が分かれる.
*
* [リンクや](https://www.google.co.jp)
*
* インラインコード `Hello().hello()` も可能.
*
* ### リスト
* - foo
* - bar
*
* 1. one
* 1. two
*
* ### コードブロック
* ```kotlin
* fun main(args: Array<String>) {
* val hello = Hello()
* hello.hello()
* }
* ```
*
* ### サポート対処外?
* 任意の改行は(単純な改行)
* いれることが(半角スペース2つ)
* できない(`<br>`タグ)<br>
* ?????
*
* > 引用文
*
* |テーブルも|無理っぽい|
* |---------|---------|
* |foo |bar |
* |fizz |buzz |
*
* <font color="red">任意の HTML タグも書くことができなさそう.</font>
*
* `<` のようなエスケープ記法は、 < のように単独なら大丈夫だけど、
* <html> のように続けて書こうとするとなぜかうまくいかなくなるので、
* `<html>` のようにインラインコードで書くのが無難そう...
*
* -----------------------------------------------------------------------
* 区切り線もだめっぽい?
*/
class Hello
出力結果
説明
- Javadoc 同様、
/**
から*/
までがドキュメントコメントとして解釈される - KDoc は、基本的に Markdown で記述する
- 見出し (
#
) も利用可能だが、クラス名とかがレベル1なので、自分で書くドキュメンテーションコメントはレベル2からにしたほうが良さげ - 試した範囲だと、以下の記法は使えなかった
- 任意の改行
- テーブル
- 区切り線
- HTML の直書き
- また、
<
や>
のようなエスケープの記法は、単独で使用していると問題なく<
,>
と表示される- しかし、なぜか
<html>
のように文字を続けてしまうとそのまま表示されてしまう - とりあえずインラインコードにすれば回避はできるっぽいけどなんか変な気がする
- しかし、なぜか
ブロックタグ
Javadoc でいうところの @param
とかのこと。
Kotlin でも同じようなブロックタグが使えるが、 Kotlin の言語仕様に合わせて色々独自のブロックタグが用意されている。
パラメータ
書式
@param パラメータ名 パラメータの説明
例
package sample.kdoc
/**
* Hello クラス.
* @param T 型引数
*/
class Hello<T> {
/**
* メソッド.
* @param name 名前
*/
fun method(name: String) = ""
}
出力結果
説明
- クラスの型引数、またはメソッドのパラメータを説明するために使用する
戻り値
書式
@return 戻り値の説明
例
package sample.kdoc
/**
* Hello クラス.
*/
class Hello {
/**
* メソッド.
* @return 戻り値の説明
*/
fun method() = ""
}
出力結果
説明
- 戻り値の説明を記述するときに使用する
プライマリコンストラクタ
書式
@constructor コンストラクタの説明
例
package sample.kdoc
/**
* Hello クラス.
*
* クラスの詳細な説明.
*
* @param T 型引数の説明
*
* @constructor
* プライマリコンストラクタの説明.
*
* 詳細な説明は空行を開けてから書ける.
* @param value プライマリコンストラクタ引数の説明は `@constructor` の後に書く
*/
class Hello<T> (value: String) {
/**
* セカンダリコンストラクタの説明.
*
* セカンダリコンストラクタの詳細な説明
* @param int セカンダリコンストラクタの引数の説明
*/
constructor(int: Int): this("int=$int")
}
出力結果
説明
- プライマリコンストラクタについてのドキュメントコメントを書きたい場合に使用する
-
@constructor
を使わずに書くと、クラスのドキュメントコメントとして処理されてしまう
-
- 引数の説明を指定する場合は、
@constructor
の後で@param
を使う- 前に書くと、クラスの型引数の注釈と判断されてしまう
- 空行を入れれば詳細な説明も書ける
レシーバー
書式
@receiver レシーバーの説明
例
package sample.kdoc
/**
* Hello クラス.
*/
class Hello {
/**
* メソッドの説明.
* @param lambda 引数の説明
* @receiver レシーバの説明
*/
fun method(lambda: String.() -> Unit) {
"hello".lambda()
}
}
出力結果
説明
- レシーバについて説明を書くときに使用する
プロパティ
書式
@property プロパティ名 プロパティの説明
例
package sample.kdoc
/**
* Hello クラス.
*
* @property foo
* プライマリコンストラクタの場合、ドキュメントコメントが書きづらいので、
* `@property` ブロックタグを使用することで、クラスのドキュメントコメント内に記述できる.
*/
class Hello (val foo: String) {
/**
* クラス内で宣言されているプロパティの場合は、普通にドキュメントコメントを書ける.
*/
val bar = 1
}
出力結果
説明
- プライマリコンストラクタで定義したプロパティにドキュメントを書きたいときに使用する
- クラスのボディで宣言しているプロパティであれば、そのプロパティの前にドキュメントコメントを書けばいい
- しかし、プライマリコンストラクタで定義したプロパティの場合は、ドキュメントコメントが書きづらくなる
- そこで、クラスのドキュメントコメント内で
@property
を使用することで、プライマリコンストラクタで定義したプロパティのドキュメントを書ける
例外
書式
@throws 例外クラス 例外の説明
@exception 例外クラス 例外の説明
例
package sample.kdoc
/**
* Hello クラス.
*/
class Hello {
/**
* メソッドの説明.
* @throws IOException 例外の説明
* @exception SQLException 例外の説明
*/
fun method() = ""
}
出力結果
説明
- メソッドがスローする例外について説明するときに使用する
-
@throws
,@exception
のどちらを使っても、結果は同じ
サンプル
書式
@sample 埋め込むサンプルの識別子
例
フォルダ構成
|-build.gradle
|-samples/
| `-method-sample.kt
`-src/main/kotlin/
`-sample/kdoc/
`-Hello.kt
build.gradle
...
dokka {
outputFormat = 'html'
samples = ["samples/method-sample.kt"]
}
method-sample.kt
package sample
fun sampleImplementation() {
val hello = Hello()
hello.method()
}
Hello.kt
package sample.kdoc
/**
* Hello クラス.
*/
class Hello {
/**
* メソッドの説明.
* @sample sample.sampleImplementation
*/
fun method() = ""
}
出力結果
説明
- 外部で用意したサンプル実装をドキュメント上に埋め込むときに使用する
- 任意の場所にサンプルコードを記述した Kotlin のソースコードを配置する
-
build.gradle
で、dokka.samples
にサンプルのファイルを置いた場所を設定する-
dokka.samples
は、ディレクトリの指定も可能
-
- サンプルコードを埋め込みたい場所のドキュメントコメントで
@sample <識別子>
と記述する - 識別子は、サンプルコード(関数)を特定できる完全修飾名にする
Author
書式
@author 作成者
例
package sample.kdoc
/**
* Hello クラス.
*
* @author 作成者の名前
*/
class Hello
出力結果
説明
- コードの作成者を明記するときに使用する
Since
書式
@since バージョン
例
package sample.kdoc
/**
* Hello クラス.
*
* @since 1.0
*/
class Hello
出力結果
説明
- 対象が導入されたバージョンを明記するときに使用する
出力対象から除外する
書式
@suppress
例
package sample.kdoc
/**
* Hello クラス.
*/
class Hello {
/**
* メソッドの説明.
*/
fun method() = ""
/**
* このメソッドの説明の出力は除外される.
* @suppress
*/
fun method2() = ""
}
出力結果
説明
- ドキュメントの出力から除外したい場合に使用する
- 外部に公開しない API でドキュメントとしては出力しないが、内部的には残しておきたい、みたいなケースで使用するっぽい
リンク
フォルダ構成
`-src/main/kotlin/
`-sample/kdoc/
|-foo/
| `-Foo.kt
`-Hello.kt
Foo.kt
package sample.kdoc.foo
/**
* Foo クラス.
*/
class Foo {
companion object {
/**
* fuga プロパティ
*/
val fuga = ""
}
/**
* hoge プロパティ
*/
val hoge = ""
/**
* fizz メソッド.
*/
fun fizz() = ""
/**
* fizz(String) メソッド.
*/
fun fizz(text: String, int: Int) = ""
}
/**
* function 関数.
*/
fun function() = ""
Hello.kt
package sample.kdoc
import sample.kdoc.foo.Foo
/**
* Hello クラス.
*
* - [Foo]
* - [Foo.hoge]
* - [Foo.fizz]
* - [sample.kdoc.foo.function]
* - [Foo.fuga]
*/
class Hello
出力結果
説明
Hello.kt
* - [Foo]
* - [Foo.hoge]
* - [Foo.fizz]
* - [sample.kdoc.foo.function]
* - [Foo.fuga]
- 他の要素(クラス、メソッド、プロパティ、関数など)へのリンクを指定するには、
[]
を使用する- Javadoc の
{@link}
に該当
- Javadoc の
- リンクしたい要素を完全修飾名で記述する
-
import
している場合は省略して記述できる(Javadoc と同じ)
オーバーロードしているメソッドの指定
オーバーロードしているメソッドたちは、 KDoc では次のように1つにまとめられて出力される。
つまり、 Javadoc の {@link}
のようにシグネチャを指定してオーバーロードしているメソッドごとにリンクを指定する、ということはしない。
表示テキストを変更する
package sample.kdoc
import sample.kdoc.foo.Foo
/**
* Hello クラス.
*
* - [任意のテキスト][Foo]
*/
class Hello
出力結果
説明
- リンクの表示テキストを任意のものに変更したい場合は、
[表示するテキスト][リンク先の識別子]
と記述する
モジュールとパッケージのドキュメント
フォルダ構成
|-build.gradle
|-docs/
: `-module_package.md
build.gradle
...
dokka {
outputFormat = 'html'
includes = ['docs/module_package.md']
}
module_package.md
# Module モジュール名?
モジュールの説明
## 詳細な説明
モジュールの詳細な説明
# Package sample.kdoc
パッケージの説明1
## 詳細な説明
パッケージの詳細な説明1
# Package sample.kdoc.foo
パッケージの説明2
## 詳細な説明
パッケージの詳細な説明2
出力結果
説明
- モジュールやパッケージの説明は、別途 Markdown ファイルを作成して組み込む
- オプションの
dokka.includes
で Markdown ファイルを指定する - レベル1の見出しでモジュールとパッケージのどちらを記述するか指定する
- モジュールの場合は
# Module 【モジュール名】
- パッケージの場合は
# Package 【パッケージ名】
と書くのがルール - ただ、モジュール名が何を指していて、どう使われているのかはよくわからない
- モジュールの場合は
- 1つのファイルに複数のパッケージの説明を含めることが可能
- パッケージ毎にファイルを分けることも可能(その場合は、
dokka.includes
で複数ファイルを指定する)
- パッケージ毎にファイルを分けることも可能(その場合は、
- 仕様なのかバグなのかは分からないが、空行を入れてもなぜか全て1行にまとめられしまう
- レベル2以上の見出しを挟めば、一応分けられるけども...