patterncsharpMinor
Using Roslyn to find interfaces within a solution
Viewed 0 times
roslynwithinusingfindinterfacessolution
Problem
The intent of the below code is to find all interfaces within a solution whose fully-qualified names match the given predicate. It seems to work, but as I am new to Roslyn I'm guessing there are things that could be improved. I'd appreciate any pointers.
Here's another approach I tried. I couldn't really see any benefit to doing it this way. It's more verbose and difficult to follow:
```
public static async Task> GetMatchingInterfacesInSolution(string solutionPath, Func predicate)
{
var workspace = MSBuildWorkspace.Create();
var solution = await workspace.OpenSolutionAsync(solutionPath);
var compilations = await Task.WhenAll(solution.Projects.Select(x => x.GetCompilationAsync()));
return compilations
.Select(x => x.Assembly.GlobalNamespace)
.SelectMany(x => FindInterfacesRecursive(x, predicate))
.ToImmutableList();
}
private static IEnumerable FindInterfacesRecursive(INamespaceSymbol @namespace, Func predicate)
{
foreach (var member in @namespace.GetMembers())
{
var childNamespace = member as INamespaceSymbol;
if (childNamespace != null)
{
foreach (var @interface in FindInterfacesRecursive(childNamespace
public async Task> GetMatchingInterfacesInSolution(string solutionPath, Func predicate)
{
var workspace = MSBuildWorkspace.Create();
var solution = await workspace.OpenSolutionAsync(solutionPath);
var compilations = await Task.WhenAll(solution.Projects.Select(x => x.GetCompilationAsync()));
return compilations
.SelectMany(x => x.SyntaxTrees.Select(y => new { Compilation = x, SyntaxTree = y }))
.Select(x => x.Compilation.GetSemanticModel(x.SyntaxTree))
.SelectMany(
x => x
.SyntaxTree
.GetRoot()
.DescendantNodes()
.OfType()
.Select(y => x.GetDeclaredSymbol(y)))
.Where(x => predicate(x.ToDisplayString()))
.ToImmutableList();
}Here's another approach I tried. I couldn't really see any benefit to doing it this way. It's more verbose and difficult to follow:
```
public static async Task> GetMatchingInterfacesInSolution(string solutionPath, Func predicate)
{
var workspace = MSBuildWorkspace.Create();
var solution = await workspace.OpenSolutionAsync(solutionPath);
var compilations = await Task.WhenAll(solution.Projects.Select(x => x.GetCompilationAsync()));
return compilations
.Select(x => x.Assembly.GlobalNamespace)
.SelectMany(x => FindInterfacesRecursive(x, predicate))
.ToImmutableList();
}
private static IEnumerable FindInterfacesRecursive(INamespaceSymbol @namespace, Func predicate)
{
foreach (var member in @namespace.GetMembers())
{
var childNamespace = member as INamespaceSymbol;
if (childNamespace != null)
{
foreach (var @interface in FindInterfacesRecursive(childNamespace
Solution
- Name captured variables as you would name local variables.
- First
SelectManyandSelectcan be merged into a singleSelectMany.
code:
public async Task> GetMatchingInterfacesInSolution(string solutionPath, Func predicate)
{
var workspace = MSBuildWorkspace.Create();
var solution = await workspace.OpenSolutionAsync(solutionPath);
var compilations = await Task.WhenAll(solution.Projects.Select(x => x.GetCompilationAsync()));
return compilations
.SelectMany(compilation => compilation.SyntaxTrees.Select(syntaxTree => compilation.GetSemanticModel(syntaxTree)))
.SelectMany(
semanticModel => semanticModel
.SyntaxTree
.GetRoot()
.DescendantNodes()
.OfType()
.Select(interfaceDeclarationSyntax => semanticModel.GetDeclaredSymbol(interfaceDeclarationSyntax)))
.Where(symbol => predicate(symbol.ToDisplayString()))
.ToImmutableList();
}Code Snippets
public async Task<IImmutableList<ISymbol>> GetMatchingInterfacesInSolution(string solutionPath, Func<string, bool> predicate)
{
var workspace = MSBuildWorkspace.Create();
var solution = await workspace.OpenSolutionAsync(solutionPath);
var compilations = await Task.WhenAll(solution.Projects.Select(x => x.GetCompilationAsync()));
return compilations
.SelectMany(compilation => compilation.SyntaxTrees.Select(syntaxTree => compilation.GetSemanticModel(syntaxTree)))
.SelectMany(
semanticModel => semanticModel
.SyntaxTree
.GetRoot()
.DescendantNodes()
.OfType<InterfaceDeclarationSyntax>()
.Select(interfaceDeclarationSyntax => semanticModel.GetDeclaredSymbol(interfaceDeclarationSyntax)))
.Where(symbol => predicate(symbol.ToDisplayString()))
.ToImmutableList();
}Context
StackExchange Code Review Q#84932, answer score: 4
Revisions (0)
No revisions yet.