でプライベートコンストラクタを自動的に追加します。Sensei
ユーティリティクラスでは、フィールドやメソッドがスタティックである場合、インスタンス化する理由は明らかではありません。
例:UtilityClass utility = new UtilityClass();
以下のコードは、Utilityクラスの簡単な実装です。
public class UtilityClass {
public static final Boolean ULTIMATE_TRUTH = true;
public static boolean getTrue(){
return ULTIMATE_TRUTH;
}
}
このようなコーディングパターンは、静的解析ツールが拾い上げることができますが、問題を解決する能力は供給されないことが多いです。
Sensei を使ってコーディングパターンを特定し、プライベートコンストラクタを自動的に生成して、私がそのクラスをインスタンス化できないようにすることができます。
クラスを検索する
ユーティリティクラスに新しいレシピを追加します。
- スタティッククラス:プライベートコンストラクタの作成
そして最初は、クラスを検索するためのシンプルなマッチャーを作ります。
の検索を行います。
class: {}
これはどんなクラスにもマッチするので、クイックフィックスを書き始めるには十分です。うまくいくクイックフィックスができたら、プライベートコンストラクタを必要とするクラスがある可能性が高いときに、検索がハイライトされるように改良してみます。
クイックフィックス
クイックフィックスでは、プライベートコンストラクタを生成したいと思います。
例のクラスでは次のようになります。
private UtilityClass(){}。
上記のコードを自分のクラスに追加するために、私のQuick FixはMethodを追加し、メソッドの名前はクラスの名前を使用したMustacheテンプレートにします。
availableFixes:
- name: "add private constructor"
actions:
- addMethod:
method: "private {{{ name }}}(){}"
GUI Editorでは、Show Variablesを使ってMustacheテンプレートを作成し、フィールドを編集してprivate modifier、brackets、bracesを追加して、構文的に正しいものにしています。
これで、どのクラスにもプライベートコンストラクタを追加できるようになりました。
QuickFixのプレビューでは、Mustacheのテンプレートを書きながら、生成されたコードを確認できるので助かります。
これで問題を解決することができました。最適なタイミングでレシピが表示されるように、検索条件を改良してみます。
欠落したコンストラクタの検索
理想的には、すべてのクラスに対してエラーのフラグを立てるようなレシピは作りたくありません。そこで、検索条件を追加して、コンストラクタを持たないクラスにのみマッチするようにします。
の検索を行います。
class:
without:
child:
method:
constructor: true
YAMLはGUIとは若干異なります。
GUIでは、コンストラクタの'yes'である子メソッドのないクラスを探すように設定しています。GUIでは'true'の代わりに'yes'を使うことで、少しでも人間に優しいGUIを実現しています。
このレシピは、コンストラクタを持たないクラスに対してのみ表示されます。
原因となりそうなものを絞り込む
そこで、さらに踏み込んで、静的なメソッドやフィールドの存在を確認したいと思います。
コンストラクタのないクラスで、すべてのパブリックスタティックフィールドまたはすべてのパブリックスタティックメソッドを持つクラスを探します。
の検索を行います。
class:
with:
anyOf:
- child:
method:
allOf:
- modifier:"public"
- modifier:"static"
- child:
field:
allOf:
- modifier:"static"
- modifier:"public"
without:
child:
method:
constructor: true
Sensei は、コードを静的に分析してすべてのエラーを報告するのではなく、プログラマーである私を IDE で支援するために使用されているので、このフィルタは、私のコードベースでデフォルトのパブリック コンストラクタを持つ正当な理由があるほとんどのクラスを除外するのに十分です。
プロジェクトによっては、ユーティリティークラスがプライベートメソッドを持っている可能性があるので、「すべて」ではなく「任意の」パブリックスタティックメソッドの存在を探すことにするかもしれません。
- 子:
フィールド:
anyOf:
- 修飾語。"static"
- 修飾子。"public"
ヒント
Sensei は、静的解析ツールを置き換えるためのものではありません。Sensei は、コーディングプロセスや技術に関連する一般的な問題に対して、静的解析ツールを補強することができます。問題を浮き彫りにするのに十分なマッチングを再現し、QuickFixコードを生成することで開発プロセスをサポートします。
私がやろうとしているのは、必要な場面をすべて含んだシンプルなレシピを作ることですが、すべてのクラスで提案されないようにフィルタリングすることです。
今回の場合、プライベートコンストラクタを作成できるかどうかわからなかったので、まずQuickFixを作成しました。その後、検索条件をより具体的にするためにリファクタリングを行いました。
レシピを作るときに、検索の仕方がよくわからないことがあるので、まずそれを解決します。
レシピは、QuickFixのリファクタリングと検索を切り替えながら、段階的に構築していくと作りやすいですね。
---
IntelliJの「Preferences ‾ Plugins」(Mac)または「Settings ‾ Plugins」(Windows)から、「sensei secure code」を検索して、「Sensei 」をインストールできます。
このためのソースコードとレシピは、Secure Code Warrior GitHub アカウントの `sensei-blog-examples` リポジトリの `pojoexamples` モジュールの中にあります。
https://github.com/securecodewarrior/sensei-blog-examples