【问题标题】:Line number counter using java AST parser使用 java AST 解析器的行号计数器
【发布时间】:2015-03-21 20:39:59
【问题描述】:

我有一些有趣的练习 - 用 Ja​​va 读取 .java 文件,找到这个 .java 文件中的每个代码部分(如方法等),并说出每个方法中有多少行号,没有空格和 cmets并且还可以找到每个方法中的项目数。

这是我使用的一些示例 - Java Parser 也是如此。通过代码,我可以说出我在方法中有多少行号,但不能删除空格和 cmets 的数量。有人可以帮我吗?

代码:

public static void main(String[] args) throws ParseException, IOException {
    File f = new File(".").getAbsoluteFile();
    File srcRoot = new File(f, "src");
    String srcFilename = TestMethodLineNumber.class.getName().replaceAll("\\.", "/") + ".java";
    File src = new File(srcRoot, srcFilename);
    System.out.println(f);
    System.out.println(srcRoot);
    System.out.println(src);
    getMethodLineNumbers(src);
}

private static void getMethodLineNumbers(File src) throws ParseException, IOException {
    CompilationUnit cu = JavaParser.parse(src);
    new MethodVisitor().visit(cu, null);
}

/**
 * Simple visitor implementation for visiting MethodDeclaration nodes.
 */
private static class MethodVisitor extends VoidVisitorAdapter {
    @Override
    public void visit(MethodDeclaration m, Object arg) {
        System.out.println("From [" + m.getBeginLine() + "," + m.getBeginColumn() + "] to [" + m.getEndLine() + ","
                + m.getEndColumn() + "] is method:");
        System.out.println(m);
    }
}

}

【问题讨论】:

  • 欢迎来到 SO。请阅读How to Ask。您的问题是“为什么精简代码不起作用?”输入,而您还没有达到质量标准,所以我投票结束您的问题。
  • @EngineerDollery:他没有问为什么他的代码不起作用;他展示了计算答案的代码,他希望改进该答案。他想要一些关于如何改进他的答案的建议。
  • @akyurkchiev:您的代码使用方法的最左侧和最右侧节点计算大小。它不做的是下降进入树以查找cmets或空格并调整答案的方法;本质上,您需要遍历子树并检查代码叶之间的位置间隙。虽然我已经用另一个解析器/AST 系统做到了这一点,但我不是 AST Java 解析器专家,所以我无法为您提供太多细节;我敢肯定其他一些有进取心的人可能可以。
  • @IraBaxter -- 我已经形成了不同的意见,但我会向你更大的智慧低头,谢谢你的提醒。
  • 如果我没有正确发布我的问题,我感到非常抱歉。 @IraBaxter 是对的,我只是寻求一些建议来改进我的代码 - 只计算代码并排除 cmets 和空格。我将不胜感激任何帮助或建议 :)

标签: java abstract-syntax-tree


【解决方案1】:

在我看来,JavaParser 已经删除了空行,我将使用该线程 Removing all types of comments in java file 中的一种技术来删除所有 cmets,然后使用 JavaParser 获取结果。

一般来说,除非您真正研究可执行代码,否则此类问题并不总是很有趣。考虑:

if (a)
{
    runA();
}
else
{
    runB();
}

你的计数将是 8,这究竟告诉你什么?知道有一个 if 语句和/或两个方法调用是否更有趣?你真的需要更好的约束来知道你要做什么:

a ? runA() : b ? runB(): runError("nothing true");

只有一行,但您有 3 个潜在的执行分支。您还可能会遇到一些跨越多行的非常疯狂的语句。

MyFancyObject myFancyObject = new MyFancyObject("This is my really long name",
                                                123113212,
                                                "2014-11-20 18:43:12",
                                                anotherArg, yetAnother,
                                                moar);

这应该是 5 行还是 1 行?

【讨论】:

  • 我认为你没有回答他的问题。
  • 他的问题是“有人可以帮助我吗?”更普遍的问题是关于删除空格(在我的回答中是不需要的)和删除 cmets(在我的回答中)。
  • 他不想删除空格。他想计数方法中的空白,以便他可以从整个方法的明显行数中减去该计数。
猜你喜欢
  • 1970-01-01
  • 2022-06-27
  • 2011-05-02
  • 1970-01-01
  • 2016-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多