Samselvaprabu
Samselvaprabu

Reputation: 18167

Is there any way to get the list of functions from .cs file?

My manager asked me to get the list of functions available inside each .cs file in our project.

But the number of .cs files are huge.

It is tough to look by manual.

Is there any way to find the function name in .cs files by writing script or code?

Upvotes: 1

Views: 5144

Answers (8)

brz
brz

Reputation: 1959

You can do this with Microsoft.CodeAnalysis.CSharp

The following example should get you going. It assumes you have one class within a namespace:

var output = new List<string>();

var csFilePath = @"C:\File.cs";
var csFileContent = File.ReadAllText(csFilePath);
SyntaxTree tree = CSharpSyntaxTree.ParseText(csFileContent );
CompilationUnitSyntax root = tree.GetCompilationUnitRoot();
var nds = (NamespaceDeclarationSyntax)root.Members[0];
var cds = (ClassDeclarationSyntax) nds.Members[0];

foreach(var ds in cds.Members){
    //Only take methods into consideration
    if(ds is MethodDeclarationSyntax){
        var mds = (MethodDeclarationSyntax) ds;
        
        //Method name
        var methodName = ((SyntaxToken) mds.Identifier).ValueText;
        
        output.Add(methodName);
    }
}

Upvotes: 0

RobertBaron
RobertBaron

Reputation: 2854

In Project Properties, in the Build section, enable XML documentation file. Build your project. The output XML file gives you the list of all classes and their methods, argument names/types, etc.

enter image description here

Upvotes: 0

Sapnandu
Sapnandu

Reputation: 642

I have tried with following code please try this one.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace filedetection
{
class Program
{
    static void Main(string[] args)
    {
        string path = @"D:\projects\projectsfortest\BusinessTest";
        DirectoryInfo d = new DirectoryInfo(path);//Assuming Test is your Folder
        FileInfo[] Files = d.GetFiles("*.cs"); //Getting Text files
        string str = "";
        foreach (FileInfo file in Files)
        {                
            Program program = new Program();
            List<string> allmethord = program.GetAllMethodNames(path+"\\"+file.Name);
            foreach (string methord in allmethord)
            {
                Console.WriteLine(methord);
            }
        }

        Console.ReadKey();
    }

    public List<string> GetAllMethodNames(string strFileName)
    {
        List<string> methodNames = new List<string>();
        var strMethodLines = File.ReadAllLines(strFileName)
                                    .Where(a => (a.Contains("protected") ||
                                                a.Contains("private") ||
                                                a.Contains("public")) &&
                                                !a.Contains("_") && !a.Contains("class"));
        foreach (var item in strMethodLines)
        {
            if (item.IndexOf("(") != -1)
            {
                string strTemp = String.Join("", item.Substring(0, item.IndexOf(")")+1).Reverse());
                strTemp = String.Join("", strTemp.Substring(0, strTemp.IndexOf("  ")).Reverse());
                methodNames.Add(strTemp);                    
            }
        }
        return methodNames.Distinct().ToList();
    }
  }
}

Upvotes: 0

alroc
alroc

Reputation: 28174

Do not create something yourself if someone else has already done the hard work.

Since you have the source code, use a tool like Sandcastle which is designed for generating documentation of the source code. You haven't specified what format the output needs to be, so this may or may not be acceptable.

This is something your project/team should be able to do at any time; someone could add a new method or class 5 minutes after you're finished, making your work obsolete.

Upvotes: 0

ravikanth
ravikanth

Reputation: 25810

Have you looked at Roslyn?

Check the Get-RoslynInfo script cmdlet by Doug Finke: http://www.dougfinke.com/blog/index.php/2011/10/30/analyze-your-c-source-files-using-powershell-and-the-get-roslyninfo-cmdlet/

Upvotes: 4

JTMon
JTMon

Reputation: 3199

Use reflection. If all the files are in the project then you can use:

Type[] types = Assembly.GetExecutingAssembly().GetTypes();
foreach (Type toCheck in toProcess)
{
    MemberInfo[] memberInfos = toCheck.GetMembers(BindingFlags.NonPublic | BindingFlags.Public | OtherBindingFlagsYouMayNeed);
    //Loop over the membersInfos and do what you need to such as retrieving their names
    // and adding them to a file
}

If the project is compiled into a dll then you can use:

Assembly assembly = Assembly.LoadFrom(filePath); //filePath is for the dll
Type[] toProcess = assembly.GetTypes();
//rest of the code is same as above

EDIT: In case you wanted to find out functions per physical file as @BAF mentions, you would get the base directory for the assembly (through .CodeBase), then do a directory tree walk looking for all .cs files and then you would implement a parser that can distinguish method declarations (might need a lexer as well to help with that) inside each file. There is nothing terribly difficult about either but they do require some work and are too complex to include as an answer here. At lease this is the easiest answer that would cover all types of method declarations that I can think of unless someone can suggest an easier way.

Upvotes: 5

Huusom
Huusom

Reputation: 5912

If you can't compile the csharp files to assemblies you'll have to write a parser. It is fairly easy to write a regular expression that matches a method declaration (look at the C# language specification). But you will get som false positives (methods declared in block comments), and you also has to consider getters and setters.

If you have one or more assemblies it is quite easy. You can even use System.Reflection from powershell: [System.Reflection.Assembly]::ReflectionOnlyLoad(..). Or you can use Mono.Cecil for assembly examination.

But if you already have the assemblies then use NDepend. You'll get more code information than you need, and they have a free trial.

Upvotes: 0

LukeHennerley
LukeHennerley

Reputation: 6444

Use reflection as mentioned - this will return only the functions which you have made:

  Assembly a = Assembly.LoadFile("Insert File Path");
  var typesWithMethods = a.GetTypes().Select(x => x.GetMethods(BindingFlags.Public).Where(y => y.ReturnType.Name != "Void" &&
                                                    y.Name != "ToString" &&
                                                    y.Name != "Equals" &&
                                                    y.Name != "GetHashCode" &&
                                                    y.Name != "GetType"));
  foreach (var assemblyType in typesWithMethods)
  {
    foreach (var function in assemblyType)
    {
      //do stuff with method
    }
  }

You will have a list of types and then within each type, a list of functions.

  public class TestType
  {
    public void Test()
    {

    }
    public string Test2()
    {
      return "";
    }
  }

Using the above test type, the code I provide will print Test2 because this is a function. Hope this is what you were looking for.

Edit: Obviously then you can filter to public with the binding flags as mentioned in the other post, using the overload in GetMethods().

Upvotes: 0

Related Questions