gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-05 07:42:49 33 4
gpt4 key购买 nike

我正在尝试编写一个分析器,我需要使用 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;
}

我听说使用 symbolFinder 是正确的,但我不确定该怎么做。
符号查找器需要一个解决方案,我只能通过 hack 访问它,所以我假设还有另一种方法可以做到这一点。

问题:

  1. 当我尝试查找对一个变量的所有引用时,只返回声明,但我没有找到任何其他引用我该如何解决这个问题?

  2. 一旦我有了引用,我如何确定它是否是一个作业?

最佳答案

我最初找不到任何引用资料,因为我的文档不在正确的解决方案中。分析器没有为您提供获得解决方案的方法,正如@SLaks 所说,出于性能原因,您不应该这样做:

要获得解决方案,您需要在 AnalyzerOptions 中反射(reflect)我已经写了一个答案如何这样做 here

但是,如果需要,您可以执行此操作获取解决方案中的等效符号并解决该问题。这是潜在的危险

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

然后你可以像这样获取引用:

var equivalentSymbol = await GetEquivalentSymbol(context, field, cancellationToken);

var references = await SymbolFinder.FindReferencesAsync(equivalentSymbol, context.GetSolution(), cancellationToken);

关于c# - Roslyn 查找对字段所做的所有分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44164004/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com