【テクニカル・上級編】IntelliJ IDEAの『プラグイン開発』で業務効率を自動化:独自のインテンション・アクションを作成する方法 – 総合開発環境(IDE)生産性向上バイブル

IntelliJ IDEAの深淵へ:Intention Actionによる「社内フレームワークの強制力」の実装とDevOps的自動化

多くの開発チームが「コード規約」をドキュメント化し、CIでLintを回すことに腐心している。しかし、それは「違反を見つけてから怒る」という後手の手法に過ぎない。真のDevOpsアーキテクトが目指すべきは、開発者がIDE上でコードを書いている瞬間に、正しい選択肢以外を提示させない「物理的な強制力」の構築である。

今回は、IntelliJ Platform Plugin SDKを活用し、社内独自の設計パターンやセキュリティ規約をIDEのネイティブ機能として統合する「カスタムIntention Action」の実装と、それを組織全体に配布・運用するためのパイプライン設計について深掘りする。

—

1. なぜ「Intention Action」なのか:AST操作の真髄

Intention Action(`PsiElementBaseIntentionAction`)は、単なるコード補完ではない。これはIDEが構文解析したAST(抽象構文木)を直接操作する権限を開発者に与えるものだ。

従来のLintツールは、ファイル保存後やCI実行時に結果が出るため、「コンテキストスイッチ」が発生する。一方、Intention Actionは、開発者がカーソルを合わせた瞬間に「この社内仕様に沿っていないコードを、最適化されたパターンへ即座に変換する」という推論的修正を可能にする。

実装のコア:PsiElementの書き換え

以下は、特定の社内ロガーの使用を強制し、標準の `System.out.println` を検知した瞬間に削除・置換するIntentionの骨子である。

// PsiElementBaseIntentionActionを継承し、特定のコードパターンを検知する
class ForceCompanyLoggerIntention : PsiElementBaseIntentionAction() {

// アクションのテキストを定義(Alt+Enterで表示される文字列)
override fun getText() = “Replace to CompanyLogger”
override fun getFamilyName() = “Code Quality Enforcement”

// どの要素でこのアクションを有効にするか(PsiMethodCallExpressionを狙い撃つ)
override fun isAvailable(project: Project, editor: Editor?, element: PsiElement): Boolean {
return element is PsiMethodCallExpression &&
element.methodExpression.text == “System.out.println”
}

// 修正のロジック本体(WriteCommandAction内で実行する必要がある)
override fun invoke(project: Project, editor: Editor?, element: PsiElement) {
val factory = JavaPsiFacade.getInstance(project).elementFactory
// 新しいロガー呼び出しを生成
val newCall = factory.createExpressionFromText(“CompanyLogger.info(args)”, element)
// ASTの書き換えを実行
element.replace(newCall)
}
}

この実装において重要なのは、`WriteCommandAction` の内部で処理が完結することだ。これにより、IDEのUndoスタックに統合され、開発者は「IDEの標準機能」として安心して使用できる。

—

2. CI/CDパイプラインと同期したプラグイン配布戦略

個別の開発者が手動でプラグインをインストールする時代は終わっている。組織のルールは「コード」として配布されるべきだ。

Gradleを用いたプラグインの自動配布

IntelliJのプロジェクト設定(`.idea/` ディレクトリ)と組み合わせ、特定のプロジェクトを開いた際にのみ有効化される「プロジェクトローカルプラグイン」の構成を推奨する。

// build.gradle.kts (プラグイン配布用の設定)
intellij {
version.set(“2023.2”)
// 社内リポジトリ経由でカスタムプラグインを配布可能にする設定
plugins.set(listOf(“com.intellij.java”))
}

tasks.publishPlugin {
// CIパイプラインから社内Marketplace(JFrog Artifactory等)へ自動デプロイ
token.set(System.getenv(“ORG_MARKETPLACE_TOKEN”))
}

Dockerコンテナによる「IDE開発環境」の完全再現

IntelliJのヘッドレスモードを利用し、CI上で `detekt` や `Checkstyle` だけでなく、独自プラグインの「静的解析精度」をテストする。

Docker上でIDEの検証を実行するスクリプトの断片
開発者が書いたコードをヘッドレスIntelliJに流し込み、
独自プラグインの自動修正が意図したAST変換を行うかを確認する
./gradlew runIdeForUiTests –headless \
-Dplugin.test.path=/workspace/src/test/resources/malformed_code.java \
-Dresult.output=/workspace/build/reports/intention_test.json

—

3. パフォーマンス最適化ハック:Psi解析の重さを制御する

Intention Actionのロジックが重いと、IDEの入力ラグ(タイピングが重くなる現象)に直結する。これを防ぐための鉄則は以下の通りだ。

1. `isAvailable` での早期リターン: 複雑な型解決やインデックス検索は `invoke` まで遅延させる。`isAvailable` は頻繁に呼ばれるため、`PsiElement` の単純な比較だけに留めること。
2. ReadActionの活用: ASTへのアクセスは必ず `ApplicationManager.getApplication().runReadAction` 内で行う。これを怠ると、UIスレッドがロックされ、IDEが「フリーズ」したように見える。
3. インデックスの活用: 大規模なプロジェクトで特定のクラスを探す際は、必ず `StubIndex` を経由する。文字列検索で全ファイルを走査するのは、アーキテクトとして最も避けるべきアンチパターンである。

—

4. 伝説のリードエンジニアからの提言

「自動化」とは単に作業を省くことではない。「組織の知識(ドメイン知識)」をIDEというインターフェースに定着させ、新人エンジニアであってもシニアと同じ設計判断を下せるようにすることだ。

独自のIntention Actionを開発するということは、あなたのチームの「暗黙知」を「IDEの機能」へと昇華させる作業である。この仕組みを一度構築すれば、社内のコーディング規約をドキュメント化して配布する工数はゼロになる。なぜなら、規約を守ることが「最も楽で速い方法」になるからだ。

次は、あなたのチームが持つ「負の設計パターン」をASTの構造として捉え直し、IDEの力でそれを根絶せよ。その先には、コードレビューの時間が劇的に短縮され、本質的なアーキテクチャ設計に集中できる素晴らしいチームの姿があるはずだ。

タイトルとURLをコピーしました