Учитывая список MethodDeclarationSyntax
Я хотел бы собрать все методы в решении, которые вызывают этот метод транзитивно.
Я использовал следующий код:
var methods = new Stack<MethodDeclarationSyntax>();
... // fill methods with original method to start from
var visited = new HashSet<MethodDeclarationSyntax>();
while (methods.Count > 0)
{
var method = methods.Pop();
if (!visited.Add(method))
{
continue;
}
var methodSymbol = (await solution.GetDocument(method.SyntaxTree).GetSemanticModelAsync()).GetDeclaredSymbol(method);
foreach (var referencer in await SymbolFinder.FindCallersAsync(methodSymbol, solution))
{
var callingMethod = (MethodDeclarationSyntax) referencer.CallingSymbol.DeclaringSyntaxReferences[0].GetSyntax();
methods.Push(callingMethod);
}
}
Проблема в том, что MethodDeclarationSyntax
не кажется одноэлементным, поэтому этот цикл работает вечно, снова и снова посещая одни и те же методы.
Какой правильный способ уникальной идентификации MethodDeclarationSyntax
в словаре / Hashset?
Редактировать 1)
В качестве обходного пути я использую следующий MethodDeclarationSyntaxComparer
для инициализации моего HashSet
, но это выглядиточень хрупкий:
private class MethodDeclarationSyntaxComparer: IEqualityComparer<MethodDeclarationSyntax>
{
public bool Equals(MethodDeclarationSyntax x, MethodDeclarationSyntax y)
{
var xloc = x.GetLocation();
var yloc = y.GetLocation();
return xloc.SourceTree.FilePath == yloc.SourceTree.FilePath &&
xloc.SourceSpan == yloc.SourceSpan;
}
public int GetHashCode(MethodDeclarationSyntax obj)
{
var loc = obj.GetLocation();
return (loc.SourceTree.FilePath.GetHashCode() * 307) ^ loc.SourceSpan.GetHashCode();
}
}