Skip to content

Commit 968fb8f

Browse files
committed
Found another ECJ Annotation Processor Bug
1 parent 7e175dc commit 968fb8f

File tree

10 files changed

+180
-1
lines changed

10 files changed

+180
-1
lines changed

ecj-test/.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ remotejdk*
22
zulu*
33
*.jar
44
*.tar.gz
5-
bin/
5+
bin*/
6+
src-gen/

ecj-test/compile-proc.params

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
-d
2+
bin-proc
3+
-s
4+
src-gen
5+
-verbose
6+
--release
7+
11
8+
src-proc/sample/processor/api/GeneratedResourceFamilyDefinition.java
9+
src-proc/sample/processor/api/WrapperDefinition.java
10+
src-proc/sample/processor/api/ResourceDefinition.java
11+
src-proc/sample/processor/GeneratorAnnotationProcessor.java

ecj-test/compile-procsample.params

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
-d
2+
bin
3+
-s
4+
src-gen
5+
-verbose
6+
--release
7+
11
8+
-processorpath
9+
bin-proc
10+
-processor
11+
sample.processor.GeneratorAnnotationProcessor
12+
-classpath
13+
bin-proc
14+
src/sample/processor/usage/testing/ITestResource.java
15+
src/sample/processor/usage/checks/ISomeChecks.java
16+
src/sample/processor/usage/MyResources.java
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package sample.processor;
2+
3+
import java.io.IOException;
4+
import java.io.PrintWriter;
5+
import java.util.Set;
6+
7+
import javax.annotation.processing.AbstractProcessor;
8+
import javax.annotation.processing.RoundEnvironment;
9+
import javax.annotation.processing.SupportedAnnotationTypes;
10+
import javax.annotation.processing.SupportedSourceVersion;
11+
import javax.lang.model.SourceVersion;
12+
import javax.lang.model.element.Element;
13+
import javax.lang.model.element.PackageElement;
14+
import javax.lang.model.element.TypeElement;
15+
import javax.tools.JavaFileObject;
16+
17+
import sample.processor.api.GeneratedResourceFamilyDefinition;
18+
19+
@SupportedAnnotationTypes({ "sample.processor.api.GeneratedResourceFamilyDefinition",
20+
"sample.processor.api.WrapperDefinition", "sample.processor.api.ResourceDefinition" })
21+
@SupportedSourceVersion(SourceVersion.RELEASE_8)
22+
public class GeneratorAnnotationProcessor extends AbstractProcessor {
23+
24+
@Override
25+
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
26+
27+
for (TypeElement annotation : annotations) {
28+
Set<? extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(annotation);
29+
30+
for (Element element : annotatedElements) {
31+
GeneratedResourceFamilyDefinition annotation2 = element
32+
.getAnnotation(GeneratedResourceFamilyDefinition.class);
33+
if (annotation2 != null) {
34+
String wrapperClassName = annotation2.wrapper().className();
35+
if (wrapperClassName == null || wrapperClassName.trim().isEmpty())
36+
continue;
37+
38+
try {
39+
writeWrapperFile(wrapperClassName, (TypeElement) element);
40+
} catch (IOException e) {
41+
throw new IllegalStateException("Unable to generate output. " + e.getMessage(), e);
42+
}
43+
}
44+
45+
}
46+
}
47+
48+
return true;
49+
}
50+
51+
private void writeWrapperFile(String simpleClassName, TypeElement annotatedElement) throws IOException {
52+
String packageName = ((PackageElement) annotatedElement.getEnclosingElement()).getQualifiedName() + ".wrappers";
53+
54+
String wrapperClassName = packageName + "." + simpleClassName;
55+
JavaFileObject builderFile = processingEnv.getFiler().createSourceFile(wrapperClassName, annotatedElement);
56+
57+
try (PrintWriter out = new PrintWriter(builderFile.openWriter())) {
58+
59+
out.print("package ");
60+
out.print(packageName);
61+
out.println(";");
62+
out.println();
63+
64+
out.print("public class ");
65+
out.print(simpleClassName);
66+
out.println(" {");
67+
out.println();
68+
69+
out.println("}");
70+
}
71+
}
72+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package sample.processor.api;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
@Retention(RetentionPolicy.RUNTIME)
9+
@Target({ElementType.TYPE})
10+
public @interface GeneratedResourceFamilyDefinition {
11+
12+
Class<?> feature();
13+
14+
WrapperDefinition wrapper() default @WrapperDefinition(className="");
15+
16+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package sample.processor.api;
2+
3+
public @interface ResourceDefinition {
4+
5+
Class<?> family();
6+
7+
String[] checks() default {};
8+
9+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package sample.processor.api;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
@Target(ElementType.TYPE)
9+
@Retention(RetentionPolicy.RUNTIME)
10+
public @interface WrapperDefinition {
11+
12+
/**
13+
* name of the wrapper class to generate.
14+
*/
15+
String className();
16+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package sample.processor.usage;
2+
3+
import sample.processor.api.GeneratedResourceFamilyDefinition;
4+
import sample.processor.api.WrapperDefinition;
5+
import sample.processor.usage.testing.ITestResource;
6+
7+
@GeneratedResourceFamilyDefinition(wrapper = @WrapperDefinition(className = "MyResourceWrapperForTesting"), feature = ITestResource.class)
8+
public class MyResources {
9+
10+
public void doSomething() {
11+
// whatever
12+
}
13+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package sample.processor.usage.checks;
2+
3+
public interface ISomeChecks {
4+
public final static String CHECK_FOO = "Is Foo Present";
5+
public final static String CHECK_BAR = "Is Bar Absent";
6+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package sample.processor.usage.testing;
2+
3+
import sample.processor.api.ResourceDefinition;
4+
import sample.processor.usage.MyResources;
5+
import sample.processor.usage.checks.ISomeChecks;
6+
import sample.processor.usage.wrappers.MyResourceWrapperForTesting;
7+
8+
/**
9+
* A Test resource
10+
*/
11+
@ResourceDefinition(family = MyResources.class, checks = { ISomeChecks.CHECK_FOO })
12+
public interface ITestResource {
13+
14+
/**
15+
* For testing use the generated {@link MyResourceWrapperForTesting}
16+
*/
17+
String TEST_NAME = "foobar";
18+
19+
}

0 commit comments

Comments
 (0)