From c5d9191e019b1531ac55dfaf79e47e15c6942a2c Mon Sep 17 00:00:00 2001 From: Sergio del Amo Date: Sun, 7 Apr 2024 12:31:09 +0200 Subject: [PATCH 1/3] projectVersion=4.5.0-SNAPSHOT [ci skip] --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 41276cbc523..6da77fc45d6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -projectVersion=4.4.2-SNAPSHOT +projectVersion=4.5.0-SNAPSHOT projectGroupId=io.micronaut projectDesc=Core components supporting the Micronaut Framework title=Micronaut Core From 5e6a9b0af44c6ea2f521e9469a5a7d7219f385dd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Apr 2024 10:53:39 +0200 Subject: [PATCH 2/3] fix(deps): update dependency ch.qos.logback:logback-classic to v1.5.4 (#10695) * fix(deps): update dependency io.micronaut.aws:micronaut-aws-bom to v4.5.0 (#10691) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * fix(deps): update dependency ch.qos.logback:logback-classic to v1.5.4 --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 15fb5784713..3dc361833de 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -32,10 +32,10 @@ jazzer = "0.22.1" jcache = "1.1.1" junit5 = "5.10.2" junit-platform="1.10.2" -logback = "1.5.3" +logback = "1.5.4" logbook-netty = "2.16.0" log4j = "2.22.1" -micronaut-aws = "4.4.3" +micronaut-aws = "4.5.0" micronaut-groovy = "4.2.0" micronaut-session = "4.2.0" micronaut-sql = "5.3.0" From 3182849fa0c324a04454832abe5da2867d7bf45b Mon Sep 17 00:00:00 2001 From: altro3 Date: Wed, 10 Apr 2024 15:54:02 +0700 Subject: [PATCH 3/3] Add ability to get constantValue for final fields (#10693) * Add ability to get constantValue for final fields Fixed #10692 * Update core-processor/src/main/java/io/micronaut/inject/ast/FieldElement.java --------- Co-authored-by: Sergio del Amo --- .../io/micronaut/inject/ast/FieldElement.java | 24 ++++++ .../groovy/visitor/GroovyFieldElement.java | 10 +++ .../visitor/GroovyEnumElementSpec.groovy | 32 ++++++++ .../processing/visitor/JavaFieldElement.java | 5 ++ .../annotation/JavaEnumElementSpec.groovy | 32 ++++++++ .../ast/visitor/KotlinEnumElementSpec.groovy | 73 +++++++++++++++++++ 6 files changed, 176 insertions(+) create mode 100644 inject-kotlin/src/test/groovy/io/micronaut/kotlin/processing/ast/visitor/KotlinEnumElementSpec.groovy diff --git a/core-processor/src/main/java/io/micronaut/inject/ast/FieldElement.java b/core-processor/src/main/java/io/micronaut/inject/ast/FieldElement.java index 8689aaeffc3..2bb9e1d9824 100644 --- a/core-processor/src/main/java/io/micronaut/inject/ast/FieldElement.java +++ b/core-processor/src/main/java/io/micronaut/inject/ast/FieldElement.java @@ -26,6 +26,30 @@ */ public interface FieldElement extends TypedElement, MemberElement { + /** + * Returns the value of this variable if this is a {@code final} + * field initialized to a compile-time constant. Returns {@code + * null} otherwise. The value will be of a primitive type or a + * {@code String}. If the value is of a primitive type, it is + * wrapped in the appropriate wrapper class (such as {@link + * Integer}). + * + *

Note that not all {@code final} fields will have + * constant values. In particular, {@code enum} constants are + * not considered to be compile-time constants. To have a + * constant value, a field's type must be either a primitive type + * or {@code String}. + * + * @return the value of this variable if this is a {@code final} + * field initialized to a compile-time constant, or {@code null} + * otherwise + * + * @since 4.5.0 + */ + default Object getConstantValue() { + return null; + } + /** * Obtain the generic type with the associated annotation metadata for the field. * diff --git a/inject-groovy/src/main/groovy/io/micronaut/ast/groovy/visitor/GroovyFieldElement.java b/inject-groovy/src/main/groovy/io/micronaut/ast/groovy/visitor/GroovyFieldElement.java index 403619a0653..04e645fdb76 100644 --- a/inject-groovy/src/main/groovy/io/micronaut/ast/groovy/visitor/GroovyFieldElement.java +++ b/inject-groovy/src/main/groovy/io/micronaut/ast/groovy/visitor/GroovyFieldElement.java @@ -25,6 +25,7 @@ import io.micronaut.inject.ast.annotation.ElementAnnotationMetadataFactory; import org.codehaus.groovy.ast.ClassNode; import org.codehaus.groovy.ast.FieldNode; +import org.codehaus.groovy.ast.expr.ConstantExpression; import java.lang.reflect.Modifier; import java.util.Map; @@ -149,6 +150,15 @@ public boolean isPackagePrivate() { return !Modifier.isPublic(fieldNode.getModifiers()) && !Modifier.isProtected(fieldNode.getModifiers()) && !Modifier.isPrivate(fieldNode.getModifiers()); } + @Override + public Object getConstantValue() { + if (fieldNode.hasInitialExpression() + && fieldNode.getInitialValueExpression() instanceof ConstantExpression constExpression) { + return constExpression.getValue(); + } + return null; + } + @NonNull @Override public ClassElement getType() { diff --git a/inject-groovy/src/test/groovy/io/micronaut/ast/groovy/visitor/GroovyEnumElementSpec.groovy b/inject-groovy/src/test/groovy/io/micronaut/ast/groovy/visitor/GroovyEnumElementSpec.groovy index e3d8ed3ec41..e61330dc171 100644 --- a/inject-groovy/src/test/groovy/io/micronaut/ast/groovy/visitor/GroovyEnumElementSpec.groovy +++ b/inject-groovy/src/test/groovy/io/micronaut/ast/groovy/visitor/GroovyEnumElementSpec.groovy @@ -76,4 +76,36 @@ enum MyEnum { enumConstantAnnotation.stringValue().get() == "C" } } + + void "get enum constantValue for final fields"() { + given: + def element = (EnumElement) buildClassElement(""" +package test + +enum MyEnum { + + ENUM_VAL1(10), + ENUM_VAL2(11), + UNRECOGNIZED(-1), + ; + + public static final int ENUM_VAL1_VALUE = 10 + public static final int ENUM_VAL2_VALUE = 11 + + private final int value + + MyEnum(int value) { + this.value = value + } +} +""") + expect: + for (def field : element.fields) { + if (field.name == 'ENUM_VAL1_VALUE') { + field.constantValue == 10 + } else if (field.name == 'ENUM_VAL2_VALUE') { + field.constantValue == 11 + } + } + } } diff --git a/inject-java/src/main/java/io/micronaut/annotation/processing/visitor/JavaFieldElement.java b/inject-java/src/main/java/io/micronaut/annotation/processing/visitor/JavaFieldElement.java index d319ed0a66c..a2ec2de4fc9 100644 --- a/inject-java/src/main/java/io/micronaut/annotation/processing/visitor/JavaFieldElement.java +++ b/inject-java/src/main/java/io/micronaut/annotation/processing/visitor/JavaFieldElement.java @@ -86,6 +86,11 @@ public FieldElement withAnnotationMetadata(AnnotationMetadata annotationMetadata return (FieldElement) super.withAnnotationMetadata(annotationMetadata); } + @Override + public Object getConstantValue() { + return variableElement.getConstantValue(); + } + @NonNull @Override public ClassElement getType() { diff --git a/inject-java/src/test/groovy/io/micronaut/annotation/JavaEnumElementSpec.groovy b/inject-java/src/test/groovy/io/micronaut/annotation/JavaEnumElementSpec.groovy index 5565e82ad91..52e2d5c9d6b 100644 --- a/inject-java/src/test/groovy/io/micronaut/annotation/JavaEnumElementSpec.groovy +++ b/inject-java/src/test/groovy/io/micronaut/annotation/JavaEnumElementSpec.groovy @@ -71,4 +71,36 @@ enum MyEnum { expect: element.values().size() == 2; } + + void "get enum constantValue for final fields"() { + given: + def element = (EnumElement) buildClassElement(""" +package test; + +enum MyEnum { + + ENUM_VAL1(10), + ENUM_VAL2(11), + UNRECOGNIZED(-1), + ; + + public static final int ENUM_VAL1_VALUE = 10; + public static final int ENUM_VAL2_VALUE = 11; + + private final int value; + + MyEnum(int value) { + this.value = value; + } +} +""") + expect: + for (def field : element.fields) { + if (field.name == 'ENUM_VAL1_VALUE') { + field.constantValue == 10 + } else if (field.name == 'ENUM_VAL2_VALUE') { + field.constantValue == 11 + } + } + } } diff --git a/inject-kotlin/src/test/groovy/io/micronaut/kotlin/processing/ast/visitor/KotlinEnumElementSpec.groovy b/inject-kotlin/src/test/groovy/io/micronaut/kotlin/processing/ast/visitor/KotlinEnumElementSpec.groovy new file mode 100644 index 00000000000..5cc8e477a99 --- /dev/null +++ b/inject-kotlin/src/test/groovy/io/micronaut/kotlin/processing/ast/visitor/KotlinEnumElementSpec.groovy @@ -0,0 +1,73 @@ +package io.micronaut.kotlin.processing.ast.visitor + +import io.micronaut.annotation.processing.test.AbstractKotlinCompilerSpec +import io.micronaut.inject.ast.ClassElement +import io.micronaut.inject.ast.ElementQuery +import io.micronaut.inject.ast.EnumElement +import spock.lang.Ignore +import spock.lang.PendingFeature + +class KotlinEnumElementSpec extends AbstractKotlinCompilerSpec { + + void "test is enum"() { + given: + def element = buildClassElement("test.MyEnum", """ +package test + +enum class MyEnum { + A, B +} +""") + expect: + element.isEnum() + element.getPrimaryConstructor().get().getDeclaringType().isEnum() + } + + void "test inner enum is enum"() { + given: + def element = buildClassElement("test.Foo",""" +package test + +class Foo { + + enum class MyEnum { + A, B + } +} +""") + expect: + element.getEnclosedElement(ElementQuery.of(ClassElement.class)).get().getPrimaryConstructor().get().getDeclaringType().isEnum() + } + + @Ignore + @PendingFeature(reason = "constantValue not available with KSP") + void "get enum constantValue for final fields"() { + given: + def element = (EnumElement) buildClassElement("test.MyEnum", """ +package test + +enum class MyEnum( + value: Int +) { + + ENUM_VAL1(10), + ENUM_VAL2(11), + UNRECOGNIZED(-1), + ; + + companion object { + const val ENUM_VAL1_VALUE = 10 + const val ENUM_VAL2_VALUE = 11 + } +} +""") + expect: + for (def field : element.fields) { + if (field.name == 'ENUM_VAL1_VALUE') { + field.constantValue == 10 + } else if (field.name == 'ENUM_VAL2_VALUE') { + field.constantValue == 11 + } + } + } +}