Skip to content

Commit 79e9e3a

Browse files
committed
feature: use incremental graph for single method #2
1 parent 11d2ee6 commit 79e9e3a

4 files changed

Lines changed: 37 additions & 22 deletions

File tree

src/main/kotlin/org/skgroup/securityinspector/actions/BuildCallGraphAction.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ class BuildCallGraphAction : AnAction() {
4343
uiComponents.progressBar,
4444
uiComponents.infoArea,
4545
uiComponents.rootListModel,
46-
uiComponents.sinkListModel
4746
)
4847

4948
}

src/main/kotlin/org/skgroup/securityinspector/analysis/graphs/callgraph/CallGraph.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,19 @@ data class CallGraph(
2727
fun addSpecialNode(node: MethodNode, type: NodeType) {
2828
nodeTypes[node] = type
2929
}
30+
31+
fun merge(other: CallGraph) {
32+
// 合并节点
33+
this.nodes.addAll(other.nodes)
34+
35+
// 合并边
36+
other.edges.forEach { (from, toSet) ->
37+
val existingSet = this.edges.getOrPut(from) { mutableSetOf() }
38+
existingSet.addAll(toSet)
39+
}
40+
41+
this.edgeTypes.putAll(other.edgeTypes)
42+
this.nodeTypes.putAll(other.nodeTypes)
43+
}
44+
3045
}

src/main/kotlin/org/skgroup/securityinspector/ui/panel/CallGraphToolWindowPanel.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ class CallGraphToolWindowPanel(private val project: Project) {
3232
uiComponents.progressBar,
3333
uiComponents.infoArea,
3434
uiComponents.rootListModel,
35-
uiComponents.sinkListModel,
3635
uiComponents.searchComboBox
3736
)
3837
uiComponents.runAnalysisButton.isEnabled = true
@@ -63,10 +62,8 @@ class CallGraphToolWindowPanel(private val project: Project) {
6362

6463
private fun updateRootAndSinkLists(callGraph: CallGraph) {
6564
uiComponents.rootListModel.clear()
66-
// uiComponents.sinkListModel.clear()
6765

6866
val (roots, sinks) = CallGraphSearcher.calculateRootsAndSinks(callGraph)
6967
roots.forEach(uiComponents.rootListModel::addElement)
70-
// sinks.forEach(uiComponents.sinkListModel::addElement)
7168
}
7269
}

src/main/kotlin/org/skgroup/securityinspector/ui/service/CallGraphGenerator.kt

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ object CallGraphGenerator {
2929
progressBar: JProgressBar,
3030
infoArea: JTextArea,
3131
rootListModel: DefaultListModel<MethodNode>,
32-
sinkListModel: DefaultListModel<MethodNode>,
3332
searchComboBox: ComboBox<AnalysisScope>
3433
) {
3534
progressBar.apply {
@@ -136,15 +135,13 @@ object CallGraphGenerator {
136135
* @param progressBar
137136
* @param infoArea
138137
* @param rootListModel
139-
* @param sinkListModel
140138
*/
141139
fun generate(
142140
project: Project,
143141
method: PsiMethod,
144142
progressBar: JProgressBar,
145143
infoArea: JBTextArea,
146144
rootListModel: DefaultListModel<MethodNode>,
147-
sinkListModel: DefaultListModel<MethodNode>
148145
) {
149146
progressBar.apply {
150147
isVisible = true
@@ -155,9 +152,8 @@ object CallGraphGenerator {
155152
}
156153

157154
// TODO 现在的调用图只有一个方法的上下文,非常残缺,需要拓展
158-
// TODO 现在每次生成会覆盖原有调用图(因为方法从完整调用图得来),对于单个方法,需要考虑增量
159155
ProgressManager.getInstance().run(object : Task.Backgroundable(project, "Generating CallGraph", true) {
160-
private var newGraph: CallGraph? = null
156+
private var tempGraph: CallGraph? = null
161157

162158
override fun run(indicator: ProgressIndicator) {
163159

@@ -175,15 +171,31 @@ object CallGraphGenerator {
175171
}
176172
progressBar.string = "Building CallGraph for method ${method.name}"
177173

178-
newGraph = builder.getCallGraph(project)
174+
tempGraph = builder.getCallGraph(project)
179175
}
180176

177+
// override fun onSuccess() {
178+
// newGraph?.let { graph ->
179+
// ApplicationManager.getApplication().invokeLater {
180+
// CallGraphMemoryService.getInstance(project).setCallGraph(graph)
181+
// infoArea.append("Build CallGraph for method ${method.name} with ${graph.nodes.size} methods.\n")
182+
// updateRootAndSinkLists(graph, rootListModel)
183+
// }
184+
// }
185+
// }
186+
//注释原有图生成,采用增量方式替换
181187
override fun onSuccess() {
182-
newGraph?.let { graph ->
188+
tempGraph?.let { delta ->
183189
ApplicationManager.getApplication().invokeLater {
184-
CallGraphMemoryService.getInstance(project).setCallGraph(graph)
185-
infoArea.append("Build CallGraph for method ${method.name} with ${graph.nodes.size} methods.\n")
186-
updateRootAndSinkLists(graph, rootListModel)
190+
val memoryService = CallGraphMemoryService.getInstance(project)
191+
val currentGraph = memoryService.getCallGraph() ?: CallGraph()
192+
193+
// 合并
194+
currentGraph.merge(delta)
195+
memoryService.setCallGraph(currentGraph)
196+
197+
infoArea.append("Added ${delta.nodes.size} nodes for Call graph")
198+
updateRootAndSinkLists(currentGraph, rootListModel)
187199
}
188200
}
189201
}
@@ -206,21 +218,13 @@ object CallGraphGenerator {
206218
private fun updateRootAndSinkLists(
207219
callGraph: CallGraph,
208220
rootListModel: DefaultListModel<MethodNode>,
209-
// sinkListModel: DefaultListModel<MethodNode>
210221
) {
211222
rootListModel.clear()
212-
// sinkListModel.clear()
213223

214224
val allCallees = callGraph.edges.values.flatten().toSet()
215225
val roots = callGraph.nodes.filter { it !in allCallees }.sortedBy { it.name }
216226

217-
val sinks = callGraph.nodes.filter { node ->
218-
val callees = callGraph.edges[node]
219-
callees.isNullOrEmpty()
220-
}.sortedBy { it.name }
221-
222227
roots.forEach(rootListModel::addElement)
223-
// sinks.forEach(sinkListModel::addElement)
224228
}
225229

226230
private fun showModuleSelectorDialog(project: Project): Module {

0 commit comments

Comments
 (0)