I'll explain the situation with an example.
Suppose I have created a Roslyn Analyzer which throws Error when Class name is TestClass. Analyzer code is as below:
public override void Initialize(AnalysisContext context)
{
context.RegisterSyntaxNodeAction(Method, SyntaxKind.ClassDeclaration);
}
private static void Method(SyntaxNodeAnalysisContext context)
{
var node = (ClassDeclarationSyntax)context.Node;
var name = node.TryGetInferredMemberName();
if(name == "TestClass")
{
context.ReportDiagnostic(Diagnostic.Create(Rule, context.Node.GetLocation()));
}
}
So i install the Analyzer nupkg in some ConsoleApp project. Console project has following code in Program.cs file
using System;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
class TestClass
{
static void test()
{
Console.WriteLine("TestClass");
}
}
}
Now if i build the ConsoleApp project in Visual Studio then i get Error as "TestClass name not to be used" which is fine. But when i try to build the same project using msbuild command in Developer Command Prompt for VS 2017 i don't see any error from Analyzer. I want that all the errors shown in Error list in VS should be shown in Dev Cmd.
My end goal is to create a stand-alone code analysis tool project and then use MSBuildWorkspace to compile ConsoleApp project and get the analyzer errors/warnings. Part of code is as below:
var filePath = @"C:\Users\user\repos\ConsoleApp\ConsoleApp.sln";
var msbws = MSBuildWorkspace.Create();
var soln = await msbws.OpenSolutionAsync(filePath);
var errors = new List<Diagnostic>();
foreach (var proj in soln.Projects)
{
var name = proj.Name;
var compilation = await proj.GetCompilationAsync();
errors.AddRange(compilation.GetDiagnostics().Where(n => n.Severity == DiagnosticSeverity.Error).ToList());
}
var count = errors.Count();
Above code does not show errors/warnings from analyzer.
How can i achieve this? Thanks in Advance.
To show analyzer errors/warnings during msbuild in VS Dev Cmd, you just have to pass rebuild switch for example
msbuild Tempsolution.sln /t:rebuild
And for MSBuidlWorkspace, this code worked for me. We have to manually specify the analyzer to use by using compilation.WithAnalyzer(ImmutableArray<DiagnosticAnalyzer>);
.
MSBuildLocator.RegisterDefaults();
var filePath = @"C:\Users\user\repos\ConsoleApp\ConsoleApp.sln";
var msbws = MSBuildWorkspace.Create();
var soln = await msbws.OpenSolutionAsync(filePath);
var errors = new List<Diagnostic>();
foreach (var proj in soln.Projects)
{
var analyzer = proj.AnalyzerReferences.Where(alz => alz.Display.ToLower() == "Your analyzer name").FirstOrDefault();
var compilation = await proj.GetCompilationAsync();
var compWithAnalyzer = compilation.WithAnalyzers(analyzer.GetAnalyzersForAllLanguages());
var res = compWithAnalyzer.GetAllDiagnosticsAsync().Result;
errors.AddRange(res.Where(r => r.Severity == DiagnosticSeverity.Error).ToList());
}
var count = errors.Count();