Skip to content

Commit 7037047

Browse files
authored
Merge pull request #20 from SpringKill-team/feature/right-click-menu
Feature/right click menu
2 parents 7c32ec1 + 19901cb commit 7037047

4 files changed

Lines changed: 51 additions & 26 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: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ import com.intellij.openapi.progress.ProgressManager
77
import com.intellij.openapi.progress.Task
88
import com.intellij.openapi.project.Project
99
import com.intellij.openapi.ui.ComboBox
10-
import com.intellij.psi.PsiFile
11-
import com.intellij.psi.PsiJavaFile
12-
import com.intellij.psi.PsiMethod
10+
import com.intellij.psi.*
11+
import com.intellij.psi.search.GlobalSearchScope
1312
import com.intellij.psi.search.ProjectScope
13+
import com.intellij.psi.search.searches.ReferencesSearch
14+
import com.intellij.psi.util.PsiTreeUtil
1415
import com.intellij.ui.Gray
1516
import com.intellij.ui.components.JBTextArea
1617
import org.skgroup.securityinspector.analysis.ast.nodes.MethodNode
@@ -29,7 +30,6 @@ object CallGraphGenerator {
2930
progressBar: JProgressBar,
3031
infoArea: JTextArea,
3132
rootListModel: DefaultListModel<MethodNode>,
32-
sinkListModel: DefaultListModel<MethodNode>,
3333
searchComboBox: ComboBox<AnalysisScope>
3434
) {
3535
progressBar.apply {
@@ -136,15 +136,13 @@ object CallGraphGenerator {
136136
* @param progressBar
137137
* @param infoArea
138138
* @param rootListModel
139-
* @param sinkListModel
140139
*/
141140
fun generate(
142141
project: Project,
143142
method: PsiMethod,
144143
progressBar: JProgressBar,
145144
infoArea: JBTextArea,
146145
rootListModel: DefaultListModel<MethodNode>,
147-
sinkListModel: DefaultListModel<MethodNode>
148146
) {
149147
progressBar.apply {
150148
isVisible = true
@@ -154,10 +152,8 @@ object CallGraphGenerator {
154152
string = "Initializing..."
155153
}
156154

157-
// 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

@@ -170,20 +166,46 @@ object CallGraphGenerator {
170166
indicator.text = "Analyzing ${method.name}"
171167

172168
val builder = CallGraphBuilder()
169+
ReferencesSearch.search(method, GlobalSearchScope.projectScope(project)).forEach { reference ->
170+
var callerMethod: PsiMethod = method
171+
ApplicationManager.getApplication().runReadAction {
172+
callerMethod = PsiTreeUtil.getParentOfType(reference.element, PsiMethod::class.java)
173+
?: return@runReadAction
174+
}
175+
if (callerMethod != method) {
176+
generate(project, callerMethod, progressBar, infoArea, rootListModel)
177+
}
178+
}
173179
ApplicationManager.getApplication().runReadAction {
174180
method.accept(builder)
175181
}
176182
progressBar.string = "Building CallGraph for method ${method.name}"
177183

178-
newGraph = builder.getCallGraph(project)
184+
tempGraph = builder.getCallGraph(project)
179185
}
180186

187+
// override fun onSuccess() {
188+
// newGraph?.let { graph ->
189+
// ApplicationManager.getApplication().invokeLater {
190+
// CallGraphMemoryService.getInstance(project).setCallGraph(graph)
191+
// infoArea.append("Build CallGraph for method ${method.name} with ${graph.nodes.size} methods.\n")
192+
// updateRootAndSinkLists(graph, rootListModel)
193+
// }
194+
// }
195+
// }
196+
//注释原有图生成,采用增量方式替换
181197
override fun onSuccess() {
182-
newGraph?.let { graph ->
198+
tempGraph?.let { delta ->
183199
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)
200+
val memoryService = CallGraphMemoryService.getInstance(project)
201+
val currentGraph = memoryService.getCallGraph() ?: CallGraph()
202+
203+
// 合并
204+
currentGraph.merge(delta)
205+
memoryService.setCallGraph(currentGraph)
206+
207+
infoArea.append("Added ${delta.nodes.size} nodes for Call graph\n")
208+
updateRootAndSinkLists(currentGraph, rootListModel)
187209
}
188210
}
189211
}
@@ -206,21 +228,13 @@ object CallGraphGenerator {
206228
private fun updateRootAndSinkLists(
207229
callGraph: CallGraph,
208230
rootListModel: DefaultListModel<MethodNode>,
209-
// sinkListModel: DefaultListModel<MethodNode>
210231
) {
211232
rootListModel.clear()
212-
// sinkListModel.clear()
213233

214234
val allCallees = callGraph.edges.values.flatten().toSet()
215235
val roots = callGraph.nodes.filter { it !in allCallees }.sortedBy { it.name }
216236

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

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

0 commit comments

Comments
 (0)