最近因为项目需要,要对工程的代码进行统计,网上有很多的代码统计工具,最常用的是<SourceCounter>,但是我发现没有针对我的需求的功能,大多是递归目录、指定文件类型、统计所有代码行数和注释行、空白行等,而我的需求是在此基础之上,还要统计每个文件中方法的个数、每个方法的行数、方法的分级(这里说的分级是指每个方法的代码行数在某个范围内,就对应一个等级)等信息。在网上苦苦搜寻了一阵,发现并没有这样的代码统计工具(也许是我没有找到,呵呵,如果您知道可以告诉我,我可以参考下,互相学习嘛),于是决定自己动手,丰衣足食。
大致的思路就是正则匹配、标记、统计。由于时间紧促,功能不是十分地完善,希望能够通过这篇文章抛砖引玉,来完善这个小程序。废话不多说,直接上代码。
统计方法的个数
public static void CountMethods(string path) { int count = 0; Regex reg = new Regex(@"\s*\w*\s*\w*\s*\w*\s+\w+\([^=!><]*\)(//.*)?\{?$"); string[] lines = File.ReadAllLines(path); for (int i = 0; i < lines.Length; i++) { if (reg.IsMatch(lines[i].ToString())) { count++; } } string info = string.Format("total methods:{0}",count); Tool.Print(info); }
统计方法名称
public static void GetMethodNameAndLines(string path) { string[] input = File.ReadAllLines(path); MatchCollection mc = null; Regex reg = new Regex(@"\s*\w*\s*\w*\s*\w+\s+\w+\([^=!><.]*\)(//.*)?\{?$"); ArrayList al = new ArrayList(); for (int i = 0; i < input.Length; i++) { mc = reg.Matches(input[i]); if (mc.Count > 0) { al.Add(mc[0].ToString()); } } for (int m = 0; m < al.Count; m++) { Console.WriteLine(string.Format("第{0}个方法:{1}",m+1,al[m].ToString())); } Console.ReadLine(); }
正则与栈结合,统计方法行数名称和个数
public static void StackCount(string path) { Stack stack = new Stack(); //ht存放方法名和方法行数 Hashtable ht = new Hashtable(); //指示是否为有效方法行 bool isLine = false; //指示方法是否结束 bool isEnd = false; string methodName = ""; //标记后续是否还有方法 0-无 1-有 int flag = 0; //临时存放方法行数 int count = 0; //方法之外的普通行 int j = 0; //匹配方法名 Regex regMethodName = new Regex(@"\s+\w+\s*\("); //匹配方法开始行 Regex regLineStart = new Regex(@"\s*\w*\s*\w*\s*\w+\s+\w+\([^=!><.]*\)(//.*)?\{?$"); //匹配左大括号 Regex regLeft = new Regex(@"\s+\{"); //匹配右大括号 Regex regRight = new Regex(@"\s+\}"); //存放源码字符串数组 string[] lines = File.ReadAllLines(path); for (int i = 0; i < lines.Length; i++) { if (regLineStart.IsMatch(lines[i])) { Match mc = regMethodName.Match(lines[i].ToString()); methodName = Tool.GetMethodName(mc.ToString()); if (lines[i].ToString().Contains('{')) { stack.Push(lines[i].ToString()); } isLine = true; isEnd = false; flag = 1; count++; } else if (regLeft.IsMatch(lines[i].ToString())) { if (isLine) { count++; stack.Push(lines[i].ToString()); } } else if (regRight.IsMatch(lines[i])) { if (!isEnd) { stack.Pop(); count++; } if (stack.Count == 0) { isLine = false; isEnd = true; if (flag != 0) { ht.Add(methodName, count); count = 0; } else { j++; } flag = 0; } } else if (isLine) { count++; } else { j++; } } foreach (DictionaryEntry de in ht) { Console.WriteLine(de.Key.ToString()); Console.WriteLine(de.Value.ToString()); } Console.ReadLine(); }
最后,附上运行效果图