Skip to content

Commit

Permalink
Migrate from Hickory to Elementary (#50)
Browse files Browse the repository at this point in the history
  • Loading branch information
basil authored Aug 8, 2022
1 parent f62ff12 commit 0964f71
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 113 deletions.
10 changes: 7 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.jolira</groupId>
<artifactId>hickory</artifactId>
<version>1.0.0</version>
<groupId>com.karuslabs</groupId>
<artifactId>elementary</artifactId>
<version>1.1.2</version>
<scope>test</scope>
</dependency>
<dependency>
Expand All @@ -76,6 +76,10 @@
<id>repo.jenkins-ci.org</id>
<url>https://repo.jenkins-ci.org/public/</url>
</repository>
<repository>
<id>elementary-releases</id>
<url>https://repo.karuslabs.com/repository/elementary-releases/</url>
</repository>
</repositories>

</project>
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
package org.jvnet.hudson.annotation_indexer;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import com.karuslabs.elementary.Results;
import com.karuslabs.elementary.junit.JavacExtension;
import com.karuslabs.elementary.junit.annotations.Inline;
import com.karuslabs.elementary.junit.annotations.Options;
import com.karuslabs.elementary.junit.annotations.Processors;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
Expand All @@ -13,66 +21,97 @@
import java.net.URLClassLoader;
import java.util.Collections;
import java.util.Iterator;
import net.java.dev.hickory.testing.Compilation;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

public class AnnotationProcessorImplTest {
@ExtendWith(JavacExtension.class)
@Options("-Werror")
@Processors(AnnotationProcessorImpl.class)
class AnnotationProcessorImplTest {

@Test public void allInOne() {
Compilation compilation = new Compilation();
compilation.addSource("some.api.A").
addLine("package some.api;").
addLine("@" + Indexed.class.getCanonicalName() + " @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public @interface A {}");
compilation.addSource("some.pkg.Stuff").
addLine("package some.pkg;").
addLine("@some.api.A public class Stuff {}");
compilation.doCompile(null, "-source", "8");
assertEquals(Collections.emptyList(), Utils.filterObsoleteSourceVersionWarnings(compilation.getDiagnostics()));
assertEquals("some.pkg.Stuff" + System.getProperty("line.separator"), Utils.getGeneratedResource(compilation, "META-INF/services/annotations/some.api.A"));
@Inline(
name = "some.api.A",
source = {
"package some.api;",
"@org.jvnet.hudson.annotation_indexer.Indexed @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public @interface A {}",
})
@Inline(
name = "some.pkg.Stuff",
source = {
"package some.pkg;",
"@some.api.A public class Stuff {}",
})
@Test
void allInOne(Results results) {
assertEquals(Collections.emptyList(), results.diagnostics);
assertEquals("some.pkg.Stuff" + System.getProperty("line.separator"), Utils.getGeneratedResource(results.sources, "META-INF/services/annotations/some.api.A"));
}

@Indexed @Retention(RetentionPolicy.RUNTIME) public @interface A {}
@Test public void separate() {
Compilation compilation = new Compilation();
compilation.addSource("some.pkg.Stuff").
addLine("package some.pkg;").
addLine("@" + A.class.getCanonicalName() + " public class Stuff {}");
compilation.doCompile(null, "-source", "8");
assertEquals(Collections.emptyList(), Utils.filterObsoleteSourceVersionWarnings(compilation.getDiagnostics()));
assertEquals("some.pkg.Stuff" + System.getProperty("line.separator"), Utils.getGeneratedResource(compilation, "META-INF/services/annotations/" + A.class.getName()));
@Inline(
name = "some.pkg.A",
source = {
"package some.pkg;",
"@org.jvnet.hudson.annotation_indexer.Indexed @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public @interface A {}",
})
@Inline(
name = "some.pkg.Stuff",
source = {
"package some.pkg;",
"@A public class Stuff {}",
})
@Test
void separate(Results results) {
assertEquals(Collections.emptyList(), results.diagnostics);
assertEquals("some.pkg.Stuff" + System.getProperty("line.separator"), Utils.getGeneratedResource(results.sources, "META-INF/services/annotations/some.pkg.A"));
}

@Test public void incremental() {
Compilation compilation = new Compilation();
compilation.addSource("some.pkg.Stuff").
addLine("package some.pkg;").
addLine("@" + A.class.getCanonicalName() + " public class Stuff {}");
compilation.doCompile(null, "-source", "8");
assertEquals(Collections.emptyList(), Utils.filterObsoleteSourceVersionWarnings(compilation.getDiagnostics()));
assertEquals("some.pkg.Stuff" + System.getProperty("line.separator"), Utils.getGeneratedResource(compilation, "META-INF/services/annotations/" + A.class.getName()));
compilation = new Compilation(compilation);
compilation.addSource("some.pkg.MoreStuff").
addLine("package some.pkg;").
addLine("@" + A.class.getCanonicalName() + " public class MoreStuff {}");
compilation.doCompile(null, "-source", "8");
assertEquals(Collections.emptyList(), Utils.filterObsoleteSourceVersionWarnings(compilation.getDiagnostics()));
assertEquals("some.pkg.MoreStuff" + System.getProperty("line.separator") + "some.pkg.Stuff" + System.getProperty("line.separator"), Utils.getGeneratedResource(compilation, "META-INF/services/annotations/" + A.class.getName()));
@Inline(
name = "some.pkg.A",
source = {
"package some.pkg;",
"@org.jvnet.hudson.annotation_indexer.Indexed @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public @interface A {}",
})
@Inline(
name = "some.pkg.Stuff",
source = {
"package some.pkg;",
"@A public class Stuff {}",
})
@Inline(
name = "some.pkg.MoreStuff",
source = {
"package some.pkg;",
"@A public class MoreStuff {}",
})
@Test
void multiple(Results results) {
assertEquals(Collections.emptyList(), results.diagnostics);
assertEquals("some.pkg.MoreStuff" + System.getProperty("line.separator") + "some.pkg.Stuff" + System.getProperty("line.separator"), Utils.getGeneratedResource(results.sources, "META-INF/services/annotations/some.pkg.A"));
}

@Indexed @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface B {}
@B public static abstract class Super {}
@Test public void subclass() {
Compilation compilation = new Compilation();
compilation.addSource("some.pkg.Stuff").
addLine("package some.pkg;").
addLine("public class Stuff extends " + Super.class.getCanonicalName() + " {}");
compilation.doCompile(null, "-source", "8");
assertEquals(Collections.emptyList(), Utils.filterObsoleteSourceVersionWarnings(compilation.getDiagnostics()));
@Inline(
name = "some.pkg.B",
source = {
"package some.pkg;",
"@org.jvnet.hudson.annotation_indexer.Indexed @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Inherited public @interface B {}",
})
@Inline(
name = "some.pkg.Super",
source = {
"package some.pkg;",
"@B public abstract class Super {}",
})
@Inline(
name = "some.pkg.Stuff",
source = {
"package some.pkg;",
"public class Stuff extends Super {}",
})
@Test
void subclass(Results results) {
assertEquals(Collections.emptyList(), results.diagnostics);
/* XXX #7188605 currently broken on JDK 6; perhaps need to use a ElementScanner6 on roundEnv.rootElements whose visitType checks for annotations
assertEquals("some.pkg.Stuff\n", Utils.getGeneratedResource(compilation, "META-INF/services/annotations/" + B.class.getName()));
assertEquals("some.pkg.Stuff\n", Utils.getGeneratedResource(results.sources, "META-INF/services/annotations/some.pkg.B"));
*/
}

Expand All @@ -81,7 +120,7 @@ public interface Inaccessible {}
public static class Problematic {@C public Inaccessible bad() {return null;}}
public static class Fine {@C public String good() {return null;}}
public static class StillOK {@C public void whatever() {}}
@Test public void linkageErrorRobustness() throws Exception {
@Test void linkageErrorRobustness() throws Exception {
ClassLoader cl = new URLClassLoader(new URL[] {Index.class.getProtectionDomain().getCodeSource().getLocation(), AnnotationProcessorImplTest.class.getProtectionDomain().getCodeSource().getLocation()}, AnnotationProcessorImplTest.class.getClassLoader().getParent()) {
@Override protected Class<?> findClass(String name) throws ClassNotFoundException {
if (name.endsWith("$Inaccessible")) {
Expand All @@ -104,7 +143,7 @@ public static class StillOK {@C public void whatever() {}}

@Indexed @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.CONSTRUCTOR) public @interface OnConst {}
public static class Stuff {@OnConst public Stuff() {}}
@Test public void constructors() throws Exception {
@Test void constructors() throws Exception {
Iterator<AnnotatedElement> it = Index.list(OnConst.class, Stuff.class.getClassLoader()).iterator();
assertTrue(it.hasNext());
Constructor<?> c = (Constructor<?>) it.next();
Expand All @@ -114,7 +153,7 @@ public static class Stuff {@OnConst public Stuff() {}}


@Indexed @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PACKAGE) public @interface OnPackage {}
@Test public void packageinfo() throws IOException {
@Test void packageinfo() throws IOException {
Iterator<AnnotatedElement> it = Index.list(OnPackage.class, Stuff.class.getClassLoader()).iterator();
assertTrue(it.hasNext());
final Package p = (Package) it.next();
Expand Down
65 changes: 10 additions & 55 deletions src/test/java/org/jvnet/hudson/annotation_indexer/Utils.java
Original file line number Diff line number Diff line change
@@ -1,69 +1,24 @@
package org.jvnet.hudson.annotation_indexer;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.io.UncheckedIOException;
import java.util.List;
import java.util.Locale;
import javax.tools.Diagnostic;
import javax.tools.FileObject;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardLocation;
import net.java.dev.hickory.testing.Compilation;

// XXX partial copy of class from Stapler; should be pushed up into Hickory ASAP
class Utils {

// Filter out warnings about source 1.6 is obsolete in java 9
// This usually appears with other warnings
public static final List<String> IGNORE = List.of(
"RELEASE_6" // Filter out warnings about source 1.6 is obsolete in java 9+
);

public static List<Diagnostic<? extends JavaFileObject>> filterObsoleteSourceVersionWarnings(List<Diagnostic<? extends JavaFileObject>> diagnostics) {
List<Diagnostic<? extends JavaFileObject>> r = new ArrayList<>();
for (Diagnostic<? extends JavaFileObject> d : diagnostics) {
if (!isIgnored(d.getMessage(Locale.ENGLISH))) {
r.add(d);
}
}
return r;
}

private static boolean isIgnored(String message) {
for (String i : IGNORE) {
if (message.contains(i)) return true;
}
return false;
}

private static JavaFileManager fileManager(Compilation compilation) {
try {
Field f = Compilation.class.getDeclaredField("jfm");
f.setAccessible(true);
return (JavaFileManager) f.get(compilation);
} catch (Exception x) {
throw new AssertionError(x);
public static String getGeneratedResource(List<JavaFileObject> generated, String filename) {
JavaFileObject fo = generated.stream()
.filter(it -> it.getName().equals("/" + StandardLocation.CLASS_OUTPUT + "/" + filename))
.findFirst()
.orElse(null);
if (fo == null) {
return null;
}
}

/**
* Replacement for {@link Compilation#getGeneratedResource} that actually works.
* https://code.google.com/p/jolira-tools/issues/detail?id=11
*/
public static String getGeneratedResource(Compilation compilation, String filename) {
try {
FileObject fo = fileManager(compilation).getFileForOutput(StandardLocation.CLASS_OUTPUT, "", filename, null);
if (fo == null) {
return null;
}
return fo.getCharContent(true).toString();
} catch (FileNotFoundException x) {
return null;
} catch (IOException x) {
throw new RuntimeException(x);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}

Expand Down

0 comments on commit 0964f71

Please sign in to comment.