ElixirLSコードアクション:自動修正機能の活用ガイド
コードアクションとは
ElixirLSはElixir言語向けのLanguage Server Protocol(LSP)実装として、コードアクション機能を提供しています。この機能は、コード内の問題点を自動的に検出し、最適な修正案を提示することで、開発者の作業効率を大幅に向上させます。
本記事では、ElixirLSのコードアクション機能の詳細な仕組みから実際の活用方法まで、包括的に解説します。
主要機能と実装例
未使用変数の自動検出
Elixirではアンダースコアで始まる変数は「未使用」であることを明示的に示します。ElixirLSは未使用変数を検出し、自動的にアンダースコアを付加する修正を提案します。
# 修正前
def calculate_square(value) do
squared = value * value
# 警告: "squared"が未使用
IO.puts("計算完了")
end
# 適用後
def calculate_square(value) do
_squared = value * value
IO.puts("計算完了")
end
関数名の類似性提案
存在しない関数を呼び出した場合、ElixirLSは関数名の類似性を計算し、候補をリストアップします。
# 問題のあるコード
defmodule Geometry do
def area do
# Math.circle_area/1は未定義
Math.circle_area(5)
end
end
# 提案される修正:
# - Math.ellipse_area/1
# - Math.calculate_area/1
技術的仕組み
診断情報の処理フロー
コードアクションの処理は、以下の段階を経て実行されます:
- 診断エンジンによる問題検出
- 問題类型の分類とコードアクションへのマッピング
- 修正コードの生成と提示
類似度計算アルゴリズム
関数名候補の選定には、Jaro-Winkler距離アルゴリズムを採用しています。このアルゴリズムは短い文字列間の類似度評価に特화しており、関数名のような識別子に適しています。
| パラメータ | デフォルト値 | 用途 |
|---|---|---|
| 類似度閾値 | 0.77 | 提案する下限 |
| 最大候補数 | 5 | 表示件数上限 |
AST変換によるコード生成
抽象構文木(AST)を操作し、構文的に正しい修正コードを生成します。
# AST変換の概念コード
ast
|> Macro.postwalk(fn
{:., meta, [module, old_func]} ->
{:., meta, [module, new_func]}
other ->
other
end)
実践的な利用シナリオ
シナリオ1:リファクタリング時の変数命名
# 修正前
def validate_input(input) do
temp = check_format(input)
# "temp"が未使用
process_input(input)
end
# 適用後 - 意図的な未使用を示す
def validate_input(input) do
_temp = check_format(input)
process_input(input)
end
シナリオ2:関数呼び出しの誤り修正
# 問題のあるコード
defmodule Statistics do
def mean(list) do
# List.average/1は未定義
List.average([1, 2, 3])
end
end
# 推奨修正:
# - List.foldl/3 と手動計算
# - Enum.sum/1 と Enum.count/1 を組み合わせ
設定とカスタマイズ
コードアクション設定
VS Codeやその他の対応エディタでは、settings.jsonで動作を制御できます。
{
"elixirLS.codeAction": {
"enableUnusedVariableFix": true,
"enableFunctionSuggestions": true,
"similarityThreshold": 0.75
}
}
パフォーマンス最適化設定
| 状況 | 最適化手法 | 効果 |
|---|---|---|
| 大規模プロジェクト | インクリメンタル解析 | メモリ使用量の削減 |
| 連続保存時 | デバウンス処理 | 応答速度の向上 |
| 複雑なモジュール | ASTキャッシュ | 再解析の高速化 |
実装アーキテクチャ
モジュラー構成
ElixirLSのコードアクション機能は、責任分離された複数のモジュールで構成されています。
defmodule ElixirLS.LanguageServer.Providers.CodeAction do
alias ElixirLS.LanguageServer.Providers.CodeAction.UnusedVariableFixer
alias ElixirLS.LanguageServer.Providers.CodeAction.FunctionRenamer
@fixers [UnusedVariableFixer, FunctionRenamer]
def code_actions(source_file, uri, diagnostic) do
Enum.flat_map(@fixers, fn fixer ->
fixer.process(source_file, uri, diagnostic)
end)
end
end
例外処理と堅牢性
defmodule ElixirLS.LanguageServer.Providers.CodeAction.UnusedVariableFixer do
def process(%SourceFile{} = source, uri, diagnostics) do
Enum.flat_map(diagnostics, fn diag ->
case extract_variable_info(diag) do
{:ok, var_name, line} ->
generate_fix(source, uri, line, var_name)
:error ->
[]
end
end)
end
end
ベストプラクティス
警告を放置しない
警告は潜在的な問題を示唆しています。コードアクションを活用して、問題を早期に発見・対処することで、コード品質の維持に寄与します。
# 警告の意味を理解した上で適用
def transform(data) do
result = parse(data) # 結果を使用しない場合
_result = parse(data) # 意図を明確に表現
:ok
end
LSP機能の統合活用
コードアクションは、他のLSP機能(コード補完、定義移動、リファクタリングなど)と連携して、より効率的な開発環境を実現します。
FAQ
修正提案が表示されない
ElixirLSは構文的な問題を主にサポートしています。セマンティックなエラーや複雑なロジックに関する問題は、コードアクションでは対応できない場合があります。
類似度閾値の変更方法
現バージョンでは、ソースコードの定数修正が必要です。将来的には設定ファイルからの変更がサポートされる可能性があります。
パフォーマンスへの影響
コードアクションはオンデマンドで実行されるため、適切な設定下身常駐プロセスへの影響は最小限に抑えられます。
活用のポイント
- 警告アイコンが表示されたら積極的にコードアクションを活用
- 自動適用前に修正内容を確認し、意図を理解する
- チーム内でコードアクションの設定を統一し、コーディングスタイルを維持
ElixirLSのコードアクション機能を効果的に活用することで、Elixir開発の生産性を向上させることができます。日々の開発において積極的に取り入れ、コード品質の維持に役立ててください。