Reputation: 18167
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
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
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.
Upvotes: 0
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
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
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
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
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
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