Skip to content

File tree

3 files changed

+2027
-0
lines changed

3 files changed

+2027
-0
lines changed
 
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
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+
}

‎jacodb-panda-dynamic/src/test/resources/samples/codeqlSamples/parametersArgumentsMismatch.json

Lines changed: 1899 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
function add(a: number, b: number) {
2+
return a + b
3+
}
4+
5+
function foo() {
6+
let bad = add(5)
7+
let good = add(5, 7)
8+
}
9+
10+
class User {
11+
private name: String
12+
13+
getName() {
14+
return this.name
15+
}
16+
17+
setName(newName: String) {
18+
this.name = newName
19+
}
20+
}
21+
22+
function rightUsage() {
23+
let user = new User()
24+
user.setName("")
25+
console.log(user.getName())
26+
}
27+
28+
function wrongUsage() {
29+
let user = new User("Walter")
30+
console.log(user.getName("Walter"))
31+
user.setName()
32+
}

0 commit comments

Comments
 (0)
Please sign in to comment.