Skip to content

Commit 1584c4b

Browse files
authored
Merge pull request #3 from lahodaj/JDK-8224922
Improvements to JDK-8224922
2 parents d1b6fab + b301d92 commit 1584c4b

File tree

5 files changed

+344
-14
lines changed

5 files changed

+344
-14
lines changed

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ public void visitTopLevel(JCCompilationUnit tree) {
376376
Name name = names.package_info;
377377
ClassSymbol c = syms.enterClass(tree.modle, name, tree.packge);
378378
c.flatname = names.fromString(tree.packge + "." + name);
379-
c.sourcefile = tree.sourcefile;
379+
c.classfile = c.sourcefile = tree.sourcefile;
380380
c.completer = Completer.NULL_COMPLETER;
381381
c.members_field = WriteableScope.create(c);
382382
tree.packge.package_info = c;
@@ -495,7 +495,7 @@ public void visitClassDef(JCClassDecl tree) {
495495
// Fill out class fields.
496496
c.completer = Completer.NULL_COMPLETER; // do not allow the initial completer linger on.
497497
c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree);
498-
c.sourcefile = env.toplevel.sourcefile;
498+
c.classfile = c.sourcefile = env.toplevel.sourcefile;
499499
c.members_field = WriteableScope.create(c);
500500
c.clearAnnotationMetadata();
501501

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ private void enterModule(JCCompilationUnit toplevel, ClassSymbol c, Set<ModuleSy
329329
}
330330
}
331331
sym.completer = getSourceCompleter(toplevel);
332-
sym.module_info.sourcefile = toplevel.sourcefile;
332+
sym.module_info.classfile = sym.module_info.sourcefile = toplevel.sourcefile;
333333
decl.sym = sym;
334334

335335
if (multiModuleMode || modules.isEmpty()) {

src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -728,16 +728,21 @@ public boolean isAutomaticModule(ModuleElement module) {
728728
}
729729

730730
@Override @DefinedBy(Api.LANGUAGE_MODEL)
731-
public javax.tools.JavaFileObject getFileObjectOf(Element e) {
732-
return switch(e.getKind()) {
733-
case PACKAGE -> ((PackageSymbol)e).sourcefile;
734-
// TODO: ModuleSymbol doesn't directly have a JavaFileObject field at present.
735-
case MODULE -> null;
736-
// TODO: this is likely not quite right for nested types
737-
// that have already been compiled; their class file
738-
// should be their own class file rather than the class
739-
// file for the outermost class.
740-
default -> ((Symbol)e).outermostClass().classfile;
731+
public JavaFileObject getFileObjectOf(Element e) {
732+
Symbol sym = (Symbol) e;
733+
return switch(sym.kind) {
734+
case PCK -> {
735+
if (((PackageSymbol) sym).package_info == null) {
736+
yield null;
737+
}
738+
yield ((PackageSymbol) sym).package_info.classfile;
739+
}
740+
case MDL -> {
741+
ModuleSymbol msym = (ModuleSymbol) sym;
742+
yield msym.module_info.classfile;
743+
}
744+
case TYP -> ((ClassSymbol) sym).classfile;
745+
default -> sym.enclClass().classfile;
741746
};
742747
}
743748

Lines changed: 324 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,324 @@
1+
/*
2+
* Copyright (c) 2021, 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 8224922
27+
* @summary Verify the behavior of the Elements.getFileObjectOf
28+
* @library /tools/lib
29+
* @modules jdk.compiler/com.sun.tools.javac.api
30+
* jdk.compiler/com.sun.tools.javac.main
31+
* jdk.jdeps/com.sun.tools.classfile
32+
* @build toolbox.ToolBox toolbox.JavacTask toolbox.TestRunner
33+
* @build TestFileObjectOf
34+
* @run main TestFileObjectOf
35+
*/
36+
37+
import com.sun.source.tree.VariableTree;
38+
import com.sun.source.util.TreePath;
39+
import java.nio.file.Path;
40+
import java.nio.file.Paths;
41+
import java.util.ArrayDeque;
42+
import java.util.List;
43+
import java.util.Queue;
44+
import java.util.Set;
45+
46+
import javax.annotation.processing.*;
47+
import javax.lang.model.SourceVersion;
48+
import javax.lang.model.element.*;
49+
import javax.lang.model.util.Elements;
50+
51+
import com.sun.source.util.TreePathScanner;
52+
import com.sun.source.util.Trees;
53+
import javax.tools.JavaFileObject;
54+
import toolbox.JavacTask;
55+
import toolbox.Task;
56+
import toolbox.TestRunner;
57+
import toolbox.ToolBox;
58+
59+
public class TestFileObjectOf extends TestRunner {
60+
61+
private final ToolBox tb;
62+
63+
TestFileObjectOf() {
64+
super(System.err);
65+
tb = new ToolBox();
66+
}
67+
68+
public static void main(String... args) throws Exception {
69+
new TestFileObjectOf().runTests(m -> new Object[] { Paths.get(m.getName()) });
70+
}
71+
72+
@Test
73+
public void testSourceFiles(Path base) throws Exception {
74+
Path src = base.resolve("src");
75+
tb.writeJavaFiles(src,
76+
"""
77+
module m {}
78+
""",
79+
"""
80+
package test;
81+
""",
82+
"""
83+
package test;
84+
public class TestClass {
85+
int fieldTestClass;
86+
TestClass() { }
87+
void methodTestClass(int parameterTestClass) {
88+
int localTestClass;
89+
}
90+
public static class InnerClass {
91+
int fieldInnerClass;
92+
InnerClass() {}
93+
void methodInnerClass(int parameterInnerClass) {
94+
int localInnerClass;
95+
}
96+
}
97+
}
98+
""",
99+
"""
100+
package test;
101+
public enum TestEnum {
102+
CONSTANT;
103+
}
104+
""",
105+
"""
106+
package test2;
107+
public class TestClass2 {}
108+
""");
109+
Path classes = base.resolve("classes").resolve("m");
110+
tb.createDirectories(classes);
111+
112+
//from source, implicit:
113+
{
114+
String moduleInfoSource = src.resolve("module-info.java").toUri().toString();
115+
String packageInfoSource = src.resolve("test").resolve("package-info.java").toUri().toString();
116+
String testClassSource = src.resolve("test").resolve("TestClass.java").toUri().toString();
117+
String testEnumSource = src.resolve("test").resolve("TestEnum.java").toUri().toString();
118+
String testClass2Source = src.resolve("test2").resolve("TestClass2.java").toUri().toString();
119+
120+
List<String> log;
121+
122+
log = new JavacTask(tb)
123+
.options("-Xpkginfo:always",
124+
"-processorpath", System.getProperty("test.classes"),
125+
"-processor", PrintFiles.class.getName(),
126+
"-sourcepath", src.toString())
127+
.outdir(classes)
128+
.classes("java.lang.Object")
129+
.run()
130+
.writeAll()
131+
.getOutputLines(Task.OutputKind.STDOUT);
132+
133+
List<String> expected = List.of(
134+
"m: " + moduleInfoSource,
135+
"test: " + packageInfoSource,
136+
"test2: " + "<null>",
137+
"TestClass: " + testClassSource,
138+
"TestEnum: " + testEnumSource,
139+
"TestClass2: " + testClass2Source,
140+
"<init>: " + testClassSource,
141+
"InnerClass: " + testClassSource,
142+
"fieldTestClass: " + testClassSource,
143+
"methodTestClass: " + testClassSource,
144+
"parameterTestClass: " + testClassSource,
145+
"localTestClass: " + testClassSource,
146+
"<init>: " + testEnumSource,
147+
"CONSTANT: " + testEnumSource,
148+
"valueOf: " + testEnumSource,
149+
"values: " + testEnumSource,
150+
"<init>: " + testClass2Source,
151+
"<init>: " + testClassSource,
152+
"fieldInnerClass: " + testClassSource,
153+
"methodInnerClass: " + testClassSource,
154+
"parameterInnerClass: " + testClassSource,
155+
"localInnerClass: " + testClassSource
156+
);
157+
158+
if (!expected.equals(log))
159+
throw new AssertionError("expected output not found: " + log);
160+
}
161+
162+
tb.cleanDirectory(classes);
163+
164+
//from source, explicit:
165+
{
166+
String moduleInfoSource = src.resolve("module-info.java").toUri().toString();
167+
String packageInfoSource = src.resolve("test").resolve("package-info.java").toUri().toString();
168+
String testClassSource = src.resolve("test").resolve("TestClass.java").toUri().toString();
169+
String testEnumSource = src.resolve("test").resolve("TestEnum.java").toUri().toString();
170+
String testClass2Source = src.resolve("test2").resolve("TestClass2.java").toUri().toString();
171+
172+
List<String> log;
173+
174+
log = new JavacTask(tb)
175+
.options("-Xpkginfo:always",
176+
"-processorpath", System.getProperty("test.classes"),
177+
"-processor", PrintFiles.class.getName())
178+
.outdir(classes)
179+
.files(tb.findJavaFiles(src))
180+
.run()
181+
.writeAll()
182+
.getOutputLines(Task.OutputKind.STDOUT);
183+
184+
List<String> expected = List.of(
185+
"m: " + moduleInfoSource,
186+
"test: " + packageInfoSource,
187+
"test2: " + "<null>",
188+
"TestClass: " + testClassSource,
189+
"TestEnum: " + testEnumSource,
190+
"TestClass2: " + testClass2Source,
191+
"<init>: " + testClassSource,
192+
"InnerClass: " + testClassSource,
193+
"fieldTestClass: " + testClassSource,
194+
"methodTestClass: " + testClassSource,
195+
"parameterTestClass: " + testClassSource,
196+
"localTestClass: " + testClassSource,
197+
"<init>: " + testEnumSource,
198+
"CONSTANT: " + testEnumSource,
199+
"valueOf: " + testEnumSource,
200+
"values: " + testEnumSource,
201+
"<init>: " + testClass2Source,
202+
"<init>: " + testClassSource,
203+
"fieldInnerClass: " + testClassSource,
204+
"methodInnerClass: " + testClassSource,
205+
"parameterInnerClass: " + testClassSource,
206+
"localInnerClass: " + testClassSource
207+
);
208+
209+
if (!expected.equals(log))
210+
throw new AssertionError("expected output not found: " + log);
211+
}
212+
213+
//from class:
214+
{
215+
String moduleInfoSource = classes.resolve("module-info.class").toUri().toString();
216+
String packageInfoSource = classes.resolve("test").resolve("package-info.class").toUri().toString();
217+
String testClassSource = classes.resolve("test").resolve("TestClass.class").toUri().toString();
218+
String testInnerClassSource = classes.resolve("test").resolve("TestClass$InnerClass.class").toUri().toString();
219+
String testEnumSource = classes.resolve("test").resolve("TestEnum.class").toUri().toString();
220+
String testClass2Source = classes.resolve("test2").resolve("TestClass2.class").toUri().toString();
221+
222+
List<String> log;
223+
224+
log = new JavacTask(tb)
225+
.options("-processorpath", System.getProperty("test.classes"),
226+
"-processor", PrintFiles.class.getName(),
227+
"--module-path", classes.toString(),
228+
"--add-modules", "m")
229+
.outdir(classes)
230+
.classes("java.lang.Object")
231+
.run()
232+
.writeAll()
233+
.getOutputLines(Task.OutputKind.STDOUT);
234+
235+
List<String> expected = List.of(
236+
"m: " + moduleInfoSource,
237+
"test: " + packageInfoSource,
238+
"test2: " + "<null>",
239+
"TestClass: " + testClassSource,
240+
"TestEnum: " + testEnumSource,
241+
"TestClass2: " + testClass2Source,
242+
"<init>: " + testClassSource,
243+
"InnerClass: " + testInnerClassSource,
244+
"fieldTestClass: " + testClassSource,
245+
"methodTestClass: " + testClassSource,
246+
"<clinit>: " + testEnumSource,
247+
"<init>: " + testEnumSource,
248+
"CONSTANT: " + testEnumSource,
249+
"valueOf: " + testEnumSource,
250+
"values: " + testEnumSource,
251+
"<init>: " + testClass2Source,
252+
"<init>: " + testInnerClassSource,
253+
"fieldInnerClass: " + testInnerClassSource,
254+
"methodInnerClass: " + testInnerClassSource
255+
);
256+
257+
if (!expected.equals(log))
258+
throw new AssertionError("expected output not found: " + log);
259+
}
260+
}
261+
262+
@SupportedAnnotationTypes("*")
263+
@SupportedOptions("fromClass")
264+
public static final class PrintFiles extends AbstractProcessor {
265+
266+
@Override
267+
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
268+
if (!roundEnv.processingOver())
269+
return false;
270+
271+
Elements elements = processingEnv.getElementUtils();
272+
Trees trees = Trees.instance(processingEnv);
273+
Queue<Element> q = new ArrayDeque<>();
274+
q.add(elements.getModuleElement("m"));
275+
276+
while (!q.isEmpty()) {
277+
Element currentElement = q.remove();
278+
279+
handleDeclaration(currentElement);
280+
281+
switch (currentElement.getKind()) {
282+
case METHOD -> {
283+
ExecutableElement method = (ExecutableElement) currentElement;
284+
TreePath tp = trees.getPath(method);
285+
if (tp != null) {
286+
new TreePathScanner<>() {
287+
@Override
288+
public Object visitVariable(VariableTree node, Object p) {
289+
Element el = trees.getElement(getCurrentPath());
290+
handleDeclaration(el);
291+
return super.visitVariable(node, p);
292+
}
293+
}.scan(tp, null);
294+
}
295+
}
296+
case MODULE -> {
297+
q.add(elements.getPackageElement("test"));
298+
q.add(elements.getPackageElement("test2"));
299+
}
300+
default ->
301+
currentElement.getEnclosedElements()
302+
.stream()
303+
.sorted((e1, e2) -> e1.getSimpleName().toString().compareTo(e2.getSimpleName().toString()))
304+
.forEach(q::add);
305+
}
306+
}
307+
308+
return false;
309+
}
310+
311+
void handleDeclaration(Element el) {
312+
Elements elements = processingEnv.getElementUtils();
313+
JavaFileObject fileObjects = elements.getFileObjectOf(el);
314+
System.out.println(el.getSimpleName() + ": " + (fileObjects != null ? fileObjects.toUri().toString() : "<null>"));
315+
}
316+
317+
@Override
318+
public SourceVersion getSupportedSourceVersion() {
319+
return SourceVersion.latestSupported();
320+
}
321+
322+
}
323+
324+
}

test/langtools/tools/javac/tree/NoPrivateTypesExported.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ public class NoPrivateTypesExported extends JavacTestingAbstractProcessor {
8989
"java.text.",
9090
"java.util.",
9191
"javax.lang.model.",
92-
"javax.annotation.processing.SupportedSourceVersion"
92+
"javax.annotation.processing.SupportedSourceVersion",
93+
"javax.tools.JavaFileObject"
9394
));
9495
Set<String> javaxToolsProcessingAcceptableTemp = new HashSet<>();
9596
javaxToolsProcessingAcceptableTemp.addAll(javaxLangModelAcceptable);

0 commit comments

Comments
 (0)