目前我已经有了这段代码:
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做了类似的事情,这很容易做 - 但我如何从诊断中的功能中做到这一点?
我错过了一些明显的东西吗?
答案 0 :(得分:1)
您可以简单地使用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相对应的类型 - 该类型应位于层次结构中的某个位置。