Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a LINQ Query Provider for querying C# files?

Tags:

c#

linq

Is there such a thing as a LINQ Query Provider for querying C# files?

I have a Winforms app that I use to assist me in generating code as well as to supplement Visual Studio's editing capabilities for existing code. One thing I would like to be able to do is to query a given class to see if a method exists. Or query for a list of classes, or query for classes with a particular type in the method signature, etc.

Further, I would love to be able to run the usual CRUDs on said C# files, but I realize that this may be out of scope for this question.

SOLVED!

Thanks to the folks who suggested Roslyn, and especially thanks to the code sample provided by Konrad Kokosa below, I was able to get exactly what I needed.

First thing you need to do is download the Roslyn DLLs (I used NuGet). Then query away. Here is another example for getting an alphabetized list of all methods in a class:

static List<string> GetMethodList(string filename, string className)
{
    var syntaxTree = SyntaxTree.ParseFile(filename);
    var root = syntaxTree.GetRoot();
    var @class = root.DescendantNodes().OfType<ClassDeclarationSyntax>().FirstOrDefault(md => md.Identifier.ValueText.Equals(className));
   
    return (List<string>) @class.DescendantNodes().OfType<MethodDeclarationSyntax>().ToList().OrderBy(m => m.Identifier.ValueText).Select(m => m.Identifier.ValueText);
}
like image 212
Matt Cashatt Avatar asked Jan 15 '14 18:01

Matt Cashatt


2 Answers

I've found Roslyn very intuitive. Here is an example of parsing source file for a specified methodName within specified class className:

static void GetClassMethod(string filename, string className, string methodName)
{
    var syntaxTree = SyntaxTree.ParseFile(filename);
    var root = syntaxTree.GetRoot();
    var @class = root.DescendantNodes()
                      .OfType<ClassDeclarationSyntax>()
                      .Where(md => md.Identifier.ValueText.Equals(className))
                      .FirstOrDefault();
    var method = @class.DescendantNodes()
                      .OfType<MethodDeclarationSyntax>()
                      .Where(md => md.Identifier.ValueText.Equals(methodName))
                      .FirstOrDefault();
}

From this example you can easily build querying all classes withing a file.

like image 68
Konrad Kokosa Avatar answered Oct 26 '22 13:10

Konrad Kokosa


Microsoft is working on a project called Roslyn which allows you to interact with C# code via ordinary .NET objects:

http://msdn.microsoft.com/en-us/vstudio/roslyn.aspx

It hasn't been officially released, though, and I'm honestly not sure that it would include things like manipulating the source files (for example, to add a function to a class).

If you're working with code that is already compiled, you could probably use a combination of a few tricks, such as loading an assembly at runtime and then using reflection to interrogate it.

However, I would suggest taking a look at tools that are already available for generating code, like T4 Templates. There might be a better way to solve the underlying problem than interrogating C# source files.

like image 27
Ryan Avatar answered Oct 26 '22 13:10

Ryan