Java - 检查java文件是否写得很好

时间:2016-07-24 12:30:46

标签: java parsing compilation compiler-errors

我的java应用程序必须解析很多java源代码,我正在使用这个解析器https://github.com/javaparser/javaparser

这是我调用另一个解析单个文件的函数的函数:

private static void createSimplifiedAST(String userFolder, String userProjectFolder, ArrayList userProjectFiles){
    File projectDir = new File(usersFolderPath + userFolder + "/" + userProjectFolder);

    // explore all java files inside a directory (user's project folder)
    new DirExplorer((level, path, file) -> path.endsWith(".java"), (level, path, file) -> {
        System.out.println(path);
        System.out.println(Strings.repeat("=", path.length()));

        // create root of simplified AST of user's single file
        TreeNode<String> projectSingleFile = new ArrayMultiTreeNode<String>("projectFileTreeRoot");

        // create simplified AST of user's single file
        declarationNumber = 0;
        forNumber = 0;
        forEachNumber = 0;
        whileNumber = 0;
        try {
            iterateASTNodes(file, projectSingleFile);
        } catch (ParseException ex) {
            Logger.getLogger(JavaSourceCodeParser.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(JavaSourceCodeParser.class.getName()).log(Level.SEVERE, null, ex);
        }

        // prints single file tree
        System.out.println(projectSingleFile);

        // save simplified ASTs to txts
        saveASTToTxt(userFolder, userProjectFolder, file, projectSingleFile);

        // add simplified AST of single file to user's project files array list
        userProjectFiles.add(projectSingleFile);

    }).explore(projectDir);
}

这是解析单个文件的函数:

private static void iterateASTNodes(File file, TreeNode<String> treeNode) throws ParseException, IOException{
    try {
        new NodeIterator(new NodeIterator.NodeHandler() {
            @Override
            public boolean handle(Node node) {
                if (node instanceof VariableDeclarator) {
                    treeNode.add(new ArrayMultiTreeNode<>("declaration" + declarationNumber));
                    declarationNumber++;
                    return false;
                } else if (node instanceof ForStmt) {
                    treeNode.add(new ArrayMultiTreeNode<>("for" + forNumber));
                    forNumber++;
                    iterateASTNodesWrapper(node, treeNode.find("for" + (forNumber - 1)));
                    return false;
                } else if (node instanceof ForeachStmt) {
                    treeNode.add(new ArrayMultiTreeNode<>("foreach" + forEachNumber));
                    forEachNumber++;
                    iterateASTNodesWrapper(node, treeNode.find("foreach" + (forEachNumber - 1)));
                    return false;
                } else if (node instanceof WhileStmt) {
                    treeNode.add(new ArrayMultiTreeNode<>("while" + whileNumber));
                    whileNumber++;
                    iterateASTNodesWrapper(node, treeNode.find("while" + (whileNumber - 1)));
                    return false;
                } else {
                    return true;
                }
            }
        }).explore(JavaParser.parse(file));
    } catch (ParseException | IOException ex) {
        System.err.println("  ERROR: lexical error!");
    }
}

这是NodeIterator类:

public class NodeIterator {
    public interface NodeHandler {
        boolean handle(Node node);
    }

    private NodeHandler nodeHandler;

    public NodeIterator(NodeHandler nodeHandler) {
        this.nodeHandler = nodeHandler;
    }

    public void explore(Node node) {
        if (nodeHandler.handle(node)) {
            for (Node child : node.getChildrenNodes()) {
                explore(child);
            }
        }
    }
}

DirExplorer课程:

public class DirExplorer {
    public interface FileHandler {
        void handle(int level, String path, File file);
    }

    public interface Filter {
        boolean interested(int level, String path, File file);
    }

    private FileHandler fileHandler;
    private Filter filter;

    public DirExplorer(Filter filter, FileHandler fileHandler) {
        this.filter = filter;
        this.fileHandler = fileHandler;
    }

    public void explore(File root) {
        explore(0, "", root);
    }

    private void explore(int level, String path, File file) {
        try {
            if (file.isDirectory()) {
                for (File child : file.listFiles()) {
                    explore(level + 1, path + "/" + child.getName(), child);
                }
            } else {
                if (filter.interested(level, path, file)) {
                    fileHandler.handle(level, path, file);
                }
            }
        } catch (Exception e) {
            System.out.println("  ERROR: something went wrong!\n");
        }
    }
}

当我运行程序时,在某些时候,它会在解析此文件时停止:

public class Test {
    /**<caret>
    public void foo() {
    }
}

我已经理解它因词法错误而停止了,这个:

Exception in thread "main" com.github.javaparser.TokenMgrError: Lexical error at line 6, column 2.  Encountered: <EOF> after : ""
at com.github.javaparser.ASTParserTokenManager.getNextToken(ASTParserTokenManager.java:2480)
at com.github.javaparser.ASTParser.jj_ntk(ASTParser.java:9154)
at com.github.javaparser.ASTParser.ClassOrInterfaceBody(ASTParser.java:829)
at com.github.javaparser.ASTParser.ClassOrInterfaceDeclaration(ASTParser.java:470)
at com.github.javaparser.ASTParser.TypeDeclaration(ASTParser.java:398)
at com.github.javaparser.ASTParser.CompilationUnit(ASTParser.java:203)
at com.github.javaparser.JavaParser.parse(JavaParser.java:111)
at com.github.javaparser.JavaParser.parse(JavaParser.java:158)
at com.github.javaparser.JavaParser.parse(JavaParser.java:177)
at javasourcecodeparser.JavaSourceCodeParser.iterateASTNodes(JavaSourceCodeParser.java:89)
at javasourcecodeparser.JavaSourceCodeParser.lambda$createSimplifiedAST$1(JavaSourceCodeParser.java:178)
at javasourcecodeparser.DirExplorer.explore(DirExplorer.java:35)
at javasourcecodeparser.DirExplorer.explore(DirExplorer.java:31)
at javasourcecodeparser.DirExplorer.explore(DirExplorer.java:31)
at javasourcecodeparser.DirExplorer.explore(DirExplorer.java:31)
at javasourcecodeparser.DirExplorer.explore(DirExplorer.java:31)
at javasourcecodeparser.DirExplorer.explore(DirExplorer.java:31)
at javasourcecodeparser.DirExplorer.explore(DirExplorer.java:31)
at javasourcecodeparser.DirExplorer.explore(DirExplorer.java:31)
at javasourcecodeparser.DirExplorer.explore(DirExplorer.java:24)
at javasourcecodeparser.JavaSourceCodeParser.createSimplifiedAST(JavaSourceCodeParser.java:194)
at javasourcecodeparser.JavaSourceCodeParser.main(JavaSourceCodeParser.java:225)

现在,这个错误会停止整个程序,而我无法解析另一个&#34; good&#34;码。

我想要的是程序必须跳过带有词汇错误的文件并继续解析其他文件。

有什么想法吗?也许只是在编译成功的情况下尝试编译每个文件并解析它?

1 个答案:

答案 0 :(得分:1)

你没有向我们展示堆栈跟踪,但我希望在这个方法调用中抛出异常:

JavaParser.parse(file)

如果是这样,解决方案只是重构代码,以便捕获该调用抛出的异常,然后继续下一个文件。