1. ホーム
  2. c#

閉じたファイルに対してコード診断のシンタックス・ノード・アクションを動作させるにはどうしたらいいですか?

2023-10-15 16:31:29

質問

Roslyn (in VS2015 Preview) を使用して、コード診断のセットを構築しています。理想的には、通常の言語ルールに違反しているかのように、それらが生成するすべてのエラーが永続的なエラーとして機能するようにしたいと思います。

多くのオプションがありますが、どれも一貫して動作させるのに苦労しています。私は、初歩的な構文ノード アクションを実装することができました。

context.RegisterSyntaxNodeAction(AnalyzeSyntaxNode, SyntaxKind.InvocationExpression);

の中に Initialize メソッドに記述しています。なんと、この診断に違反するファイルを開くと(VSIXプロジェクトを実行しながら)、VS2015はエラーを表示するのです。

  • 正しいコードのビットの下の赤い点線
  • 余白に赤いブロック
  • エラーリストでのエラー

しかし、ファイルを閉じるとエラーは消えます。

を使ってみましたが context.RegisterCompilationEndAction も使ってみましたが、これには2つの問題があります。

  • 矛盾して発火するようです。 通常 を開くと起動しますが、常に起動するわけではありません。クリーンアップ/再構築では起動しませんが、これは奇妙に思えます。
  • 診断が作成されましたが 直接 を作成しましたが、診断機能を実装するために、このような訪問者を使用しています - これは無能かもしれません。

    private static void AnalyzeEndCompilation(CompilationEndAnalysisContext context)
    {
        foreach (var tree in context.Compilation.SyntaxTrees)
        {
            var visitor = new ReportingVisitor(context.Compilation.GetSemanticModel(tree));
            visitor.Visit(tree.GetRoot());
            foreach (var diagnostic in visitor.Diagnostics)
            {
                context.ReportDiagnostic(diagnostic);
            }
        }
    }
    
    

    診断が作成されていることは知っています - ブレークポイントが ReportDiagnostic 行のブレークポイントが何度もヒットしています - しかし、エラーリストには何も表示されません。(一方、同様の ReportDiagnostic をメソッドの開始時に呼び出すか、ファイル パスを含む構文ツリーごとに 1 回呼び出す必要があります。 が行います。 が表示されるようになります)。

私はここで何を間違えているのでしょうか?最初のアプローチ (構文ノードのアクション) は、実現可能であれば理想的です。プロジェクトのプロパティで、コンパイラーが IDE でのインタラクティブな処理だけでなく、プロジェクト全体のコンパイルにもそれを使用するようにする必要があるのでしょうか? これはおそらく、まだ完成していない Roslyn の統合の一部なのでしょうか?

(有用であるなら、クラスの完全なコードを含めることができます - この場合、信号よりもノイズになると思われますが。)

どのように解決するのですか?

閉じたファイルの問題については、開いているファイルまたは閉じたファイルのどちらからでも、すべての診断が報告されるようにすることが私たちの意図です。 プレビューの ToolsOptionsText EditorC#Advanced にそのためのユーザー オプションがあり、閉じたファイルに診断を含めるかどうかを切り替えることができます。 VS 2015がリリースされる前に、これをデフォルトにしたいと考えています。 ただし、このオプションはVS内の解析にのみ適用されることに注意してください。 アナライザーがコンパイラーに渡される場合 (Visual Studio に VSIX をインストールするのではなく、Solution Explorer でアナライザーを追加するか、アナライザー付きのパッケージへの NuGet パッケージ参照を追加する)、コンパイラーがレポートするのは すべて 診断が報告されます。

の 2 番目の問題については RegisterCompilationEndedAnalyzer については、VS 2015 Preview では Visual Studio 内で確実に呼び出されるわけではありません。 これは、メソッド本体内の "local" の変更についてすべてを再分析することを避けるために、いくつかの最適化を行うためです。 同様の理由で、現在、ロケーションで報告されるエラーを報告しません。 で報告されるエラーは報告しません。 メソッド本体で報告されたエラーは報告しません。 最近、VS がより長い時間をかけて完全な再分析を開始するように変更されました。 RegisterCompilationEndedAnalyzer は将来のビルドで確実に呼び出され、場所に関係なくエラーを報告するようになりました。

しかし、あなたの場合、正しいことは SyntaxNodeAnalyzer を使用し続け、閉じたファイルでの診断を有効にするために VS オプションを切り替えて、プロジェクトのコンパイル オプションに診断を添付することです。

これが役に立つことを願っています。