2021/12/06(月)開催の「ZOZO Tech Talk #1 - Android」で発表したスライドです。 https://zozotech-inc.connpass.com/event/230668/
Android Lintでコードの宣言順をチェックする 2021/12/06(Mon) ZOZO Tech Talk #1 - Android 株式会社ZOZO ZOZOTOWN開発本部 ZOZOTOWNアプリ部 Androidブロック 鈴木 優佑Copyright © ZOZO, Inc.
View Slide
© ZOZO, Inc.株式会社ZOZO ZOZOTOWN開発本部 ZOZOTOWNアプリ部 Androidブロック鈴木 優佑 ● 2020年 新卒入社 ● 静岡県出身 実家はお茶農家🍵 2
© ZOZO, Inc.3課題
© ZOZO, Inc.4課題 コードの宣言順を意識して実装・レビューをしなければならない ● 宣言順が開発ガイドに定義されている ○ コードの保守性向上のため ○ 基本的にはKotlinのコーディング規約に準拠 ○ ZOZOTOWN固有のルールあり ● 開発ガイドを確認する必要があり、開発・レビューの負担につながる ● レビュー時に指摘漏れが発生する可能性がある コードの宣言順についての開発ガイド参考: Kotlinのコーディング規約: https://kotlinlang.org/docs/coding-conventions.html
© ZOZO, Inc.5課題 コードの宣言順を意識して実装・レビューをしなければならない ● 宣言順が開発ガイドに定義されている ○ コードの保守性向上のため ○ 基本的にはKotlinのコーディング規約に準拠 ○ ZOZOTOWN固有のコードあり ● 開発ガイドを確認する必要があり、開発・レビューの負担につながる ● レビュー時に指摘漏れが発生する可能性がある コードの宣言順についての開発ガイド参考: Kotlinのコーディング規約: https://kotlinlang.org/docs/coding-conventions.html
© ZOZO, Inc.6解決方法
© ZOZO, Inc.7 Android Lintのカスタムルール作成により コードの宣言順をチェックする
© ZOZO, Inc.8Android Lintとは?
© ZOZO, Inc.Android Lintとは? ● Androidプロジェクト標準のLint ● Gradle, XML, Java, Kotlinなどのファイル解析が可能 ● カスタムルールを作成することが可能 9Android開発のための静的コード解析ツール Android StudioでのLint指摘の例
© ZOZO, Inc.10Android Lintの仕組み
© ZOZO, Inc.11Lintチェックソースコード 抽象構文木 レポートAndroid Lintの仕組み 全体の流れ
© ZOZO, Inc.12Lintチェックソースコード 抽象構文木 レポートAndroid Lintの仕組み 全体の流れ
© ZOZO, Inc.13PSI(Program Structure Interface) IntelliJ製のAST 言語ごとに異なるPSIが存在する 今回はこちらを使用する UAST(Universal AST) UASTをサポートする言語で共通の表現を提供 Java/Kotlin両方で同じ表現を使用できる Android Lintの仕組み 抽象構文木(AST; Abstract Syntax Tree) 通常の構文木から、意味的な情報のみを取り出したもの PSIの例UASTの例
© ZOZO, Inc.14Lintチェックソースコード 抽象構文木 レポートAndroid Lintの仕組み 全体の流れ
© ZOZO, Inc.15Registry Issueを登録 ServiceLoader経由でインスタンスを提供 Issue Lintチェックで特定される問題 問題の種類、深刻度などの情報が含まれる Detector ASTの情報をもとにコードを解析 Issueをレポート Android Lintの仕組み Lintチェック ASTの情報をもとに、コードの問題を検出する 依存関係
© ZOZO, Inc.16実装の概要
© ZOZO, Inc.17モジュールについて ← Detectorを定義← Registryを定義← Issueを定義↓ RegistryをLint APIへ提供
© ZOZO, Inc.18Registry: Issueを登録、ServiceLoader経由でインスタンスを提供
© ZOZO, Inc.19Registry: Issueを登録、ServiceLoader経由でインスタンスを提供 検出するIssueのリスト定義
© ZOZO, Inc.20Registry: Issueを登録、ServiceLoader経由でインスタンスを提供 Lint APIのバージョンを設定基本的にはCURRENT_APIを設定
© ZOZO, Inc.21Registry: Issueを登録、ServiceLoader経由でインスタンスを提供 Lintの作成者情報を定義
© ZOZO, Inc.22Registry: Issueを登録、ServiceLoader経由でインスタンスを提供 ● resources/META-INF/services/ 配下にファイルを作成 ● Detectorを完全修飾名で定義 ● Lint APIからServiceLoaderを使用してインスタンス化される
© ZOZO, Inc.23Issue: Lintチェックで特定される問題
© ZOZO, Inc.24Issue: Lintチェックで特定される問題 IssueのID
© ZOZO, Inc.25Issue: Lintチェックで特定される問題 Issueの要約(通常5~6語以下)修正方法ではなく問題点を説明宣言順が正しくない旨の文言を設定
© ZOZO, Inc.26Issue: Lintチェックで特定される問題 Issueの種類開発者の生産性に関連するIssueのためPRODUCTIVITYを設定
© ZOZO, Inc.27Issue: Lintチェックで特定される問題 Issueの説明と修正方法開発ガイドを参照し、宣言順の修正を促す文言を設定
© ZOZO, Inc.28Issue: Lintチェックで特定される問題 Issueの優先度(1〜10の範囲)Lintタスクによって検出した問題の並び替えに使用される今回はサンプルコードと同じ6を設定
© ZOZO, Inc.29Issue: Lintチェックで特定される問題 Issueの深刻度(Fatal, Error, Warning, etc.)問題を無視しても正しく動作するためWARNINGを設定
© ZOZO, Inc.30Issue: Lintチェックで特定される問題 DetectorとScopeを設定Kotlinのファイルに対してチェックを行うためJAVA_FILE_SCOPEを設定
© ZOZO, Inc.311. テストの作成2. 正しい宣言順の定義3. 宣言の種類を判別4. 宣言の種類をModelへ変換5. 宣言順が正しいかチェック6. テストがPassすることを確認Detector: ASTの情報をもとにコードを解析、Issueをレポート
© ZOZO, Inc.321. テストの作成2. 正しい宣言順の定義3. 宣言の種類を判別4. 宣言の種類をModelへ変換5. 宣言順が正しいかチェック6. テストがPassすることを確認Detector: ASTの情報をもとにコードを解析、Issueをレポート
© ZOZO, Inc.33Detector: ASTの情報をもとにコードを解析、Issueをレポート テストの作成● Detector実装前にテストを作成 ● Detectorが正しく警告をレポートするかのテスト Detectorのテストコード
© ZOZO, Inc.341. テストの作成2. 正しい宣言順の定義3. 宣言の種類を判別4. 宣言の種類をModelへ変換5. 宣言順が正しいかチェック6. テストがPassすることを確認Detector: ASTの情報をもとにコードを解析、Issueをレポート
© ZOZO, Inc.35● 開発ガイドに記載されている宣言順をenumで定義 ● ordinalにより順番の取得が可能 ○ 例: DeclarationType.VAL.ordinal-> 2 Detector: ASTの情報をもとにコードを解析、Issueをレポート 正しい宣言順の定義 宣言順を定義したenum
© ZOZO, Inc.361. テストの作成2. 正しい宣言順の定義3. 宣言の種類を判別4. 宣言の種類をModelへ変換5. 宣言順が正しいかチェック6. テストがPassすることを確認Detector: ASTの情報をもとにコードを解析、Issueをレポート
© ZOZO, Inc.37Detector: ASTの情報をもとにコードを解析、Issueをレポート 宣言の種類を判別 PSIの情報をもとに、どの宣言の種類かを判別 宣言の種類の判別ロジック(全体像) メソッドの判別ロジック
© ZOZO, Inc.381. テストの作成2. 正しい宣言順の定義3. 宣言の種類を判別4. 宣言の種類をModelへ変換5. 宣言順が正しいかチェック6. テストがPassすることを確認Detector: ASTの情報をもとにコードを解析、Issueをレポート
© ZOZO, Inc.39Detector: ASTの情報をもとにコードを解析、Issueをレポート 宣言の種類をModelへ変換 ● 決定した宣言の種類に関する情報をModelへmap ● List化 宣言の種類の情報を格納するクラス
© ZOZO, Inc.401. テストの作成2. 正しい宣言順の定義3. 宣言の種類を判別4. 宣言の種類をModelへ変換5. 宣言順が正しいかチェック6. テストがPassすることを確認Detector: ASTの情報をもとにコードを解析、Issueをレポート
© ZOZO, Inc.41Detector: ASTの情報をもとにコードを解析、Issueをレポート 宣言順が正しいかチェック
© ZOZO, Inc.42Detector: ASTの情報をもとにコードを解析、Issueをレポート 宣言順が正しいかチェックlist: 宣言の種類が格納されたListcontext: Issueレポート作成用のJavaContext
© ZOZO, Inc.43Detector: ASTの情報をもとにコードを解析、Issueをレポート 宣言順が正しいかチェックListの先頭から2つずつ要素を取得
© ZOZO, Inc.44Detector: ASTの情報をもとにコードを解析、Issueをレポート 宣言順が正しいかチェックweight(正しい宣言順の番号)を比較currentDeclarationのweight > nextDeclarationのweight→ Issueをレポートする
© ZOZO, Inc.451. テストの作成2. 正しい宣言順の定義3. 宣言の種類を判別4. 宣言の種類をModelへ変換5. 宣言順が正しいかチェック6. テストがPassすることを確認Detector: ASTの情報をもとにコードを解析、Issueをレポート
© ZOZO, Inc.46weight(正しい宣言順の番号)を比較currentDeclarationのweight > nextDeclarationのweight→ IssueをレポートするAndroid Studio上でDetectorのテストを実行した結果テストがPassすることを確認Detector: ASTの情報をもとにコードを解析、Issueをレポート
© ZOZO, Inc.47導入結果
© ZOZO, Inc.48導入結果 Android Studio上での警告例 GitHub上での指摘
© ZOZO, Inc.49宣言順の修正をしている様子 動画が再生されない場合: https://drive.google.com/file/d/1PSV0dAqGX9S_XmHMt2N12CFe3XJonSHF/view?usp=sharing
© ZOZO, Inc.50今後の展望
© ZOZO, Inc.51今後の展望 ● プロダクト(ZOZOTOWN Android)に導入する○ 細かなプログラムの修正○ ビルドエラーの修正● 自動コード整形機能を導入する○ Android Lint LintFixの追加○ Ktlintに移行してFormatterを作成