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

最近因为项目需要,要对工程的代码进行统计,网上有很多的代码统计工具,最常用的是<SourceCounter>,但是我发现没有针对我的需求的功能,大多是递归目录、指定文件类型、统计所有代码行数和注释行、空白行等,而我的需求是在此基础之上,还要统计每个文件中方法的个数、每个方法的行数、方法的分级(这里说的分级是指每个方法的代码行数在某个范围内,就对应一个等级)等信息。在网上苦苦搜寻了一阵,发现并没有这样的代码统计工具(也许是我没有找到,呵呵,如果您知道可以告诉我,我可以参考下,互相学习嘛),于是决定自己动手,丰衣足食。

大致的思路就是正则匹配、标记、统计。由于时间紧促,功能不是十分地完善,希望能够通过这篇文章抛砖引玉,来完善这个小程序。废话不多说,直接上代码。

统计方法的个数

public static void CountMethods(string path)

        {

            int count = 0;

            Regex reg = new Regex(@"\s*\w*\s*\w*\s*\w*\s+\w+\([^=!><]*\)(//.*)?\s*\{?$");

            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+\([^=!><.]*\)(//.*)?\s*\{?$");

            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+\([^=!><.]*\)(//.*)?\s*\{?$");

            //匹配左大括号

            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++;

              //此处避免不规范写法导致的统计失误
                        if (lines[i].Contains('{') && lines[i].Contains('}'))
                        {
                            continue;
                        }

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) {

                //解决重载方法的重名问题
                            if (ht.ContainsKey(methodName))
                            {
                                //isOverride += 1;
                                methodName = methodName + "重载+" + i;
                            }

                 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(); }

最后,附上运行效果图

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

 

 

 

 作者:湫楓 謃箜

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

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

 

你可能感兴趣的:(代码)