1
+ /*
2
+ * Copyright 2022 UnitTestBot contributors (utbot.org)
3
+ * <p>
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ * <p>
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ * <p>
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ package analysis
18
+
19
+ import org.jacodb.panda.dynamic.api.*
20
+ import org.junit.jupiter.api.Nested
21
+ import org.junit.jupiter.api.Test
22
+ import org.junit.jupiter.api.Disabled
23
+ import parser.loadIr
24
+
25
+ private val logger = mu.KotlinLogging .logger {}
26
+
27
+ class SimpleStaticAnalysisTest {
28
+ @Nested
29
+ inner class ArgumentParameterCorrespondenceTest {
30
+
31
+ private fun analyse (programName : String , startMethods : List <String >) : List <Pair <PandaInst , PandaMethod >> {
32
+ val parser = loadIr(" /samples/${programName} .json" )
33
+ val project = parser.getProject()
34
+ val graph = PandaApplicationGraphImpl (project)
35
+ val methods = graph.project.classes.flatMap { it.methods }
36
+ val mismatches = mutableListOf<Pair <PandaInst , PandaMethod >>()
37
+ for (method in methods) {
38
+ if (startMethods.contains(method.name)) {
39
+ for (inst in method.instructions) {
40
+ var callExpr : PandaCallExpr ? = null
41
+ if (inst is PandaCallInst ) {
42
+ callExpr = inst.callExpr
43
+ }
44
+ if (inst is PandaAssignInst ) {
45
+ if (inst.rhv is PandaCallExpr ) {
46
+ callExpr = inst.callExpr
47
+ }
48
+ }
49
+ if (callExpr == null ) {
50
+ continue
51
+ }
52
+ val callee = callExpr.method
53
+
54
+ // TODO(): need more smart check that callee is not variadic function
55
+ if (callee.name == " log" ) {
56
+ continue
57
+ }
58
+ if (callExpr.args.size != callee.parameters.size) {
59
+ mismatches.add(Pair (inst, callee))
60
+ logger.info { " parameter-argument count mismatch for call: $inst (expected ${callee.parameters.size} arguments, but got ${callExpr.args.size} )" }
61
+ }
62
+ }
63
+ }
64
+ }
65
+ return mismatches
66
+ }
67
+
68
+ @Test
69
+ fun `test for mismatch detection in regular function call` () {
70
+ val mismatches = analyse(
71
+ programName = " codeqlSamples/parametersArgumentsMismatch" ,
72
+ startMethods = listOf (" foo" )
73
+ )
74
+ assert (mismatches.size == 1 )
75
+ }
76
+
77
+ @Test
78
+ fun `positive example - test for mismatch detection in class method call` () {
79
+ val mismatches = analyse(
80
+ programName = " codeqlSamples/parametersArgumentsMismatch" ,
81
+ startMethods = listOf (" rightUsage" )
82
+ )
83
+ assert (mismatches.isEmpty())
84
+ }
85
+
86
+ @Disabled(" Don't work cause we can't resolve constructors yet" )
87
+ @Test
88
+ fun `counterexample - test for mismatch detection in class method call` () {
89
+ val mismatches = analyse(
90
+ programName = " codeqlSamples/parametersArgumentsMismatch" ,
91
+ startMethods = listOf (" wrongUsage" )
92
+ )
93
+ assert (mismatches.size == 3 )
94
+ }
95
+ }
96
+ }
0 commit comments