2024.10.01
自社の社内情報を未来の“ゴミ”にしないための備え 「情報量が多すぎる」時代がもたらす課題とは?
kotlinでもJavaでも検出できるCustom Lintの作り方(全1記事)
リンクをコピー
記事をブックマーク
釘宮慎之介氏:はい、よろしくお願いします。「kotlinでもJavaでも検出できるCustom Lintの作り方」というタイトルで発表します。自己紹介なんですが、釘宮と申します。Androidエンジニアで、DMM.comというところで働いています。
さっそくアジェンダですが「kotlinを使ったAndroidプロジェクトでlintをかける時にどうしたらいいんだっけ?」という話と、「Custom Lintを作るにはどうしたらいいんだっけ?」という話をします。その後に、「じゃあ実際にandroidのlintでCustom Lintを作ってみましょう。」「(作ったandroid-lintのCustom Lintを)テストしてみましょう。使ってみましょう」という流れで話していきます。
kotlinを使ったAndroidプロジェクトでlintをかけるには、以前までは主に2つの方法しかありませんでした。それが「Ktlint」と「detekt」という方法です。
android-gralde-plugin 3.1.0ぐらいから、androidのlintでもkotlinのlintをかけることができるようになりました。android-lintのいいところは、公式が作っているという点、標準のlintのタスクでちゃんとlintしてくれるという点です。あと、後述するんですけど、Custom Lintを作る際に、型情報を使ったlintとかも作れるという点と、加えてkotlinだけじゃなくて、Javaもそのままlintのチェックをかけることができるという点があります。
(Ktlint、detekt、android-lintには)それぞれいいところがあります。所感でいうと、Ktlintとdetektはそんなに大差はなく、どっちかというとStyle寄りで、インデントのサイズとかそこらへんを見てくれるのかなというところがあります。
ただ、Ktlintはルールの一部無視ができないというか、やればできるんですけど、けっこう難しかったりします。なので、僕自身はKtlintを使ってるんですけど、もしかしたらdetektのほうが使いやすいかもしれないです。
androidのlintに関しては、Styleもロジックも確認はできるんですけど、標準のlintのタスクでインデントのサイズとかを見てくれないようなので、そこがちょっと弱いのかなと思っています。
どれを使えばいいのかっていう主観なんですけど、androidのlintを外すことはできないので、Styleとかを見たいのであれば、androidのlintに加えてKtlintやdetektを併用するのがいいのかなと考えています。
Custom Lintの作り方なんですけど、これはKtlint、detekt、androidのlintの場合も一緒で、まずはASTを知らなければ作れません。(スライドを指して)このように、コードはツリーの構造で、コンパイラやIDEとかを解釈します。
例えば、「引数が複数あったら絶対改行してね」みたいなCustom Lintを作りたいとします。上がNGで、下がOKの場合、こういうlintを作りたいっていう時です。
NGの時もOKの時も、PSI、ASTのツリーはこのようになります。
(一部省略しているのでスライド上では)一番上に、ARGUMENTのLISTというノードがあり、その下にARGUMENTである1、カンマ、スペース、2があるというツリーになります。
さっきのOKの時、つまりちゃんと改行されてる時は、この3つ目のスペース、WHITE SPACEに改行コードが含まれていて。
NGの時には改行コードが含まれてません。
なので、Custom Lintを作りたい時は、こういうことを確認します。このようにツリーの構造になっていて、加えて3つ目のWHITE SPACEのところには改行コードがちゃんと含まれてるかという確認をして、逆に入ってない時はNGを出すというようにやります。
それで、「なんとなくわかったけど、まぁツリーがどうなってるかわかんないっすよね」と思うと思いますが、大丈夫です。僕もわかんないんです(笑)。これに関しては、「PsiViewer」というプラグインが用意されています。どういうものかというと、左側にコードを表示して、右側にツリー構造がどうなってるのかを表示してくれるプラグインなので、これを使ってにらめっこしながら作るといいんじゃないかなと思います。
次に、androidのlintでCustom Lintを作ってみます。例えば、RxJavaを使っているとして、Disposableを適切に処理してないでそのままにしている場合は警告を出すというCustom Lintを作ります。
手順は5つです。まずプロジェクトを作る。次にDetectorを作って、Issueを作って、Registryを作る。最後にこのRegistryを登録するという手順です。
プロジェクトを作るところについては、いつも通り作ればいいんですが、「googlesamples」というgithubがあって、そこにテンプレートみたいなものがあるので、それを持ってくるとか、ならうのがいいと思います。
Detectorを作るところについては、(スライドを指して)完成形がこんなコードになります。
まず、Detectorというものをextendして、UastScannerというものをimplementします。Uastというのは、Unified ASTの略です。
その次に、createUastHandlerというものをオーバーライドします。つまり実際は何をやるかというと、UIElementHandlerというものを実装することになります。
このUIElementHandlerは、ツリーの上から順にスキャンしていってくれて、その各種ノードが見つかった時に、各種のvisitメソッドを呼びます。このvisitメソッドをオーバーライドして使うようになります。
今回はPsiViewerを見ると、DOT_QUALIFIED_EXPRESSIONというものが来た時に確認するだけで済みそうなので、それに対応するvisitメソッドをオーバーライドするようにします。
visit対象のノードクラスで、さっきのDOT_QUALIFIED_EXPRESSIONというもののクラス情報を、上のgetApplicableUastTypesというところに返してあげるようにします。これはお約束になっていて、これをしないとvisitメソッドをオーバーライドしても呼ばれないということがあるのでやります。
実際のvisitメソッドの中身は、こうなっています。
これ、ソースって見れますかね? 大丈夫かな。この中身は何かというと、親がBLOCKになっている時にメソッドチェーンの最後がsubscribeというものになっています。そのsubscribeのメソッドの返り値がDisposableになっている時にレポートする、となっています。
1つ(話を)戻すと、このDisposableの型が返ってくる情報がKtlintやdetektだと取れなくて、androidのlintでできる点がメリットだと思っています。
加えて、kotlinの場合以外に、Javaの場合も書くようにします。UastScannerはkotlinとJavaと区別なくvisitしてくれるんですけど、kotlinとJavaの時でPSIの型が違うので、別途こちらもPsiViewerとにらめっこしながら作ることになります。
Detectorができたら、Issueというものを作っていきます。このIssueの中には、ID情報や説明とかが入っています。
その後に、作ったIssueをRegistryというところに登録して。
このRegistryをbuild.gradleに記述すればCustom Lintは完成です。
作ったCustom Lintをテストしていきます。テストメソッドの書き方はこのようになっています。
対象のコードを文字列で用意します。これは長くなることが多いので、ファイル読み込みにするのがいいと思います。用意したら、それをkotlinファイルとして渡す、つまりkotlinメソッドを呼んで文字列を渡します。そして、lintにかけたらエラー文言が出てくるので、適切なエラー文言になっているかをexpectメソッドで確認します。Javaの時はこの2箇所をJavaに変えればOKです。
作ったCustom Lintの使い方です。これは簡単で、同一プロジェクトにCustom Lintのモジュールがある場合は、dependenciesにlintChecks projectのモジュール名を入れればOKです。他のプロジェクトとかでも同じCustom Lintを使いたい時には、JARにしてあげて、そのJARのパスをlintChecksで渡してあげればOKです。ここまでできれば無事動くことが確認できました。
まとめです。kotlinでlintをかける方法は3つあるっていうことを説明しました。kotlinでもdetektでもandroid-lintの場合でも、Custom Lintを作る際はASTを知らなければいけませんということを説明しました。最後にCustom Lintの作り方を説明しました。ご静聴ありがとうございました。
(会場拍手)
2024.10.29
5〜10万円の低単価案件の受注をやめたら労働生産性が劇的に向上 相見積もり案件には提案書を出さないことで見えた“意外な効果”
2024.10.24
パワポ資料の「手戻り」が多すぎる問題の解消法 資料作成のプロが語る、修正の無限ループから抜け出す4つのコツ
2024.10.28
スキル重視の採用を続けた結果、早期離職が増え社員が1人に… 下半期の退職者ゼロを達成した「関係の質」向上の取り組み
2024.10.22
気づかぬうちに評価を下げる「ダメな口癖」3選 デキる人はやっている、上司の指摘に対する上手な返し方
2024.10.24
リスクを取らない人が多い日本は、むしろ稼ぐチャンス? 日本のGDP4位転落の今、個人に必要なマインドとは
2024.10.23
「初任給40万円時代」が、比較的早いうちにやってくる? これから淘汰される会社・生き残る会社の分かれ目
2024.10.23
「どうしてもあなたから買いたい」と言われる営業になるには 『無敗営業』著者が教える、納得感を高める商談の進め方
2024.10.28
“力を抜くこと”がリーダーにとって重要な理由 「人間の達人」タモリさんから学んだ自然体の大切さ
2024.10.29
「テスラの何がすごいのか」がわからない学生たち 起業率2年連続日本一の大学で「Appleのフレームワーク」を教えるわけ
2024.10.30
職場にいる「困った部下」への対処法 上司・部下間で生まれる“常識のズレ”を解消するには