Skip to content

Commit 1da7ff1

Browse files
author
Steve Salas
committed
Can support method signatures with generics
1 parent cf551e4 commit 1da7ff1

File tree

2 files changed

+137
-1
lines changed

2 files changed

+137
-1
lines changed

codepulse/src/main/scala/com/secdec/codepulse/data/bytecode/CodePath.scala

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import com.secdec.codepulse.data.MethodSignature
2424
import com.secdec.codepulse.data.MethodTypeParam
2525
import java.lang.reflect.Modifier
2626

27+
import scala.util.matching.Regex
28+
2729
/** Represents the Logical Location of a Method in a codebase.
2830
*
2931
* A CodePath generally starts with a Package (though it doesn't have to), followed by
@@ -73,9 +75,26 @@ object CodePath {
7375
}
7476
}
7577

78+
val expr: Regex = new Regex("^([^<]+?)(`\\d+)?<(.+)>$")
79+
7680
def typeParamToString(tp: MethodTypeParam): String = tp match {
7781
case MethodTypeParam.Primitive(name) => name.toLowerCase
78-
case MethodTypeParam.ReferenceType(ref) => ref.substring(1 + ref.lastIndexOf('.'))
82+
case MethodTypeParam.ReferenceType(ref) => {
83+
val result:String = ref match {
84+
case expr(part1, _, part2) => {
85+
typeParamToString(MethodTypeParam.ReferenceType(part1)) + "<" + typeParamToString(MethodTypeParam.ReferenceType(part2)) + ">"
86+
}
87+
case _ => {
88+
val types = ref.split(",")
89+
if (types.length > 1) {
90+
types.map(x => typeParamToString(MethodTypeParam.ReferenceType(x))).mkString(",")
91+
} else {
92+
ref.substring(1 + ref.lastIndexOf('.'))
93+
}
94+
}
95+
}
96+
result
97+
}
7998
case MethodTypeParam.ArrayType(tp2) => typeParamToString(tp2) + "[]"
8099
}
81100

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package com.secdec.codepulse.data.bytecode.test
2+
3+
import com.secdec.codepulse.data.bytecode.CodePath
4+
import com.secdec.codepulse.data.{MethodSignature, MethodTypeParam}
5+
import org.scalatest.{FunSpec, Matchers}
6+
7+
class CodeTreeSuite extends FunSpec with Matchers {
8+
describe("Method with generic return value") {
9+
it("should include generic return value") {
10+
assert(CodePath.methodSignatureToString(MethodSignature("Method",
11+
"AClass",
12+
None,
13+
1,
14+
List(),
15+
MethodTypeParam.ReferenceType("System.Collections.Generic.List<String>"))) == "public List<String> Method()")
16+
}
17+
}
18+
19+
describe("Method with generic and inner generic return value") {
20+
it("should include both generics in return value") {
21+
assert(CodePath.methodSignatureToString(MethodSignature("Method",
22+
"AClass",
23+
None,
24+
1,
25+
List(),
26+
MethodTypeParam.ReferenceType("System.Collections.Generic.List<System.Collections.Generic.Dictionary<System.String,System.String>>"))) == "public List<Dictionary<String,String>> Method()")
27+
}
28+
}
29+
30+
describe("Method with generic and inner generic return value and parameter count") {
31+
it("should include both generics in return value") {
32+
assert(CodePath.methodSignatureToString(MethodSignature("Method",
33+
"AClass",
34+
None,
35+
1,
36+
List(),
37+
MethodTypeParam.ReferenceType("List`1<System.Collections.Generic.Dictionary`2<System.String,System.String>>"))) == "public List<Dictionary<String,String>> Method()")
38+
}
39+
}
40+
41+
describe("Method with generic parameter") {
42+
it("should include generic parameter") {
43+
assert(CodePath.methodSignatureToString(MethodSignature("Method",
44+
"AClass",
45+
None,
46+
1,
47+
List(MethodTypeParam.ReferenceType("System.Collections.Generic.List<System.String>")),
48+
MethodTypeParam.ReferenceType("void"))) == "public void Method(List<String>)")
49+
}
50+
}
51+
52+
describe("Method with generic parameters") {
53+
it("should include generic parameters") {
54+
assert(CodePath.methodSignatureToString(MethodSignature("Method",
55+
"AClass",
56+
None,
57+
1,
58+
List(MethodTypeParam.ReferenceType("System.Collections.Generic.List<System.String>"), MethodTypeParam.ReferenceType("System.Collections.Generic.Dictionary<System.String,int>")),
59+
MethodTypeParam.ReferenceType("void"))) == "public void Method(List<String>, Dictionary<String,int>)")
60+
}
61+
}
62+
63+
describe("Method with generic parameters and parameter count") {
64+
it("should include generic parameters") {
65+
assert(CodePath.methodSignatureToString(MethodSignature("Method",
66+
"AClass",
67+
None,
68+
1,
69+
List(MethodTypeParam.ReferenceType("System.Collections.Generic.List`1<System.String>"), MethodTypeParam.ReferenceType("System.Collections.Generic.Dictionary`2<System.String,int>")),
70+
MethodTypeParam.ReferenceType("void"))) == "public void Method(List<String>, Dictionary<String,int>)")
71+
}
72+
}
73+
74+
describe("Method with reference and primitive parameters") {
75+
it("should include reference and primitive parameters") {
76+
assert(CodePath.methodSignatureToString(MethodSignature("Method",
77+
"AClass",
78+
None,
79+
1,
80+
List(MethodTypeParam.ReferenceType("System.String"), MethodTypeParam.Primitive("int")),
81+
MethodTypeParam.ReferenceType("void"))) == "public void Method(String, int)")
82+
}
83+
}
84+
85+
describe("Method returning reference type") {
86+
it("should include reference type return") {
87+
assert(CodePath.methodSignatureToString(MethodSignature("Method",
88+
"AClass",
89+
None,
90+
1,
91+
List(),
92+
MethodTypeParam.ReferenceType("System.String"))) == "public String Method()")
93+
}
94+
}
95+
96+
describe("Method returning primitive type") {
97+
it("should include primitive type return") {
98+
assert(CodePath.methodSignatureToString(MethodSignature("Method",
99+
"AClass",
100+
None,
101+
1,
102+
List(),
103+
MethodTypeParam.ReferenceType("int"))) == "public int Method()")
104+
}
105+
}
106+
107+
describe("Method returning primitive type with reference type parameters") {
108+
it("should include primitive type return with reference type parameters") {
109+
assert(CodePath.methodSignatureToString(MethodSignature("Method",
110+
"AClass",
111+
None,
112+
1,
113+
List(MethodTypeParam.Primitive("int"), MethodTypeParam.ReferenceType("System.String")),
114+
MethodTypeParam.Primitive("bool"))) == "public bool Method(int, String)")
115+
}
116+
}
117+
}

0 commit comments

Comments
 (0)