Does anyone know how to retrieve all available types (the semantic) within a solution? The creation of the compilation out of several projects is easy.
MSBuildWorkspace workspace = MSBuildWorkspace.Create();
var solution = await workspace.OpenSolutionAsync(solutionPath, cancellationToken);
var compilations = await Task.WhenAll(solution.Projects.Select(x => x.GetCompilationAsync(cancellationToken)));
Just iterating over all ClassDeclarations is not enough for me because I want all types and the connection between them.
foreach (var tree in compilation.SyntaxTrees)
{
var source = tree.GetRoot(cancellationToken).DescendantNodes();
var classDeclarations = source.OfType<ClassDeclarationSyntax>();
}
For a given compilation you can reach all available types through Compilation.GlobalNamespace
by iterating over all GetTypeMembers()
and GetNamespaceMembers()
recursively. This is not giving you all the types in the solution, but all types that are available from the current compilation (project) through all its references.
In order not to reinvent the wheel, it is:
IEnumerable<INamedTypeSymbol> GetAllTypes(Compilation compilation) =>
GetAllTypes(compilation.GlobalNamespace);
IEnumerable<INamedTypeSymbol> GetAllTypes(INamespaceSymbol @namespace)
{
foreach (var type in @namespace.GetTypeMembers())
foreach (var nestedType in GetNestedTypes(type))
yield return nestedType;
foreach (var nestedNamespace in @namespace.GetNamespaceMembers())
foreach (var type in GetAllTypes(nestedNamespace))
yield return type;
}
IEnumerable<INamedTypeSymbol> GetNestedTypes(INamedTypeSymbol type)
{
yield return type;
foreach (var nestedType in type.GetTypeMembers()
.SelectMany(nestedType => GetNestedTypes(nestedType)))
yield return nestedType;
}
List<ISymbol> ls = new List<ISymbol>();
foreach (Document d in p.Documents)
{
SemanticModel m = d.GetSemanticModelAsync().Result;
List<ClassDeclarationSyntax> lc = d.GetSyntaxRootAsync().Result.DescendantNodes().OfType<ClassDeclaractionSyntax>().ToList();
foreach ( var c in lc )
{
ISymbol s = m.GetDeclaredSymbol(c);
ls.Add(s);
}
}
Once you can access the solution, it is:
IEnumerable<INamedTypeSymbol> types =
solution
.Projects
.SelectMany(project => project.Documents)
.Select(document =>
new
{
Model = document.GetSemanticModelAsync().Result,
Declarations = document.GetSyntaxRootAsync().Result
.DescendantNodes().OfType<TypeDeclarationSyntax>()
})
.SelectMany(pair =>
pair.Declarations.Select(declaration =>
pair.Model.GetDeclaredSymbol(declaration) as INamedTypeSymbol));
来源:https://stackoverflow.com/questions/37327056/retrieve-all-types-with-roslyn-within-a-solution