我正在尋找一種方法來找到每個介面方法,只有一個參考
換句話說:已實作但從未呼叫的方法。
我的目標是清理死代碼。
謝謝,
uj5u.com熱心網友回復:
您可以使用 Roslyn 撰寫一個命令列工具來相當容易地做到這一點。將您的專案加載到 中MSBuildWorkspace,探索語意樹以獲取所有方法,然后使用SymbolFinder.FindReferencesAsync查找對每個方法的所有參考,并為每個沒有參考的方法列印警告。
您也可以將其撰寫為 Roslyn 分析器。但是,您不能SymbolFinder在這種情況下使用(您沒有可用的作業區,無論如何對于分析器來說都太慢了),但是您可以使用它RegisterOperationAction來查找呼叫或參考方法的位置,并且在同時RegisterSymbolAction用于查找所有方法,然后將它們放在一起以查找所有未參考的方法。
這樣的事情可能是一個起點。它關心方法是在介面上定義還是從介面實作(一旦您在此處闡明了規則,這將很容易添加),并且它只是經過表面測驗,但它似乎可以作業。
(您需要使用分析器模板創建一個新專案:如果您以前從未撰寫過分析器,請按照教程進行操作)。
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class UnusedMethodAnalyzer : DiagnosticAnalyzer
{
public const string DiagnosticId = "UNUSED";
private const string Category = "Unused Methods";
private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, "Method is not referenced", "Method '{0}' is not referenced", Category, DiagnosticSeverity.Warning, isEnabledByDefault: true);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(Rule); } }
public override void Initialize(AnalysisContext context)
{
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
context.EnableConcurrentExecution();
context.RegisterCompilationStartAction(Analyze);
}
private void Analyze(CompilationStartAnalysisContext context)
{
// Key: IMethodSymbol. Value: true if we've seen a reference to this method, false if we've just seen its definition
var methods = new ConcurrentDictionary<IMethodSymbol, bool>(SymbolEqualityComparer.Default);
context.RegisterOperationAction(ctx =>
{
methods.AddOrUpdate(((IInvocationOperation)ctx.Operation).TargetMethod, true, (_, _) => true);
}, OperationKind.Invocation);
context.RegisterOperationAction(ctx =>
{
methods.AddOrUpdate(((IMethodReferenceOperation)ctx.Operation).Method, true, (_, _) => true);
}, OperationKind.MethodReference);
context.RegisterSymbolAction(ctx =>
{
methods.TryAdd((IMethodSymbol)ctx.Symbol, false);
}, SymbolKind.Method);
context.RegisterCompilationEndAction(ctx =>
{
foreach (var kvp in methods)
{
if (!kvp.Value)
{
var methodSymbol = kvp.Key;
var diagnostic = Diagnostic.Create(Rule, methodSymbol.Locations[0], methodSymbol.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat));
ctx.ReportDiagnostic(diagnostic);
}
}
});
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/455809.html
上一篇:無法在VisualStudio2022Enterprise中安裝GithubCopilot擴展
下一篇:如何找到所有TreeNode?
