Fix getJvmName for @JvmRecord data class properties#2813
Fix getJvmName for @JvmRecord data class properties#2813MariusVolkhart wants to merge 1 commit intogoogle:mainfrom
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
|
CLA violation is due to Claude Code. I didn't see anything in the CONTRIBUTING.md indicating agentic AI was not allowed, and wanted to be clear on the fact that it was used as part of this change. Please advise if you want me to make changes or are unable to accept the PR as a result. Thank you. |
6cd15c8 to
86affbb
Compare
|
To me it seems like the tool requires all the owners of the commit (you and anthropic agent) need to sign the CLA. Obviously, the agent itself can't sign it so probably to the time being the workaround is not commit code using the agent |
@JvmRecord data classes compile to Java records, whose component accessors use bare property names (e.g. name()) rather than bean-style getters (getName()). ResolverAAImpl.getJvmName unconditionally used JvmAbi.getterName() which always added the get prefix. Add a check for the @JvmRecord annotation alongside the existing annotation class check, since both use bare property names as accessor names. Fixes google#2812
86affbb to
112045f
Compare
jaschdoc
left a comment
There was a problem hiding this comment.
Hey thank you for opening the PR and apologies for the slow response. I left some comments that aim to improve the test suite and readability. Cheers!
| @JvmRecord | ||
| data class TestRecordClass(val x: Int, val y: String) | ||
| // FILE: TestLibRecordClass.kt | ||
| @JvmRecord | ||
| data class TestLibRecordClass(val x: Int, val y: String) |
There was a problem hiding this comment.
How are these classes distinct except for the name? It's better if the classes are a bit more diverse. I'm thinking an approximation of a matrix of the following:
- Classes with different number of parameters
- Different property names
- Classes extending other types
- Classes with type parameters
- Classes marked as JvmRecords that override a val declared in a non-annotation interface, e.g.,
interface Example { val x: Int } - Classes with different names (like you already have)
- Classes with
varandvalproperties
If you have type parameters and or normal parameters and a class that extends another type, then it's also a good idea to override some parameters and add some locally, e.g.,
interface Example<A> {
val x: A
}
data class Ext<A, B>(override val x: A, val y: B) : Example<A>| class JvmNameRecordProcessor : AbstractTestProcessor() { | ||
| val results = mutableListOf<String>() | ||
| override fun toResult(): List<String> { | ||
| return results |
There was a problem hiding this comment.
This should be sorted to ensure results are reproducible.
| if (containingClass?.classKind == ClassKind.ANNOTATION_CLASS || | ||
| containingClass != null && containingClass.annotations.any { | ||
| it.annotationType.resolve().declaration.qualifiedName?.asString() == "kotlin.jvm.JvmRecord" | ||
| } | ||
| ) { | ||
| return name | ||
| } |
There was a problem hiding this comment.
I think we can improve the readability of this by extracting some variables so it reads
if (isAnnotationClass || isJvmRecord) {
return name
}Additionally, we can shortcircuit the expensive type resolution by checking for the short name first in the lambda:
any {
it.shortName.asString() == "JvmRecord" ||
it.annotationType.resolve().declaration.qualifiedName?.asString() == "kotlin.jvm.Record
}Lastly, maybe we can rename name to propertyName so it's clearer what the name. I know you didn't change it, but let's improve it.
| import org.junit.jupiter.api.parallel.ExecutionMode | ||
|
|
||
| @Execution(ExecutionMode.SAME_THREAD) | ||
| class KSPAA17Test : AbstractKSPAATest() { |
There was a problem hiding this comment.
Did you try adding the test to the existing test suite?
| cls.getAllProperties().map { | ||
| "(${it.getter?.let { resolver.getJvmName(it) }}, " + | ||
| "${it.setter?.let { resolver.getJvmName(it) }})" | ||
| }.toList().joinToString() |
There was a problem hiding this comment.
It's more stable if you use resolver.getSymbolsWithAnnotation("kotlin.jvm.JvmRecord") and filter for class declaration instances.
It might also be a bit cleaner if you flatmap over getAllProperties and then return a list of size at most two, that contains the getter and setter names which you can the call joinToString on, e.g.,
getAllProperties().flatMap {
// create a list that contains the jvm getter name if it exists and the setter name if it exists
}The names should probably also be qualified / prefixed with the class names.
@JvmRecord data classes compile to Java records, whose component accessors use bare property names (e.g. name()) rather than bean-style getters (getName()). ResolverAAImpl.getJvmName unconditionally used JvmAbi.getterName() which always added the get prefix.
Add a check for the @JvmRecord annotation alongside the existing annotation class check, since both use bare property names as accessor names.
Fixes #2812