8323057: Recoverable errors may be reported before unrecoverable errors when annotation processing is skipped
Reviewed-by: vromero
This commit is contained in:
parent
c84af49386
commit
72f199024d
@ -30,7 +30,7 @@ import java.nio.file.FileSystemNotFoundException;
|
||||
import java.nio.file.InvalidPathException;
|
||||
import java.nio.file.ReadOnlyFileSystemException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
@ -41,6 +41,7 @@ import java.util.Queue;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.ToIntFunction;
|
||||
|
||||
import javax.annotation.processing.Processor;
|
||||
import javax.lang.model.SourceVersion;
|
||||
@ -986,10 +987,7 @@ public class JavaCompiler {
|
||||
|
||||
// In case an Abort was thrown before processAnnotations could be called,
|
||||
// we could have deferred diagnostics that haven't been reported.
|
||||
if (deferredDiagnosticHandler != null) {
|
||||
deferredDiagnosticHandler.reportDeferredDiagnostics();
|
||||
log.popDiagnosticHandler(deferredDiagnosticHandler);
|
||||
}
|
||||
reportDeferredDiagnosticAndClearHandler();
|
||||
} finally {
|
||||
if (verbose) {
|
||||
elapsed_msec = elapsed(start_msec);
|
||||
@ -1196,8 +1194,7 @@ public class JavaCompiler {
|
||||
// or other errors during enter which cannot be fixed by running
|
||||
// any annotation processors.
|
||||
if (processAnnotations) {
|
||||
deferredDiagnosticHandler.reportDeferredDiagnostics();
|
||||
log.popDiagnosticHandler(deferredDiagnosticHandler);
|
||||
reportDeferredDiagnosticAndClearHandler();
|
||||
return ;
|
||||
}
|
||||
}
|
||||
@ -1233,8 +1230,7 @@ public class JavaCompiler {
|
||||
// processing
|
||||
if (!explicitAnnotationProcessingRequested()) {
|
||||
log.error(Errors.ProcNoExplicitAnnotationProcessingRequested(classnames));
|
||||
deferredDiagnosticHandler.reportDeferredDiagnostics();
|
||||
log.popDiagnosticHandler(deferredDiagnosticHandler);
|
||||
reportDeferredDiagnosticAndClearHandler();
|
||||
return ; // TODO: Will this halt compilation?
|
||||
} else {
|
||||
boolean errors = false;
|
||||
@ -1268,8 +1264,7 @@ public class JavaCompiler {
|
||||
}
|
||||
}
|
||||
if (errors) {
|
||||
deferredDiagnosticHandler.reportDeferredDiagnostics();
|
||||
log.popDiagnosticHandler(deferredDiagnosticHandler);
|
||||
reportDeferredDiagnosticAndClearHandler();
|
||||
return ;
|
||||
}
|
||||
}
|
||||
@ -1286,10 +1281,7 @@ public class JavaCompiler {
|
||||
}
|
||||
} catch (CompletionFailure ex) {
|
||||
log.error(Errors.CantAccess(ex.sym, ex.getDetailValue()));
|
||||
if (deferredDiagnosticHandler != null) {
|
||||
deferredDiagnosticHandler.reportDeferredDiagnostics();
|
||||
log.popDiagnosticHandler(deferredDiagnosticHandler);
|
||||
}
|
||||
reportDeferredDiagnosticAndClearHandler();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1859,6 +1851,18 @@ public class JavaCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
public void reportDeferredDiagnosticAndClearHandler() {
|
||||
if (deferredDiagnosticHandler != null) {
|
||||
ToIntFunction<JCDiagnostic> diagValue =
|
||||
d -> d.isFlagSet(RECOVERABLE) ? 1 : 0;
|
||||
Comparator<JCDiagnostic> compareDiags =
|
||||
(d1, d2) -> diagValue.applyAsInt(d1) - diagValue.applyAsInt(d2);
|
||||
deferredDiagnosticHandler.reportDeferredDiagnostics(compareDiags);
|
||||
log.popDiagnosticHandler(deferredDiagnosticHandler);
|
||||
deferredDiagnosticHandler = null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Close the compiler, flushing the logs
|
||||
*/
|
||||
public void close() {
|
||||
|
@ -1268,9 +1268,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
// we're specifically expecting Abort here, but if any Throwable
|
||||
// comes by, we should flush all deferred diagnostics, rather than
|
||||
// drop them on the ground.
|
||||
deferredDiagnosticHandler.reportDeferredDiagnostics();
|
||||
log.popDiagnosticHandler(deferredDiagnosticHandler);
|
||||
compiler.setDeferredDiagnosticHandler(null);
|
||||
compiler.reportDeferredDiagnosticAndClearHandler();
|
||||
throw t;
|
||||
} finally {
|
||||
if (!taskListener.isEmpty())
|
||||
|
@ -27,6 +27,7 @@ package com.sun.tools.javac.util;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
@ -172,6 +173,16 @@ public class Log extends AbstractLog {
|
||||
}
|
||||
deferred = null; // prevent accidental ongoing use
|
||||
}
|
||||
|
||||
/** Report selected deferred diagnostics. */
|
||||
public void reportDeferredDiagnostics(Comparator<JCDiagnostic> order) {
|
||||
JCDiagnostic[] diags = deferred.toArray(s -> new JCDiagnostic[s]);
|
||||
Arrays.sort(diags, order);
|
||||
for (JCDiagnostic d : diags) {
|
||||
prev.report(d);
|
||||
}
|
||||
deferred = null; // prevent accidental ongoing use
|
||||
}
|
||||
}
|
||||
|
||||
public enum WriterKind { NOTICE, WARNING, ERROR, STDOUT, STDERR }
|
||||
|
110
test/langtools/tools/javac/processing/errors/TestErrorOrder.java
Normal file
110
test/langtools/tools/javac/processing/errors/TestErrorOrder.java
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8323057
|
||||
* @summary javac should print not-recoverable errors before recoverable errors
|
||||
* @library /tools/lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* @build toolbox.TestRunner toolbox.ToolBox TestErrorOrder
|
||||
* @run main TestErrorOrder
|
||||
*/
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
import javax.annotation.processing.RoundEnvironment;
|
||||
import javax.annotation.processing.SupportedAnnotationTypes;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
|
||||
import toolbox.JavacTask;
|
||||
import toolbox.Task;
|
||||
import toolbox.Task.Expect;
|
||||
import toolbox.TestRunner;
|
||||
import toolbox.TestRunner.Test;
|
||||
import toolbox.ToolBox;
|
||||
|
||||
public class TestErrorOrder extends TestRunner {
|
||||
public static void main(String... args) throws Exception {
|
||||
new TestErrorOrder().runTests(m -> new Object[] { Paths.get(m.getName()) });
|
||||
}
|
||||
|
||||
private final ToolBox tb = new ToolBox();
|
||||
|
||||
public TestErrorOrder() {
|
||||
super(System.err);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testErrorsAfter(Path outerBase) throws Exception {
|
||||
Path src = outerBase.resolve("src");
|
||||
tb.writeJavaFiles(src,
|
||||
"package t;\n" +
|
||||
"public class T {\n" +
|
||||
" public void test(Undefined u) { }\n" +
|
||||
" \n" +
|
||||
" @SuppressWarnings(\"\")\n" +
|
||||
" @SuppressWarnings(\"\")\n" +
|
||||
" public void test() { }\n" +
|
||||
"}");
|
||||
Path classes = outerBase.resolve("classes");
|
||||
Files.createDirectories(classes);
|
||||
List<String> actual = new JavacTask(tb)
|
||||
.outdir(classes.toString())
|
||||
.options("-XDrawDiagnostics",
|
||||
"-processor", "TestErrorOrder$P",
|
||||
"-processorpath", System.getProperty("test.classes"))
|
||||
.files(tb.findJavaFiles(src))
|
||||
.run(Expect.FAIL)
|
||||
.writeAll()
|
||||
.getOutputLines(Task.OutputKind.DIRECT);
|
||||
List<String> expected = List.of(
|
||||
"T.java:6:5: compiler.err.duplicate.annotation.missing.container: java.lang.SuppressWarnings",
|
||||
"T.java:3:22: compiler.err.cant.resolve.location: kindname.class, Undefined, , , (compiler.misc.location: kindname.class, t.T, null)",
|
||||
"2 errors"
|
||||
);
|
||||
|
||||
tb.checkEqual(expected, actual);
|
||||
}
|
||||
|
||||
@SupportedAnnotationTypes("*")
|
||||
public static class P extends AbstractProcessor {
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceVersion getSupportedSourceVersion() {
|
||||
return SourceVersion.latest();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user