Skip to content

Commit 0cd57e7

Browse files
committed
Try to fix dropped AP warnings
1 parent e796928 commit 0cd57e7

4 files changed

Lines changed: 185 additions & 9 deletions

File tree

src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -688,9 +688,17 @@ public JCTree.JCCompilationUnit parse(String filename) {
688688
* @param filename The name of the file to be parsed.
689689
*/
690690
public JCTree.JCCompilationUnit parse(JavaFileObject filename) {
691+
return parse(filename, false);
692+
}
693+
694+
/** Parse contents of file.
695+
* @param filename The name of the file to be parsed.
696+
* @param silent Blocks task events
697+
*/
698+
public JCTree.JCCompilationUnit parse(JavaFileObject filename, boolean silent) {
691699
JavaFileObject prev = log.useSource(filename);
692700
try {
693-
return parse(filename, readSource(filename));
701+
return parse(filename, readSource(filename), silent);
694702
} finally {
695703
log.useSource(prev);
696704
}
@@ -1024,6 +1032,10 @@ public List<JCCompilationUnit> parseFiles(Iterable<JavaFileObject> fileObjects)
10241032
}
10251033

10261034
public List<JCCompilationUnit> parseFiles(Iterable<JavaFileObject> fileObjects, boolean force) {
1035+
return parseFiles(fileObjects, force, false);
1036+
}
1037+
1038+
public List<JCCompilationUnit> parseFiles(Iterable<JavaFileObject> fileObjects, boolean force, boolean silent) {
10271039
if (!force && shouldStop(CompileState.PARSE))
10281040
return List.nil();
10291041

@@ -1033,7 +1045,7 @@ public List<JCCompilationUnit> parseFiles(Iterable<JavaFileObject> fileObjects,
10331045
for (JavaFileObject fileObject : fileObjects) {
10341046
if (!filesSoFar.contains(fileObject)) {
10351047
filesSoFar.add(fileObject);
1036-
trees.append(parse(fileObject));
1048+
trees.append(parse(fileObject, silent));
10371049
}
10381050
}
10391051
return trees.toList();

src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import java.util.Map.Entry;
3535
import java.util.function.Predicate;
3636
import java.util.regex.*;
37+
import java.util.stream.Collectors;
3738

3839
import javax.annotation.processing.*;
3940
import javax.lang.model.SourceVersion;
@@ -991,6 +992,9 @@ class Round {
991992
/** The set of module-info files to be processed this round. */
992993
List<ModuleSymbol> moduleInfoFiles;
993994

995+
/** All source files from this and previous rounds. */
996+
Set<JavaFileObject> cumulativeSourceFiles;
997+
994998
/** Create a round (common code). */
995999
private Round(int number, Set<JCCompilationUnit> treesToClean,
9961000
Log.DeferredDiagnosticHandler deferredDiagnosticHandler) {
@@ -1019,7 +1023,7 @@ private Round(int number, Set<JCCompilationUnit> treesToClean,
10191023
this(1, treesToClean, deferredDiagnosticHandler);
10201024
this.roots = roots;
10211025
genClassFiles = new HashMap<>();
1022-
1026+
cumulativeSourceFiles = roots.stream().map(JCCompilationUnit::getSourceFile).collect(Collectors.toSet());
10231027
// The reverse() in the following line is to maintain behavioural
10241028
// compatibility with the previous revision of the code. Strictly speaking,
10251029
// it should not be necessary, but a javah golden file test fails without it.
@@ -1035,14 +1039,16 @@ private Round(int number, Set<JCCompilationUnit> treesToClean,
10351039

10361040
/** Create a new round. */
10371041
private Round(Round prev,
1038-
Set<JavaFileObject> newSourceFiles, Map<ModuleSymbol, Map<String,JavaFileObject>> newClassFiles) {
1042+
Set<JavaFileObject> sourceFiles, Map<ModuleSymbol, Map<String,JavaFileObject>> newClassFiles) {
10391043
this(prev.number+1, prev.treesToClean, null);
10401044
prev.newRound();
10411045
this.genClassFiles = prev.genClassFiles;
10421046

1047+
this.cumulativeSourceFiles = new HashSet<>(prev.cumulativeSourceFiles);
1048+
this.cumulativeSourceFiles.addAll(sourceFiles);
10431049
//parse the generated files even despite errors reported so far, to eliminate
10441050
//recoverable errors related to the type declared in the generated files:
1045-
List<JCCompilationUnit> parsedFiles = compiler.parseFiles(newSourceFiles, true);
1051+
List<JCCompilationUnit> parsedFiles = compiler.parseFiles(sourceFiles, true, false);
10461052
roots = prev.roots.appendList(parsedFiles);
10471053

10481054
// Check for errors after parsing
@@ -1196,8 +1202,7 @@ void run(boolean lastRound, boolean errorStatus) {
11961202

11971203
void showDiagnostics(boolean showAll) {
11981204
deferredDiagnosticHandler.reportDeferredDiagnostics(
1199-
ACCEPT_NON_RECOVERABLE_LINTS.and(showAll ? ACCEPT_ALL
1200-
: ACCEPT_NON_RECOVERABLE));
1205+
showAll ? ACCEPT_ALL : ACCEPT_NON_RECOVERABLE.and(ACCEPT_NON_RECOVERABLE_LINTS));
12011206
log.popDiagnosticHandler(deferredDiagnosticHandler);
12021207
compiler.setDeferredDiagnosticHandler(null);
12031208
}
@@ -1322,6 +1327,8 @@ public boolean doProcessing(List<JCCompilationUnit> roots,
13221327
} while (moreToDo && !errorStatus);
13231328

13241329
// run last round
1330+
compiler.parseFiles(round.cumulativeSourceFiles, true, true); // Replay warnings, no events
1331+
// All classes are already entered
13251332
round.run(true, errorStatus);
13261333
round.showDiagnostics(true);
13271334

@@ -1361,7 +1368,13 @@ public boolean doProcessing(List<JCCompilationUnit> roots,
13611368

13621369
if (compiler.continueAfterProcessAnnotations()) {
13631370
round.finalCompiler();
1364-
compiler.enterTrees(compiler.initModules(roots));
1371+
// We already did enterTrees in the final round
1372+
Log.DiagnosticHandler discardHandler = log.new DiscardDiagnosticHandler();
1373+
try {
1374+
compiler.enterTrees(compiler.initModules(roots));
1375+
} finally {
1376+
log.popDiagnosticHandler(discardHandler);
1377+
}
13651378
} else {
13661379
compiler.todo.clear();
13671380
}
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/*
2+
* Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8381654
27+
* @summary AP interference with tokenizer warnings
28+
* @library /tools/lib
29+
* @modules
30+
* jdk.compiler/com.sun.tools.javac.api
31+
* jdk.compiler/com.sun.tools.javac.main
32+
* @build toolbox.ToolBox toolbox.JavacTask
33+
* @run junit ${test.main.class}
34+
*/
35+
36+
37+
import java.nio.file.Files;
38+
import java.nio.file.Path;
39+
import java.util.List;
40+
import java.util.Set;
41+
42+
import javax.annotation.processing.AbstractProcessor;
43+
import javax.annotation.processing.RoundEnvironment;
44+
import javax.annotation.processing.SupportedAnnotationTypes;
45+
import javax.lang.model.SourceVersion;
46+
import javax.lang.model.element.TypeElement;
47+
import org.junit.jupiter.api.BeforeEach;
48+
import org.junit.jupiter.api.TestInfo;
49+
import org.junit.jupiter.params.ParameterizedTest;
50+
import org.junit.jupiter.params.provider.MethodSource;
51+
import toolbox.JavacTask;
52+
import toolbox.Task;
53+
import toolbox.ToolBox;
54+
55+
public class TestParserWarnings {
56+
57+
static boolean[] apOptions() {
58+
return new boolean[] {false, true};
59+
}
60+
61+
final ToolBox tb = new ToolBox();
62+
Path base, src, classes;
63+
64+
@ParameterizedTest @MethodSource("apOptions")
65+
public void testPreviewWarning(boolean useProcessor) throws Exception {
66+
tb.writeJavaFiles(src, """
67+
public record MyRec() {}
68+
""");
69+
70+
JavacTask task = new JavacTask(tb)
71+
.options("--enable-preview",
72+
"-source", Integer.toString(Runtime.version().feature()),
73+
"-XDforcePreview",
74+
"-XDrawDiagnostics")
75+
.files(tb.findJavaFiles(src))
76+
.outdir(classes);
77+
if (useProcessor) {
78+
task.processors(new ProcessorImpl());
79+
}
80+
List<String> log = task
81+
.run()
82+
.writeAll()
83+
.getOutputLines(Task.OutputKind.DIRECT);
84+
85+
List<String> expected = List.of(
86+
"- compiler.note.preview.filename: MyRec.java, DEFAULT",
87+
"- compiler.note.preview.recompile"
88+
);
89+
90+
tb.checkEqual(expected, log);
91+
}
92+
93+
@ParameterizedTest @MethodSource("apOptions")
94+
public void testTextBlockWarning(boolean useProcessor) throws Exception {
95+
tb.writeJavaFiles(src, """
96+
class TextBlockWhitespace {
97+
String m() {
98+
return ""\"
99+
\\u0009\\u0009\\u0009\\u0009tab indentation
100+
\\u0020\\u0020\\u0020\\u0020space indentation and trailing space\\u0020
101+
\\u0020\\u0020\\u0020\\u0020""\";
102+
}
103+
}
104+
""");
105+
106+
JavacTask task = new JavacTask(tb)
107+
.options("-Xlint:text-blocks",
108+
"-XDrawDiagnostics")
109+
.files(tb.findJavaFiles(src))
110+
.outdir(classes);
111+
if (useProcessor) {
112+
task.processors(new ProcessorImpl());
113+
}
114+
List<String> log = task
115+
.run()
116+
.writeAll()
117+
.getOutputLines(Task.OutputKind.DIRECT);
118+
119+
List<String> expected = List.of(
120+
"TextBlockWhitespace.java:3:16: compiler.warn.inconsistent.white.space.indentation",
121+
"TextBlockWhitespace.java:3:16: compiler.warn.trailing.white.space.will.be.removed",
122+
"2 warnings"
123+
);
124+
125+
tb.checkEqual(expected, log);
126+
}
127+
128+
@SupportedAnnotationTypes("*")
129+
private static class ProcessorImpl extends AbstractProcessor {
130+
@Override
131+
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
132+
return false;
133+
}
134+
135+
@Override
136+
public SourceVersion getSupportedSourceVersion() {
137+
return SourceVersion.latest();
138+
}
139+
}
140+
141+
@BeforeEach
142+
public void setUp(TestInfo info) throws Exception {
143+
base = Path.of(".").resolve(info.getTestMethod().get().getName());
144+
if (Files.exists(base)) {
145+
tb.cleanDirectory(base);
146+
}
147+
src = base.resolve("src");
148+
classes = base.resolve("classes");
149+
Files.createDirectories(classes);
150+
}
151+
}

test/langtools/tools/lib/toolbox/ToolBox.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ public void checkEqual(List<String> l1, List<String> l2) throws Error {
151151
String s2 = l2.get(i);
152152
if (!Objects.equals(s1, s2)) {
153153
throw new Error("comparison failed, index " + i +
154-
", (" + s1 + ":" + s2 + ")");
154+
", (" + s1 + ":" + s2 + "), l1.size=" + l1.size() + ", l2.size=" + l2.size());
155155
}
156156
}
157157
throw new Error("comparison failed: l1.size=" + l1.size() + ", l2.size=" + l2.size());

0 commit comments

Comments
 (0)