-
Notifications
You must be signed in to change notification settings - Fork 23
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
Fix line prompt managment #356
Fix line prompt managment #356
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It still fails when asking to generate test for the package line in Kotlin :(
java.lang.NullPointerException
at org.jetbrains.research.testspark.tools.llm.generation.PromptManager.getMethodDescriptor(PromptManager.kt:294)
at org.jetbrains.research.testspark.tools.llm.generation.PromptManager.generatePrompt$lambda$6(PromptManager.kt:128)
at com.intellij.openapi.application.impl.RwLockHolder.runReadAction(RwLockHolder.kt:271)
at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:845)
at org.jetbrains.research.testspark.tools.llm.generation.PromptManager.generatePrompt(PromptManager.kt:69)
at org.jetbrains.research.testspark.tools.llm.generation.LLMProcessManager.runTestGenerator(LLMProcessManager.kt:105)
at org.jetbrains.research.testspark.tools.Pipeline$runTestGeneration$1.run(Pipeline.kt:96)
at com.intellij.openapi.progress.impl.CoreProgressManager.startTask(CoreProgressManager.java:477)
at com.intellij.openapi.progress.impl.ProgressManagerImpl.startTask(ProgressManagerImpl.java:133)
at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcessWithProgressAsynchronously$6(CoreProgressManager.java:528)
at com.intellij.openapi.progress.impl.ProgressRunner.lambda$submit$4(ProgressRunner.java:250)
at com.intellij.openapi.progress.ProgressManager.lambda$runProcess$0(ProgressManager.java:100)
at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$1(CoreProgressManager.java:221)
at com.intellij.platform.diagnostic.telemetry.helpers.TraceKt.use(trace.kt:46)
at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$2(CoreProgressManager.java:220)
at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$executeProcessUnderProgress$13(CoreProgressManager.java:660)
at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:735)
at com.intellij.openapi.progress.impl.CoreProgressManager.computeUnderProgress(CoreProgressManager.java:691)
at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:659)
at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:79)
at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:202)
at com.intellij.openapi.progress.ProgressManager.runProcess(ProgressManager.java:100)
at com.intellij.openapi.progress.impl.ProgressRunner.lambda$submit$5(ProgressRunner.java:250)
at com.intellij.openapi.progress.impl.ProgressRunner$ProgressRunnable.run(ProgressRunner.java:500)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:702)
at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:699)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1.run(Executors.java:699)
at java.base/java.lang.Thread.run(Thread.java:840)
fun generatePromptForLine( | ||
lineUnderTest: String, | ||
method: MethodRepresentation, | ||
interestingClassesFromMethod: List<ClassRepresentation>, | ||
method: MethodRepresentation?, | ||
interestingClassesFromMethod: List<ClassRepresentation>?, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deeper you get on the method calling chain, more places there will be where you'll need to replace T
with T?
. It is generally better to have as few T?
params as possible; otherwise, your Kotlin code turns into Java.
I recommend resolving all of these problems inside PromptManager
before calling methods of PromptGenerator
:
CodeType.LINE -> {
val lineNumber = codeType.objectIndex
// get code of line under test
val document = psiHelper.getDocumentFromPsiFile()
val lineStartOffset = document!!.getLineStartOffset(lineNumber - 1)
val lineEndOffset = document.getLineEndOffset(lineNumber - 1)
val lineUnderTest = document.getText(TextRange.create(lineStartOffset, lineEndOffset))
val psiMethod = getPsiMethod(cut, getMethodDescriptor(cut, lineNumber))
val context = if (psiMethod != null) createMethodRepresentation(psiMethod) else cut!!.fullText
val interestingClassesFromMethod = if (psiMethod != null) {
psiHelper.getInterestingPsiClassesWithQualifiedNames(cut, psiMethod)
?.map(this::createClassRepresentation)
?.toList()
}
else {
emptyList()
}
promptGenerator.generatePromptForLine(
lineUnderTest,
context,
interestingClassesFromMethod,
testSamplesCode,
)
}
And rename the method
parameter of promptGenerator.generatePromptForLine
to context
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea is to minimize the number of places where you need to replace T
with T?
. Check all the places where you did the change; likely you will manage to avoid it by having a simple if
in the caller's code.
fun insertMethodsSignatures(interestingClasses: List<ClassRepresentation>?) = apply { | ||
interestingClasses ?: return@apply | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try to have this "if" check inside the caller part.
@@ -125,19 +125,19 @@ class PromptManager( | |||
|
|||
CodeType.LINE -> { | |||
val lineNumber = codeType.objectIndex | |||
val psiMethod = getPsiMethod(cut, getMethodDescriptor(cut, lineNumber))!! | |||
val psiMethod = getPsiMethod(cut, getMethodDescriptor(cut, lineNumber)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will fail if I start generation for the following Kotlin code on a line (*)
:
class CalcKotlin {
val a = 10;
fun add(a: Int, b: Int) = a + b
}
val a = 10; // (*)
Here is the stack trace:
2024-09-24 17:32:24,807 [ 83815] SEVERE - #c.i.o.p.Task - null
java.lang.NullPointerException
at org.jetbrains.research.testspark.tools.llm.generation.PromptManager.getMethodDescriptor(PromptManager.kt:294)
at org.jetbrains.research.testspark.tools.llm.generation.PromptManager.generatePrompt$lambda$6(PromptManager.kt:128)
at com.intellij.openapi.application.impl.RwLockHolder.runReadAction(RwLockHolder.kt:271)
at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:845)
at org.jetbrains.research.testspark.tools.llm.generation.PromptManager.generatePrompt(PromptManager.kt:69)
at org.jetbrains.research.testspark.tools.llm.generation.LLMProcessManager.runTestGenerator(LLMProcessManager.kt:105)
at org.jetbrains.research.testspark.tools.Pipeline$runTestGeneration$1.run(Pipeline.kt:96)
at com.intellij.openapi.progress.impl.CoreProgressManager.startTask(CoreProgressManager.java:477)
at com.intellij.openapi.progress.impl.ProgressManagerImpl.startTask(ProgressManagerImpl.java:133)
at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcessWithProgressAsynchronously$6(CoreProgressManager.java:528)
at com.intellij.openapi.progress.impl.ProgressRunner.lambda$submit$4(ProgressRunner.java:250)
at com.intellij.openapi.progress.ProgressManager.lambda$runProcess$0(ProgressManager.java:100)
at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$1(CoreProgressManager.java:221)
at com.intellij.platform.diagnostic.telemetry.helpers.TraceKt.use(trace.kt:46)
at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$2(CoreProgressManager.java:220)
at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$executeProcessUnderProgress$13(CoreProgressManager.java:660)
at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:735)
at com.intellij.openapi.progress.impl.CoreProgressManager.computeUnderProgress(CoreProgressManager.java:691)
at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:659)
at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:79)
at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:202)
at com.intellij.openapi.progress.ProgressManager.runProcess(ProgressManager.java:100)
at com.intellij.openapi.progress.impl.ProgressRunner.lambda$submit$5(ProgressRunner.java:250)
at com.intellij.openapi.progress.impl.ProgressRunner$ProgressRunnable.run(ProgressRunner.java:500)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:702)
at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:699)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1.run(Executors.java:699)
at java.base/java.lang.Thread.run(Thread.java:840)
When we generate tests for a line, PromptManager::getMethodDescriptor
method asserts that there will always be a method surrounding the selected line (i.e., currentPsiMethod = psiHelper.getSurroundingMethod(caret)!!
), which is false in this scenario:
private fun getMethodDescriptor(
psiClass: PsiClassWrapper?,
lineNumber: Int,
): String {
// Processing function outside the class
if (psiClass == null) {
/* problem here -> */ val currentPsiMethod = psiHelper.getSurroundingMethod(caret)!!
return psiHelper.generateMethodDescriptor(currentPsiMethod)
}
private fun createMethodRepresentation(psiMethod: PsiMethodWrapper?): MethodRepresentation? { | ||
psiMethod ?: return null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest moving the nullness check of psiMethod
to the caller.
b40a077
to
3079173
Compare
The issues are addressed in #344. |
Description of changes made
In case of lackness of method, add code of class.
Other notes
Closes #351
Closes #247