Merge pull request #29130 from sreenath-tm
* pr/29130: Polish "Adapt FieldHint to recent GraalVM versions" Adapt FieldHint to recent GraalVM versions Closes gh-29130
This commit is contained in:
		
						commit
						c8f7a76659
					
				| 
						 | 
				
			
			@ -73,7 +73,7 @@ class AutowiredAnnotationBeanRegistrationAotContributionTests {
 | 
			
		|||
		RegisteredBean registeredBean = getAndApplyContribution(
 | 
			
		||||
				PrivateFieldInjectionSample.class);
 | 
			
		||||
		assertThat(RuntimeHintsPredicates.reflection()
 | 
			
		||||
				.onField(PrivateFieldInjectionSample.class, "environment").withWriteMode())
 | 
			
		||||
				.onField(PrivateFieldInjectionSample.class, "environment"))
 | 
			
		||||
				.accepts(this.generationContext.getRuntimeHints());
 | 
			
		||||
		compile(registeredBean, (postProcessor, compiled) -> {
 | 
			
		||||
			PrivateFieldInjectionSample instance = new PrivateFieldInjectionSample();
 | 
			
		||||
| 
						 | 
				
			
			@ -92,7 +92,7 @@ class AutowiredAnnotationBeanRegistrationAotContributionTests {
 | 
			
		|||
		RegisteredBean registeredBean = getAndApplyContribution(
 | 
			
		||||
				PackagePrivateFieldInjectionSample.class);
 | 
			
		||||
		assertThat(RuntimeHintsPredicates.reflection()
 | 
			
		||||
				.onField(PackagePrivateFieldInjectionSample.class, "environment").withWriteMode())
 | 
			
		||||
				.onField(PackagePrivateFieldInjectionSample.class, "environment"))
 | 
			
		||||
				.accepts(this.generationContext.getRuntimeHints());
 | 
			
		||||
		compile(registeredBean, (postProcessor, compiled) -> {
 | 
			
		||||
			PackagePrivateFieldInjectionSample instance = new PackagePrivateFieldInjectionSample();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -290,7 +290,7 @@ enum InstrumentedMethod {
 | 
			
		|||
	 * {@link Field#set(Object, Object)}.
 | 
			
		||||
	 */
 | 
			
		||||
	FIELD_SET(Field.class, "set", HintType.REFLECTION,
 | 
			
		||||
			invocation -> reflection().onField(invocation.getInstance()).withWriteMode()),
 | 
			
		||||
			invocation -> reflection().onField(invocation.getInstance())),
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,10 +17,6 @@
 | 
			
		|||
package org.springframework.aot.hint;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.util.function.Consumer;
 | 
			
		||||
 | 
			
		||||
import org.springframework.lang.Nullable;
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A hint that describes the need for reflection on a {@link Field}.
 | 
			
		||||
| 
						 | 
				
			
			@ -30,115 +26,8 @@ import org.springframework.util.Assert;
 | 
			
		|||
 */
 | 
			
		||||
public final class FieldHint extends MemberHint {
 | 
			
		||||
 | 
			
		||||
	private final FieldMode mode;
 | 
			
		||||
 | 
			
		||||
	private final boolean allowUnsafeAccess;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	private FieldHint(Builder builder) {
 | 
			
		||||
		super(builder.name);
 | 
			
		||||
		this.mode = (builder.mode != null ? builder.mode : FieldMode.WRITE);
 | 
			
		||||
		this.allowUnsafeAccess = builder.allowUnsafeAccess;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return whether setting the value of the field should be allowed.
 | 
			
		||||
	 * @return {@code true} to allow {@link Field#set(Object, Object)}.
 | 
			
		||||
	 * @deprecated in favor of {@link #getMode()}
 | 
			
		||||
	 */
 | 
			
		||||
	@Deprecated
 | 
			
		||||
	public boolean isAllowWrite() {
 | 
			
		||||
		return this.mode == FieldMode.WRITE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the {@linkplain FieldMode mode} that applies to this hint.
 | 
			
		||||
	 * @return the mode
 | 
			
		||||
	 */
 | 
			
		||||
	public FieldMode getMode() {
 | 
			
		||||
		return this.mode;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return whether using {@code Unsafe} on the field should be allowed.
 | 
			
		||||
	 * @return {@code true} to allow unsafe access
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isAllowUnsafeAccess() {
 | 
			
		||||
		return this.allowUnsafeAccess;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return a {@link Consumer} that applies the given {@link FieldMode}
 | 
			
		||||
	 * to the accepted {@link Builder}.
 | 
			
		||||
	 * @param mode the mode to apply
 | 
			
		||||
	 * @return a consumer to apply the mode
 | 
			
		||||
	 */
 | 
			
		||||
	public static Consumer<Builder> builtWith(FieldMode mode) {
 | 
			
		||||
		return builder -> builder.withMode(mode);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Builder for {@link FieldHint}.
 | 
			
		||||
	 */
 | 
			
		||||
	public static class Builder {
 | 
			
		||||
 | 
			
		||||
		private final String name;
 | 
			
		||||
 | 
			
		||||
		@Nullable
 | 
			
		||||
		private FieldMode mode;
 | 
			
		||||
 | 
			
		||||
		private boolean allowUnsafeAccess;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Builder(String name) {
 | 
			
		||||
			this.name = name;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Specify if setting the value of the field should be allowed.
 | 
			
		||||
		 * @param allowWrite {@code true} to allow {@link Field#set(Object, Object)}
 | 
			
		||||
		 * @return {@code this}, to facilitate method chaining
 | 
			
		||||
		 * @deprecated in favor of {@link #withMode(FieldMode)}
 | 
			
		||||
		 */
 | 
			
		||||
		@Deprecated
 | 
			
		||||
		public Builder allowWrite(boolean allowWrite) {
 | 
			
		||||
			if (allowWrite) {
 | 
			
		||||
				return withMode(FieldMode.WRITE);
 | 
			
		||||
			}
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Specify that the {@linkplain FieldMode mode} is required.
 | 
			
		||||
		 * @param mode the required mode
 | 
			
		||||
		 * @return {@code this}, to facilitate method chaining
 | 
			
		||||
		 */
 | 
			
		||||
		public Builder withMode(FieldMode mode) {
 | 
			
		||||
			Assert.notNull(mode, "'mode' must not be null");
 | 
			
		||||
			if ((this.mode == null || !this.mode.includes(mode))) {
 | 
			
		||||
				this.mode = mode;
 | 
			
		||||
			}
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Specify whether using {@code Unsafe} on the field should be allowed.
 | 
			
		||||
		 * @param allowUnsafeAccess {@code true} to allow unsafe access
 | 
			
		||||
		 * @return {@code this}, to facilitate method chaining
 | 
			
		||||
		 */
 | 
			
		||||
		public Builder allowUnsafeAccess(boolean allowUnsafeAccess) {
 | 
			
		||||
			this.allowUnsafeAccess = allowUnsafeAccess;
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Create a {@link FieldHint} based on the state of this builder.
 | 
			
		||||
		 * @return a field hint
 | 
			
		||||
		 */
 | 
			
		||||
		FieldHint build() {
 | 
			
		||||
			return new FieldHint(this);
 | 
			
		||||
	FieldHint(String name) {
 | 
			
		||||
		super(name);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,51 +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 java.lang.reflect.Field;
 | 
			
		||||
 | 
			
		||||
import org.springframework.lang.Nullable;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Represents the need of reflection for a given {@link Field}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Phillip Webb
 | 
			
		||||
 * @since 6.0
 | 
			
		||||
 * @see ReflectionHints
 | 
			
		||||
 */
 | 
			
		||||
public enum FieldMode {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Only field read is required.
 | 
			
		||||
	 */
 | 
			
		||||
	READ,
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Full field read and write is required.
 | 
			
		||||
	 */
 | 
			
		||||
	WRITE;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Specify if this mode already includes the specified {@code other} mode.
 | 
			
		||||
	 * @param other the other mode to check
 | 
			
		||||
	 * @return {@code true} if this mode includes the other mode
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean includes(@Nullable FieldMode other) {
 | 
			
		||||
		return (other == null || this.ordinal() >= other.ordinal());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -148,34 +148,13 @@ public class ReflectionHints {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Register the need for reflection on the specified {@link Field},
 | 
			
		||||
	 * enabling {@link FieldMode#WRITE}.
 | 
			
		||||
	 * Register the need for reflection on the specified {@link Field}.
 | 
			
		||||
	 * @param field the field that requires reflection
 | 
			
		||||
	 * @return {@code this}, to facilitate method chaining
 | 
			
		||||
	 */
 | 
			
		||||
	public ReflectionHints registerField(Field field) {
 | 
			
		||||
		return registerField(field, FieldMode.WRITE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Register the need for reflection on the specified {@link Field}
 | 
			
		||||
	 * using the specified {@link FieldMode}.
 | 
			
		||||
	 * @param field the field that requires reflection
 | 
			
		||||
	 * @return {@code this}, to facilitate method chaining
 | 
			
		||||
	 */
 | 
			
		||||
	public ReflectionHints registerField(Field field, FieldMode mode) {
 | 
			
		||||
		return registerField(field, FieldHint.builtWith(mode));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Register the need for reflection on the specified {@link Field}.
 | 
			
		||||
	 * @param field the field that requires reflection
 | 
			
		||||
	 * @param fieldHint a builder to further customize the hints of this field
 | 
			
		||||
	 * @return {@code this}, to facilitate method chaining
 | 
			
		||||
	 */
 | 
			
		||||
	public ReflectionHints registerField(Field field, Consumer<FieldHint.Builder> fieldHint) {
 | 
			
		||||
		return registerType(TypeReference.of(field.getDeclaringClass()),
 | 
			
		||||
				typeHint -> typeHint.withField(field.getName(), fieldHint));
 | 
			
		||||
				typeHint -> typeHint.withField(field.getName()));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,7 +57,7 @@ public final class TypeHint implements ConditionalHint {
 | 
			
		|||
		this.type = builder.type;
 | 
			
		||||
		this.reachableType = builder.reachableType;
 | 
			
		||||
		this.memberCategories = Set.copyOf(builder.memberCategories);
 | 
			
		||||
		this.fields = builder.fields.values().stream().map(FieldHint.Builder::build).collect(Collectors.toSet());
 | 
			
		||||
		this.fields = builder.fields.stream().map(FieldHint::new).collect(Collectors.toSet());
 | 
			
		||||
		this.constructors = builder.constructors.values().stream().map(ExecutableHint.Builder::build).collect(Collectors.toSet());
 | 
			
		||||
		this.methods = builder.methods.values().stream().map(ExecutableHint.Builder::build).collect(Collectors.toSet());
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -147,7 +147,7 @@ public final class TypeHint implements ConditionalHint {
 | 
			
		|||
		@Nullable
 | 
			
		||||
		private TypeReference reachableType;
 | 
			
		||||
 | 
			
		||||
		private final Map<String, FieldHint.Builder> fields = new HashMap<>();
 | 
			
		||||
		private final Set<String> fields = new HashSet<>();
 | 
			
		||||
 | 
			
		||||
		private final Map<ExecutableKey, ExecutableHint.Builder> constructors = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -185,35 +185,12 @@ public final class TypeHint implements ConditionalHint {
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Register the need for reflection on the field with the specified name,
 | 
			
		||||
		 * enabling write access.
 | 
			
		||||
		 * Register the need for reflection on the field with the specified name.
 | 
			
		||||
		 * @param name the name of the field
 | 
			
		||||
		 * @return {@code this}, to facilitate method chaining
 | 
			
		||||
		 */
 | 
			
		||||
		public Builder withField(String name) {
 | 
			
		||||
			return withField(name, FieldMode.WRITE);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Register the need for reflection on the field with the specified name
 | 
			
		||||
		 * using the specified {@link FieldMode}.
 | 
			
		||||
		 * @param name the name of the field
 | 
			
		||||
		 * @param mode the requested mode
 | 
			
		||||
		 * @return {@code this}, to facilitate method chaining
 | 
			
		||||
		 */
 | 
			
		||||
		public Builder withField(String name, FieldMode mode) {
 | 
			
		||||
			return withField(name, FieldHint.builtWith(mode));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Register the need for reflection on the field with the specified name.
 | 
			
		||||
		 * @param name the name of the field
 | 
			
		||||
		 * @param fieldHint a builder to further customize the hints of this field
 | 
			
		||||
		 * @return {@code this}, to facilitate method chaining
 | 
			
		||||
		 */
 | 
			
		||||
		public Builder withField(String name, Consumer<FieldHint.Builder> fieldHint) {
 | 
			
		||||
			FieldHint.Builder builder = this.fields.computeIfAbsent(name, FieldHint.Builder::new);
 | 
			
		||||
			fieldHint.accept(builder);
 | 
			
		||||
			this.fields.add(name);
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,8 +28,6 @@ import java.util.function.Predicate;
 | 
			
		|||
 | 
			
		||||
import org.springframework.aot.hint.ExecutableHint;
 | 
			
		||||
import org.springframework.aot.hint.ExecutableMode;
 | 
			
		||||
import org.springframework.aot.hint.FieldHint;
 | 
			
		||||
import org.springframework.aot.hint.FieldMode;
 | 
			
		||||
import org.springframework.aot.hint.MemberCategory;
 | 
			
		||||
import org.springframework.aot.hint.ReflectionHints;
 | 
			
		||||
import org.springframework.aot.hint.RuntimeHints;
 | 
			
		||||
| 
						 | 
				
			
			@ -375,57 +373,10 @@ public class ReflectionHintsPredicates {
 | 
			
		|||
 | 
			
		||||
		private final Field field;
 | 
			
		||||
 | 
			
		||||
		private FieldMode mode = FieldMode.READ;
 | 
			
		||||
 | 
			
		||||
		private boolean allowUnsafeAccess;
 | 
			
		||||
 | 
			
		||||
		FieldHintPredicate(Field field) {
 | 
			
		||||
			this.field = field;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Refine the current predicate to match if write access is allowed on the field.
 | 
			
		||||
		 * @return the refined {@link RuntimeHints} predicate
 | 
			
		||||
		 * @see FieldHint#isAllowWrite()
 | 
			
		||||
		 * @deprecated in favor of {@link #withReadMode()} or {@link #withWriteMode()}
 | 
			
		||||
		 */
 | 
			
		||||
		@Deprecated
 | 
			
		||||
		public FieldHintPredicate allowWrite() {
 | 
			
		||||
			this.mode = FieldMode.WRITE;
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Refine the current predicate to match if read access is allowed on the field.
 | 
			
		||||
		 * @return the refined {@link RuntimeHints} predicate
 | 
			
		||||
		 * @see FieldHint#getMode()
 | 
			
		||||
		 */
 | 
			
		||||
		public FieldHintPredicate withReadMode() {
 | 
			
		||||
			// FieldMode.READ is already the default and should not override a writeMode() call.
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Refine the current predicate to match if write access is allowed on the field.
 | 
			
		||||
		 * @return the refined {@link RuntimeHints} predicate
 | 
			
		||||
		 * @see FieldHint#getMode()
 | 
			
		||||
		 */
 | 
			
		||||
		public FieldHintPredicate withWriteMode() {
 | 
			
		||||
			this.mode = FieldMode.WRITE;
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Refine the current predicate to match if unsafe access is allowed on the field.
 | 
			
		||||
		 * @return the refined {@link RuntimeHints} predicate
 | 
			
		||||
		 * @see FieldHint#isAllowUnsafeAccess() ()
 | 
			
		||||
		 */
 | 
			
		||||
		public FieldHintPredicate allowUnsafeAccess() {
 | 
			
		||||
			this.allowUnsafeAccess = true;
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		public boolean test(RuntimeHints runtimeHints) {
 | 
			
		||||
			TypeHint typeHint = runtimeHints.reflection().getTypeHint(this.field.getDeclaringClass());
 | 
			
		||||
| 
						 | 
				
			
			@ -447,9 +398,7 @@ public class ReflectionHintsPredicates {
 | 
			
		|||
 | 
			
		||||
		private boolean exactMatch(TypeHint typeHint) {
 | 
			
		||||
			return typeHint.fields().anyMatch(fieldHint ->
 | 
			
		||||
					this.field.getName().equals(fieldHint.getName())
 | 
			
		||||
							&& (fieldHint.getMode().includes(this.mode))
 | 
			
		||||
							&& (!this.allowUnsafeAccess || this.allowUnsafeAccess == fieldHint.isAllowUnsafeAccess()));
 | 
			
		||||
					this.field.getName().equals(fieldHint.getName()));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,7 +26,6 @@ import java.util.stream.Stream;
 | 
			
		|||
import org.springframework.aot.hint.ExecutableHint;
 | 
			
		||||
import org.springframework.aot.hint.ExecutableMode;
 | 
			
		||||
import org.springframework.aot.hint.FieldHint;
 | 
			
		||||
import org.springframework.aot.hint.FieldMode;
 | 
			
		||||
import org.springframework.aot.hint.MemberCategory;
 | 
			
		||||
import org.springframework.aot.hint.ReflectionHints;
 | 
			
		||||
import org.springframework.aot.hint.TypeHint;
 | 
			
		||||
| 
						 | 
				
			
			@ -78,12 +77,6 @@ class ReflectionHintsWriter {
 | 
			
		|||
	private Map<String, Object> toAttributes(FieldHint hint) {
 | 
			
		||||
		Map<String, Object> attributes = new LinkedHashMap<>();
 | 
			
		||||
		attributes.put("name", hint.getName());
 | 
			
		||||
		if (hint.getMode() == FieldMode.WRITE) {
 | 
			
		||||
			attributes.put("allowWrite", true);
 | 
			
		||||
		}
 | 
			
		||||
		if (hint.isAllowUnsafeAccess()) {
 | 
			
		||||
			attributes.put("allowUnsafeAccess", hint.isAllowUnsafeAccess());
 | 
			
		||||
		}
 | 
			
		||||
		return attributes;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,8 +98,7 @@ public class FileNativeConfigurationWriterTests {
 | 
			
		|||
		FileNativeConfigurationWriter generator = new FileNativeConfigurationWriter(tempDir);
 | 
			
		||||
		RuntimeHints hints = new RuntimeHints();
 | 
			
		||||
		ReflectionHints reflectionHints = hints.reflection();
 | 
			
		||||
		reflectionHints.registerType(StringDecoder.class, builder -> {
 | 
			
		||||
			builder
 | 
			
		||||
		reflectionHints.registerType(StringDecoder.class, builder -> builder
 | 
			
		||||
				.onReachableType(String.class)
 | 
			
		||||
				.withMembers(MemberCategory.PUBLIC_FIELDS, MemberCategory.DECLARED_FIELDS,
 | 
			
		||||
						MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS, MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS,
 | 
			
		||||
| 
						 | 
				
			
			@ -108,15 +106,11 @@ public class FileNativeConfigurationWriterTests {
 | 
			
		|||
						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", TypeReference.listOf(Charset.class))
 | 
			
		||||
					.withMethod("getDefaultCharset", Collections.emptyList(), ExecutableMode.INTROSPECT);
 | 
			
		||||
		});
 | 
			
		||||
				.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" ] }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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" ] }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -87,7 +87,7 @@ class InjectionCodeGeneratorTests {
 | 
			
		|||
		TestBean bean = new TestBean();
 | 
			
		||||
		Field field = ReflectionUtils.findField(bean.getClass(), "age");
 | 
			
		||||
		this.generator.generateInjectionCode(field, INSTANCE_VARIABLE, CodeBlock.of("$L", 123));
 | 
			
		||||
		assertThat(RuntimeHintsPredicates.reflection().onField(TestBean.class, "age").withWriteMode())
 | 
			
		||||
		assertThat(RuntimeHintsPredicates.reflection().onField(TestBean.class, "age"))
 | 
			
		||||
				.accepts(this.hints);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,7 +32,6 @@ import org.assertj.core.api.InstanceOfAssertFactories;
 | 
			
		|||
import org.junit.jupiter.api.BeforeEach;
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
 | 
			
		||||
import org.springframework.aot.hint.FieldMode;
 | 
			
		||||
import org.springframework.aot.hint.TypeReference;
 | 
			
		||||
import org.springframework.aot.test.generate.TestGenerationContext;
 | 
			
		||||
import org.springframework.aot.test.generate.compile.CompileWithTargetClassAccess;
 | 
			
		||||
| 
						 | 
				
			
			@ -129,13 +128,8 @@ class PersistenceAnnotationBeanPostProcessorAotContributionTests {
 | 
			
		|||
					.singleElement().satisfies(typeHint -> {
 | 
			
		||||
						assertThat(typeHint.getType()).isEqualTo(
 | 
			
		||||
								TypeReference.of(DefaultPersistenceContextField.class));
 | 
			
		||||
						assertThat(typeHint.fields()).singleElement()
 | 
			
		||||
								.satisfies(fieldHint -> {
 | 
			
		||||
									assertThat(fieldHint.getName())
 | 
			
		||||
											.isEqualTo("entityManager");
 | 
			
		||||
									assertThat(fieldHint.getMode()).isEqualTo(FieldMode.WRITE);
 | 
			
		||||
									assertThat(fieldHint.isAllowUnsafeAccess()).isFalse();
 | 
			
		||||
								});
 | 
			
		||||
						assertThat(typeHint.fields()).singleElement().satisfies(fieldHint ->
 | 
			
		||||
								assertThat(fieldHint.getName()).isEqualTo("entityManager"));
 | 
			
		||||
					});
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue