@@ -22,10 +22,8 @@ package com.demonwav.mcdev.platform.mixin.expression.gui
2222
2323import com.demonwav.mcdev.platform.mixin.expression.MEExpressionMatchUtil
2424import com.demonwav.mcdev.util.constantStringValue
25- import com.intellij.openapi.application.ApplicationManager
2625import 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
2927import com.intellij.openapi.module.Module
3028import com.intellij.openapi.progress.checkCanceled
3129import com.intellij.openapi.project.Project
@@ -41,8 +39,9 @@ import com.mxgraph.util.mxRectangle
4139import com.mxgraph.view.mxGraph
4240import java.awt.Dimension
4341import java.util.SortedMap
44- import java.util.concurrent.Callable
42+ import kotlinx.coroutines.CoroutineScope
4543import kotlinx.coroutines.Dispatchers
44+ import kotlinx.coroutines.launch
4645import kotlinx.coroutines.withContext
4746import org.objectweb.asm.tree.ClassNode
4847import org.objectweb.asm.tree.MethodNode
@@ -53,15 +52,21 @@ private const val INTRA_GROUP_SPACING = 75
5352private const val LINE_NUMBER_STYLE = " LINE_NUMBER"
5453
5554class FlowDiagram (
55+ private val scope : CoroutineScope ,
5656 val ui : FlowDiagramUi ,
5757 private val flowGraph : FlowGraph ,
5858 private val clazz : ClassNode ,
5959 val method : MethodNode ,
6060) {
6161 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 ? {
6368 val flowGraph = FlowGraph .parse(project, clazz, method) ? : return null
64- return buildDiagram(flowGraph, clazz, method)
69+ return buildDiagram(scope, flowGraph, clazz, method)
6570 }
6671 }
6772
@@ -91,6 +96,12 @@ class FlowDiagram(
9196 flowGraph.highlightMatches(node, soft)
9297 ui.refresh()
9398 }
99+
100+ flowGraph.onHighlightChanged { exprText, node ->
101+ scope.launch(Dispatchers .EDT ) {
102+ ui.showExpr(exprText, node)
103+ }
104+ }
94105 }
95106
96107 fun populateMatchStatuses (
@@ -105,41 +116,42 @@ class FlowDiagram(
105116 val oldHighlightRoot = flowGraph.highlightRoot
106117 ui.setMatchToolbarVisible(false )
107118 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
123139 }
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) {
130141 if (jump) {
131142 showBestNode()
132143 }
133- ui.refresh()
134- ui.setExprText(exprText)
135144 }
136- .submit(ApplicationManager .getApplication()::executeOnPooledThread)
145+ ui.refresh()
146+ }
137147 }
138148 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+ }
143155 }
144156 }
145157 }
@@ -161,7 +173,12 @@ class FlowDiagram(
161173 }
162174}
163175
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 {
165182 val graph = MxFlowGraph (flowGraph)
166183 setupStyles(graph)
167184 val groupedCells = addGraphContent(graph, flowGraph)
@@ -171,7 +188,7 @@ private suspend fun buildDiagram(flowGraph: FlowGraph, clazz: ClassNode, method:
171188 val ui = withContext(Dispatchers .EDT ) {
172189 FlowDiagramUi (graph, calculateBounds, lineNumberNodes)
173190 }
174- return FlowDiagram (ui, flowGraph, clazz, method)
191+ return FlowDiagram (scope, ui, flowGraph, clazz, method)
175192}
176193
177194private class MxFlowGraph (private val flowGraph : FlowGraph ) : mxGraph() {
0 commit comments