@@ -30,6 +30,8 @@ import com.intellij.psi.PsiFile
30
30
import com.intellij.psi.PsiFileFactory
31
31
import com.intellij.psi.PsiManager
32
32
import com.intellij.psi.PsiMethod
33
+ import com.intellij.psi.SmartPointerManager
34
+ import com.intellij.psi.SmartPsiElementPointer
33
35
import com.intellij.psi.codeStyle.CodeStyleManager
34
36
import com.intellij.psi.codeStyle.JavaCodeStyleManager
35
37
import com.intellij.psi.search.GlobalSearchScopesCore
@@ -91,10 +93,12 @@ import java.util.concurrent.CountDownLatch
91
93
import java.util.concurrent.TimeUnit
92
94
import kotlin.reflect.KClass
93
95
import kotlin.reflect.full.functions
96
+ import mu.KotlinLogging
94
97
import org.utbot.intellij.plugin.util.IntelliJApiHelper.Target.*
95
98
import org.utbot.intellij.plugin.util.IntelliJApiHelper.run
96
99
97
100
object CodeGenerationController {
101
+ private val logger = KotlinLogging .logger {}
98
102
99
103
private class UtilClassListener {
100
104
var requiredUtilClassKind: UtilClassKind ? = null
@@ -115,35 +119,27 @@ object CodeGenerationController {
115
119
val latch = CountDownLatch (testSetsByClass.size)
116
120
117
121
val reports = mutableListOf<TestsGenerationReport >()
118
- val testFiles = mutableListOf<PsiFile >()
122
+ val testFilesPointers = mutableListOf<SmartPsiElementPointer < PsiFile > >()
119
123
val utilClassListener = UtilClassListener ()
120
124
for (srcClass in testSetsByClass.keys) {
121
125
val testSets = testSetsByClass[srcClass] ? : continue
122
126
try {
123
127
val classPackageName = model.getTestClassPackageNameFor(srcClass)
124
128
val testDirectory = allTestPackages[classPackageName] ? : baseTestDirectory
125
129
val testClass = createTestClass(srcClass, testDirectory, model) ? : continue
126
- val testClassFile = testClass.containingFile
130
+ val testFilePointer = SmartPointerManager .getInstance(model.project).createSmartPsiElementPointer( testClass.containingFile)
127
131
val cut = psi2KClass[srcClass] ? : error(" Didn't find KClass instance for class ${srcClass.name} " )
128
132
runWriteCommandAction(model.project, " Generate tests with UtBot" , null , {
129
133
try {
130
- generateCodeAndReport(
131
- srcClass,
132
- cut,
133
- testClass,
134
- testClassFile,
135
- testSets,
136
- model,
137
- latch,
138
- reports,
139
- utilClassListener
140
- )
141
- testFiles.add(testClassFile)
134
+ generateCodeAndReport(srcClass, cut, testClass, testFilePointer, testSets, model, latch, reports, utilClassListener)
135
+ testFilesPointers.add(testFilePointer)
142
136
} catch (e: IncorrectOperationException ) {
137
+ logger.error { e }
143
138
showCreatingClassError(model.project, createTestClassName(srcClass))
144
139
}
145
140
})
146
141
} catch (e: IncorrectOperationException ) {
142
+ logger.error { e }
147
143
showCreatingClassError(model.project, createTestClassName(srcClass))
148
144
}
149
145
}
@@ -187,7 +183,7 @@ object CodeGenerationController {
187
183
188
184
mergeSarifReports(model, sarifReportsPath)
189
185
if (model.runGeneratedTestsWithCoverage) {
190
- RunConfigurationHelper .runTestsWithCoverage(model, testFiles )
186
+ RunConfigurationHelper .runTestsWithCoverage(model, testFilesPointers )
191
187
}
192
188
}
193
189
}
@@ -275,7 +271,7 @@ object CodeGenerationController {
275
271
}
276
272
277
273
runWriteCommandAction(model.project, " UtBot util class reformatting" , null , {
278
- reformat(model, utUtilsFile, utUtilsClass)
274
+ reformat(model, SmartPointerManager .getInstance(model.project).createSmartPsiElementPointer( utUtilsFile) , utUtilsClass)
279
275
})
280
276
281
277
val utUtilsDocument = PsiDocumentManager
@@ -301,7 +297,7 @@ object CodeGenerationController {
301
297
run (WRITE_ACTION ) {
302
298
unblockDocument(model.project, utilsClassDocument)
303
299
executeCommand {
304
- utilsClassDocument.setText(utUtilsText)
300
+ utilsClassDocument.setText(utUtilsText.replace( " jdk.internal.misc " , " sun.misc " ) )
305
301
}
306
302
unblockDocument(model.project, utilsClassDocument)
307
303
}
@@ -569,7 +565,7 @@ object CodeGenerationController {
569
565
srcClass : PsiClass ,
570
566
classUnderTest : KClass <* >,
571
567
testClass : PsiClass ,
572
- file : PsiFile ,
568
+ filePointer : SmartPsiElementPointer < PsiFile > ,
573
569
testSets : List <UtMethodTestSet >,
574
570
model : GenerateTestsModel ,
575
571
reportsCountDown : CountDownLatch ,
@@ -597,7 +593,7 @@ object CodeGenerationController {
597
593
testClassPackageName = testClass.packageName
598
594
)
599
595
600
- val editor = CodeInsightUtil .positionCursorAtLBrace(testClass.project, file , testClass)
596
+ val editor = CodeInsightUtil .positionCursorAtLBrace(testClass.project, filePointer.containingFile , testClass)
601
597
// TODO: Use PsiDocumentManager.getInstance(model.project).getDocument(file)
602
598
// if we don't want to open _all_ new files with tests in editor one-by-one
603
599
run (THREAD_POOL ) {
@@ -609,27 +605,28 @@ object CodeGenerationController {
609
605
unblockDocument(testClass.project, editor.document)
610
606
// TODO: JIRA:1246 - display warnings if we rewrite the file
611
607
executeCommand(testClass.project, " Insert Generated Tests" ) {
612
- editor.document.setText(generatedTestsCode)
608
+ editor.document.setText(generatedTestsCode.replace( " jdk.internal.misc.Unsafe " , " sun.misc.Unsafe " ) )
613
609
}
614
610
unblockDocument(testClass.project, editor.document)
615
611
616
612
// after committing the document the `testClass` is invalid in PsiTree,
617
613
// so we have to reload it from the corresponding `file`
618
- val testClassUpdated = (file as PsiClassOwner ).classes.first() // only one class in the file
614
+ val testClassUpdated = (filePointer.containingFile as PsiClassOwner ).classes.first() // only one class in the file
619
615
620
616
// reformatting before creating reports due to
621
617
// SarifReport requires the final version of the generated tests code
622
618
run (THREAD_POOL ) {
623
- IntentionHelper (model.project, editor, file ).applyIntentions()
619
+ IntentionHelper (model.project, editor, filePointer ).applyIntentions()
624
620
run (EDT_LATER ) {
625
621
runWriteCommandAction(testClassUpdated.project, " UtBot tests reformatting" , null , {
626
- reformat(model, file , testClassUpdated)
622
+ reformat(model, filePointer , testClassUpdated)
627
623
})
628
624
unblockDocument(testClassUpdated.project, editor.document)
629
625
630
626
// uploading formatted code
627
+ val file = filePointer.containingFile
631
628
val codeGenerationResultFormatted =
632
- codeGenerationResult.copy(generatedCode = file.text)
629
+ codeGenerationResult.copy(generatedCode = file? .text? : generatedTestsCode )
633
630
634
631
// creating and saving reports
635
632
reports + = codeGenerationResultFormatted.testsGenerationReport
@@ -652,9 +649,10 @@ object CodeGenerationController {
652
649
}
653
650
}
654
651
655
- private fun reformat (model : GenerateTestsModel , file : PsiFile , testClass : PsiClass ) {
652
+ private fun reformat (model : GenerateTestsModel , smartPointer : SmartPsiElementPointer < PsiFile > , testClass : PsiClass ) {
656
653
val project = model.project
657
654
val codeStyleManager = CodeStyleManager .getInstance(project)
655
+ val file = smartPointer.containingFile? : return
658
656
codeStyleManager.reformat(file)
659
657
when (model.codegenLanguage) {
660
658
CodegenLanguage .JAVA -> {
@@ -694,6 +692,7 @@ object CodeGenerationController {
694
692
SarifReportIdea .createAndSave(model, testSets, generatedTestsCode, sourceFinding)
695
693
}
696
694
} catch (e: Exception ) {
695
+ logger.error { e }
697
696
showErrorDialogLater(
698
697
project,
699
698
message = " Cannot save Sarif report via generated tests: error occurred '${e.message} '" ,
0 commit comments