1

I'm working on a code report project. Currently, I'm able to compile the solution projects, get the diagnostics related to the compilation, etc.. The problem appears when I try to load my custom IDiagnosticAnalyzers, I've tried to use the AnalyzerFileReference and the AnalyzerImageReference without any result, Always I access the projects.Analizers are empty.

var inmutableArray = (new List<IDiagnosticAnalyzer>
    {
        new VariableEndedWithIdNamedCorrectlyDiagnosticAnalyzer()
    }).ToImmutableArray();
var analyzerImageReference = new AnalyzerImageReference(inmutableArray);

foreach (Project project in solution.Projects)
{                  
    project.AddAnalyzerReference(analyzerImageReference );
    //No analizers loaded....
}

UPDATE (thanks for the feedback [Josh Varty])

I've tried this two ways:

var newProjects = new List<Project>();
foreach (Project project in solution.Projects)
{
    var newSolutionn= solution.AddAnalyzerReference(project.Id, analyzerImageReference);
    newProjects.Add(newSolutionn.Projects.FirstOrDefault(p=> p.Id == project.Id));
}

foreach (Project project in solution.Projects)
{
    var newProject = project.AddAnalyzerReference( analyzerImageReference);
}

In both cases have the analyzers loaded but when I get the compilation and I get the diagnostics, I don't get the output related to this analyzers (I think they are not being called at the get compilation function).

var compilation = newProject.GetCompilationAsync().Result;

var diagnostics =   compilation.GetDiagnostics();

Any suggestions?

Custodio
  • 8,594
  • 15
  • 80
  • 115
jriera
  • 21
  • 3
  • Projects (as with most things in Roslyn) are immutable. So `AddAnalyzerReference()` doesn't mutate the project, but instead returns a new project. See: http://source.roslyn.codeplex.com/#Microsoft.CodeAnalysis.Workspaces/Workspace/Solution/Project.cs,611b8f534848ad4e – JoshVarty Nov 13 '14 at 19:13
  • I have answered the same question [here](https://stackoverflow.com/a/62345679/12759888) – EnigmaticJohn Jun 12 '20 at 14:03

3 Answers3

1

As I commented, most Roslyn objects are immutable. This means methods like AddAnalyzerReference() don't mutate the project, but instead return a new one.

I don't have an analyzer to test this, but I believe you can use the following. Note that I'm using Solution.AddAnalyzerReference() instead of the one you were using.

var inmutableArray =(new List<IDiagnosticAnalyzer>
        {
            new VariableEndedWithIdNamedCorrectlyDiagnosticAnalyzer()
        }).ToImmutableArray();
var analyzerImageReference = new AnalyzerImageReference(inmutableArray);

Solution newSolution = solution;

//We iterate over the original solution
foreach (Project project in solution.Projects)
{                   
    //But we save our work in the newSolution
    newSolution = newSolution.AddAnalyzerReference(project.Id, analyzerImageReference);
}

//Now newSolution should contain all your changes.
//Maybe you want to save this reference?
solution = newSolution;
JoshVarty
  • 9,066
  • 4
  • 52
  • 80
  • I've tried it and it works, however, when I get the compilation, I don't get the results provided from the custom analyzers. Thanks for all. – jriera Nov 14 '14 at 11:22
1

I've found the way to do it:

 public static Task<ImmutableArray<Diagnostic>> GetDiagnosticsAsync(this Compilation compilation, ImmutableArray<DiagnosticAnalyzer> analyzers, AnalyzerOptions options, CancellationToken cancellationToken = default(CancellationToken))
    {
        options = options ?? new AnalyzerOptions(ImmutableArray<AdditionalStream>.Empty, ImmutableDictionary<string, string>.Empty);
        Compilation newCompilation = null;
        var analyzerDriver = AnalyzerDriver.Create(compilation, analyzers, options, out newCompilation, cancellationToken);
        newCompilation.GetDiagnostics(cancellationToken);

        return analyzerDriver.GetDiagnosticsAsync();
    }

I've published a version of the open source project that I've been working using Roslyn, you can see the code and other thing related to analyzers and codefix.

https://bitbucket.org/jrierapeiro/codeanalyzer

jriera
  • 21
  • 3
  • I tried to implement this and VS complained with "AnalyzerDriver is not accesible due to its protection level". Any ideas? – Léster Jul 04 '18 at 20:04
1

I had similar question which i answered over here. You have to use compilation.WithAnalyzer(analyzer) and then getDiagnostics()