Skip to content

Commit 3cbdefd

Browse files
committed
Avoid accidental KProperty1 loading.
1 parent 3faceb0 commit 3cbdefd

File tree

2 files changed

+28
-14
lines changed

2 files changed

+28
-14
lines changed

src/main/java/org/springframework/data/core/TypedPropertyPaths.java

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.springframework.core.KotlinDetector;
3939
import org.springframework.core.ResolvableType;
4040
import org.springframework.data.core.MemberDescriptor.FieldDescriptor;
41+
import org.springframework.data.core.MemberDescriptor.KPropertyPathDescriptor;
4142
import org.springframework.data.core.MemberDescriptor.KPropertyReferenceDescriptor;
4243
import org.springframework.data.core.MemberDescriptor.MethodDescriptor;
4344
import org.springframework.util.CompositeIterator;
@@ -126,18 +127,23 @@ public static <P, T> TypedPropertyPath<T, P> of(PropertyReference<T, P> lambda)
126127

127128
PropertyPathMetadata metadata = getMetadata(lambda);
128129

129-
if (KotlinDetector.isKotlinReflectPresent() && metadata instanceof KPropertyPathMetadata kMetadata
130+
if (KotlinDetector.isKotlinReflectPresent()) {
131+
if (metadata instanceof KPropertyPathMetadata kMetadata
130132
&& kMetadata.getProperty() instanceof KPropertyReferenceImpl<?, ?> ref) {
131-
return KotlinDelegate.of(ref);
133+
return KotlinDelegate.of(ref);
134+
}
132135
}
133136

134137
return new ResolvedPropertyReference<>(lambda, metadata);
135138
}
136139

140+
/**
141+
* Delegate to handle property path composition of single-property and property-path KProperty1 references.
142+
*/
137143
static class KotlinDelegate {
138144

139145
@SuppressWarnings({ "rawtypes", "unchecked" })
140-
public static <T, P> TypedPropertyPath<T, P> of(KProperty1<T, P> property) {
146+
public static <T, P> TypedPropertyPath<T, P> of(Object property) {
141147

142148
if (property instanceof KPropertyReferenceImpl paths) {
143149

@@ -152,16 +158,22 @@ public static <T, P> TypedPropertyPath<T, P> of(KProperty1<T, P> property) {
152158
Class<?> owner = impl.getJavaField() != null ? impl.getJavaField().getDeclaringClass()
153159
: impl.getGetter().getCaller().getMember().getDeclaringClass();
154160
KPropertyPathMetadata metadata = TypedPropertyPaths.KPropertyPathMetadata
155-
.of(MemberDescriptor.KPropertyReferenceDescriptor.create(owner, property));
161+
.of(MemberDescriptor.KPropertyReferenceDescriptor.create(owner, (KProperty1) impl));
156162
return new TypedPropertyPaths.ResolvedKPropertyPath(metadata);
157163
}
158164

159-
if (property.getGetter().getProperty() instanceof KProperty1Impl impl) {
160-
return of(impl);
165+
if (property instanceof KProperty1 kProperty) {
166+
167+
if (kProperty.getGetter().getProperty() instanceof KProperty1Impl impl) {
168+
return of(impl);
169+
}
170+
171+
throw new IllegalArgumentException("Property " + kProperty.getName() + " is not a KProperty");
161172
}
162173

163-
throw new IllegalArgumentException("Property " + property.getName() + " is not a KProperty");
174+
throw new IllegalArgumentException("Property " + property + " is not a KProperty");
164175
}
176+
165177
}
166178

167179
/**
@@ -190,8 +202,8 @@ public static <P, T> TypedPropertyPath<T, P> of(TypedPropertyPath<T, P> lambda)
190202
@SuppressWarnings({ "unchecked", "rawtypes" })
191203
public static <T, P> TypedPropertyPath<T, P> of(TypedPropertyPath<T, P> delegate, PropertyPathMetadata metadata) {
192204

193-
if (KotlinDetector.isKotlinReflectPresent() && metadata instanceof KPropertyPathMetadata kmp) {
194-
return new ResolvedKPropertyPath(kmp.getProperty(), metadata);
205+
if (KotlinDetector.isKotlinReflectPresent() && metadata instanceof KPropertyPathMetadata) {
206+
return new ResolvedKPropertyPath(((KPropertyPathMetadata) metadata).getProperty(), metadata);
195207
}
196208

197209
return new ResolvedTypedPropertyPath<>(delegate, metadata);
@@ -228,12 +240,12 @@ private static PropertyPathMetadata read(Object lambda) {
228240

229241
if (KotlinDetector.isKotlinReflectPresent()) {
230242

231-
if (reference instanceof KPropertyReferenceDescriptor kProperty) {
232-
return KPropertyPathMetadata.of(kProperty);
243+
if (reference instanceof KPropertyReferenceDescriptor descriptor) {
244+
return KPropertyPathMetadata.of(descriptor);
233245
}
234246

235-
if (reference instanceof MemberDescriptor.KPropertyPathDescriptor kProperty) {
236-
return KPropertyPathMetadata.of(kProperty);
247+
if (reference instanceof KPropertyPathDescriptor descriptor) {
248+
return KPropertyPathMetadata.of(descriptor);
237249
}
238250
}
239251

@@ -342,7 +354,7 @@ public static KPropertyPathMetadata of(KPropertyReferenceDescriptor descriptor)
342354
/**
343355
* Create a new {@code KPropertyPathMetadata}.
344356
*/
345-
public static KPropertyPathMetadata of(MemberDescriptor.KPropertyPathDescriptor descriptor) {
357+
public static KPropertyPathMetadata of(KPropertyPathDescriptor descriptor) {
346358
return new KPropertyPathMetadata(descriptor.getOwner(), descriptor.property(), descriptor.getType());
347359
}
348360

src/main/kotlin/org/springframework/data/core/KPropertyExtensions.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ fun <T : Any, P> KProperty1<T, P>.toPath(): TypedPropertyPath<T, P> =
5151
* @since 4.1
5252
*/
5353
@JvmName("div")
54+
@Suppress("UNCHECKED_CAST")
5455
operator fun <T, M, P> KProperty1<T, M?>.div(other: KProperty1<M, P?>): KProperty1<T, P> =
5556
KSinglePropertyReference(this, other) as KProperty1<T, P>
5657

@@ -71,5 +72,6 @@ operator fun <T, M, P> KProperty1<T, M?>.div(other: KProperty1<M, P?>): KPropert
7172
* @since 4.1
7273
*/
7374
@JvmName("divIterable")
75+
@Suppress("UNCHECKED_CAST")
7476
operator fun <T, M, P> KProperty1<T, Collection<M?>?>.div(other: KProperty1<M, P?>): KProperty1<T, P> =
7577
KIterablePropertyReference(this, other) as KProperty1<T, P>

0 commit comments

Comments
 (0)