Skip to content

Commit

Permalink
Store enum values as strings
Browse files Browse the repository at this point in the history
  • Loading branch information
dstepanov committed Sep 6, 2024
1 parent 9d339f7 commit eb30f20
Show file tree
Hide file tree
Showing 11 changed files with 175 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -591,9 +591,7 @@ private static void pushValue(Type declaringType, ClassVisitor declaringClassWri
invokeLoadClassValueMethod(declaringType, declaringClassWriter, methodVisitor, loadTypeMethods, acv);
}
} else if (value instanceof Enum<?> enumObject) {
Class<?> declaringClass = enumObject.getDeclaringClass();
Type t = Type.getType(declaringClass);
methodVisitor.getStatic(t, enumObject.name(), t);
methodVisitor.push(enumObject.name()); // Always store enum values as string
} else if (value.getClass().isArray()) {
Class<?> jt = ReflectionUtils.getPrimitiveType(value.getClass().getComponentType());
final Type componentType = Type.getType(jt);
Expand Down
2 changes: 2 additions & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ include "test-suite-logback-graalvm"
include "test-suite-netty-ssl-graalvm"
include "test-suite-kotlin-graalvm"
include "test-utils"
include "test-suite-annotation-remapper"
include "test-suite-annotation-remapper-visitor"

// benchmarks
include "benchmarks"
11 changes: 11 additions & 0 deletions test-suite-annotation-remapper-visitor/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
plugins {
id "java"
}

description = "A simple remapping visitor"

dependencies {
implementation(projects.injectJava)
// Use an enum that shouldn't be present and the runtime to simulate added enum value that doesn't exist
implementation libs.blaze.persistence.core
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package example.micronaut;

import com.blazebit.persistence.spi.JpqlFunctionKind;
import io.micronaut.inject.ast.ClassElement;
import io.micronaut.inject.visitor.TypeElementVisitor;
import io.micronaut.inject.visitor.VisitorContext;

public class AddAnnotationWithEnumVisitor implements TypeElementVisitor<Object, Object> {

@Override
public VisitorKind getVisitorKind() {
return VisitorKind.ISOLATING;
}

@Override
public void visitClass(ClassElement element, VisitorContext context) {
// Simulate annotating with enum value
// Micronaut should store the string value and not the enum value in the metadata
element.annotate("Something", builder -> builder.value(JpqlFunctionKind.DETERMINISTIC));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
example.micronaut.AddAnnotationWithEnumVisitor
34 changes: 34 additions & 0 deletions test-suite-annotation-remapper/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
plugins {
id "java"
id "org.graalvm.buildtools.native"
}

description = "Test suite for definitions with added enum values"

tasks.withType(Test).configureEach {
useJUnitPlatform()
}

dependencies {
testAnnotationProcessor(projects.testSuiteAnnotationRemapperVisitor)
testAnnotationProcessor(projects.injectJava)
testImplementation(projects.httpServerNetty)
implementation(projects.jacksonDatabind)
testImplementation(projects.httpClient)
testImplementation(libs.logback.classic)
testImplementation(libs.micronaut.test.junit5) {
exclude group: 'io.micronaut'
}
}

graalvmNative {
toolchainDetection = false
metadataRepository {
enabled = true
}
binaries {
configureEach {
resources.autodetect()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2017-2020 original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package example.micronaut;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PACKAGE, ElementType.TYPE, ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD})
public @interface AddEnumAnnotationValueHere {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package example.micronaut;

import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;

@AddEnumAnnotationValueHere
@Controller("/hello")
public class HelloController {

@Get
public MyRecord index() {
return new MyRecord("Denis", 123);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package example.micronaut;

import io.micronaut.context.BeanContext;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.client.HttpClient;
import io.micronaut.http.client.annotation.Client;
import io.micronaut.inject.BeanDefinition;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;

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

@MicronautTest
public class HelloControllerTest {

@Inject
@Client("/")
HttpClient client;

@Inject
BeanContext beanContext;

@Test
void testHelloWorldResponse() {
String response = client.toBlocking()
.retrieve(HttpRequest.GET("/hello"));
assertEquals("""
{"name":"Denis","age":123}""", response);
}

@Test
void testNewAnnotationIsAdded() {
BeanDefinition<HelloController> beanDefinition = beanContext.getBeanDefinition(HelloController.class);
assertTrue(beanDefinition.hasAnnotation("Something"));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package example.micronaut;

import io.micronaut.core.annotation.Introspected;

@AddEnumAnnotationValueHere
@Introspected
public record MyRecord(String name, int age) {
}
16 changes: 16 additions & 0 deletions test-suite-annotation-remapper/src/test/resources/logback.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<configuration>

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>

<root level="info">
<appender-ref ref="STDOUT" />
</root>

</configuration>

0 comments on commit eb30f20

Please sign in to comment.