@@ -22,10 +22,8 @@ package com.demonwav.mcdev.platform.mixin.expression.gui
22
22
23
23
import com.demonwav.mcdev.platform.mixin.expression.MEExpressionMatchUtil
24
24
import com.demonwav.mcdev.util.constantStringValue
25
- import com.intellij.openapi.application.ApplicationManager
26
25
import com.intellij.openapi.application.EDT
27
- import com.intellij.openapi.application.ModalityState
28
- import com.intellij.openapi.application.ReadAction
26
+ import com.intellij.openapi.application.readAction
29
27
import com.intellij.openapi.module.Module
30
28
import com.intellij.openapi.progress.checkCanceled
31
29
import com.intellij.openapi.project.Project
@@ -41,8 +39,9 @@ import com.mxgraph.util.mxRectangle
41
39
import com.mxgraph.view.mxGraph
42
40
import java.awt.Dimension
43
41
import java.util.SortedMap
44
- import java.util.concurrent.Callable
42
+ import kotlinx.coroutines.CoroutineScope
45
43
import kotlinx.coroutines.Dispatchers
44
+ import kotlinx.coroutines.launch
46
45
import kotlinx.coroutines.withContext
47
46
import org.objectweb.asm.tree.ClassNode
48
47
import org.objectweb.asm.tree.MethodNode
@@ -53,15 +52,21 @@ private const val INTRA_GROUP_SPACING = 75
53
52
private const val LINE_NUMBER_STYLE = " LINE_NUMBER"
54
53
55
54
class FlowDiagram (
55
+ private val scope : CoroutineScope ,
56
56
val ui : FlowDiagramUi ,
57
57
private val flowGraph : FlowGraph ,
58
58
private val clazz : ClassNode ,
59
59
val method : MethodNode ,
60
60
) {
61
61
companion object {
62
- suspend fun create (project : Project , clazz : ClassNode , method : MethodNode ): FlowDiagram ? {
62
+ suspend fun create (
63
+ project : Project ,
64
+ scope : CoroutineScope ,
65
+ clazz : ClassNode ,
66
+ method : MethodNode
67
+ ): FlowDiagram ? {
63
68
val flowGraph = FlowGraph .parse(project, clazz, method) ? : return null
64
- return buildDiagram(flowGraph, clazz, method)
69
+ return buildDiagram(scope, flowGraph, clazz, method)
65
70
}
66
71
}
67
72
@@ -91,6 +96,12 @@ class FlowDiagram(
91
96
flowGraph.highlightMatches(node, soft)
92
97
ui.refresh()
93
98
}
99
+
100
+ flowGraph.onHighlightChanged { exprText, node ->
101
+ scope.launch(Dispatchers .EDT ) {
102
+ ui.showExpr(exprText, node)
103
+ }
104
+ }
94
105
}
95
106
96
107
fun populateMatchStatuses (
@@ -105,41 +116,42 @@ class FlowDiagram(
105
116
val oldHighlightRoot = flowGraph.highlightRoot
106
117
ui.setMatchToolbarVisible(false )
107
118
flowGraph.resetMatches()
108
- ReadAction .nonBlocking(Callable <String ?> run@{
109
- val stringLit = stringRef.element ? : return @run null
110
- val modifierList = modifierListRef.element ? : return @run null
111
- val expression = stringLit.constantStringValue?.let (MEExpressionMatchUtil ::createExpression)
112
- ? : return @run null
113
- val pool = MEExpressionMatchUtil .createIdentifierPoolFactory(module, clazz, modifierList)(method)
114
- for ((virtualInsn, root) in flowGraph.flowMap) {
115
- val node = flowGraph.allNodes.getValue(root)
116
- MEExpressionMatchUtil .findMatchingInstructions(
117
- clazz, method, pool, flowGraph.flowMap, expression, listOf (virtualInsn),
118
- ExpressionContext .Type .MODIFY_EXPRESSION_VALUE , // most permissive
119
- false ,
120
- node::reportMatchStatus,
121
- node::reportPartialMatch
122
- ) {}
119
+ scope.launch(Dispatchers .Default ) {
120
+ val success = readAction run@{
121
+ val stringLit = stringRef.element ? : return @run false
122
+ val modifierList = modifierListRef.element ? : return @run false
123
+ val expression = stringLit.constantStringValue?.let (MEExpressionMatchUtil ::createExpression)
124
+ ? : return @run false
125
+ val pool = MEExpressionMatchUtil .createIdentifierPoolFactory(module, clazz, modifierList)(method)
126
+ for ((virtualInsn, root) in flowGraph.flowMap) {
127
+ val node = flowGraph.allNodes.getValue(root)
128
+ MEExpressionMatchUtil .findMatchingInstructions(
129
+ clazz, method, pool, flowGraph.flowMap, expression, listOf (virtualInsn),
130
+ ExpressionContext .Type .MODIFY_EXPRESSION_VALUE , // most permissive
131
+ false ,
132
+ node::reportMatchStatus,
133
+ node::reportPartialMatch
134
+ ) {}
135
+ }
136
+ flowGraph.setExprText(expression.src.toString())
137
+ flowGraph.highlightMatches(oldHighlightRoot, false )
138
+ true
123
139
}
124
- flowGraph.markHasMatchData()
125
- flowGraph.highlightMatches(oldHighlightRoot, false )
126
- StringUtil .escapeStringCharacters(expression.src.toString())
127
- })
128
- .finishOnUiThread(ModalityState .nonModal()) { exprText ->
129
- exprText ? : return @finishOnUiThread
140
+ if (success) {
130
141
if (jump) {
131
142
showBestNode()
132
143
}
133
- ui.refresh()
134
- ui.setExprText(exprText)
135
144
}
136
- .submit(ApplicationManager .getApplication()::executeOnPooledThread)
145
+ ui.refresh()
146
+ }
137
147
}
138
148
this .jumpToExpression = {
139
- ReadAction .run<Nothing > {
140
- val target = stringRef.element
141
- if (target is Navigatable && target.isValid && target.canNavigate()) {
142
- target.navigate(true )
149
+ scope.launch {
150
+ readAction {
151
+ val target = stringRef.element
152
+ if (target is Navigatable && target.isValid && target.canNavigate()) {
153
+ target.navigate(true )
154
+ }
143
155
}
144
156
}
145
157
}
@@ -161,7 +173,12 @@ class FlowDiagram(
161
173
}
162
174
}
163
175
164
- private suspend fun buildDiagram (flowGraph : FlowGraph , clazz : ClassNode , method : MethodNode ): FlowDiagram {
176
+ private suspend fun buildDiagram (
177
+ scope : CoroutineScope ,
178
+ flowGraph : FlowGraph ,
179
+ clazz : ClassNode ,
180
+ method : MethodNode
181
+ ): FlowDiagram {
165
182
val graph = MxFlowGraph (flowGraph)
166
183
setupStyles(graph)
167
184
val groupedCells = addGraphContent(graph, flowGraph)
@@ -171,7 +188,7 @@ private suspend fun buildDiagram(flowGraph: FlowGraph, clazz: ClassNode, method:
171
188
val ui = withContext(Dispatchers .EDT ) {
172
189
FlowDiagramUi (graph, calculateBounds, lineNumberNodes)
173
190
}
174
- return FlowDiagram (ui, flowGraph, clazz, method)
191
+ return FlowDiagram (scope, ui, flowGraph, clazz, method)
175
192
}
176
193
177
194
private class MxFlowGraph (private val flowGraph : FlowGraph ) : mxGraph() {
0 commit comments