如何在没有符号查找器的诊断中获取符号引用



目前我有这段代码:

    private async Task<bool> IsMentionedInDisposeCallAsync(SyntaxNodeAnalysisContext context, FieldDeclarationSyntax fieldDeclarationSyntax)
    {
        foreach (var variableDeclaratorSyntax in fieldDeclarationSyntax.Declaration.Variables)
        {
            var declaredSymbol = context.SemanticModel.GetDeclaredSymbol(variableDeclaratorSyntax);
            if (declaredSymbol is IFieldSymbol fieldSymbol)
            {
//              SymbolFinder.FindReferencesAsync()
                var b = fieldSymbol.Locations;
//              context.SemanticModel.Compilation.
            }
        }
        return false;
    }

而这个场景:

private static readonly string TestSourceImplementsDisposableAndDoesMentionDisposableField = @"
using System;
using System.IO;
namespace ConsoleApplication1
{
    public class SampleDisposable : IDisposable
    {
        public void Dispose()
        {
        }
    }
    public class SampleConsumer : IDisposable
    {
        private SampleDisposable _disposable = new SampleDisposable();
        private IDisposable _ms = new MemoryStream();
        public void Dispose()
        {
            _disposable?.Dispose();
            _ms?.Dispose();
        }
    }
}";

最终,我的愿望是弄清楚处置方法是否正在访问一次性领域。不幸的是,我似乎找不到一种方法来不使用 SymbolFinder,这需要一个解决方案。

我用 SymbolFinder 做了类似的事情,这是一件容易的事情 - 但是我如何从诊断中可用的功能中做到这一点?

我在这里错过了一些明显的东西吗?

您可以简单地使用 SemanticModel 来分析用于字段的类型,如下所示:

private async Task<bool> IsMentionedInDisposeCallAsync(SyntaxNodeAnalysisContext context, FieldDeclarationSyntax fieldDeclarationSyntax)
{
    foreach (var variableDeclaratorSyntax in fieldDeclarationSyntax.Declaration.Variables)
    {
        var declaredSymbol = context.SemanticModel.GetDeclaredSymbol(variableDeclaratorSyntax);
        if (declaredSymbol is IFieldSymbol fieldSymbol)
        {
            var isDisposeable = CheckIsTypeIDisposeable(fieldSymbol.Type as INamedTypeSymbol);
            //              SymbolFinder.FindReferencesAsync()
            var b = fieldSymbol.Locations;
            //              context.SemanticModel.Compilation.
        }
    }
    return false;
}
private string fullQualifiedAssemblyNameOfIDisposeable = typeof(IDisposable).AssemblyQualifiedName;
private bool CheckIsTypeIDisposeable(INamedTypeSymbol type)
{
    // Identify the IDisposable class. You can use any method to do this here
    // A type.ToDisplayString() == "System.IDisposable" might do it for you
    if(fullQualifiedAssemblyNameOfIDisposeable == 
        type.ToDisplayString() + ", " + type.ContainingAssembly.ToDisplayString())
    {
        return true;
    }
    if(type.BaseType != null)
    {
        if (CheckIsTypeIDisposeable(type.BaseType))
        {
            return true;
        }
    }
    foreach(var @interface in type.AllInterfaces)
    {
        if (CheckIsTypeIDisposeable(@interface))
        {
            return true;
        }
    }
    return false;
}

基本上,您将递归搜索类和基类的所有接口,以找到与 IDisposeable 对应的类型 - 它应该在层次结构中的某个位置。

最新更新