主にプログラミング関連のメモ帳 ♪(✿╹ヮ╹)ノ
書いてあるコードは自己責任でご自由にどうぞ。記事本文の無断転載は禁止です。
2021/08/23
Visual Studio の PostBuild イベントなどで使うツールで、エラーフォーマットを Visual Studio 側にあわせてあげることで、
それらをエラーリストに綺麗に表示してくれるようになります。
ということで、今日はその実装方法について書いてみます。
今回は Roslyn を使っているアプリで、 C# のシンタックスエラーが発生したケースを考えます。
その場合は、次のようなクラスを作って GetMessage()
の結果を標準エラー出力に投げつけると良いです。
using System;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using SharpX.Compiler.Composition.Interfaces;
namespace SharpX.Compiler.Composition.Abstractions
{
public class VisualStudioCatchError : IError
{
private readonly CapturedType _captured;
private readonly Diagnostic? _diagnostic;
private readonly string? _msg;
private readonly CSharpSyntaxNode? _node;
public VisualStudioCatchError(CSharpSyntaxNode node, string message)
{
_node = node;
_msg = message;
_captured = CapturedType.Node;
}
public VisualStudioCatchError(Diagnostic diagnostic)
{
_diagnostic = diagnostic;
_captured = CapturedType.Diagnostic;
}
public string GetMessage()
{
return _captured switch
{
CapturedType.Diagnostic => GetMessage(_diagnostic!),
CapturedType.Node => GetMessage(_node!, _msg!),
_ => throw new ArgumentOutOfRangeException()
};
}
private static string GetMessage(Diagnostic diagnostic)
{
var path = diagnostic.Location.SourceTree?.FilePath ?? "InMemory.cs";
var position = diagnostic.Location.GetLineSpan().StartLinePosition;
return $"{path}({position.Line + 1},{position.Character}): Error {diagnostic.Id}: {diagnostic.GetMessage()}";
}
private static string GetMessage(CSharpSyntaxNode node, string msg)
{
var path = node.SyntaxTree.FilePath;
var position = node.GetLocation().GetLineSpan().StartLinePosition;
return $"{path}({position.Line + 1},{position.Character}): Error SXC0001: {msg}";
}
private enum CapturedType
{
Node,
Diagnostic
}
}
}
フォーマットとしては FilePath(Line, Column): [Error|Warning]: CODE0000: Error Message
ですね。
Visual Studio 2010 時代の MSDN 記事しか見つかりませんでしたが、これで良い感じに動いたりします。
(Line, Column)
部はオプションだったりしますが、設定するとコードジャンプも効くのでコードを解析して~ってタイプの場合は、設定しておくのを推奨します。
ということで、ではではー