使用Roslyn MSBuildWorkspace项目AddAnalyzerReference不加载分析器

时间:2014-11-13 17:22:29

标签: c# compilation roslyn

我正在处理代码报告项目。 目前,我能够编译解决方案项目,获得与编译相关的诊断等。 当我尝试加载自定义IDiagnosticAnalyzers时出现问题,我尝试使用AnalyzerFileReference和AnalyzerImageReference而没有任何结果,总是我访问项目.Analizers是空的。

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....
}

更新(感谢反馈[Josh Varty])

我尝试过这两种方式:

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);
}

在这两种情况下都加载了分析器,但是当我得到编译并得到诊断信息时,我没有得到与此分析器相关的输出(我认为它们没有在get compilation函数中调用)。

var compilation = newProject.GetCompilationAsync().Result;

var diagnostics =   compilation.GetDiagnostics();

有什么建议吗?

3 个答案:

答案 0 :(得分:1)

正如我评论的那样,大多数Roslyn对象都是不可变的。这意味着像AddAnalyzerReference()这样的方法不会改变项目,而是返回一个新项目。

我没有分析仪来测试这个,但我相信你可以使用以下内容。请注意,我使用的是Solution.AddAnalyzerReference(),而不是您正在使用的那个。

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;

答案 1 :(得分:1)

我找到了办法:

 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();
    }

我发布了一个我使用Roslyn工作的开源项目版本,您可以看到与分析器和codefix相关的代码和其他内容。

https://bitbucket.org/jrierapeiro/codeanalyzer

答案 2 :(得分:1)

我有类似的问题,我在here上回答过。 您必须使用compiling.WithAnalyzer(analyzer),然后使用getDiagnostics()