JBRes-7073: Add transformation for renaming methods#35
Conversation
Qodana Community for JVMIt seems all right 👌 No new problems were found according to the checks applied 💡 Qodana analysis was run in the pull request mode: only the changed files were checked View the detailed Qodana reportTo be able to view the detailed Qodana report, you can either:
To get - name: 'Qodana Scan'
uses: JetBrains/[email protected]
with:
upload-result: trueContact Qodana teamContact us at [email protected]
|
Vladislav0Art
left a comment
There was a problem hiding this comment.
Overall, good! 🎉
Left some comments. Highly suggest integrating them.
...hub/pderakhshanfar/codecocoonplugin/components/transformations/RenameMethodTransformation.kt
Outdated
Show resolved
Hide resolved
| private fun haveSameSignature(m1: PsiMethod, m2: PsiMethod): Boolean { | ||
| return m1.manager.areElementsEquivalent(m1.parameterList, m2.parameterList) | ||
| } |
There was a problem hiding this comment.
[question; making sure] Is the order of parameters preserved? i.e., haveSameSignature(f1, f2) == false, with the f1 and f2 defined below.
fun f1(a: Int, b: String) {}
fun f2(b: String, a: Int) {}There was a problem hiding this comment.
I think so. The method's javadoc says: "Checks if the specified two PSI elements represent the same source element". From what I undestand, this means for f1 and f2 it would return false.
...hub/pderakhshanfar/codecocoonplugin/components/transformations/RenameMethodTransformation.kt
Outdated
Show resolved
Hide resolved
| val suggestedName = getNewMethodName(method) | ||
|
|
||
| // Validation check | ||
| if (isNameAvailable(method, suggestedName)) { | ||
| method to suggestedName | ||
| } else { | ||
| // Fallback: try adding a suffix or skip | ||
| val fallbackName = "${suggestedName}Internal" | ||
| if (isNameAvailable(method, fallbackName)) { | ||
| method to fallbackName | ||
| } else { | ||
| null // Skip this method to avoid compilation errors | ||
| } |
There was a problem hiding this comment.
[important] The implementation is nicely done! 👍🏻 and we can improve on this piece of code.
Proposal
You generate a single suggested name. What if you do, let's say, 10? or N?
I suggest making getNewMethodName generate a list of suggested names (parameterized by N), sorted by the most fitting first. Then, here, you'll iterate over each and try to apply.
In the prompt used in getNewMethodName, ask AI generate a list of N sorted name suggestions separated by a newline.
In general, it's better to implement all such suggestion-generating functions this way, instead of requesting a single suggestion over a single call.
Notes
- You can add
"${suggestedName}Internal"at the end of the generated list, so that you don't need an else-block. null // Skip this method to avoid compilation errors- do not silently ignore the failure; log it instead. There is a HeadlessLogger just for that.
...hub/pderakhshanfar/codecocoonplugin/components/transformations/RenameMethodTransformation.kt
Outdated
Show resolved
Hide resolved
| method.annotations.isEmpty() && | ||
| !method.isConstructor && | ||
| method.name != "toString" && | ||
| !method.name.startsWith("get") && | ||
| !method.name.startsWith("set") && | ||
| !method.name.startsWith("is") |
There was a problem hiding this comment.
Should other Java default methods be mentioned here as well?
equalshashCodeclonewait/notify/notifyAll/finalize
There was a problem hiding this comment.
Very good point! I though they should have @Override, which would filter them out before, but indeed it is not mandatory, so I added them in the filter.
Changes
coreto be mainbuild.gradle.kts. See commit.→ This was necessary to be able to send an LLM request from the
javamodule.→ Because Koog must be called with
runBlocking, which requires coroutines, I had to add the dependency back, see here. But then I was once again getting aLinkageError. I think the issue is that IntelliJ 2025.1 and lower comes with an older version of coroutines. I tried changing to 2025.2 or newer, but that breaks the indexing in headless mode. And in the older version thelimitedParallelismmethod does not exist, leading to an error.RenameMethodTransformationclass:a. Finds all methods that meet the criteria (not a getter/setter/constructor, if it is part of an interface that implements from a library file, if the method overrides a different method, etc).
b. Calls an LLM to find a substitute name (which is then checked for uniqueness).
c. Renames all usages and references of the original method.