Skip to content

Commit 066e503

Browse files
committed
feature: Enhance CallGraph with MethodSigGraph integration and search functionality
1 parent 6cfa06e commit 066e503

9 files changed

Lines changed: 359 additions & 156 deletions

File tree

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

Lines changed: 140 additions & 115 deletions
Large diffs are not rendered by default.

src/main/kotlin/org/skgroup/securityinspector/analysis/graphs/callgraph/MethodsigGraph.kt renamed to src/main/kotlin/org/skgroup/securityinspector/analysis/graphs/callgraph/MethodSigGraph.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import org.skgroup.securityinspector.analysis.ast.nodes.MethodSigNode
88
* @author springkill
99
* @version 1.0
1010
*/
11-
data class MethodsigGraph(
11+
data class MethodSigGraph(
1212
val nodes: MutableSet<MethodSigNode> = LinkedHashSet(),
1313
) {
14-
fun merge(other: MethodsigGraph) {
14+
fun merge(other: MethodSigGraph) {
1515
this.nodes.addAll(other.nodes)
1616
}
1717
}

src/main/kotlin/org/skgroup/securityinspector/ui/component/CallGraphUIComponents.kt

Lines changed: 80 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import com.intellij.ui.components.*
1212
import com.intellij.ui.content.ContentFactory
1313
import com.intellij.ui.treeStructure.Tree
1414
import com.intellij.util.ui.JBUI
15+
import org.skgroup.securityinspector.analysis.ast.nodes.BaseAstNode
1516
import org.skgroup.securityinspector.analysis.ast.nodes.MethodNode
1617
import org.skgroup.securityinspector.analysis.graphs.callgraph.CallGraph
1718
import org.skgroup.securityinspector.enums.AnalysisScope
@@ -46,6 +47,7 @@ class CallGraphUIComponents(val project: Project) {
4647
val sinkField = JBTextField(15)
4748
val searchButton = JButton("Search")
4849

50+
val findMethodButton = JButton("Find Method")
4951
val containInfo = JBCheckBox("Info").apply {
5052
addActionListener {
5153
val enabled = isSelected
@@ -60,6 +62,39 @@ class CallGraphUIComponents(val project: Project) {
6062
}
6163
}
6264

65+
val classNameLabel = JBLabel("Class Name:")
66+
val classNameField = JBTextField(20)
67+
68+
val accessModifierLabel = JBLabel("Access Modifier:")
69+
val accessModifierField = JBTextField(10)
70+
71+
val methodModifierLabel = JBLabel("Method Modifier:")
72+
val methodModifierField = JBTextField(10)
73+
74+
val methodNameLabel = JBLabel("Method Name:")
75+
val methodNameField = JBTextField(15)
76+
77+
val paramCountLabel = JBLabel("Param Count:")
78+
val paramCountField = JBTextField(5)
79+
80+
val paramTypeLabel = JBLabel("Param Type:")
81+
val paramTypeField = JBTextField(15)
82+
83+
val paramNameLabel = JBLabel("Param Name:")
84+
val paramNameField = JBTextField(15)
85+
86+
val varargsLabel = JBLabel("Varargs:")
87+
val varargsField = JBTextField(5)
88+
89+
val throwsClauseLabel = JBLabel("Throws Clause:")
90+
val throwsClauseField = JBTextField(15)
91+
92+
val returnTypeLabel = JBLabel("Return Type:")
93+
val returnTypeField = JBTextField(15)
94+
95+
val annotationsLabel = JBLabel("Annotations:")
96+
val annotationsField = JBTextField(20)
97+
6398
val systemPlatformLabel =
6499
JBLabel("System Plat: ${System.getProperty("os.name")}", LEFT).apply {
65100
border = JBUI.Borders.empty(5)
@@ -119,37 +154,50 @@ class CallGraphUIComponents(val project: Project) {
119154
}
120155

121156
val fields = listOf(
122-
"Class Name:" to JBTextField(20),
123-
"Access Modifier:" to JBTextField(10),
124-
"Method Modifier:" to JBTextField(10),
125-
"Method Name:" to JBTextField(15),
126-
"Param Count:" to JBTextField(5),
127-
"Param Type:" to JBTextField(15),
128-
"Param Name:" to JBTextField(15),
129-
"Varargs:" to JBTextField(5),
130-
"Throws Clause:" to JBTextField(15),
131-
"Return Type:" to JBTextField(15),
132-
"Annotations:" to JBTextField(20)
157+
classNameLabel,
158+
classNameField,
159+
accessModifierLabel,
160+
accessModifierField,
161+
methodModifierLabel,
162+
methodModifierField,
163+
methodNameLabel,
164+
methodNameField,
165+
paramCountLabel,
166+
paramCountField,
167+
paramTypeLabel,
168+
paramTypeField,
169+
paramNameLabel,
170+
paramNameField,
171+
varargsLabel,
172+
varargsField,
173+
throwsClauseLabel,
174+
throwsClauseField,
175+
returnTypeLabel,
176+
returnTypeField,
177+
annotationsLabel,
178+
annotationsField,
133179
)
134180

135-
fields.forEachIndexed { index, (labelText, textField) ->
136-
c.gridx = 0
137-
c.gridy = index
138-
c.weightx = 0.0
139-
add(JBLabel(labelText), c)
140-
141-
c.gridx = 1
142-
c.weightx = 1.0
143-
add(textField, c)
181+
fields.forEachIndexed { index, it ->
182+
if (it is JBLabel) {
183+
c.gridx = 0
184+
c.gridy = index
185+
c.weightx = 0.0
186+
add(it, c)
187+
} else {
188+
c.gridx = 1
189+
c.gridy = index - 1
190+
c.weightx = 1.0
191+
add(it, c)
192+
}
144193
}
145194

146195
c.gridx = 0
147196
c.gridy = fields.size
148197
c.gridwidth = 2
149198
c.fill = GridBagConstraints.NONE
150199
c.anchor = GridBagConstraints.CENTER
151-
val actionButton = JButton("Find Method")
152-
add(actionButton, c)
200+
add(findMethodButton, c)
153201
}
154202

155203
val toggleButton = JButton("Toggle Panel")
@@ -162,7 +210,7 @@ class CallGraphUIComponents(val project: Project) {
162210
val centerPanel = createCenterPanel()
163211
splitter = JBSplitter(false, 0.8f).apply {
164212
firstComponent = centerPanel
165-
secondComponent = methodFinderPanel
213+
secondComponent = null
166214
dividerWidth = 5
167215
}
168216
mainPanel.add(splitter, BorderLayout.CENTER)
@@ -214,21 +262,23 @@ class CallGraphUIComponents(val project: Project) {
214262
panel.add(JBLabel("ROOT:"), c)
215263

216264
c.gridx = 1
217-
c.weightx = 0.0
218265
panel.add(sourceField, c)
219266

220267
c.gridx = 2
221-
c.weightx = 0.0
222268
panel.add(JBLabel("SINK:"), c)
223269

224270
c.gridx = 3
225-
c.weightx = 0.0
226271
panel.add(sinkField, c)
227272

228273
c.gridx = 4
229-
c.weightx = 0.0
230274
panel.add(searchButton, c)
231275

276+
c.gridx = 5
277+
panel.add(containInfo, c)
278+
279+
c.gridx = 6
280+
panel.add(containPath, c)
281+
232282
c.weightx = 0.0
233283

234284
c.gridx = 0
@@ -267,10 +317,10 @@ class CallGraphUIComponents(val project: Project) {
267317
// 取出这个节点的 userObject
268318
val userObject = node.userObject
269319

270-
if (userObject is MethodNode) {
320+
if (userObject is BaseAstNode) {
271321
val offset = userObject.sourceSpan
272322
offset?.let {
273-
OpenFileDescriptor(project, it.virtualFile, offset.offset).navigate(true)
323+
OpenFileDescriptor(project, it.virtualFile, offset.offset-1).navigate(true)
274324
}
275325
}
276326
}
@@ -368,7 +418,7 @@ class CallGraphUIComponents(val project: Project) {
368418
init {
369419
var isPanelVisible = true
370420
toggleButton.addActionListener {
371-
if (isPanelVisible) {
421+
if (!isPanelVisible) {
372422
// 隐藏面板:将 secondComponent 设置为 null
373423
splitter.secondComponent = null
374424
} else {

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

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,33 @@ class CallGraphToolWindowPanel(private val project: Project) {
4141
CallGraphSearcher.search(
4242
sourceField = uiComponents.sourceField,
4343
sinkField = uiComponents.sinkField,
44-
// infoArea = uiComponents.infoArea,
4544
searchResultRootNode = uiComponents.searchResultRootNode,
4645
searchResultTreeModel = uiComponents.searchResultTreeModel,
4746
project = project
4847
)
4948
}
5049

50+
uiComponents.findMethodButton.addActionListener {
51+
val sigGraph = service.getMethodSigGraph()
52+
sigGraph?.let {
53+
CallGraphSearcher.search(
54+
it,
55+
uiComponents.classNameField.text,
56+
uiComponents.accessModifierField.text,
57+
uiComponents.methodModifierField.text,
58+
uiComponents.methodNameField.text,
59+
uiComponents.paramCountField.text.toIntOrNull(),
60+
uiComponents.paramTypeField.text,
61+
uiComponents.paramNameField.text,
62+
uiComponents.varargsField.text,
63+
uiComponents.throwsClauseField.text,
64+
uiComponents.returnTypeField.text,
65+
uiComponents.annotationsField.text,
66+
uiComponents.searchResultRootNode,
67+
uiComponents.searchResultTreeModel
68+
)
69+
}
70+
}
5171
}
5272

5373
private fun loadPersistedState() {

src/main/kotlin/org/skgroup/securityinspector/ui/renderer/ResultTreeRenderer.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.skgroup.securityinspector.ui.renderer
22

33
import org.skgroup.securityinspector.analysis.ast.nodes.MethodNode
4+
import org.skgroup.securityinspector.analysis.ast.nodes.MethodSigNode
45
import org.skgroup.securityinspector.enums.RefMode
56
import org.skgroup.securityinspector.utils.IconUtil
67
import java.awt.Component
@@ -45,6 +46,11 @@ class ResultTreeRenderer : DefaultTreeCellRenderer() {
4546
userObject
4647
}
4748

49+
is MethodSigNode -> {
50+
icon = IconUtil.newIcon
51+
"${userObject.className}# ${userObject.methodName}"
52+
}
53+
4854
else -> userObject.toString()
4955
}
5056
}

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,15 @@ 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.openapi.vfs.VirtualFile
1110
import com.intellij.psi.*
12-
import com.intellij.psi.search.GlobalSearchScope
1311
import com.intellij.psi.search.ProjectScope
1412
import com.intellij.psi.search.searches.ReferencesSearch
1513
import com.intellij.psi.util.PsiTreeUtil
1614
import com.intellij.ui.Gray
1715
import org.skgroup.securityinspector.analysis.ast.nodes.MethodNode
1816
import org.skgroup.securityinspector.analysis.graphs.callgraph.CallGraph
1917
import org.skgroup.securityinspector.analysis.graphs.callgraph.CallGraphBuilder
18+
import org.skgroup.securityinspector.analysis.graphs.callgraph.MethodSigGraph
2019
import org.skgroup.securityinspector.enums.AnalysisScope
2120
import org.skgroup.securityinspector.ui.component.CallGraphUIComponents
2221
import org.skgroup.securityinspector.ui.component.ModuleSelectorDialog
@@ -47,6 +46,7 @@ object CallGraphGenerator {
4746

4847
ProgressManager.getInstance().run(object : Task.Backgroundable(project, "Generating CallGraph", true) {
4948
private var newGraph: CallGraph? = null
49+
private var sigGraph: MethodSigGraph? = null
5050
private lateinit var javaFiles: List<PsiFile>
5151

5252
//private var scope = ProjectScope.getAllScope(project)
@@ -98,7 +98,7 @@ object CallGraphGenerator {
9898
ApplicationManager.getApplication().runReadAction {
9999
if (psiFile is PsiJavaFile) {
100100
if (processedFiles.add(psiFile)) {
101-
PsiTreeUtil.findChildrenOfType(psiFile, PsiMethod::class.java).forEach{
101+
PsiTreeUtil.findChildrenOfType(psiFile, PsiMethod::class.java).forEach {
102102
it.accept(builder)
103103
}
104104
// psiFile.accept(builder)
@@ -115,6 +115,7 @@ object CallGraphGenerator {
115115
}
116116

117117
newGraph = builder.getCallGraph(project)
118+
sigGraph = builder.getMethodSigGraph()
118119
}
119120

120121
override fun onSuccess() {
@@ -126,6 +127,11 @@ object CallGraphGenerator {
126127
updateRootList(graph, rootListModel)
127128
}
128129
}
130+
131+
ApplicationManager.getApplication().invokeLater {
132+
sigGraph?.let { CallGraphMemoryService.getInstance(project).setMethodSigGraph(it) }
133+
}
134+
129135
}
130136

131137
override fun onFinished() {

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package org.skgroup.securityinspector.ui.service
33
import com.intellij.openapi.components.Service
44
import com.intellij.openapi.project.Project
55
import org.skgroup.securityinspector.analysis.graphs.callgraph.CallGraph
6+
import org.skgroup.securityinspector.analysis.graphs.callgraph.MethodSigGraph
67

78
/**
89
* 类描述:CallGraphMemoryService 类用于在内存中维护 CallGraph 实例
@@ -16,11 +17,13 @@ class CallGraphMemoryService(private val project: Project) {
1617

1718
// 内存中维护的图结构
1819
private var callGraph: CallGraph? = null
20+
private var methodSigGraph: MethodSigGraph? = null
1921

2022
/**
2123
* 获取当前内存中的调用图(可能为空)
2224
*/
2325
fun getCallGraph(): CallGraph? = callGraph
26+
fun getMethodSigGraph(): MethodSigGraph? = methodSigGraph
2427

2528
/**
2629
* Set call graph 设置(更新)新的调用图
@@ -31,6 +34,10 @@ class CallGraphMemoryService(private val project: Project) {
3134
callGraph = newGraph
3235
}
3336

37+
fun setMethodSigGraph(newGraph: MethodSigGraph) {
38+
methodSigGraph = newGraph
39+
}
40+
3441
companion object {
3542
fun getInstance(project: Project): CallGraphMemoryService {
3643
return project.getService(CallGraphMemoryService::class.java)

0 commit comments

Comments
 (0)