Reputation: 5877
In C# syntax analysis, the PropertyDeclarationSyntax
and MethodDeclarationSyntax
both have an Identifier
property. However, they both inherit from CSharpSyntaxNode
which does not.
I'd like to write a method that can take a CompilationUnitSyntax
object, extract all PropertyDeclarationSyntax
or MethodDeclarationSyntax
objects from it and populate a list with their names. Here's what I have so far:
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System.Linq;
class Program
{
static List<string> GrabNames(CompilationUnitSyntax root)
{
List<MethodDeclarationSyntax> methods = root.DescendantNodes().OfType<MethodDeclarationSyntax>().ToList();
List<string> methodNames = new List<string>();
foreach (MethodDeclarationSyntax method in methods)
{
methodNames.Add(method.Identifier.Text);
}
return methodNames;
}
static void Main(string[] args)
{
string fileContainingCode = "test.cs"; // file path
string CodeAsText = File.ReadAllText(fileContainingCode);
SyntaxTree tree = CSharpSyntaxTree.ParseText(CodeAsText);
CompilationUnitSyntax root = tree.GetCompilationUnitRoot();
List<string> names = GrabNames(root);
}
I can think of one ugly solution, namely to add a string parameter called NodeTypeAsString
and based on its value have two branches of an if
statement do the exact same thing, but then on different types.
However, I'm thinking there has got to be a better/cleaner way. How can I achieve this without duplicating too much code?
Upvotes: 0
Views: 390
Reputation: 8442
I don't think there is a clean OOP-style solution to this problem.
I suggest to use the following function:
string GetIdentifier(SyntaxNode node) => switch node {
PropertyDeclarationSyntax p => p.Identifier,
MethodDeclarationSyntax m => m.Identifier,
_ => throw new NotSupportedException();
}
Use it like so:
var names = root
.DescendantNodes()
.Where(n => n.IsKind(SyntaxKind.PropertyDeclaration)
|| n.IsKind(SyntaxKind.MethodDeclaration))
.Select(GetIdentifier)
.ToArray();
Upvotes: 2