8283661: Unexpected TypeElement in ANALYZE TaskEvent

Reviewed-by: vromero, jlahoda
This commit is contained in:
Jonathan Gibbons 2022-03-25 21:16:51 +00:00
parent f4fd53d0ae
commit 36b36efa12
3 changed files with 195 additions and 9 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2022, 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
@ -1305,7 +1305,7 @@ public class JavaCompiler {
log.printVerbose("checking.attribution", env.enclClass.sym);
if (!taskListener.isEmpty()) {
TaskEvent e = new TaskEvent(TaskEvent.Kind.ANALYZE, env.toplevel, env.enclClass.sym);
TaskEvent e = newAnalyzeTaskEvent(env);
taskListener.started(e);
}
@ -1390,12 +1390,30 @@ public class JavaCompiler {
}
finally {
if (!taskListener.isEmpty()) {
TaskEvent e = new TaskEvent(TaskEvent.Kind.ANALYZE, env.toplevel, env.enclClass.sym);
TaskEvent e = newAnalyzeTaskEvent(env);
taskListener.finished(e);
}
}
}
private TaskEvent newAnalyzeTaskEvent(Env<AttrContext> env) {
JCCompilationUnit toplevel = env.toplevel;
ClassSymbol sym;
if (env.enclClass.sym == syms.predefClass) {
if (TreeInfo.isModuleInfo(toplevel)) {
sym = toplevel.modle.module_info;
} else if (TreeInfo.isPackageInfo(toplevel)) {
sym = toplevel.packge.package_info;
} else {
throw new IllegalStateException("unknown env.toplevel");
}
} else {
sym = env.enclClass.sym;
}
return new TaskEvent(TaskEvent.Kind.ANALYZE, toplevel, sym);
}
/**
* Prepare attributed parse trees, in conjunction with their attribution contexts,
* for source or code generation.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2022, 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
@ -445,10 +445,8 @@ public class JavacElements implements Elements {
@DefinedBy(Api.LANGUAGE_MODEL)
public PackageElement getPackageOf(Element e) {
if (e.getKind() == ElementKind.MODULE)
return null;
else
return cast(Symbol.class, e).packge();
Symbol sym = cast(Symbol.class, e);
return (sym.kind == MDL || sym.owner.kind == MDL) ? null : sym.packge();
}
@DefinedBy(Api.LANGUAGE_MODEL)
@ -456,7 +454,9 @@ public class JavacElements implements Elements {
Symbol sym = cast(Symbol.class, e);
if (modules.getDefaultModule() == syms.noModule)
return null;
return (sym.kind == MDL) ? ((ModuleElement) e) : sym.packge().modle;
return (sym.kind == MDL) ? ((ModuleElement) e)
: (sym.owner.kind == MDL) ? (ModuleElement) sym.owner
: sym.packge().modle;
}
@DefinedBy(Api.LANGUAGE_MODEL)

View File

@ -0,0 +1,168 @@
/*
* Copyright (c) 2022, 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 8283661
* @summary Unexpected TypeElement in ANALYZE TaskEvent
* @modules jdk.compiler
* @run main TestTypeElement
*/
import java.io.IOException;
import java.io.PrintStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
import com.sun.source.util.JavacTask;
import com.sun.source.util.TaskEvent;
import com.sun.source.util.TaskListener;
public class TestTypeElement {
public static void main(String... args) throws Exception {
new TestTypeElement().run();
}
private PrintStream log;
private Elements elements;
private int errors;
void run() throws Exception {
log = System.err;
List<JavaFileObject> files = List.of(
createFileObject("module-info.java", "module m { }"),
createFileObject("p/package-info.java", "/** Comment. */ package p;"),
createFileObject("p/C.java", "package p; public class C { }")
);
JavaCompiler c = ToolProvider.getSystemJavaCompiler();
JavacTask t = (JavacTask) c.getTask(null, null, null, List.of("-d", "classes"), null, files);
t.addTaskListener(new TaskListener() {
@Override
public void started(TaskEvent e) {
log.println("started: " + e);
checkTypeElement(e);
}
@Override
public void finished(TaskEvent e) {
log.println("finished: " + e);
checkTypeElement(e);
}
});
elements = t.getElements();
t.call();
if (errors > 0) {
log.println(errors + " errors occurred");
throw new Exception(errors + " errors occurred");
}
}
private void checkTypeElement(TaskEvent e) {
TypeElement te = e.getTypeElement();
if (te != null) {
showTypeElement(e.getTypeElement());
}
switch (e.getKind()) {
case COMPILATION, PARSE, ENTER -> {
checkEqual(te, null);
}
case ANALYZE, GENERATE -> {
if (te == null) {
error("type element is null");
return;
}
switch (te.getQualifiedName().toString()) {
case "m.module-info" -> {
checkEqual(elements.getModuleOf(te), elements.getModuleElement("m"));
checkEqual(elements.getPackageOf(te), null);
}
case "p.package-info", "p.C" -> {
checkEqual(elements.getModuleOf(te), elements.getModuleElement("m"));
checkEqual(elements.getPackageOf(te), elements.getPackageElement("p"));
}
}
}
}
}
private void showTypeElement(TypeElement e) {
log.println("type element: " + e);
try {
log.println(" module element: " + elements.getModuleOf(e));
} catch (Throwable t) {
log.println(" module element: " + t);
}
try {
log.println(" package element: " + elements.getPackageOf(e));
} catch (Throwable t) {
log.println(" package element: " + t);
}
}
private <T> void checkEqual(T found, T expected) {
if (found != expected) {
error("mismatch");
log.println(" found: " + found);
log.println("expected: " + expected);
}
}
private void error(String message) {
log.println("Error: " + message);
errors++;
}
private JavaFileObject createFileObject(String name, String body) {
return createFileObject(name, JavaFileObject.Kind.SOURCE, body);
}
private JavaFileObject createFileObject(String name, JavaFileObject.Kind kind, String body) {
try {
return new SimpleJavaFileObject(new URI("myfo:///" + name), kind) {
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
return body;
}
};
} catch (URISyntaxException e) {
throw new IllegalArgumentException(name, e);
}
}
}