99import io .jooby .SneakyThrows ;
1010import io .jooby .internal .apt .Primitives ;
1111import io .jooby .internal .apt .TypeDefinition ;
12- import io .jooby .internal .apt .asm .ArrayWriter ;
1312import org .objectweb .asm .ClassWriter ;
1413import org .objectweb .asm .MethodVisitor ;
1514import org .objectweb .asm .Opcodes ;
1615import org .objectweb .asm .Type ;
1716
1817import javax .lang .model .element .AnnotationMirror ;
1918import javax .lang .model .element .AnnotationValue ;
19+ import javax .lang .model .element .Element ;
2020import javax .lang .model .element .ExecutableElement ;
21+ import javax .lang .model .element .Name ;
22+ import javax .lang .model .element .TypeElement ;
23+ import javax .lang .model .element .VariableElement ;
2124import javax .lang .model .type .TypeMirror ;
2225import javax .lang .model .util .Elements ;
2326import javax .lang .model .util .Types ;
3336
3437import static io .jooby .SneakyThrows .throwingConsumer ;
3538import static java .util .Collections .singletonList ;
39+ import static java .util .Collections .sort ;
3640import static org .objectweb .asm .Opcodes .ACC_PRIVATE ;
3741import static org .objectweb .asm .Opcodes .ACC_STATIC ;
3842import static org .objectweb .asm .Opcodes .ALOAD ;
5963import static org .objectweb .asm .Opcodes .POP ;
6064
6165public class RouteAttributesWriter {
66+
67+ private static class EnumValue {
68+ private String type ;
69+
70+ private String value ;
71+
72+ public EnumValue (String type , String value ) {
73+ this .type = type ;
74+ this .value = value ;
75+ }
76+ }
77+
6278 private static final Predicate <String > HTTP_ANNOTATION = it ->
6379 it .startsWith ("io.jooby.annotations" )
6480 || it .startsWith ("javax.ws.rs" );
@@ -67,8 +83,10 @@ public class RouteAttributesWriter {
6783 || it .endsWith ("NotNull" )
6884 || it .endsWith ("Nullable" );
6985
86+ private static final Predicate <String > KOTLIN_ANNOTATION = it -> it .equals ("kotlin.Metadata" );
87+
7088 private static final Predicate <String > ATTR_FILTER = HTTP_ANNOTATION .negate ()
71- .and (NULL_ANNOTATION .negate ());
89+ .and (NULL_ANNOTATION .negate ()). and ( KOTLIN_ANNOTATION . negate ()) ;
7290
7391 private final Elements elements ;
7492
@@ -147,6 +165,13 @@ private Object annotationValue(AnnotationValue annotationValue) {
147165 if (value instanceof AnnotationMirror ) {
148166 Map <String , Object > annotation = annotationMap (singletonList ((AnnotationMirror ) value ), null );
149167 return annotation .isEmpty () ? null : annotation ;
168+ } else if (value instanceof VariableElement ) {
169+ // enum
170+ VariableElement vare = (VariableElement ) annotationValue .getValue ();
171+ TypeMirror typeMirror = vare .asType ();
172+ Element element = types .asElement (typeMirror );
173+ Name binaryName = elements .getBinaryName ((TypeElement ) element );
174+ return new EnumValue (binaryName .toString (), value .toString ());
150175 } else if (value instanceof List ) {
151176 List <AnnotationValue > values = (List ) value ;
152177 if (values .size () > 0 ) {
@@ -169,8 +194,9 @@ private void annotationValue(ClassWriter writer, MethodVisitor visitor, Object v
169194 .visitMethodInsn (INVOKESTATIC , moduleInternalName , newMap , "()Ljava/util/Map;" , false );
170195 } else if (value instanceof List ) {
171196 List values = (List ) value ;
197+ String componentType = values .get (0 ) instanceof EnumValue ? ((EnumValue ) values .get (0 )).type : values .get (0 ).getClass ().getName ();
172198 if (values .size () > 0 ) {
173- ArrayWriter .write (visitor , values . get ( 0 ). getClass () , values , throwingConsumer (v ->
199+ ArrayWriter .write (visitor , componentType , values , throwingConsumer (v ->
174200 annotationValue (writer , visitor , v )
175201 ));
176202 Method asList = Arrays .class .getDeclaredMethod ("asList" , Object [].class );
@@ -245,6 +271,10 @@ private void annotationSingleValue(MethodVisitor visitor, Object value)
245271 } else {
246272 visitor .visitLdcInsn (typeDef .toJvmType ());
247273 }
274+ } else if (value instanceof EnumValue ) {
275+ EnumValue enumValue = (EnumValue ) value ;
276+ Type type = Type .getObjectType (enumValue .type .replace ("." , "/" ));
277+ visitor .visitFieldInsn (GETSTATIC , type .getInternalName (), enumValue .value , type .getDescriptor ());
248278 }
249279
250280 Method wrapper = Primitives .wrapper (value .getClass ());
0 commit comments