我想找到代码中的所有类引用。我已经研究过 Roslyn 及其功能,但我对它的所有功能有点不知所措。我见过的所有示例都以正在读入的小代码片段开始,但我只想将我的代码指向一个程序集,让它发挥魔力。
因此,给定这样的类结构:
class MyClassA { }
class MyClassB
{
void Do()
{
var instance = new MyClassA();
}
}
我真正想要的是找到
MyClassA
和 MyClassB
之间的所有依赖关系(例如 Visual Studio 的“引用”功能,仅在代码中)。我可以将其指向已编译的程序集,也可以指向 proj 或 sln 文件。
更新
我查看了评论中的建议,现在已经构建了类似这样的东西:
class Program
{
static async Task Main(string[] args)
{
using (var workspace = MSBuildWorkspace.Create())
{
var solution = await workspace.OpenSolutionAsync(
"C:\\src\\mySolution.sln");
foreach (var project in solution.Projects)
{
var compilation = await project.GetCompilationAsync();
foreach (var document in project.Documents)
{
var model = document.GetSemanticModelAsync().Result;
}
var symbol = compilation.ResolveType("MyClassA").FirstOrDefault();
if (symbol != null)
{
var references = await SymbolFinder.FindReferencesAsync(symbol, solution);
}
}
}
}
}
public static class Extensions
{
public static IEnumerable<INamedTypeSymbol> ResolveType(this Compilation compilation, string classFullName)
{
return new IAssemblySymbol[] { compilation.Assembly }
.Concat(compilation.References
.Select(compilation.GetAssemblyOrModuleSymbol)
.OfType<IAssemblySymbol>())
.Select(asm => asm.GetTypeByMetadataName(classFullName))
.Where(cls => cls != null);
}
但是,我没有找到任何符号,而且没有一个项目实际上包含文档?我做错了什么。
我也在寻找这个答案。 基于我在互联网上找到的方法参考的逻辑(https://gist.github.com/vendettamit/5a1a71eba84c741b397a#file-referencefinder-cs) 我只是在尝试一些东西:
...
foreach (var project in solution.Projects)
{
foreach (var document in project.Documents)
{
var model = await document.GetSemanticModelAsync();
var methodInvocation = await document.GetSyntaxRootAsync();
ClassDeclarationSyntax? node = null;
try
{
var classesInFile = methodInvocation.DescendantNodes().OfType<ClassDeclarationSyntax>();
node = classesInFile
.Where(x => x.Identifier.Text == myClassname).FirstOrDefault();
if (node == null)
continue;
}
catch (Exception exception)
{
// Swallow the exception of type cast.
// Could be avoided by a better filtering on above linq.
continue;
}
var symbolInfo = model.GetDeclaredSymbol(node);
methodSymbol = symbolInfo;
found = true;
break;
}
if (found) break;
}
最后我不得不使用
var symbolInfo = model.GetDeclaredSymbol(node);
而不是
model.GetSymbolInfo(node).Symbol;