Java代码行统计程序

1、统计粒度

能够统计包括:代码行数、注释、空行、总行数。

2、适用的编程语言

目前只测试过Java,其它编程语言暂时未知。

3、代码简析

代码行统计需要考虑的因素包括字符串匹配、编程语言本身的字符串,后者非常重要,往往导致难以发现的bug。该程序的核心在于递归的使用和栈的构造,需要深刻理解递归的原因和栈的几种状态。

4、参考程序

程序一:http://wenku.baidu.com/view/2a3dcbe3524de518964b7dec.html

程序二:http://www.downxia.com/downinfo/11131.html

程序三:https://code.google.com/p/boomworks/wiki/SourceCounterCN   版本:3.5.33.73 - Boom 2011-6-22

5、程序源代码

  1 /**
  2  * LOCStatistics application
  3  * @author 邝翼飞
  4  * @version 1.0
  5  * @date 2015/1/8
  6  */
  7
  8 import java.io.BufferedReader;
  9 import java.io.File;
 10 import java.io.FileReader;
 11 import java.util.Stack;
 12
 13 public class LOCStatistics {
 14     private long numCommentLine = 0;
 15     private long numWhiteLine = 0;
 16     private long numCodeLine = 0;
 17     private long numTotalLine = 0;
 18     private int numCompilationUnit = 0;
 19     private boolean isCommenting = false;
 20
 21     public LOCStatistics(){}
 22
 23     public static void main(String[] args) {
 24         String SRC_DIR = "D:\\InsightViewerTestCases\\MethodSimilarityTest";
 25         LOCStatistics loc = new LOCStatistics();
 26         if(loc.generateResult(new File(SRC_DIR))) {
 27             System.out.println("numCommentLine:\t" + loc.numCommentLine);
 28             System.out.println("numWhiteLine:\t" + loc.numWhiteLine);
 29             System.out.println("numCodeLine:\t" + loc.numCodeLine);
 30             System.out.println("numTotalLine:\t" + loc.numTotalLine);
 31             System.out.println("numCompilationUnit:\t" + loc.numCompilationUnit);
 32         }
 33         else {
 34             System.out.println("Failed to generate results!");
 35         }
 36     }
 37
 38     public boolean generateResult(File dir) {
 39         if(dir==null || !dir.exists() || !dir.isDirectory()) {
 40             return false;
 41         }
 42         isCommenting = false;
 43         File[] files = dir.listFiles();
 44         for(int i = 0; i < files.length; i++) {
 45             if (files[i].isDirectory()) {
 46                 generateResult(files[i]);
 47             }
 48             else {
 49                 try {
 50                     if (files[i].getName().endsWith(".java")) {
 51                         numCompilationUnit++;
 52                         BufferedReader br = new BufferedReader(new FileReader(files[i]));
 53                         String line = br.readLine();
 54                         while (line != null) {
 55                             numTotalLine++;
 56                             LineProperty lineProperty = extractLineProperty(line);
 57                             if(lineProperty.hasComment) {
 58                                 numCommentLine++;
 59                             }
 60                             if(lineProperty.hasCode) {
 61                                 numCodeLine++;
 62                             }
 63                             if(!lineProperty.hasComment && !lineProperty.hasCode) {
 64                                 numWhiteLine++;
 65                             }
 66                             line = br.readLine();
 67                         }
 68                         br.close();
 69                     }
 70                 }
 71                 catch (Exception e) {
 72                     e.printStackTrace();
 73                     return false;
 74                 }
 75             }
 76         }
 77         return true;
 78     }
 79
 80     private LineProperty extractLineProperty(String line) {
 81         line = line.trim();
 82         String subLine = null;
 83         LineProperty lineProperty = new LineProperty();
 84         boolean hasCode = false;
 85         boolean hasComment = false;
 86         if(line.length() == 0) {
 87             return lineProperty;
 88         }
 89         else if(isCommenting == true) {
 90             hasComment = true;
 91             if(line.matches(".*\\*/.*")) {
 92                 isCommenting = false;
 93                 int index = line.indexOf("*/");
 94                 if(line.length() == index + 2) {
 95                     hasCode = false;
 96                 }
 97                 else {
 98                     subLine = line.substring(index + 2);
 99                     lineProperty = extractLineProperty(subLine);
100                     hasCode = lineProperty.hasCode;
101                 }
102             }
103             else {
104                 hasCode = false;
105             }
106         }
107         else if(line.startsWith("//")) {
108             hasComment = true;
109         }
110         else if(line.startsWith("/*") && !line.matches(".{2,}\\*/.*")){
111             hasCode = false;
112             hasComment = true;
113             isCommenting = true;
114         }
115         else if(line.startsWith("/*") && line.matches(".{2,}\\*/.*")) {
116             if(!line.matches(".{2,}\\*/.+")) {
117                 hasCode = false;
118                 hasComment = true;
119             }
120             else {
121                 String tmps = line.substring(2);
122                 subLine = tmps.substring(tmps.indexOf("*/")+2);/*/test*/
123                 lineProperty = extractLineProperty(subLine);
124                 hasCode = lineProperty.hasCode;
125                 hasComment = true;
126             }
127         }
128         else {
129             hasCode = true;
130             int x, y;
131             x = line.indexOf("//");
132             y = line.indexOf("/*");
133             if(x==-1 && y==-1) {
134                 hasComment = false;
135             }
136             else {
137                 Stack<Character> stack = new Stack<Character>();
138                 int count = 0;
139                 for(Character ch: line.toCharArray()) {
140                     count++;
141                     // 首先判断上一个字符是否是转义符 \ 若是,则抛弃该字符
142                     if(!stack.isEmpty() && stack.peek()==‘\\‘) {
143                         stack.pop();
144                         continue;
145                     }
146                     if(ch != ‘"‘){
147                         if(ch == ‘\\‘) {
148                             stack.push(ch);
149                         }
150                         else if(!stack.isEmpty() && stack.peek()==‘"‘) {
151                             continue;
152                         }
153                         else if(ch==‘*‘ || ch==‘/‘) {
154                             if (stack.isEmpty()) {
155                                 stack.push(ch);
156                             }
157                             else {
158                                 if(stack.peek() == ‘/‘) {
159                                     break;
160                                 }
161                                 else {
162                                     stack.push(ch);
163                                 }
164                             }
165                         }
166                     }
167                     else {
168                         if(stack.isEmpty()) {
169                             stack.push(ch);
170                         }
171                         else {
172                             char tmp = stack.peek();
173                             while(tmp!=‘"‘ && !stack.isEmpty()) {
174                                 tmp = stack.pop();
175                             }
176                             if(tmp!=‘"‘ && stack.isEmpty()) {
177                                 stack.push(ch);
178                             }
179                             else {
180                                 while(!stack.isEmpty()) {
181                                     stack.pop();
182                                 }
183                             }
184                         }
185                     }
186                 }
187                 if(count <= line.length()) {
188                     subLine = line.substring(count-2);
189                     lineProperty = extractLineProperty(subLine);
190                     hasComment = lineProperty.hasComment;
191                 }
192                 else {
193                     hasComment = false;
194                 }
195             }
196         }
197         lineProperty.hasCode = hasCode;
198         lineProperty.hasComment = hasComment;
199         return lineProperty;
200     }
201
202     public long getNumCommentLine() {
203         return numCommentLine;
204     }
205
206     public void setNumCommentLine(long numCommentLine) {
207         this.numCommentLine = numCommentLine;
208     }
209
210     public long getNumWhiteLine() {
211         return numWhiteLine;
212     }
213
214     public void setNumWhiteLine(long numWhiteLine) {
215         this.numWhiteLine = numWhiteLine;
216     }
217
218     public long getNumCodeLine() {
219         return numCodeLine;
220     }
221
222     public void setNumCodeLine(long numCodeLine) {
223         this.numCodeLine = numCodeLine;
224     }
225
226     public long getNumTotalLine() {
227         return numTotalLine;
228     }
229
230     public void setNumTotalLine(long numTotalLine) {
231         this.numTotalLine = numTotalLine;
232     }
233
234     public int getNumCompilationUnit() {
235         return numCompilationUnit;
236     }
237
238     public void setNumCompilationUnit(int numCompilationUnit) {
239         this.numCompilationUnit = numCompilationUnit;
240     }
241 }
242
243 class LineProperty
244 {
245     public boolean hasCode = false;
246     public boolean hasComment = false;
247     public LineProperty() {
248         this(false, false);
249     }
250     public LineProperty(boolean hasCode, boolean hasComment) {
251         this.hasCode = hasCode;
252         this.hasComment = hasComment;
253     }
254 }

6、测试用例

 1 import java.util.ArrayList;
 2 import java.util.List;
 3
 4 @SuppressWarnings("rawtypes")
 5 public class MethodSimilarityTest {
 6
 7     public void overLoad(AA a){}
 8     public void overLoad(double x){}
 9     public void overLoad(List list){}
10
11
12
13     public static void main(String[] args) {
14 //        new MethodSimilarityTest().overLoad((new BB()).getAA());
15 //        new MethodSimilarityTest().overLoad(1);
16         new MethodSimilarityTest().overLoad(new ArrayList());
17 /** // sfska */        String s = "/*dls"; // fsdafl
18 /** // sfska */
19         s = "/*dls";
20     }
21
22 }
23
24 class AA
25 {
26     public AA getAA(){return new AA();}
27     public void c(int b){}
28 }
29 class BB extends AA
30 {
31     public BB(){this(1);this.c(1); }
32     public BB(int x){}
33 }

时间: 2024-11-11 06:55:44

Java代码行统计程序的相关文章

Java 代码行统计(转)

package codecounter; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; public class CodeCou

编写maven代码行统计插件

编写maven插件的步骤 创建一个maven-plugin项目:插件本身也是maven项目,只是它的packaging是maven-plugin. 为插件编写目标:每个插件必须包含一个或多个目标,maven称之为Mojo.编写插件时必须提供一个或多个继承自AbstractMojo的类. 为目标提供配置点:大部分maven插件以及其目标都是可配置的,因此在编写Mojo的时候需要注意提供可配置的参数. 编写代码,实现目标. 错误处理以及日志,为客户提供足够的信息. 测试插件 一:创建maven-pl

使用java代码调用exe程序 (包括参数传递)

使用Java代码调用exe 1使用场景 我现在使用eclipse+tomcat的架构建立了web server, 在这个web project中我需要建立一个定时任务,在定时任务中执行本地的一个C#工程生成的exe. 2Java代码 public class MyTask extends TimerTask { public void run() { System.out.println("call at " + (new Date())); // TODO æ­¤å¤?æ·»å? å

Git代码行统计命令集

统计某人的代码提交量,包括增加,删除: git log --author="$(git config --get user.name)" --pretty=tformat: --numstat | gawk '{ add += $1 ; subs += $2 ; loc += $1 - $2 } END { printf "added lines: %s removed lines : %s total lines: %s\n",add,subs,loc }' -

用代码统计java代码行数

public class Tongjidaima { private static int i;//代码总行数 private static int j;//文件个数 public static void main(String[] args) throws IOException { File file = new File("F:\\eclipsework\\Zhansen");//需要统计行数的文件夹路径 traverseFiles(file);//调用递归方法查看.java文件

Mac OS X代码量统计程序(Python版)

方便统计各种平台项目的代码量,主要用到了find指令来进行处理的详情点击打开链接: 源代码下载点击打开链接 源代码如下: # -*- coding: utf-8 -*- ''' Created on Jul 18, 2014 @author: Jayhomzhou @note: 计算注释以及代码的总行数(即代码量) ''' import subprocess def countCodes(codePath, fileTypes): typeStrs = '' for ft in fileType

mac OSX下git代码行统计命令

1.统计某人的代码提交量,包括增加,删除 git log --author="$(git config --get user.name)" --since=2014-07-01 --until=2016-08-01 --pretty=tformat: --numstat | awk '{ add += $1 ; subs += $2 ; loc += $1 - $2 } END { printf "added lines: %s removed lines : %s tota

TensorFlow 代码行统计

https://github.com/tensorflow/tensorflow.git

Python实现代码行数统计工具

我们经常想要统计项目的代码行数,但是如果想统计功能比较完善可能就不是那么简单了, 今天我们来看一下如何用python来实现一个代码行统计工具. 思路:首先获取所有文件,然后统计每个文件中代码的行数,最后将行数相加. 实现的功能: 统计每个文件的行数: 统计总行数: 统计运行时间: 支持指定统计文件类型,排除不想统计的文件类型: 递归统计文件夹下包括子文件件下的文件的行数: 排除空行: # coding=utf-8 import os import time basedir = '/root/sc