gpt4 book ai didi

java - 在 Java 中使用 ASTParser 实现 Metric Suite

转载 作者:行者123 更新时间:2023-11-30 03:31:01 25 4
gpt4 key购买 nike

背景 - 下面的问题

我正开始在 Java 中为 Java 实现度量套件,但我担心我的方法不合适。

目前我正在使用 JDT 的 ASTParser对于目录中的每个文件。这开始得很好,我能够收集有关每个类的每个方法的行数和平均行数的信息。这是通过 MethodVisitor 类完成的,该类扩展了 ASTVisitor 并包含方法访问(MethodDeclaration 节点)。

我现在正在尝试计算每种方法的圈复杂度。我已经拆分了方法主体,并拥有一个 ComplexityVisitor,其中包含一个访问(IfStatement 节点)和一个访问(ReturnStatement 节点)。

使用这个结构,我知道代码中有一个 if 语句,但我不确定如何知道有多少层“if else”。我发现唯一有用的方法是 node.getElseStatement() ,但这返回的内容基本上(或在我看来)是一个字符串,因此必须使用正则表达式来了解该语句可以采用的路径数。

所以我的问题是:

有没有办法在使用 eclipses ASTParser 时推断出“if - else if - else”语句中有多少层?

我应该寻找更干净的解决方案,例如 IJavaElement 还是自己解析代码,将关键字放入列表中,然后循环遍历它们。

一些示例代码 - 大部分处于测试阶段

public class Test {

private static List<ClassInfo> klasses = new ArrayList<ClassInfo>();

// Called for every file where str is what the file contains
public static void parse(String str) {
ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setSource(str.toCharArray());
parser.setKind(ASTParser.K_COMPILATION_UNIT);

final CompilationUnit cu = (CompilationUnit) parser.createAST(null);

ClassVisitor cv = new ClassVisitor();
cu.accept(cv);

MethodVisitor methodsVisitor = new MethodVisitor(cu);
cu.accept(methodsVisitor);


ClassInfo klass = new ClassInfo(cv.getClassName(),
cu.getLineNumber(cu.getLength() - 1),
methodsVisitor.getNumberOfMethods(),
methodsVisitor.getAverageLinesPerMethod(),
methodsVisitor.getMethods());

for(int i = 0; i < klass.methods.size(); i++){
parser.setSource(klass.methods.get(i).body.toCharArray());
CyclomaticComplexityVisitor ccv = new CyclomaticComplexityVisitor();

cu.accept(ccv);
}
klasses.add(klass);
}

-

public class MethodVisitor extends ASTVisitor {

private CompilationUnit cu;
private int numberOfMethods;
private int lineCount;

private List<MethodInfo> methods = new ArrayList<MethodInfo>();


public MethodVisitor(CompilationUnit cu){
this.cu = cu;
}

public boolean visit(MethodDeclaration node){
int startPos = cu.getLineNumber(node.getStartPosition());
int endPos = cu.getLineNumber(node.getStartPosition() + node.getLength());

lineCount += (endPos - startPos);
numberOfMethods++;

String methodBody = node.getBody().toString();
MethodInfo m = new MethodInfo(node.getName().getIdentifier(),
(endPos - startPos),
node.getReturnType2());
m.body = methodBody;
methods.add(m);

return true;
}

-

public class CyclomaticComplexityVisitor extends ASTVisitor {

private int complexityScore = 0;
private int edges = 0;
private int nodes = 0;
private int exitPoints = 1;
private boolean firstReturn = true;

public boolean visit(IfStatement node){
System.out.println("THERE WAS AN IF");
String statement = node.toString();
System.out.println(statement);

return true;
}

public boolean visit(ReturnStatement node){
if (firstReturn) {
firstReturn = false;
} else {
exitPoints++;
}
return true;
}

干杯

最佳答案

我不确定这是否能回答您的问题,但为了计算 McCabe 的循环复杂度 (McCC) 指标,您不需要关心 if-else-if 嵌套级别。您只需计算“分支”指令的数量并在末尾加 1 即可。请参阅 User's Guide 中的定义我们的SourceMeter工具:

麦凯布的圈复杂度 (McCC)方法:方法的复杂度,表示为其中独立控制流路径的数量。它代表源代码中可能的执行路径数量的下限,同时它也是实现完整分支测试覆盖所需的最小测试用例数量的上限。度量值的计算方式为以下指令的数量加 1:if、for、foreach、while、do-while、case 标签(属于 switch 指令)、catch、条件语句 (?:)。而且,逻辑“与”(&&) 和逻辑“或”(||) 表达式也会给值加 1,因为它们的短路计算可能会导致取决于第一个操作数的分支。不包括以下指令:else、switch、default label(属于switch指令)、try、finally。

关于java - 在 Java 中使用 ASTParser 实现 Metric Suite,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29039524/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com