Skip to content

Ensure custom KProperty include the name in the hashcode #1710

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

rozza
Copy link
Member

@rozza rozza commented May 8, 2025

The pathCache utilized the string representation of the KProperty instance. The custom implementations didn't include the name (the calculated path value), this can lead to naming collisions in the pathCache key.

This commit adds hashCode and equals methods to ensure the name value is included in our custom implementations of KProperty. Finally, the cache key is now explicitly created using the same default Any.toString() approach to ensure that all implementations of KProperty use the same logic to create the cache key.

JAVA-5868

The `pathCache` utilised the string representation of the KProperty instance.
The custom implementations didn't include the calculated path value, this can
lead to naming collisions in the pathCache key.

This commit adds `hashCode` and `equals` methods to ensure the `name` value is included
in our custom implementations of `KProperty1`. Finally, the cache key is explicitly
created using the same default `Any.toString()` implementation to ensure that all
implementations of `KProperty1` use the same logic to create the cacheKey.

JAVA-5868
@rozza rozza requested a review from nhachicha May 8, 2025 13:48
@@ -71,8 +71,7 @@ public fun <T> KProperty<T>.path(): String {
return if (this is KPropertyPath<*, T>) {
this.name
} else {
pathCache.computeIfAbsent(this.toString()) {

pathCache.computeIfAbsent("${this.javaClass.getSimpleName()}@${Integer.toHexString(hashCode())}") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

Can't we just refactor the map to

private val pathCache: MutableMap<Int, String> by lazySoft { ConcurrentHashMap<Int, String>() }

then use the hashCode

pathCache.computeIfAbsent(this.hashCode())

not sure why you concatenate the class name with the hash?

@@ -84,6 +85,15 @@ public open class KPropertyPath<T, R>(
override fun callBy(args: Map<KParameter, Any?>): R = unSupportedOperation()
override fun get(receiver: T): R = unSupportedOperation()
override fun getDelegate(receiver: T): Any? = unSupportedOperation()
override fun hashCode(): Int = Objects.hash(previous, property, name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a good idea to provide the hashCode and equals but these weren't involved in the code path since we return the name directly if the instance is KPropertyPath in

return if (this is KPropertyPath<*, T>) {
        this.name

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants