Skip to content

Commit

Permalink
ElementsImpl9#getFileObjectOf() should work for packages with
Browse files Browse the repository at this point in the history
packge-info also
  • Loading branch information
jarthana committed Feb 24, 2023
1 parent ce93063 commit 77f2f60
Show file tree
Hide file tree
Showing 8 changed files with 197 additions and 21 deletions.
Binary file modified org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ public class Java9ElementProcessor extends BaseProcessor {
boolean reportSuccessAlready = true;
RoundEnvironment roundEnv = null;
Messager _messager = null;
boolean isJre20;
boolean isJre19;
boolean isJre18;
boolean isJre17;
Expand Down Expand Up @@ -106,6 +107,9 @@ public synchronized void init(ProcessingEnvironment processingEnv) {
this.isJre18 = true;
if (current >= ClassFileConstants.MAJOR_VERSION_19) {
this.isJre19 = true;
if (current >= ClassFileConstants.MAJOR_VERSION_20) {
this.isJre20 = true;
}
}
}
} else {
Expand Down Expand Up @@ -511,7 +515,8 @@ public void testModuleJavaBase4() {
assertNotNull("java.base module null", base);
List<? extends Directive> directives = base.getDirectives();
List<Directive> filterDirective = filterDirective(directives, DirectiveKind.USES);
assertEquals("incorrect no of uses", (this.isJre11 || this.isJre12) ? 33 : (this.isJre18 ? 35 : 34), filterDirective.size());
int modCount = (this.isJre11 || this.isJre12) ? 33 : (this.isJre18 ? (this.isJre20 ? 36 : 35) : 34);
assertEquals("incorrect no of uses", modCount, filterDirective.size());
}
/*
* Test java.base module can be loaded and verify its 'provides' attributes
Expand Down Expand Up @@ -972,6 +977,8 @@ public void testGetFileObjectOf() {
JavaFileObject fo = _elementUtils.getFileObjectOf(typeElement);
assertNotNull("file object should not be null", fo);
assertEquals("should be of kind source", this.binary ? JavaFileObject.Kind.CLASS : JavaFileObject.Kind.SOURCE, fo.getKind());
String expectedUri = "mod.a/abc/internal/A." + (this.binary ? "class" : "java");
assertEndsWith("Incorrect path", fo.toUri().toString(), expectedUri);
if (this.binary && !this.isJavac) {
assertEquals("Incorrect modifier", Modifier.PUBLIC, fo.getAccessLevel());
assertEquals("Incorrect nesting kind", NestingKind.TOP_LEVEL, fo.getNestingKind());
Expand All @@ -987,13 +994,27 @@ public void testGetFileObjectOf() {
assertEquals("should be of kind source", this.binary ? JavaFileObject.Kind.CLASS : JavaFileObject.Kind.SOURCE, fo.getKind());
assertEquals("Incorrect modifier", Modifier.PUBLIC, fo.getAccessLevel());
assertEquals("Incorrect nesting kind", NestingKind.TOP_LEVEL, fo.getNestingKind());
assertEndsWith("Incorrect path", fo.toUri().toString(), expectedUri);
}

ModuleElement m = _elementUtils.getModuleOf(typeElement);
assertNotNull("Module should not be null", m);
fo = _elementUtils.getFileObjectOf(m);
assertNotNull("file object should not be null", fo);
assertEquals("should be of kind source", this.binary ? JavaFileObject.Kind.CLASS : JavaFileObject.Kind.SOURCE, fo.getKind());
expectedUri = "mod.a/module-info." + (this.binary ? "class" : "java");
assertEndsWith("Incorrect path", fo.toUri().toString(), expectedUri);

PackageElement p = _elementUtils.getPackageOf(typeElement);
assertNotNull("Module should not be null", p);
fo = _elementUtils.getFileObjectOf(p);
// TODO: Javac fails this as of now. So, exclude it
if (!this.isJavac) {
assertNotNull("file object should not be null", fo);
assertEquals("should be of kind source", this.binary ? JavaFileObject.Kind.CLASS : JavaFileObject.Kind.SOURCE, fo.getKind());
expectedUri = "mod.a/abc/internal/package-info." + (this.binary ? "class" : "java");
assertEndsWith("Incorrect path", fo.toUri().toString(), expectedUri);
}

Set<? extends ModuleElement> allModuleElements = _elementUtils.getAllModuleElements();
ModuleElement base = null;
Expand All @@ -1006,6 +1027,8 @@ public void testGetFileObjectOf() {
fo = _elementUtils.getFileObjectOf(base);
assertNotNull("file object should not be null", fo);
assertEquals("should be of kind source", JavaFileObject.Kind.CLASS, fo.getKind());
expectedUri = "java.base/module-info.class";
assertEndsWith("Incorrect path", fo.toUri().toString(), expectedUri);
VariableElement field = null;
ExecutableElement method = null;
List<? extends Element> enclosedElements = typeElement.getEnclosedElements();
Expand All @@ -1020,10 +1043,75 @@ public void testGetFileObjectOf() {
fo = _elementUtils.getFileObjectOf(field);
assertNotNull("file object should not be null", fo);
assertEquals("should be of kind source", this.binary ? JavaFileObject.Kind.CLASS : JavaFileObject.Kind.SOURCE, fo.getKind());
expectedUri = "mod.a/abc/internal/A." + (this.binary ? "class" : "java");
assertEndsWith("Incorrect path", fo.toUri().toString(), expectedUri);

assertNotNull("Method should not be null", method);
fo = _elementUtils.getFileObjectOf(method);
assertNotNull("file object should not be null", fo);
assertEquals("should be of kind source", this.binary ? JavaFileObject.Kind.CLASS : JavaFileObject.Kind.SOURCE, fo.getKind());
expectedUri = "mod.a/abc/internal/A." + (this.binary ? "class" : "java");
assertEndsWith("Incorrect path", fo.toUri().toString(), expectedUri);
}
public void testGetFileObjectOfRecords() {
TypeElement typeElement =_elementUtils.getTypeElement("xyz.NestedRecord");
assertNotNull("Type should not be null", typeElement);
JavaFileObject fo = _elementUtils.getFileObjectOf(typeElement);
assertNotNull("file object should not be null", fo);
assertEquals("should be of kind source", this.binary ? JavaFileObject.Kind.CLASS : JavaFileObject.Kind.SOURCE, fo.getKind());
String expectedUri = "xyz/NestedRecord." + (this.binary ? "class" : "java");
assertEndsWith("Incorrect path", fo.toUri().toString(), expectedUri);
List<? extends Element> inner = typeElement.getEnclosedElements();
TypeElement recordEl = null;
TypeElement enumEl = null;
for (Element element : inner) {
if (element.getKind() == ElementKind.RECORD && element.getSimpleName().toString().equals("Point")) {
recordEl = (TypeElement) element;
} else if (element.getKind() == ElementKind.ENUM && element.getSimpleName().toString().equals("Color")) {
enumEl = (TypeElement) element;
}
}
assertNotNull("Type should not be null", recordEl);
fo = _elementUtils.getFileObjectOf(recordEl);
assertNotNull("file object should not be null", fo);
assertEquals("should be of kind source", this.binary ? JavaFileObject.Kind.CLASS : JavaFileObject.Kind.SOURCE, fo.getKind());
expectedUri = this.binary ? "xyz/NestedRecord$Point.class" : "xyz/NestedRecord.java";
assertEndsWith("Incorrect path", fo.toUri().toString(), expectedUri);

assertNotNull("Type should not be null", enumEl);
fo = _elementUtils.getFileObjectOf(enumEl);
assertNotNull("file object should not be null", fo);
assertEquals("should be of kind source", this.binary ? JavaFileObject.Kind.CLASS : JavaFileObject.Kind.SOURCE, fo.getKind());
expectedUri = this.binary ? "xyz/NestedRecord$Color.class" : "xyz/NestedRecord.java";
assertEndsWith("Incorrect path", fo.toUri().toString(), expectedUri);

typeElement =_elementUtils.getTypeElement("xyz.JavaFileWithManyClasses");
assertNotNull("Type should not be null", typeElement);
fo = _elementUtils.getFileObjectOf(typeElement);
assertNotNull("file object should not be null", fo);
assertEquals("should be of kind source", this.binary ? JavaFileObject.Kind.CLASS : JavaFileObject.Kind.SOURCE, fo.getKind());
expectedUri = "xyz/JavaFileWithManyClasses." + (this.binary ? "class" : "java");
assertEndsWith("Incorrect path", fo.toUri().toString(), expectedUri);

typeElement =_elementUtils.getTypeElement("xyz.AnotherClass");
assertNotNull("Type should not be null", typeElement);
fo = _elementUtils.getFileObjectOf(typeElement);
assertNotNull("file object should not be null", fo);
assertEquals("should be of kind source", this.binary ? JavaFileObject.Kind.CLASS : JavaFileObject.Kind.SOURCE, fo.getKind());
if (this.binary) {
expectedUri = "xyz/AnotherClass.class";
}
assertEndsWith("Incorrect path", fo.toUri().toString(), expectedUri);

typeElement =_elementUtils.getTypeElement("xyz.AnotherInterface");
assertNotNull("Type should not be null", typeElement);
fo = _elementUtils.getFileObjectOf(typeElement);
assertNotNull("file object should not be null", fo);
assertEquals("should be of kind source", this.binary ? JavaFileObject.Kind.CLASS : JavaFileObject.Kind.SOURCE, fo.getKind());
if (this.binary) {
expectedUri = "xyz/AnotherInterface.class";
}
assertEndsWith("Incorrect path", fo.toUri().toString(), expectedUri);
}
private void validateModifiers(ExecutableElement method, Modifier[] expected) {
Set<Modifier> modifiers = method.getModifiers();
Expand Down Expand Up @@ -1079,6 +1167,12 @@ public void assertModifiers(Set<Modifier> modifiers, String[] expected) {
reportError("Unexpected modifiers present:" + actual.toString());
}
}
public void assertEndsWith(String msg, String whole, String tail) {
if (whole.endsWith(tail)) {
return;
}
reportError(msg + ", String \"" + whole + "\" does not end with \"" + tail + "\"");
}
public void assertTrue(String msg, boolean value) {
if (!value) reportError(msg);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module records {
exports xyz;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package xyz;

public class JavaFileWithManyClasses {}
class AnotherClass {}
interface AnotherInterface {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package xyz;
public record NestedRecord(Point a, Point b) {
record Point (int x, int y) {
}
enum Color {
RED, YELLOW, BLUE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ private void internalTest2(JavaCompiler compiler, String processor, String testM
options.add("-A" + MODULE_PROC);
options.add("-A" + testMethod);
if (compiler instanceof EclipseCompiler) {
options.add("-9");
options.add("-17");
}
BatchTestUtils.compileInModuleMode(compiler, options, MODULE_PROC, srcRoot, null, true, false);
assertEquals("succeeded", System.getProperty(MODULE_PROC));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,20 @@ public void testGetFileObjectOf() throws IOException {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
internalTest3(compiler, MODULE_PROC, "testGetFileObjectOf", null, true);
}
public void testGetFileObjectOfRecordsJavac() throws IOException {
if (!canRunJava20()) {
return;
}
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
internalTest4(compiler, "20", MODULE_PROC, "testGetFileObjectOfRecords", null, true);
}
public void testGetFileObjectOfRecords() throws IOException {
if (!canRunJava20()) {
return;
}
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
internalTest4(compiler, "20", MODULE_PROC, "testGetFileObjectOfRecords", null, true);
}
protected void internalTestWithBinary(JavaCompiler compiler, String processor, String compliance, String testMethod, String testClass, String resourceArea) throws IOException {
if (!canRunJava9()) {
return;
Expand Down Expand Up @@ -567,7 +581,7 @@ private void internalTest2(JavaCompiler compiler, String processor, String modLo
options.add("-A" + processor);
options.add("-A" + testMethod);
if (compiler instanceof EclipseCompiler) {
options.add("-9");
options.add("-17");
}
BatchTestUtils.compileInModuleMode(compiler, options, processor, srcRoot, null, true);
assertEquals("succeeded", System.getProperty(processor));
Expand All @@ -589,7 +603,33 @@ private void internalTest3(JavaCompiler compiler, String processor, String testM
options.add("-A" + processor);
options.add("-A" + testMethod);
if (compiler instanceof EclipseCompiler) {
options.add("-9");
options.add("-17");
}
BatchTestUtils.compileInModuleMode(compiler, options, processor, srcRoot, null, true, binaryMode);
assertEquals("succeeded", System.getProperty(processor));
}
/*
* Tests are run in multi-module mode but only compiling a module path
*/
private void internalTest4(JavaCompiler compiler, String compliance, String processor, String testMethod, String testClass, boolean binaryMode) throws IOException {
if (!canRunJava9()) {
return;
}
System.clearProperty(processor);
File srcRoot = TestUtils.concatPath(BatchTestUtils.getSrcFolderName());
BatchTestUtils.copyResources("mod_locations/modules", srcRoot);

List<String> options = new ArrayList<String>();
options.add("-processor");
options.add(processor);
options.add("-A" + processor);
options.add("-A" + testMethod);
if (compiler instanceof EclipseCompiler) {
options.add("-" + compliance);
} else {
options.add("-source");
options.add(compliance);
options.add("--enable-preview");
}
BatchTestUtils.compileInModuleMode(compiler, options, processor, srcRoot, null, true, binaryMode);
assertEquals("succeeded", System.getProperty(processor));
Expand All @@ -610,6 +650,14 @@ public boolean canRunJava18() {
}
return true;
}
public boolean canRunJava20() {
try {
SourceVersion.valueOf("RELEASE_20");
} catch(IllegalArgumentException iae) {
return false;
}
return true;
}
public boolean canRunJava9() {
try {
SourceVersion.valueOf("RELEASE_9");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import java.io.File;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.HashSet;
Expand Down Expand Up @@ -51,6 +52,8 @@
import org.eclipse.jdt.internal.compiler.lookup.SourceModuleBinding;
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.tool.EclipseFileManager;
import org.eclipse.jdt.internal.compiler.tool.PathFileObject;
import org.eclipse.jdt.internal.compiler.util.HashtableOfModule;
Expand Down Expand Up @@ -210,37 +213,36 @@ public boolean isAutomaticModule(ModuleElement module) {
@Override
public javax.tools.JavaFileObject getFileObjectOf(Element element) {
switch(element.getKind()) {
case INTERFACE:
case CLASS:
case ENUM:
case RECORD:
case ANNOTATION_TYPE:
TypeElement outer = getOutermostTypeElement(element);
TypeElementImpl typeElementImpl = (TypeElementImpl) outer;
Binding typeBinding = typeElementImpl._binding;
if (typeBinding instanceof SourceTypeBinding) {
SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) typeBinding;
ReferenceContext referenceContext = sourceTypeBinding.scope.referenceContext();
return getSourceJavaFileObject(referenceContext);
} else if(typeBinding instanceof BinaryTypeBinding) {
BinaryTypeBinding binaryBinding = (BinaryTypeBinding) typeBinding;
if (binaryBinding.path != null) {
return new PathFileObject(Path.of(binaryBinding.path), Kind.CLASS, Charset.defaultCharset());
}
}
break;
TypeBinding typeBinding = (TypeBinding) typeElementImpl._binding;
return getFileObjectForType(typeBinding);
case MODULE:
ModuleElementImpl moduleEl = (ModuleElementImpl) element;
ModuleBinding binding = (ModuleBinding) moduleEl._binding;
if (binding instanceof SourceModuleBinding) {
SourceModuleBinding sourceModule = (SourceModuleBinding) binding;
ModuleBinding mBinding = (ModuleBinding) moduleEl._binding;
if (mBinding instanceof SourceModuleBinding) {
SourceModuleBinding sourceModule = (SourceModuleBinding) mBinding;
return getSourceJavaFileObject(sourceModule.scope.referenceContext());
} else if (binding instanceof BinaryModuleBinding) {
BinaryModuleBinding binaryBinding = (BinaryModuleBinding) binding;
} else if (mBinding instanceof BinaryModuleBinding) {
BinaryModuleBinding binaryBinding = (BinaryModuleBinding) mBinding;
if (binaryBinding.path != null) {
return new PathFileObject(Path.of(binaryBinding.path), Kind.CLASS, Charset.defaultCharset());
}
}
break;
case PACKAGE:
PackageElementImpl packEl = (PackageElementImpl) element;
PackageBinding pBinding = (PackageBinding) packEl._binding;
Binding typeOrPackage = pBinding.getTypeOrPackage(TypeConstants.PACKAGE_INFO_NAME, pBinding.enclosingModule, true);
if (typeOrPackage != null) {
return getFileObjectForType((TypeBinding) typeOrPackage);
}
break;
case LOCAL_VARIABLE:
case FIELD:
case RECORD_COMPONENT:
Expand All @@ -256,6 +258,22 @@ public javax.tools.JavaFileObject getFileObjectOf(Element element) {
}
return null;
}
private JavaFileObject getFileObjectForType(TypeBinding binding) {
if (binding instanceof SourceTypeBinding) {
SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) binding;
ReferenceContext referenceContext = sourceTypeBinding.scope.referenceContext();
return getSourceJavaFileObject(referenceContext);
} else if(binding instanceof BinaryTypeBinding) {
BinaryTypeBinding binaryBinding = (BinaryTypeBinding) binding;
if (binaryBinding.path != null) {
Path of = Path.of(binaryBinding.path);
if (Files.exists(of)) {
return new PathFileObject(of, Kind.CLASS, Charset.defaultCharset());
}
}
}
return null;
}
private JavaFileObject getSourceJavaFileObject(ReferenceContext referenceContext) {
JavaFileManager fileManager = this._env.getFileManager();
if (fileManager instanceof EclipseFileManager) {
Expand Down

0 comments on commit 77f2f60

Please sign in to comment.