📄 coverage.java
字号:
/*
* Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
* (license2)
* Initial Developer: H2 Group
*/
package org.h2.test.coverage;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.ArrayList;
/**
* Tool to instrument java files with profiler calls. The tool can be used for
* profiling an application and for coverage testing. This class is not used at
* runtime of the tested application.
*/
public class Coverage {
static final String IMPORT = "import " + Coverage.class.getPackage().getName() + ".Profile";
ArrayList files = new ArrayList();
ArrayList exclude = new ArrayList();
Tokenizer tokenizer;
Writer writer;
Writer data;
String token = "";
String add = "";
String file;
int index;
int indent;
int line;
String last;
String word, function;
boolean perClass;
boolean perFunction = true;
void printUsage() {
System.out.println("Usage:\n" + "- copy all your source files to another directory\n"
+ " (be careful, they will be modified - don't take originals!)\n" + "- java " + getClass().getName()
+ " <directory>\n" + " this will modified the source code and create 'profile.txt'\n"
+ "- compile the modified source files\n" + "- run your main application\n"
+ "- after the application exits, a file 'notCovered.txt' is created,\n"
+ " which contains the class names, function names and line numbers\n"
+ " of code that has not been covered\n\n" + "Options:\n" + "-r recurse all subdirectories\n"
+ "-e exclude files\n" + "-c coverage on a per-class basis\n"
+ "-f coverage on a per-function basis\n" + "<dir> directory name (. for current directory)");
}
public static void main(String[] arg) {
(new Coverage()).run(arg);
}
void run(String[] arg) {
if (arg.length == 0 || arg[0].equals("-?")) {
printUsage();
return;
}
Coverage c = new Coverage();
int recurse = 1;
for (int i = 0; i < arg.length; i++) {
String s = arg[i];
if (s.equals("-r")) {
// maximum recurse is 100 subdirectories, that should be enough
recurse = 100;
} else if (s.equals("-c")) {
c.perClass = true;
} else if (s.equals("-f")) {
c.perFunction = true;
} else if (s.equals("-e")) {
c.addExclude(arg[++i]);
} else {
c.addDir(s, recurse);
}
}
try {
c.data = new BufferedWriter(new FileWriter("profile.txt"));
c.processAll();
c.data.close();
} catch (Exception e) {
e.printStackTrace();
}
}
void addExclude(String file) {
exclude.add(file);
}
boolean isExcluded(String s) {
for (int i = 0; i < exclude.size(); i++) {
if (s.startsWith(exclude.get(i).toString())) {
return true;
}
}
return false;
}
void addDir(String path, int recurse) {
File f = new File(path);
if (f.isFile() && path.endsWith(".java")) {
if (!isExcluded(path)) {
files.add(path);
}
} else if (f.isDirectory() && recurse > 0) {
String[] list = f.list();
for (int i = 0; i < list.length; i++) {
addDir(path + "/" + list[i], recurse - 1);
}
}
}
void processAll() {
int len = files.size();
long time = System.currentTimeMillis();
for (int i = 0; i < len; i++) {
long t2 = System.currentTimeMillis();
if (t2 - time > 1000 || i >= len - 1) {
System.out.println((i + 1) + " of " + len + " " + (100 * i / len) + "%");
time = t2;
}
String fileName = (String) files.get(i);
processFile(fileName);
}
}
void processFile(String name) {
file = name;
int i;
i = file.lastIndexOf('.');
if (i != -1) {
file = file.substring(0, i);
}
while (true) {
i = file.indexOf('/');
if (i < 0) {
i = file.indexOf('\\');
}
if (i < 0) {
break;
}
file = file.substring(0, i) + "." + file.substring(i + 1);
}
if (name.endsWith("Coverage.java") || name.endsWith("Tokenizer.java") || name.endsWith("Profile.java")) {
return;
}
File f = new File(name);
File fileNew = new File(name + ".new");
try {
writer = new BufferedWriter(new FileWriter(fileNew));
Reader r = new BufferedReader(new FileReader(f));
tokenizer = new Tokenizer(r);
indent = 0;
try {
process();
} catch (Exception e) {
r.close();
writer.close();
e.printStackTrace();
printError(e.getMessage());
throw e;
}
r.close();
writer.close();
File backup = new File(name + ".bak");
backup.delete();
f.renameTo(backup);
File copy = new File(name);
fileNew.renameTo(copy);
if (perClass) {
nextDebug();
}
} catch (Exception e) {
e.printStackTrace();
printError(e.getMessage());
}
}
void read() throws Exception {
last = token;
String write = token;
token = null;
tokenizer.initToken();
int i = tokenizer.nextToken();
if (i != Tokenizer.TYPE_EOF) {
token = tokenizer.getString();
if (token == null) {
token = "" + ((char) i);
} else if (i == '\'') {
// mToken="'"+getEscape(mToken)+"'";
token = tokenizer.getToken();
} else if (i == '\"') {
// mToken="\""+getEscape(mToken)+"\"";
token = tokenizer.getToken();
} else {
if (write == null) {
write = "";
} else {
write = write + " ";
}
}
}
if (write == null
|| (!write.equals("else ") && !write.equals("else") && !write.equals("super ")
&& !write.equals("super") && !write.equals("this ") && !write.equals("this")
&& !write.equals("} ") && !write.equals("}"))) {
if (add != null && !add.equals("")) {
writeLine();
write(add);
if (!perClass) {
nextDebug();
}
}
}
add = "";
if (write != null) {
write(write);
}
}
void readThis(String s) throws Exception {
if (!token.equals(s)) {
throw new Exception("Expected: " + s + " got:" + token);
}
read();
}
void process() throws Exception {
boolean imp = false;
read();
do {
while (true) {
if (token == null || token.equals("{")) {
break;
} else if (token.equals(";")) {
if (!imp) {
write(";" + IMPORT);
imp = true;
}
}
read();
}
processClass();
} while (token != null);
}
void processInit() throws Exception {
do {
if (token.equals("{")) {
read();
processInit();
} else if (token.equals("}")) {
read();
return;
} else {
read();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -