C# Roslyn查找对字段所做的所有分配

C# Roslyn查找对字段所做的所有分配,c#,roslyn,analyzer,C#,Roslyn,Analyzer,我正在尝试编写一个分析器,我需要使用Roslyn查找对字段所做的所有分配 private async static Task<bool> VariableDoesNotMutate(SyntaxNodeAnalysisContext context, VariableDeclaratorSyntax firstVariable) { var variableSymbol = context.SemanticModel.GetDeclaredSymbol(firstVariab

我正在尝试编写一个分析器,我需要使用Roslyn查找对字段所做的所有分配

private async static Task<bool> VariableDoesNotMutate(SyntaxNodeAnalysisContext context, VariableDeclaratorSyntax firstVariable)
{
    var variableSymbol = context.SemanticModel.GetDeclaredSymbol(firstVariable);
    var references = await SymbolFinder.FindReferencesAsync(variableSymbol, context.GetSolution());

    foreach (var reference in references)
    {
        //How do I check for assignment?
    }

    //need to filter by assignments
    return references.Count() > 1;
}
专用异步静态任务VariableDoesNotMutate(SyntaxNodeAnalysisContext上下文,variableDeclaratorSyntaxFirstVariable)
{
var variableSymbol=context.SemanticModel.GetDeclaredSymbol(第一个变量);
var references=await SymbolFinder.FindReferencesAsync(variableSync,context.GetSolution());
foreach(引用中的var引用)
{
//我如何检查作业?
}
//需要按作业筛选
返回references.Count()>1;
}
我听说使用symbolFinder是正确的,但我不确定如何做到这一点。
symbol finder需要一个解决方案,我只有通过黑客才能访问该解决方案,因此我假设有另一种方法可以做到这一点

问题:

  • 当我试图找到一个变量的所有引用时,只返回声明,而我没有找到任何其他引用。我如何解决这个问题

  • 一旦我有了推荐信,我如何确定这是否是一项任务


  • 我最初找不到任何引用,因为我的文档不是正确的解决方案。Analyzer不会为您提供解决方案的方法,正如@SLaks所说,出于性能原因,您不应该这样做:

    为了得到解决方案,你需要在分析中进行思考。我已经写了一个答案,如何做到这一点

    但是,如果需要,您可以在解决方案中获得等效符号,并解决该问题。这有潜在的危险

    static async Task<ISymbol> GetEquivalentSymbol(SyntaxNodeAnalysisContext context, FieldDeclarationSyntax field, CancellationToken cancellationToken)
    {
        var solution = context.GetSolution();
        var classDeclaration = field.Ancestors().OfType<ClassDeclarationSyntax>().FirstOrDefault();
        var namespaceDeclaration = field.Ancestors().OfType<NamespaceDeclarationSyntax>().FirstOrDefault();
    
        var className = classDeclaration?.Identifier.ValueText;
    
        var initialVariable = field.Declaration.Variables.FirstOrDefault();
    
        foreach (var project in solution.Projects)
        {
            foreach (var document in project.Documents)
            {
                var semanticModel = await document.GetSemanticModelAsync(cancellationToken);
                var root = await document.GetSyntaxRootAsync(cancellationToken);
                if (null != namespaceDeclaration)
                {
                    var namespaceNode = root.DescendantNodes().OfType<NamespaceDeclarationSyntax>()
                        .FirstOrDefault(node => node.Name.ToString() == namespaceDeclaration.Name.ToString());
                    if (null == namespaceNode)
                    {
                        continue;
                    }
                }
    
                var classNode = root.DescendantNodes()
                    .OfType<ClassDeclarationSyntax>()
                    .FirstOrDefault(node => node.Identifier.ValueText == className);
    
                var desiredField = classNode?.DescendantNodes().OfType<FieldDeclarationSyntax>()
                    .FirstOrDefault(x => x.Declaration.Variables.First().Identifier.ValueText == initialVariable.Identifier.ValueText);
    
                if (desiredField == null)
                {
                    continue;
                }
    
                var symbol = semanticModel.GetDeclaredSymbol(desiredField.Declaration.Variables.FirstOrDefault());
                return symbol;
            }
        }
    
        return null;
    }
    

    您可能在错误的
    解决方案
    实例中搜索。@SLaks当Analyzer没有找到解决方案的公共方法时,如何使用“查找所有分配”来查找符号?出于性能原因,您不能/不应该这样做。
    var equivalentSymbol = await GetEquivalentSymbol(context, field, cancellationToken);
    
    var references = await SymbolFinder.FindReferencesAsync(equivalentSymbol, context.GetSolution(), cancellationToken);