Skip to content

Commit 6ee811e

Browse files
Vassiliy-Kudryashovtamarinvs19
authored andcommitted
IDEA intention actions could help us with readability of generated code #158 (#615)
1 parent 12b8e4f commit 6ee811e

File tree

2 files changed

+114
-20
lines changed

2 files changed

+114
-20
lines changed

utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/generator/CodeGenerationController.kt

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -303,28 +303,33 @@ object CodeGenerationController {
303303

304304
// reformatting before creating reports due to
305305
// SarifReport requires the final version of the generated tests code
306-
runWriteCommandAction(testClassUpdated.project, "UtBot tests reformatting", null, {
307-
reformat(model, file, testClassUpdated)
308-
})
309-
unblockDocument(testClassUpdated.project, editor.document)
310-
311-
// uploading formatted code
312-
val testsCodeWithTestReportFormatted =
313-
testsCodeWithTestReport.copy(generatedCode = file.text)
314-
315-
// creating and saving reports
316-
reports += testsCodeWithTestReportFormatted.testsGenerationReport
317-
318-
saveSarifReport(
319-
testClassUpdated,
320-
testSets,
321-
model,
322-
testsCodeWithTestReportFormatted,
323-
)
306+
run(THREAD_POOL) {
307+
IntentionHelper(model.project, editor, file).applyIntentions()
308+
run(EDT_LATER) {
309+
runWriteCommandAction(testClassUpdated.project, "UtBot tests reformatting", null, {
310+
reformat(model, file, testClassUpdated)
311+
})
312+
unblockDocument(testClassUpdated.project, editor.document)
313+
314+
// uploading formatted code
315+
val testsCodeWithTestReportFormatted =
316+
testsCodeWithTestReport.copy(generatedCode = file.text)
317+
318+
// creating and saving reports
319+
reports += testsCodeWithTestReportFormatted.testsGenerationReport
320+
321+
saveSarifReport(
322+
testClassUpdated,
323+
testSets,
324+
model,
325+
testsCodeWithTestReportFormatted,
326+
)
324327

325-
reportsCountDown.countDown()
328+
reportsCountDown.countDown()
326329

327-
unblockDocument(testClassUpdated.project, editor.document)
330+
unblockDocument(testClassUpdated.project, editor.document)
331+
}
332+
}
328333
}
329334
}
330335
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package org.utbot.intellij.plugin.generator
2+
3+
import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerEx
4+
import com.intellij.codeInsight.daemon.impl.DaemonProgressIndicator
5+
import com.intellij.codeInsight.daemon.impl.HighlightInfo
6+
import com.intellij.codeInsight.intention.IntentionAction
7+
import com.intellij.openapi.command.WriteCommandAction
8+
import com.intellij.openapi.editor.Editor
9+
import com.intellij.openapi.progress.ProgressManager
10+
import com.intellij.openapi.project.DumbService
11+
import com.intellij.openapi.project.Project
12+
import com.intellij.openapi.util.Computable
13+
import com.intellij.openapi.util.Disposer
14+
import com.intellij.openapi.util.TextRange
15+
import com.intellij.psi.PsiFile
16+
17+
class IntentionHelper(val project: Project, private val editor: Editor, private val testFile: PsiFile) {
18+
fun applyIntentions() {
19+
while (true) {
20+
val actions =
21+
DumbService.getInstance(project).runReadActionInSmartMode(Computable<Map<IntentionAction, String>> {
22+
val daemonProgressIndicator = DaemonProgressIndicator()
23+
Disposer.register(project, daemonProgressIndicator)//check it
24+
val list = ProgressManager.getInstance().runProcess(Computable<List<HighlightInfo>> {
25+
try {
26+
DaemonCodeAnalyzerEx.getInstanceEx(project).runMainPasses(
27+
testFile,
28+
editor.document,
29+
daemonProgressIndicator
30+
)
31+
} catch (e: Exception) {
32+
emptyList()// 'Cannot obtain read-action' rare case
33+
}
34+
}, daemonProgressIndicator)
35+
val actions = mutableMapOf<IntentionAction, String>()
36+
list.forEach { info ->
37+
val quickFixActionRanges = info.quickFixActionRanges
38+
if (!quickFixActionRanges.isNullOrEmpty()) {
39+
val toList =
40+
quickFixActionRanges.map { pair: com.intellij.openapi.util.Pair<HighlightInfo.IntentionActionDescriptor, TextRange> -> pair.first.action }
41+
.toList()
42+
toList.forEach { intentionAction -> actions[intentionAction] = intentionAction.familyName }
43+
}
44+
}
45+
actions
46+
})
47+
if (actions.isEmpty()) break
48+
49+
var someWereApplied = false
50+
actions.forEach {
51+
if (it.value.isApplicable()) {
52+
someWereApplied = true
53+
if (it.key.startInWriteAction()) {
54+
WriteCommandAction.runWriteCommandAction(project) {
55+
editor.document.isInBulkUpdate = true
56+
it.key.invoke(project, editor, testFile)
57+
editor.document.isInBulkUpdate = false
58+
}
59+
} else {
60+
editor.document.isInBulkUpdate = true
61+
it.key.invoke(project, editor, testFile)
62+
editor.document.isInBulkUpdate = false
63+
}
64+
}
65+
}
66+
if (!someWereApplied) break
67+
}
68+
}
69+
70+
private fun String.isApplicable(): Boolean {
71+
if (this.startsWith("Change type of actual to ")) return true
72+
if (this == "Replace 'switch' with 'if'") return true // SetsTest
73+
if (this == "Replace with allMatch()") return true
74+
if (this == "Remove redundant cast(s)") return true // SetsTest
75+
if (this == "Collapse 'catch' blocks") return true // MapsTest
76+
if (this == "Replace lambda with method reference") return true // MockRandomExamplesTest
77+
if (this == "Inline variable") return true // ServiceWithFieldTest
78+
if (this == "Optimize imports") return true
79+
if (this.startsWith("Replace 'if else' with '&&'")) return true
80+
if (this.startsWith("Merge with 'case")) return true // CodegenExampleTest
81+
// if (this.equals("Simplify assertion")) return true // RecursiveTypeTest
82+
// if (this.familyName.startsWith("Try to generify ")) return true
83+
return false
84+
// "Generify File" shows TypeCookDialog to update JavaRefactoringSettings.getInstance() and then call invokeRefactoring
85+
// We may do the same without dialog interaction
86+
// "Collapse into loop" for duplicate lines like collection.add(...) comes from background later
87+
// We may implement it in codegen by ourselves
88+
}
89+
}

0 commit comments

Comments
 (0)