Skip to content

Commit 7a36da4

Browse files
committed
feature: Introduce RefMode enum and update MethodNode references. #13 #4
* Remove sink list. * Remove info area. * Add info panel. * Add some icons. * Optimize access path display. * Enhancement of MethodNode.
1 parent 3c84fe0 commit 7a36da4

42 files changed

Lines changed: 500 additions & 225 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class BuildCallGraphAction : AnAction() {
5656
project,
5757
method,
5858
uiComponents.progressBar,
59-
uiComponents.infoArea,
59+
uiComponents,
6060
uiComponents.rootListModel,
6161
)
6262

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class SearchAsSinkAction : AnAction() {
5757
CallGraphSearcher.search(
5858
uiComponents.sourceField,
5959
uiComponents.sinkField,
60-
uiComponents.infoArea,
60+
// uiComponents.infoArea,
6161
uiComponents.searchResultRootNode,
6262
uiComponents.searchResultTreeModel,
6363
project

src/main/kotlin/org/skgroup/securityinspector/analysis/ast/nodes/MethodNode.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.skgroup.securityinspector.analysis.ast.nodes
22

33
import org.skgroup.securityinspector.analysis.ast.SourceSpan
4+
import org.skgroup.securityinspector.enums.RefMode
45

56
/**
67
* Method node 是用于表示方法节点
@@ -19,9 +20,14 @@ data class MethodNode(
1920
val returnType: String,
2021
val parameters: List<ParameterNode>,
2122
val body: List<AstNode> = emptyList(),
23+
val refMode: RefMode,
2224
override val sourceSpan: SourceSpan? = null
2325
) : BaseAstNode(
2426
nodeType = "MethodDeclaration",
2527
children = body,
2628
sourceSpan = sourceSpan
27-
)
29+
){
30+
override fun toString(): String {
31+
return "MethodNode(className='$className', name='$name', returnType='$returnType', parameters=$parameters, body=$body, sourceSpan=$sourceSpan)"
32+
}
33+
}

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

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import com.intellij.psi.search.searches.ReferencesSearch
88
import com.intellij.psi.util.PsiTreeUtil
99
import org.skgroup.securityinspector.analysis.ast.nodes.MethodNode
1010
import org.skgroup.securityinspector.analysis.di.DIProcessor
11+
import org.skgroup.securityinspector.enums.RefMode
1112
import org.skgroup.securityinspector.utils.GraphUtils
1213
import java.util.ArrayDeque
1314

@@ -77,6 +78,7 @@ class CallGraphBuilder : JavaRecursiveElementVisitor() {
7778
*/
7879
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
7980
if (currentMethodStack.isEmpty()) return
81+
expression.methodExpression.qualifierExpression?.accept(this)
8082

8183
val caller = currentMethodStack.peek()
8284
// 解析被调用的方法
@@ -89,6 +91,7 @@ class CallGraphBuilder : JavaRecursiveElementVisitor() {
8991
val clazz: PsiClass? = resolvedMethod.containingClass
9092
expression.reference?.let {
9193
val calleeMethodNode = GraphUtils.getMethodNode(resolvedMethod, it)
94+
println("expression $expression resolve reference success.")
9295
// 将 callee 加入节点集合
9396
callGraph.nodes.add(calleeMethodNode)
9497
// 在 callGraph 中记录调用关系 (caller -> callee)
@@ -97,26 +100,20 @@ class CallGraphBuilder : JavaRecursiveElementVisitor() {
97100
.add(calleeMethodNode)
98101
handleIoCContainerCall(expression, caller, calleeMethodNode)
99102
} ?: run {
100-
// val calleeMethodNode = GraphUtils.getMethodNode(resolvedMethod)
101-
// callGraph.nodes.add(calleeMethodNode)
102-
// callGraph.edge
103-
// .getOrPut(caller) { mutableSetOf() }
104-
// .add(calleeMethodNode)
105-
// handleIoCContainerCall(expression, caller, calleeMethodNode)
106103
if (clazz != null) {
107104
if (clazz.isInterface) {
108105
println("$clazz is an interface")
109-
println("and the method call expression $expression can not be resolve.")
106+
println("and the method call expression $expression can not resolve reference.")
110107
}
111108
if (clazz.hasModifierProperty(PsiModifier.ABSTRACT)) {
112109
println("$clazz is an abstract class")
113-
println("and the method call expression $expression can not be resolve.")
110+
println("and the method call expression $expression can not resolve reference.")
114111
}
115112
}
116113
if (PsiTreeUtil.getParentOfType(expression, PsiLambdaExpression::class.java) != null) {
117-
println("in lambda method call expression $expression can not be resolve.")
114+
println("in lambda method call expression $expression can not resolve reference.")
118115
} else {
119-
println("unknown method call expression $expression can not be resolve.")
116+
println("unknown method call expression $expression can not resolve reference.")
120117
}
121118
}
122119
super.visitMethodCallExpression(expression)
@@ -129,6 +126,7 @@ class CallGraphBuilder : JavaRecursiveElementVisitor() {
129126
*/
130127
override fun visitNewExpression(expression: PsiNewExpression) {
131128
if (currentMethodStack.isEmpty()) return
129+
// expression.methodNewExpression.qualifierExpression?.accept(this)
132130

133131
val callerMethodNode = currentMethodStack.peek()
134132
// 解析构造方法
@@ -147,26 +145,22 @@ class CallGraphBuilder : JavaRecursiveElementVisitor() {
147145
callGraph.edges
148146
.getOrPut(callerMethodNode) { mutableSetOf() }
149147
.add(calleeMethodNode)
148+
println("expression $expression resolve reference success.")
150149
} ?: run {
151-
// val calleeMethodNode = GraphUtils.getMethodNode(constructor)
152-
// callGraph.nodes.add(calleeMethodNode)
153-
// callGraph.edges
154-
// .getOrPut(callerMethodNode) { mutableSetOf() }
155-
// .add(calleeMethodNode)
156150
if (clazz != null) {
157151
if (clazz.isInterface) {
158152
println("$clazz is an interface")
159-
println("and the method call expression $expression can not be resolve.")
153+
println("and the method call expression $expression can not resolve reference.")
160154
}
161155
if (clazz.hasModifierProperty(PsiModifier.ABSTRACT)) {
162156
println("$clazz is an abstract class")
163-
println("and the method call expression $expression can not be resolve.")
157+
println("and the method call expression $expression can not resolve referencee.")
164158
}
165159
}
166160
if (PsiTreeUtil.getParentOfType(expression, PsiLambdaExpression::class.java) != null) {
167-
println("in lambda method call expression $expression can not be resolve.")
161+
println("in lambda method call expression $expression can not resolve reference.")
168162
} else {
169-
println("unknown new expression $constructor can not be resolve.")
163+
println("unknown new expression $constructor can not resolve reference.")
170164
}
171165
}
172166
super.visitNewExpression(expression)
@@ -191,15 +185,20 @@ class CallGraphBuilder : JavaRecursiveElementVisitor() {
191185
super.visitMethodCallExpression(lambdaCall)
192186
val caller = currentMethodStack.peek()
193187
val resolvedMethod = lambdaCall.resolveMethod() ?: return
194-
val calleeMethodNode = GraphUtils.getLambdaMethodNode(resolvedMethod)
195-
196-
// 将 callee 加入图
197-
callGraph.nodes.add(calleeMethodNode)
198-
199-
// 在 callGraph 中记录调用关系 (caller -> callee)
200-
callGraph.edges
201-
.getOrPut(caller) { mutableSetOf() }
202-
.add(calleeMethodNode)
188+
lambdaCall.children.forEach { child ->
189+
val calleeMethodNode = child.reference?.let {
190+
GraphUtils.getMethodNode(resolvedMethod, it)
191+
} ?: run {
192+
GraphUtils.getLambdaMethodNode(resolvedMethod)
193+
}
194+
callGraph.nodes.add(caller)
195+
calleeMethodNode?.let {
196+
callGraph.nodes.add(it)
197+
callGraph.edges
198+
.getOrPut(caller) { mutableSetOf() }
199+
.add(it)
200+
}
201+
}
203202
}
204203

205204
override fun visitMethodReferenceExpression(expression: PsiMethodReferenceExpression) {
@@ -255,7 +254,8 @@ class CallGraphBuilder : JavaRecursiveElementVisitor() {
255254
// 其他的慢慢加吧
256255
) {
257256
// 如果是构造方法或者带有此注解的方法,可能被框架在运行时调用
258-
val containerMethodNode = MethodNode("Container", "Container", "Framework", emptyList(), emptyList())
257+
val containerMethodNode =
258+
MethodNode("Container", "Container", "Framework", emptyList(), emptyList(), RefMode.CALL)
259259
callGraph.nodes.add(containerMethodNode)
260260

261261
callGraph.edges
@@ -282,7 +282,7 @@ class CallGraphBuilder : JavaRecursiveElementVisitor() {
282282
if (qualifierExpression != null && methodName == "getBean") {
283283
// 将容器节点与被调用方法或类做额外的链接
284284
val containerMethodNode =
285-
MethodNode("ApplicationContext", "ApplicationContext", "Spring", emptyList(), emptyList())
285+
MethodNode("ApplicationContext", "ApplicationContext", "Spring", emptyList(), emptyList(), RefMode.CALL)
286286
callGraph.nodes.add(containerMethodNode)
287287
// caller -> container
288288
callGraph.edges

src/main/kotlin/org/skgroup/securityinspector/analysis/graphs/processor/DIProcessor.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import com.intellij.openapi.project.Project
44
import com.intellij.psi.*
55
import com.intellij.psi.search.GlobalSearchScope
66
import com.intellij.psi.search.searches.AnnotatedElementsSearch
7-
import com.intellij.psi.search.searches.ClassInheritorsSearch
87
import com.intellij.psi.util.PsiUtil
98
import org.skgroup.securityinspector.analysis.ast.nodes.MethodNode
109
import org.skgroup.securityinspector.analysis.graphs.callgraph.CallGraph
10+
import org.skgroup.securityinspector.enums.RefMode
1111
import org.skgroup.securityinspector.utils.GraphUtils
1212
import java.util.*
1313

@@ -123,7 +123,7 @@ class DIProcessor(
123123
if (injectionAnnotations.contains(annotation.qualifiedName)) {
124124
// 将容器 -> constructor 关系入图
125125
val constructorNode = GraphUtils.getMethodNode(constructor)
126-
val containerMethodNode = MethodNode("Container","Container", "Framework", emptyList(), emptyList())
126+
val containerMethodNode = MethodNode("Container","Container", "Framework", emptyList(), emptyList(), RefMode.CALL)
127127
callGraph.nodes.add(constructorNode)
128128
callGraph.nodes.add(containerMethodNode)
129129

@@ -217,7 +217,7 @@ class DIProcessor(
217217
GraphUtils.getMethodNode(psiClass)
218218
} else {
219219
// 找不到对应类,做一个兜底处理
220-
MethodNode(type.canonicalText ?: "UnknownType",type.canonicalText ?: "UnknownType", "DI", emptyList(), emptyList())
220+
MethodNode(type.canonicalText ?: "UnknownType",type.canonicalText ?: "UnknownType", "DI", emptyList(), emptyList(),RefMode.CALL)
221221
}
222222
}
223223

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.skgroup.securityinspector.enums
2+
3+
/**
4+
* 枚举描述:RefMode 枚举用于。
5+
*
6+
* @author springkill
7+
* @version 1.0
8+
*/
9+
enum class RefMode(val value: String) {
10+
CALL("call"),
11+
DECLARATION("declaration"),
12+
IMPLEMENTATION("implementation"),
13+
NEW("new"),
14+
}

0 commit comments

Comments
 (0)