首页 > 学院 > 开发设计 > 正文

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

2019-11-17 03:12:59
字体:
来源:转载
供稿:网友

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

最近因为项目需要,要对工程的代码进行统计,网上有很多的代码统计工具,最常用的是<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.VEVb.com/xhb-bky-blog/p/3677874.html

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


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表