ReSharper:パターンによるコード検索

よく使用する検索には、テキストの検索と用途の検索の2種類があります。 ただし、たとえば、式「 s == null || s == String.Empty



」が使用されるコード内のすべての場所など、複雑な言語構造を検索することはできません。 正規表現を使用してテキストの検索を試みることができますが、そのような正規表現は怪しげに見え、おそらく多くの間違いを含むでしょう(たとえば、プログラムのほとんどすべてのポイントでコメントの可能性を考慮しません)。 明らかに、この問題を解決するためには、言語の構文、型システムについて知っていて、開発者がクエリ言語の新しい構文を学ぶことを強制しない他の種類の検索が必要です。





スマート検索



ReSharper 5.0では、新しいタイプの検索「パターンで検索」が登場しました。これにより、テンプレートごとにコードを検索でき、このテンプレートの一部に制限を加えることができます。 たとえば、式の場合は型を指定でき、引数の場合は推定数を指定できます。



特定の例を見てみましょう。 すべての式 " enumerable.Count() > 0



"のコードを調べますenumerable



IEnumerable



型の任意の式です。

Find Usagesを使用してこの問題を解決する場合は、 Count()



メソッドを呼び出します。したがって、数十または数百の呼び出しを目で見る必要があります。これはうんざりし、エラーに満ちています。 テキストの検索は少し良く見えますが、ラインフィード、コメント、およびプロジェクトのCount()



メソッドでさまざまなタイプのオブジェクトを実装することで目的の式を記述できるという事実を考えると、それも機能しないことが明らかになります。



「パターンで検索」ウィンドウを開き(Resharper->検索->パターンで検索)、テキストボックスに次のパターンを入力します。



$enumerable$.Count() > 0







String $enumerable$



-赤で強調表示されます。 実際には、「$」記号はプレースホルダーの名前を囲み、そのようなプレースホルダーの場所を検索している間、指定された制限に一致するテキスト(プレースホルダーのタイプとそのパラメーター)が期待されます。 この場合、 $enumerable$



代わりに、タイプIEnumerable



任意の式を使用できます。 しかし、最初に、このプレースホルダーを定義する必要があります。 これを行うには、「プレースホルダーを追加」をクリックし、「式」を選択して、「名前」フィールドに「 enumerable



」(ドル記号なしのプレースホルダーの名前)を入力します。 「式タイプ」に「 IEnumerable



」と入力します(タイプ名の入力を開始すると、リゾルバーがオプションを通知します)。 「または派生型」ボックスをチェックすることを忘れないでください。



わずか数秒で、正規表現の知識がなくても、検索用のテンプレートを作成しました。 しかし、もう1つ快適で非常に強力なことがあります。テンプレートの編集ボックスの下に、「類似の構造に一致する」チェックマークがあることに注意してください。 このチェックボックスをオンにすると、サンプルと完全に一致するだけでなく、意味的に同一の構造も検索されます。 たとえば、構成要素「 a > 0



」と「 0 < a



」は意味的に同一です。 この場合、 Count()



メソッドの結果がゼロと比較される方法を気にしないため、このチェックボックスを設定したままにしておくのが妥当です。



すべて準備完了です! これで、[検索]ボタンをクリックして結果を確認できます。



スマートな交換



置換関数を使用しないこのような強力な検索は、プログラム内のすべての悪い場所を見つけるだけでなく、それらを正しいコードに置き換えることも興味深いため、完全ではありません。 これを行うには、[パターンで検索]ウィンドウで[置換]ボタンをクリックします。 置換パターンを入力するためのボックスが表示されます。 このフィールドでは、言語の観点から正しいテキストを記述できます。プレースホルダーを使用することもできます。 このフィールドに入力してください:



$enumerable$.Any()







[置換]ボタンをクリックします。



検索パターンからハイライトとQuickFixを作成する



これで、検索テンプレートと置換テンプレートが作成されました。 これからバックライトとQuickFixを作成することは論理的です。 これを行うには、パターン編集ウィンドウの[保存]ボタンをクリックするだけです。 パターンは「パターンカタログ」に保存されます。 このディレクトリは、頻繁に使用されるテンプレートを保存するために使用するか、独自の分析を作成するための強力なツールにすることができます。



カタログ(ReSharper->ツール->パターンカタログ)を開くと、ヒントテキスト、QuickFixに表示されるテキスト、およびパターンのハイライトタイプをカスタマイズできます。 これらのパラメーターをすべてパターンに設定します。



それだけです! バックライトは機能します! これで、テンプレートに一致するすべてのコードがその場で強調表示されます! 対応するQuickFixがバックライトに表示されます!



検索パターンの例



式を単純化する検索パターン:







この例では、タイプ、式、および識別子にプレースホルダーを使用しました。 同時に、彼らはそれらに制限を設定しませんでしたが、置換テンプレートでそれらを使用しました。 制限がある唯一のプレースホルダーは$seq$



で、 IEnumrable



型に制限されます。



そして、ハイライトとQuickFixを実装するパターンは次のとおりです。「 'if'を '?:'に置き換える」:







有用なパターンのアイデアがある場合は、コメントでそれらについて教えてください。 これはコミュニティにとって有用であり、おそらく最も興味深いパターンは次のReSharperパッケージに含まれるでしょう。



ReSharperの拡張機能を簡単かつ迅速に記述します



しかし、それだけではありません。 実際、パターンマッチングを実行するメカニズムは、エンドユーザーが見ることができるよりもはるかに強力です。 現在の制限は、ReSharperチームがUIで特定の側面を正しく表現する方法をまだ理解していないという事実によるものです。 たとえば、現在の実装では、何かが欠落している構造を見つけることは不可能です(たとえば、検証なしのメソッド、または特定の種類のメソッドを呼び出しますが、属性はありません)。 ただし、これはAPIを使用して実行できます。



さらに、このAPIを使用してバックライトまたはQuickFixを記述すると、時間を大幅に節約できます。 ソースコードモデルやその他の微妙な点を真剣に理解する必要はありません。 サンプルをC#構文で記述し、パラメーターを設定して結果を取得します。たとえば、「 'if'を '?:'に置き換えます」の場合、次のコードを記述します。



var myMatcher = searcherFactory

.CreatePattern( "if ($condition$) { $x$ = $expr1$; } else { $x$ = $expr2$; }" )

.AddExpressionPlaceholder( "condition" )

.AddIdentifierPlaceholder( "x" )

.AddExpressionPlaceholder( "expr1" )

.AddExpressionPlaceholder( "expr2" )

.CreateStatementMatcher();




* This source code was highlighted with Source Code Highlighter .








それは非常にシンプルで、最も重要なことには説明なしで明確であり、ReSharperの内部の知識を必要としません。 パターンAPIを使用せずにこのコードの記述を開始した場合、構文ツリーのIIfStatement



IIfStatement



インターフェイス、 IExpression



IReferenceExpression



、式の等価性の比較方法(比較する必要がある)を知る必要があります。式$x$



)の2つの出現、および他の多くの複雑なこと。



モデルに従ってコードを検索し、追加のチェック(たとえば、パターンAPIで検索できない)を実行すると、ハイライトが表示されます!



パターン検索APIは、 StructuralSearchEngine



インターフェースから使用できます。 関心のある人が十分にいる場合は、次の記事で、独自のハイライトとQuickFixを簡単に作成する方法の簡単な例を紹介します。



All Articles