Skip to content

Commit

Permalink
Merge pull request #17 from GoodforGod/dev
Browse files Browse the repository at this point in the history
[1.1.1]
  • Loading branch information
GoodforGod authored Jan 8, 2024
2 parents 5940736 + 0d8277a commit d098c4d
Show file tree
Hide file tree
Showing 25 changed files with 265 additions and 55 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ Features:

[**Gradle**](https://mvnrepository.com/artifact/io.goodforgod/graalvm-hint-processor)
```groovy
annotationProcessor "io.goodforgod:graalvm-hint-processor:1.1.0"
compileOnly "io.goodforgod:graalvm-hint-annotations:1.1.0"
annotationProcessor "io.goodforgod:graalvm-hint-processor:1.1.1"
compileOnly "io.goodforgod:graalvm-hint-annotations:1.1.1"
```

[**Maven**](https://mvnrepository.com/artifact/io.goodforgod/graalvm-hint-processor)
Expand All @@ -34,14 +34,14 @@ compileOnly "io.goodforgod:graalvm-hint-annotations:1.1.0"
<dependency>
<groupId>io.goodforgod</groupId>
<artifactId>graalvm-hint-annotations</artifactId>
<version>1.1.0</version>
<version>1.1.1</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.goodforgod</groupId>
<artifactId>graalvm-hint-processor</artifactId>
<version>1.1.0</version>
<version>1.1.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
Expand All @@ -59,7 +59,7 @@ compileOnly "io.goodforgod:graalvm-hint-annotations:1.1.0"
<path>
<groupId>io.goodforgod</groupId>
<artifactId>graalvm-hint-processor</artifactId>
<version>1.1.0</version>
<version>1.1.1</version>
</path>
</annotationProcessorPaths>
</configuration>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@
import io.goodforgod.graalvm.hint.annotation.ReflectionHint;
import io.goodforgod.graalvm.hint.annotation.ReflectionHint.AccessType;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;

Expand Down Expand Up @@ -72,33 +69,6 @@ protected Set<TypeElement> getAnnotatedTypeElements(RoundEnvironment roundEnv) {
return HintUtils.getAnnotatedElements(roundEnv, classes);
}

protected Predicate<AnnotationValue> getParentAnnotationPredicate(ReflectionHint.AccessType[] accessTypes) {
return a -> {
final List<String> accessTypeNames = Arrays.stream(accessTypes)
.map(Enum::name)
.collect(Collectors.toList());

return ((AnnotationMirror) a).getElementValues().entrySet().stream()
.filter(e -> e.getKey().getSimpleName().contentEquals("value"))
.anyMatch(entry -> {
final Object value = entry.getValue().getValue();
final List<String> annotationAccessTypes = (value instanceof Collection)
? ((Collection<?>) value).stream()
.map(attr -> {
// Java 11 and Java 17 behave differently (different impls)
final String attrValue = attr.toString();
final int classStartIndex = attrValue.lastIndexOf('.');
return (classStartIndex == -1)
? attrValue
: attrValue.substring(classStartIndex + 1);
}).collect(Collectors.toList())
: List.of(value.toString());

return annotationAccessTypes.equals(accessTypeNames);
});
};
}

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (annotations.isEmpty()) {
Expand Down Expand Up @@ -176,7 +146,7 @@ private static String getInnerTypeName(String typeName) {
}

Collections.reverse(classType);
return classType.stream().sequential().collect(Collectors.joining("$", packagePrefix + ".", ""));
return classType.stream().collect(Collectors.joining("$", packagePrefix + ".", ""));
}

private static List<String> getGraalAccessType(AccessType accessType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ private List<Configuration> getDynamicProxyConfigurations(TypeElement type) {
.collect(Collectors.toList());

if (interfaceConfigurations.isEmpty() && isSelfConfiguration(type)) {
final String elementName = type.getQualifiedName().toString();
final String elementName = HintUtils.getElementClassName(type);
if (type.getKind().isInterface()) {
return List.of(new Configuration(List.of(elementName)));
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.*;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.util.ElementFilter;
import javax.tools.Diagnostic;
import javax.tools.FileObject;
Expand Down Expand Up @@ -84,19 +85,53 @@ static List<String> getAnnotationFieldValues(AnnotationMirror mirror,
.flatMap(e -> {
final Object value = e.getValue().getValue();
if (value instanceof Collection) {
return ((Collection<?>) value).stream().map(v -> (v instanceof AnnotationValue)
? ((AnnotationValue) v).getValue().toString()
: v.toString());
} else if (value instanceof AnnotationValue) {
return Stream.of(((AnnotationValue) value).getValue().toString());
return ((Collection<?>) value).stream().map(HintUtils::getAnnotationValueAsString);
} else {
return Stream.of(getAnnotationValueAsString(value));
}

return Stream.of(value.toString());
})
.filter(e -> !e.isBlank())
.collect(Collectors.toList());
}

private static String getAnnotationValueAsString(Object v) {
if (v instanceof AnnotationValue) {
final Object itemValue = ((AnnotationValue) v).getValue();
if (itemValue instanceof DeclaredType) {
final Element element = ((DeclaredType) itemValue).asElement();
return getElementClassName(element);
} else {
return itemValue.toString();
}
} else {
return v.toString();
}
}

static String getElementClassName(Element element) {
final List<String> parts = new ArrayList<>();

Element next = element;
while (next != null) {
parts.add(next.getSimpleName().toString());
next = next.getEnclosingElement();
if (next instanceof PackageElement) {
if (!((PackageElement) next).isUnnamed()) {
parts.add(".");
parts.add(next.toString());
}
break;
} else if (next instanceof ModuleElement) {
break;
} else {
parts.add("$");
}
}

Collections.reverse(parts);
return String.join("", parts);
}

static boolean writeConfigFile(HintFile file, String data, ProcessingEnvironment processingEnv) {
try {
final FileObject fileObject = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ private static Collection<Initialization> getAnnotationPhases(TypeElement elemen
final List<String> typeNames = Arrays.asList(hint.typeNames());
final List<String> types = HintUtils.getAnnotationFieldClassNames(element, InitializationHint.class, "types");
if (types.isEmpty() && typeNames.isEmpty()) {
final String selfName = element.getQualifiedName().toString();
final String selfName = HintUtils.getElementClassName(element);
return List.of(new Initialization(selfName, phase));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ private static Collection<Access> getAnnotationAccesses(TypeElement element,
final List<String> typeNames = Arrays.asList(hint.typeNames());
final List<String> types = HintUtils.getAnnotationFieldClassNames(element, JniHint.class, "types");
if (types.isEmpty() && typeNames.isEmpty()) {
final String selfName = element.getQualifiedName().toString();
final String selfName = HintUtils.getElementClassName(element);
return List.of(new Access(selfName, accessTypes));
}

Expand Down Expand Up @@ -79,7 +79,7 @@ private static List<Access> getParentAnnotationAccesses(TypeElement type,
.toArray(JniHint.AccessType[]::new));

return (types.isEmpty() && typeNames.isEmpty())
? Stream.of(new Access(type.getQualifiedName().toString(), accessTypes))
? Stream.of(new Access(HintUtils.getElementClassName(type), accessTypes))
: Stream.concat(types.stream(), typeNames.stream()).map(t -> new Access(t, accessTypes));
})
.collect(Collectors.toList());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ private Stream<String> getTypes(TypeElement element, LinkHint hint) {
final List<String> types = HintUtils.getAnnotationFieldClassNames(element, LinkHint.class, "types");
final List<String> typeNames = Arrays.asList(hint.typeNames());
if (types.isEmpty() && typeNames.isEmpty()) {
return Stream.of(element.getQualifiedName().toString());
return Stream.of(HintUtils.getElementClassName(element));
} else {
final Stream<String> typeStream = types.stream().map(c -> c.endsWith(".class")
? c.substring(0, c.length() - 6)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ private static Collection<Access> getAnnotationAccesses(TypeElement element,
final List<String> typeNames = Arrays.asList(hint.typeNames());
final List<String> types = HintUtils.getAnnotationFieldClassNames(element, ReflectionHint.class, "types");
if (types.isEmpty() && typeNames.isEmpty()) {
final String selfName = element.getQualifiedName().toString();
final String selfName = HintUtils.getElementClassName(element);
return List.of(new Access(selfName, accessTypes));
}

Expand Down Expand Up @@ -78,7 +78,7 @@ private static List<Access> getParentAnnotationAccesses(TypeElement type,
.toArray(AccessType[]::new);

return (types.isEmpty() && typeNames.isEmpty())
? Stream.of(new Access(type.getQualifiedName().toString(), accessTypes))
? Stream.of(new Access(HintUtils.getElementClassName(type), accessTypes))
: Stream.concat(types.stream(), typeNames.stream()).map(t -> new Access(t, accessTypes));
})
.collect(Collectors.toList());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package io.goodforgod.graalvm.hint.processor;

import static io.goodforgod.graalvm.hint.processor.InnerClass.*;

import io.goodforgod.graalvm.hint.annotation.ReflectionHint;

@ReflectionHint(types = Example1.class)
public class InnerClass {

public static class Example1 {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.goodforgod.graalvm.hint.processor;

import io.goodforgod.graalvm.hint.annotation.ReflectionHint;

public class InnerSelf {

@ReflectionHint
public static class Example1 {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,88 @@ void reflectionHintForMultipleAccessHints() {
.contentsAsString(StandardCharsets.UTF_8)
.isEqualTo(getResourceContentAsString("reflectionhint/generated/reflect-config-only-many-access.json"));
}

@Test
void reflectionHintForInnerClass() {
final Compilation compilation = Compiler.javac()
.withProcessors(new ReflectionHintProcessor())
.compile(JavaFileObjects.forResource("reflectionhint/source/InnerClass.java"));

CompilationSubject.assertThat(compilation).succeeded();
CompilationSubject.assertThat(compilation)
.generatedFile(StandardLocation.CLASS_OUTPUT,
"META-INF/native-image/io.goodforgod.graalvm.hint.processor/hint/reflect-config.json")
.contentsAsString(StandardCharsets.UTF_8)
.isEqualTo(getResourceContentAsString("reflectionhint/generated/reflect-config-inner-class.json"));
}

@Test
void reflectionHintForInnerClassSelf() {
final Compilation compilation = Compiler.javac()
.withProcessors(new ReflectionHintProcessor())
.compile(JavaFileObjects.forResource("reflectionhint/source/InnerSelf.java"));

CompilationSubject.assertThat(compilation).succeeded();
CompilationSubject.assertThat(compilation)
.generatedFile(StandardLocation.CLASS_OUTPUT,
"META-INF/native-image/io.goodforgod.graalvm.hint.processor/hint/reflect-config.json")
.contentsAsString(StandardCharsets.UTF_8)
.isEqualTo(getResourceContentAsString("reflectionhint/generated/reflect-config-inner-self.json"));
}

@Test
void reflectionHintForInnerInnerClass() {
final Compilation compilation = Compiler.javac()
.withProcessors(new ReflectionHintProcessor())
.compile(JavaFileObjects.forResource("reflectionhint/source/InnerInnerClass.java"));

CompilationSubject.assertThat(compilation).succeeded();
CompilationSubject.assertThat(compilation)
.generatedFile(StandardLocation.CLASS_OUTPUT,
"META-INF/native-image/io.goodforgod.graalvm.hint.processor/hint/reflect-config.json")
.contentsAsString(StandardCharsets.UTF_8)
.isEqualTo(getResourceContentAsString("reflectionhint/generated/reflect-config-inner-inner-class.json"));
}

@Test
void reflectionHintForInnerInnerClassSelf() {
final Compilation compilation = Compiler.javac()
.withProcessors(new ReflectionHintProcessor())
.compile(JavaFileObjects.forResource("reflectionhint/source/InnerInnerSelf.java"));

CompilationSubject.assertThat(compilation).succeeded();
CompilationSubject.assertThat(compilation)
.generatedFile(StandardLocation.CLASS_OUTPUT,
"META-INF/native-image/io.goodforgod.graalvm.hint.processor/hint/reflect-config.json")
.contentsAsString(StandardCharsets.UTF_8)
.isEqualTo(getResourceContentAsString("reflectionhint/generated/reflect-config-inner-inner-self.json"));
}

@Test
void reflectionHintForInnerClassUnnamed() {
final Compilation compilation = Compiler.javac()
.withProcessors(new ReflectionHintProcessor())
.compile(JavaFileObjects.forResource("reflectionhint/source/InnerClassUnnamed.java"));

CompilationSubject.assertThat(compilation).succeeded();
CompilationSubject.assertThat(compilation)
.generatedFile(StandardLocation.CLASS_OUTPUT,
"META-INF/native-image/io.graalvm.hint/hint/reflect-config.json")
.contentsAsString(StandardCharsets.UTF_8)
.isEqualTo(getResourceContentAsString("reflectionhint/generated/reflect-config-inner-class-unnamed.json"));
}

@Test
void reflectionHintForInnerClassSelfUnnamed() {
final Compilation compilation = Compiler.javac()
.withProcessors(new ReflectionHintProcessor())
.compile(JavaFileObjects.forResource("reflectionhint/source/InnerSelfUnnamed.java"));

CompilationSubject.assertThat(compilation).succeeded();
CompilationSubject.assertThat(compilation)
.generatedFile(StandardLocation.CLASS_OUTPUT,
"META-INF/native-image/io.graalvm.hint/hint/reflect-config.json")
.contentsAsString(StandardCharsets.UTF_8)
.isEqualTo(getResourceContentAsString("reflectionhint/generated/reflect-config-inner-self-unnamed.json"));
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
[{
"name": "io.goodforgod.graalvm.hint.processor.Multiple.Example1",
"name": "io.goodforgod.graalvm.hint.processor.Multiple$Example1",
"allDeclaredFields": true
},
{
"name": "io.goodforgod.graalvm.hint.processor.Multiple.Example2",
"name": "io.goodforgod.graalvm.hint.processor.Multiple$Example2",
"allDeclaredFields": true
},
{
"name": "io.goodforgod.graalvm.hint.processor.Multiple.Example3",
"name": "io.goodforgod.graalvm.hint.processor.Multiple$Example3",
"allDeclaredConstructors": true,
"allDeclaredFields": true,
"allDeclaredMethods": true
},
{
"name": "io.goodforgod.graalvm.hint.processor.Multiple.Example4",
"name": "io.goodforgod.graalvm.hint.processor.Multiple$Example4",
"allDeclaredConstructors": true,
"allDeclaredFields": true,
"allDeclaredMethods": true
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[{
"name": "InnerClassUnnamed$Example1",
"allDeclaredConstructors": true,
"allDeclaredFields": true,
"allDeclaredMethods": true
}]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[{
"name": "io.goodforgod.graalvm.hint.processor.InnerClass$Example1",
"allDeclaredConstructors": true,
"allDeclaredFields": true,
"allDeclaredMethods": true
}]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[{
"name": "io.goodforgod.graalvm.hint.processor.InnerInnerClass$InnerClass$Example1",
"allDeclaredConstructors": true,
"allDeclaredFields": true,
"allDeclaredMethods": true
}]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[{
"name": "io.goodforgod.graalvm.hint.processor.InnerInnerSelf$InnerClass$Example1",
"allDeclaredConstructors": true,
"allDeclaredFields": true,
"allDeclaredMethods": true
}]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[{
"name": "InnerSelfUnnamed$Example1",
"allDeclaredConstructors": true,
"allDeclaredFields": true,
"allDeclaredMethods": true
}]
Loading

0 comments on commit d098c4d

Please sign in to comment.