Polish "Adapt FieldHint to recent GraalVM versions"

See gh-29130
This commit is contained in:
Stephane Nicoll
2022-09-10 15:56:26 +02:00
parent 1cb5f00723
commit 042a4f3518
16 changed files with 49 additions and 388 deletions

View File

@@ -1,38 +0,0 @@
/*
* Copyright 2002-2022 the original author or 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 org.springframework.aot.hint;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link FieldHint}.
*
* @author Phillip Webb
*/
class FieldHintTests {
@Test
void builtWithAppliesMode() {
FieldHint.Builder builder = new FieldHint.Builder("test");
assertThat(builder.build().getMode()).isEqualTo(FieldMode.WRITE);
FieldHint.builtWith(FieldMode.READ).accept(builder);
assertThat(builder.build().getMode()).isEqualTo(FieldMode.READ);
}
}

View File

@@ -1,61 +0,0 @@
/*
* Copyright 2002-2022 the original author or 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 org.springframework.aot.hint;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link FieldMode}.
*
* @author Phillip Webb
* @since 6.0
*/
class FieldModeTests {
@Test
void writeIncludesNullMode() {
assertThat(FieldMode.WRITE.includes(null)).isTrue();
}
@Test
void writeIncludesRead() {
assertThat(FieldMode.WRITE.includes(FieldMode.READ)).isTrue();
}
@Test
void writeIncludesWrite() {
assertThat(FieldMode.WRITE.includes(FieldMode.WRITE)).isTrue();
}
@Test
void readIncludesNullMode() {
assertThat(FieldMode.READ.includes(null)).isTrue();
}
@Test
void readIncludesRead() {
assertThat(FieldMode.READ.includes(FieldMode.READ)).isTrue();
}
@Test
void readDoesNotIncludeWrite() {
assertThat(FieldMode.READ.includes(FieldMode.WRITE)).isFalse();
}
}

View File

@@ -124,63 +124,12 @@ class ReflectionHintsTests {
}
@Test
void registerFieldAllowsWriteByDefault() {
void registerField() {
Field field = ReflectionUtils.findField(TestType.class, "field");
assertThat(field).isNotNull();
this.reflectionHints.registerField(field);
assertTestTypeFieldHint(fieldHint -> {
assertThat(fieldHint.getName()).isEqualTo("field");
assertThat(fieldHint.getMode()).isEqualTo(FieldMode.WRITE);
assertThat(fieldHint.isAllowUnsafeAccess()).isFalse();
});
}
@Test
void registerFieldWithEmptyCustomizerAppliesConsistentDefault() {
Field field = ReflectionUtils.findField(TestType.class, "field");
assertThat(field).isNotNull();
this.reflectionHints.registerField(field, fieldHint -> {});
assertTestTypeFieldHint(fieldHint -> {
assertThat(fieldHint.getName()).isEqualTo("field");
assertThat(fieldHint.getMode()).isEqualTo(FieldMode.WRITE);
assertThat(fieldHint.isAllowUnsafeAccess()).isFalse();
});
}
@Test
void registerFieldWithCustomizerAppliesCustomization() {
Field field = ReflectionUtils.findField(TestType.class, "field");
assertThat(field).isNotNull();
this.reflectionHints.registerField(field, fieldHint ->
fieldHint.withMode(FieldMode.READ).allowUnsafeAccess(true));
assertTestTypeFieldHint(fieldHint -> {
assertThat(fieldHint.getName()).isEqualTo("field");
assertThat(fieldHint.getMode()).isEqualTo(FieldMode.READ);
assertThat(fieldHint.isAllowUnsafeAccess()).isTrue();
});
}
@Test
void registerFieldWithMode() {
Field field = ReflectionUtils.findField(TestType.class, "field");
assertThat(field).isNotNull();
this.reflectionHints.registerField(field, FieldMode.READ);
assertTestTypeFieldHint(fieldHint -> {
assertThat(fieldHint.getName()).isEqualTo("field");
assertThat(fieldHint.getMode()).isEqualTo(FieldMode.READ);
});
}
@Test // gh-29055
void registerFieldWithCustomizersCannotDowngradeWrite() {
Field field = ReflectionUtils.findField(TestType.class, "field");
assertThat(field).isNotNull();
this.reflectionHints.registerField(field, FieldMode.WRITE);
this.reflectionHints.registerField(field, FieldMode.READ);
assertTestTypeFieldHint(fieldHint -> {
assertThat(fieldHint.getName()).isEqualTo("field");
assertThat(fieldHint.getMode()).isEqualTo(FieldMode.WRITE);
});
assertTestTypeFieldHint(fieldHint ->
assertThat(fieldHint.getName()).isEqualTo("field"));
}
private void assertTestTypeFieldHint(Consumer<FieldHint> fieldHint) {

View File

@@ -55,62 +55,9 @@ class TypeHintTests {
}
@Test
void createWithFieldAllowsWriteByDefault() {
void createWithField() {
assertFieldHint(TypeHint.of(TypeReference.of(String.class))
.withField("value"), fieldHint -> {
assertThat(fieldHint.getName()).isEqualTo("value");
assertThat(fieldHint.getMode()).isEqualTo(FieldMode.WRITE);
assertThat(fieldHint.isAllowUnsafeAccess()).isFalse();
});
}
@Test
void createWithFieldAndEmptyCustomizerAppliesConsistentDefault() {
assertFieldHint(TypeHint.of(TypeReference.of(String.class))
.withField("value", fieldHint -> {}), fieldHint -> {
assertThat(fieldHint.getName()).isEqualTo("value");
assertThat(fieldHint.getMode()).isEqualTo(FieldMode.WRITE);
assertThat(fieldHint.isAllowUnsafeAccess()).isFalse();
});
}
@Test
void createWithFieldAndCustomizerAppliesCustomization() {
assertFieldHint(TypeHint.of(TypeReference.of(String.class))
.withField("value", fieldHint -> {
fieldHint.withMode(FieldMode.READ);
fieldHint.allowUnsafeAccess(true);
}), fieldHint -> {
assertThat(fieldHint.getName()).isEqualTo("value");
assertThat(fieldHint.getMode()).isEqualTo(FieldMode.READ);
assertThat(fieldHint.isAllowUnsafeAccess()).isTrue();
});
}
@Test
void createWithFieldReuseBuilder() {
Builder builder = TypeHint.of(TypeReference.of(String.class));
builder.withField("value", fieldHint -> fieldHint.allowUnsafeAccess(true));
builder.withField("value", fieldHint -> {
fieldHint.withMode(FieldMode.WRITE);
fieldHint.allowUnsafeAccess(false);
});
assertFieldHint(builder, fieldHint -> {
assertThat(fieldHint.getName()).isEqualTo("value");
assertThat(fieldHint.getMode()).isEqualTo(FieldMode.WRITE);
assertThat(fieldHint.isAllowUnsafeAccess()).isFalse();
});
}
@Test
void createFieldWithFieldMode() {
Builder builder = TypeHint.of(TypeReference.of(String.class));
builder.withField("value", FieldMode.READ);
assertFieldHint(builder, fieldHint -> {
assertThat(fieldHint.getName()).isEqualTo("value");
assertThat(fieldHint.getMode()).isEqualTo(FieldMode.READ);
assertThat(fieldHint.isAllowUnsafeAccess()).isFalse();
});
.withField("value"), fieldHint -> assertThat(fieldHint.getName()).isEqualTo("value"));
}
void assertFieldHint(Builder builder, Consumer<FieldHint> fieldHint) {

View File

@@ -27,7 +27,6 @@ import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.aot.hint.ExecutableMode;
import org.springframework.aot.hint.FieldMode;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.TypeReference;
@@ -261,7 +260,7 @@ class ReflectionHintsPredicatesTests {
@Test
void privateConstructorInvocationDoesNotMatchConstructorHint() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
typeHint.withConstructor(TypeReference.listOf(String.class), ExecutableMode.INTROSPECT));
typeHint.withConstructor(TypeReference.listOf(String.class), ExecutableMode.INTROSPECT));
assertPredicateDoesNotMatch(reflection.onConstructor(privateConstructor).invoke());
}
@@ -480,30 +479,9 @@ class ReflectionHintsPredicatesTests {
}
@Test
void fieldWriteReflectionDoesNotMatchFieldHint() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withField("publicField",
FieldMode.READ));
assertPredicateDoesNotMatch(reflection.onField(SampleClass.class, "publicField").withWriteMode());
}
@Test
void fieldUnsafeReflectionDoesNotMatchFieldHint() {
void fieldReflectionDoesNotMatchNonRegisteredFielddHint() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withField("publicField"));
assertPredicateDoesNotMatch(reflection.onField(SampleClass.class, "publicField").allowUnsafeAccess());
}
@Test
void fieldWriteReflectionMatchesFieldHintWithWrite() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
typeHint.withField("publicField", FieldMode.WRITE));
assertPredicateMatches(reflection.onField(SampleClass.class, "publicField").withWriteMode());
}
@Test
void fieldUnsafeReflectionMatchesFieldHintWithUnsafe() {
runtimeHints.reflection().registerType(SampleClass.class,
typeHint -> typeHint.withField("publicField", fieldHint -> fieldHint.allowUnsafeAccess(true)));
assertPredicateMatches(reflection.onField(SampleClass.class, "publicField").allowUnsafeAccess());
assertPredicateDoesNotMatch(reflection.onField(SampleClass.class, "privateField"));
}
@Test

View File

@@ -32,7 +32,6 @@ import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;
import org.springframework.aot.hint.ExecutableMode;
import org.springframework.aot.hint.FieldMode;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.ProxyHints;
import org.springframework.aot.hint.ReflectionHints;
@@ -99,24 +98,19 @@ public class FileNativeConfigurationWriterTests {
FileNativeConfigurationWriter generator = new FileNativeConfigurationWriter(tempDir);
RuntimeHints hints = new RuntimeHints();
ReflectionHints reflectionHints = hints.reflection();
reflectionHints.registerType(StringDecoder.class, builder -> {
builder
.onReachableType(String.class)
.withMembers(MemberCategory.PUBLIC_FIELDS, MemberCategory.DECLARED_FIELDS,
MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS, MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS,
MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
MemberCategory.INTROSPECT_PUBLIC_METHODS, MemberCategory.INTROSPECT_DECLARED_METHODS,
MemberCategory.INVOKE_PUBLIC_METHODS, MemberCategory.INVOKE_DECLARED_METHODS,
MemberCategory.PUBLIC_CLASSES, MemberCategory.DECLARED_CLASSES)
.withField("DEFAULT_CHARSET", fieldBuilder -> fieldBuilder.withMode(FieldMode.READ))
.withField("defaultCharset", fieldBuilder -> {
fieldBuilder.withMode(FieldMode.WRITE);
fieldBuilder.allowUnsafeAccess(true);
})
.withConstructor(TypeReference.listOf(List.class, boolean.class, MimeType.class), ExecutableMode.INTROSPECT)
.withMethod("setDefaultCharset", TypeReference.listOf(Charset.class))
.withMethod("getDefaultCharset", Collections.emptyList(), ExecutableMode.INTROSPECT);
});
reflectionHints.registerType(StringDecoder.class, builder -> builder
.onReachableType(String.class)
.withMembers(MemberCategory.PUBLIC_FIELDS, MemberCategory.DECLARED_FIELDS,
MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS, MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS,
MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
MemberCategory.INTROSPECT_PUBLIC_METHODS, MemberCategory.INTROSPECT_DECLARED_METHODS,
MemberCategory.INVOKE_PUBLIC_METHODS, MemberCategory.INVOKE_DECLARED_METHODS,
MemberCategory.PUBLIC_CLASSES, MemberCategory.DECLARED_CLASSES)
.withField("DEFAULT_CHARSET")
.withField("defaultCharset")
.withConstructor(TypeReference.listOf(List.class, boolean.class, MimeType.class), ExecutableMode.INTROSPECT)
.withMethod("setDefaultCharset", TypeReference.listOf(Charset.class))
.withMethod("getDefaultCharset", Collections.emptyList(), ExecutableMode.INTROSPECT));
generator.write(hints);
assertEquals("""
[
@@ -137,7 +131,7 @@ public class FileNativeConfigurationWriterTests {
"allDeclaredClasses": true,
"fields": [
{ "name": "DEFAULT_CHARSET" },
{ "name": "defaultCharset", "allowWrite": true, "allowUnsafeAccess": true }
{ "name": "defaultCharset" }
],
"methods": [
{ "name": "setDefaultCharset", "parameterTypes": [ "java.nio.charset.Charset" ] }

View File

@@ -27,7 +27,6 @@ import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;
import org.springframework.aot.hint.ExecutableMode;
import org.springframework.aot.hint.FieldMode;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.ReflectionHints;
import org.springframework.aot.hint.TypeReference;
@@ -58,11 +57,8 @@ public class ReflectionHintsWriterTests {
MemberCategory.INTROSPECT_PUBLIC_METHODS, MemberCategory.INTROSPECT_DECLARED_METHODS,
MemberCategory.INVOKE_PUBLIC_METHODS, MemberCategory.INVOKE_DECLARED_METHODS,
MemberCategory.PUBLIC_CLASSES, MemberCategory.DECLARED_CLASSES)
.withField("DEFAULT_CHARSET", fieldBuilder -> fieldBuilder.withMode(FieldMode.READ))
.withField("defaultCharset", fieldBuilder -> {
fieldBuilder.withMode(FieldMode.WRITE);
fieldBuilder.allowUnsafeAccess(true);
})
.withField("DEFAULT_CHARSET")
.withField("defaultCharset")
.withConstructor(TypeReference.listOf(List.class, boolean.class, MimeType.class), ExecutableMode.INTROSPECT)
.withMethod("setDefaultCharset", List.of(TypeReference.of(Charset.class)))
.withMethod("getDefaultCharset", Collections.emptyList(), ExecutableMode.INTROSPECT));
@@ -85,7 +81,7 @@ public class ReflectionHintsWriterTests {
"allDeclaredClasses": true,
"fields": [
{ "name": "DEFAULT_CHARSET" },
{ "name": "defaultCharset", "allowWrite": true, "allowUnsafeAccess": true }
{ "name": "defaultCharset" }
],
"methods": [
{ "name": "setDefaultCharset", "parameterTypes": [ "java.nio.charset.Charset" ] }