Skip to content

Commit b170c76

Browse files
authored
Add a test showing how void primitive class is allocated (#237)
1 parent e87a484 commit b170c76

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed

sourcegen-bytecode-writer/src/test/java/io/micronaut/sourcegen/bytecode/ByteCodeWriterTest.java

+91
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.micronaut.sourcegen.bytecode;
22

33
import io.micronaut.context.BeanResolutionContext;
4+
import io.micronaut.core.annotation.AnnotationClassValue;
45
import io.micronaut.core.reflect.ReflectionUtils;
56
import io.micronaut.inject.visitor.VisitorContext;
67
import io.micronaut.sourcegen.custom.visitor.innerTypes.GenerateInnerTypeInEnumVisitor;
@@ -25,6 +26,7 @@
2526
import java.io.PrintStream;
2627
import java.io.PrintWriter;
2728
import java.io.StringWriter;
29+
import java.lang.reflect.Constructor;
2830
import java.util.AbstractList;
2931
import java.util.List;
3032
import java.util.Map;
@@ -52,6 +54,94 @@
5254

5355
class ByteCodeWriterTest {
5456

57+
@Test
58+
void voidClassLoading() {
59+
final Constructor<?> CONSTRUCTOR_CLASS_VALUE = ReflectionUtils.getRequiredInternalConstructor(
60+
AnnotationClassValue.class,
61+
String.class
62+
);
63+
64+
final Constructor<?> CONSTRUCTOR_CLASS_VALUE_WITH_CLASS = ReflectionUtils.getRequiredInternalConstructor(
65+
AnnotationClassValue.class,
66+
Class.class
67+
);
68+
ClassTypeDef TYPE_ANNOTATION_CLASS_VALUE = ClassTypeDef.of(AnnotationClassValue.class);
69+
ClassDef def = ClassDef.builder("example.Example")
70+
.addModifiers(Modifier.PUBLIC)
71+
.addMethod(
72+
MethodDef.builder("loadClass")
73+
.addModifiers(Modifier.PRIVATE, Modifier.FINAL, Modifier.STATIC)
74+
.returns(TYPE_ANNOTATION_CLASS_VALUE)
75+
.buildStatic(methodParameters -> StatementDef.doTry(
76+
TYPE_ANNOTATION_CLASS_VALUE.instantiate(
77+
CONSTRUCTOR_CLASS_VALUE_WITH_CLASS,
78+
ExpressionDef.constant(TypeDef.VOID)
79+
).returning()
80+
).doCatch(Throwable.class, exceptionVar -> TYPE_ANNOTATION_CLASS_VALUE.instantiate(
81+
CONSTRUCTOR_CLASS_VALUE,
82+
ExpressionDef.constant(TypeDef.VOID.name())
83+
).returning()))
84+
)
85+
.build();
86+
87+
StringWriter bytecodeWriter = new StringWriter();
88+
byte[] bytes = generateFile(def, bytecodeWriter);
89+
90+
String bytecode = bytecodeWriter.toString();
91+
Assertions.assertEquals("""
92+
// class version 61.0 (61)
93+
// access flags 0x1
94+
// signature Ljava/lang/Object;
95+
// declaration: example/Example
96+
public class example/Example {
97+
98+
99+
// access flags 0x1
100+
public <init>()V
101+
ALOAD 0
102+
INVOKESPECIAL java/lang/Object.<init> ()V
103+
RETURN
104+
105+
// access flags 0x1A
106+
private final static loadClass()Lio/micronaut/core/annotation/AnnotationClassValue;
107+
TRYCATCHBLOCK L0 L1 L2 java/lang/Throwable
108+
L0
109+
NEW io/micronaut/core/annotation/AnnotationClassValue
110+
DUP
111+
GETSTATIC java/lang/Void.TYPE : Ljava/lang/Class;
112+
INVOKESPECIAL io/micronaut/core/annotation/AnnotationClassValue.<init> (Ljava/lang/Class;)V
113+
ARETURN
114+
L1
115+
GOTO L3
116+
L2
117+
ASTORE 0
118+
NEW io/micronaut/core/annotation/AnnotationClassValue
119+
DUP
120+
LDC "void"
121+
INVOKESPECIAL io/micronaut/core/annotation/AnnotationClassValue.<init> (Ljava/lang/String;)V
122+
ARETURN
123+
GOTO L3
124+
L3
125+
}
126+
""", bytecode);
127+
128+
Assertions.assertEquals("""
129+
package example;
130+
131+
import io.micronaut.core.annotation.AnnotationClassValue;
132+
133+
public class Example {
134+
private static final AnnotationClassValue loadClass() {
135+
try {
136+
return new AnnotationClassValue(Void.TYPE);
137+
} catch (Throwable var1) {
138+
return new AnnotationClassValue("void");
139+
}
140+
}
141+
}
142+
""", decompileToJava(bytes));
143+
}
144+
55145
@Test
56146
void ifElseExpression() {
57147

@@ -118,6 +208,7 @@ Object myMethod(boolean arg1, int arg2, String arg3) {
118208
""", decompileToJava(bytes));
119209
}
120210

211+
121212
@Test
122213
void compareOpsCast() {
123214

0 commit comments

Comments
 (0)