解析javac编译错误

时间:2015-02-20 11:29:08

标签: java parsing javac

我已经做了很多环顾四周,似乎无法找到解析javac编译错误的现有库。我正在考虑自己实现一个“javac错误解析器”,但我可以预见它可能不会直接转发(需要考虑很多位)。

我没有使用ant进行构建(这有很多原因),但我可以像这样收集javac的输出:

Something.java:1: error: Something is not abstract and does not override abstract method foo(boolean) in InterfaceSomething
public class Something implements InterfaceSomething{
       ^
Something.java:49: error: incompatible types: int cannot be converted to Something[]
        return baz;
               ^
Something.java:55: error: incompatible types: int cannot be converted to Something[]
        return baz;
               ^
Note: Something.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
3 errors

理想情况下,我想要一个包含“错误”列表的对象。每个“错误”都有文件名,行号,说明和代码段。

例如,在这种情况下,错误0将成立:

A String filename = "Something.java"
An int lineNum = 1
A String description = "Something is not abstract and....."
A String codeSnippet ="public class Something implements InterfaceSomething{"

在尝试解析过去的很多事情之后,我意识到这通常是一项相当大的工作,因为总会出现一些输出略有不同或不期望的情况(因此我正在寻找有人花费的库)考虑到这些情况可以节省我重新发明轮子的时间相当长。)

我找不到这个似乎很奇怪。有什么想法吗?

编辑:重要 - 我不是要求任何人为我这样做,我完全有能力自己做,我只是想要任何有关已经存在的任何想法或建议。我不是在回答包括代码在内的答案,但也许是建议这个输出的格式规则的答案,或者是指向一些我无法找到的现有库。

1 个答案:

答案 0 :(得分:2)

我认为JavaCompilerDiagnostic类是您要检查的内容。

以下是我早期项目中的一些代码

public String compile(String source, Object... options) {
    String className = getMainClassName(source);

    if (className == null) {
        throw new WrongSourceStructureException("No public class which implements 'Solution'");
    }

    javax.tools.JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

    if (compiler == null)
        throw new BadEnvironmentException("You should specify path to JDK in your JDK_HOME and JAVA_HOME");

    Writer err = new StringWriter();
    DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
    List<String> compilerOptions = new ArrayList<String>();

    String[] opts = new String[options.length - 1];
    System.arraycopy(options, 1, opts, 0, opts.length);

    if (options != null) {
        compilerOptions.addAll(Arrays.asList(opts));
    }

    compilerOptions.add("-d");
    compilerOptions.add("./tmp/classes/");

    JavaFileObject codeSolution = new JavaSourceFromString(className, source);

    Iterable<? extends JavaFileObject> units = Arrays.asList(codeSolution);
    javax.tools.JavaCompiler.CompilationTask task = compiler.getTask(err, null, diagnostics, compilerOptions, null, units);

    boolean success = task.call();

    if (!success) {
        StringBuilder errorMessages = new StringBuilder();
        for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
            errorMessages.append(diagnostic.getMessage(null)).append("\n");
        }
        throw new NotCompiledException(errorMessages.toString());
    }

    String aPackage = getPackage(source);

    return ".tmp/classes/" + options[0] + aPackage.replace(".", "/") + "/" + className + ".class";
}

此外,还有commons-jci,它可能比标准JavaCompiler更清晰。

相关问题