【原创】从另一个角度看代码统计

背景

最近因为项目需要,要对工程的代码进行统计,网上有很多的代码统计工具,最常用的是<SourceCounter>,但是我发现没有针对我的需求的功能,大多是递归目录、指定文件类型、统计所有代码行数和注释行、空白行等,而我的需求是在此基础之上,还要统计每个文件中方法的个数、每个方法的行数、方法的分级(这里说的分级是指每个方法的代码行数在某个范围内,就对应一个等级)等信息。在网上苦苦搜寻了一阵,发现并没有这样的代码统计工具(也许是我没有找到,呵呵,如果您知道可以告诉我,我可以参考下,互相学习),于是决定自己动手,丰衣足食。大致的思路就是正则匹配、标记、统计。由于时间紧促,功能不是十分地完善,希望能够通过这篇文章抛砖引玉,来完善这个小程序。废话不多说,直接上代码

统计方法的个数

 1 public static void CountMethods(string path)
 2 {
 3     int count = 0;
 4     Regex reg = new Regex(@"s*w*s*w*s*w*s+w+([^=!><]*)(//.*)?s*{?$");
 5     string[] lines = File.ReadAllLines(path);
 6     for (int i = 0; i < lines.Length; i++)
 7     {
 8         if (reg.IsMatch(lines[i].ToString()))
 9         {
10             count++;
11         } 
12     }
13     string info = string.Format("total methods:{0}",count);
14     Tool.Print(info);
15 }

统计方法名称

 1 public static void GetMethodNameAndLines(string path)
 2 {
 3     string[] input = File.ReadAllLines(path);
 4     MatchCollection mc = null;
 5     Regex reg = new Regex(@"s*w*s*w*s*w+s+w+([^=!><.]*)(//.*)?s*{?$");
 6     ArrayList al = new ArrayList();
 7     for (int i = 0; i < input.Length; i++)
 8     {
 9         mc = reg.Matches(input[i]);
10         if (mc.Count > 0)
11         {
12             al.Add(mc[0].ToString());
13         }
14     }
15     for (int m = 0; m < al.Count; m++)
16     {
17         Console.WriteLine(string.Format("第{0}个方法:{1}",m+1,al[m].ToString()));
18     }
19     Console.ReadLine();
20 }

正则与栈结合,统计方法行数名称和个数

 1 public static void StackCount(string path)
 2 {
 3     Stack stack = new Stack();
 4     //ht存放方法名和方法行数
 5     Hashtable ht = new Hashtable();
 6     //指示是否为有效方法行
 7     bool isLine = false;
 8     //指示方法是否结束
 9     bool isEnd = false;
10     string methodName = "";
11     //标记后续是否还有方法 0-无 1-有
12     int flag = 0;
13     //临时存放方法行数
14     int count = 0;
15     //方法之外的普通行
16     int j = 0;
17     //匹配方法名
18     Regex regMethodName = new Regex(@"s+w+s*(");
19     //匹配方法开始行
20     Regex regLineStart = new Regex(@"s*w*s*w*s*w+s+w+([^=!><.]*)(//.*)?s*{?$");
21     //匹配左大括号
22     Regex regLeft = new Regex(@"s+{");
23     //匹配右大括号
24     Regex regRight = new Regex(@"s+}");
25     //存放源码字符串数组
26     string[] lines = File.ReadAllLines(path);
27     for (int i = 0; i < lines.Length; i++)
28     {
29         if (regLineStart.IsMatch(lines[i]))
30         {
31             Match mc = regMethodName.Match(lines[i].ToString());
32             methodName = Tool.GetMethodName(mc.ToString());
33             if (lines[i].ToString().Contains('{'))
34             {
35                 stack.Push(lines[i].ToString());
36             }
37             isLine = true;
38             isEnd = false;
39             flag = 1;
40             count++;
41         }
42         else if (regLeft.IsMatch(lines[i].ToString()))
43         {
44             if (isLine)
45             {
46                 count++;
47         //此处避免不规范写法导致的统计失误
48                 if (lines[i].Contains('{') && lines[i].Contains('}'))
49                 {
50                     continue;
51                 }
52                 stack.Push(lines[i].ToString());
53             }
54         }
55         else if (regRight.IsMatch(lines[i]))
56         {    
57             if (!isEnd)
58             {
59                 stack.Pop();
60                 count++;
61             }
62             if (stack.Count == 0)
63             {
64                 isLine = false;
65                 isEnd = true;
66                 if (flag != 0)
67                 {
68           //解决重载方法的重名问题
69                     if (ht.ContainsKey(methodName))
70                     {
71                         //isOverride += 1;
72                         methodName = methodName + "重载+" + i;
73                     }
74             ht.Add(methodName, count);
75                     count = 0;
76                 }
77                 else
78                 {
79                     j++;
80                 }
81                 flag = 0;
82             }
83         }
84         else if (isLine)
85         {
86             count++;
87         }
88         else
89         {
90             j++;
91         }
92     }
93     foreach (DictionaryEntry de in ht)
94     {
95         Console.WriteLine(de.Key.ToString());
96         Console.WriteLine(de.Value.ToString());
97     }
98     Console.ReadLine();
99 } 

最后,附上运行效果图

 作者:悠扬的牧笛

 博客地址:http://www.cnblogs.com/xhb-bky-blog/p/3677874.html

 声明:本博客原创文字只代表本人工作中在某一时间内总结的观点或结论,与本人所在单位没有直接利益关系。非商业,未授权贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文连接。

 
原文地址:https://www.cnblogs.com/xhb-bky-blog/p/3677874.html