Skip to content

Commit e952708

Browse files
author
thk123
committed
Adding tests for parsing methods of generic classes with inner classes
1 parent 958c006 commit e952708

File tree

3 files changed

+239
-2
lines changed

3 files changed

+239
-2
lines changed
Binary file not shown.

unit/java_bytecode/java_bytecode_parse_generics/GenericClass.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,40 @@ class SameGenericParamInnerClass<T>
3030

3131
GenericInnerClass<T> field4;
3232
SameGenericParamInnerClass<T> field5;
33-
}
33+
34+
void method(InnerClass input)
35+
{
36+
37+
}
38+
39+
void method2(InnerClass input, InnerClass input2)
40+
{
41+
42+
}
43+
44+
45+
void method3(GenericInnerClass<Foo> input)
46+
{
47+
48+
}
49+
50+
void method4(GenericInnerClass<T> input)
51+
{
52+
53+
}
54+
55+
InnerClass method5()
56+
{
57+
return null;
58+
}
59+
60+
GenericInnerClass<Foo> method6()
61+
{
62+
return null;
63+
}
64+
65+
GenericInnerClass<T> method7()
66+
{
67+
return null;
68+
}
69+
}

unit/java_bytecode/java_bytecode_parse_generics/parse_generic_inner_class.cpp

Lines changed: 202 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#include <testing-utils/load_java_class.h>
2323

2424
SCENARIO(
25-
"java_bytecode_parse_generic_inner_class",
25+
"Parse fields of inner classes on a generic class",
2626
"[core][java_bytecode][java_bytecode_parse_generics]")
2727
{
2828
const symbol_tablet &new_symbol_table = load_java_class(
@@ -100,3 +100,204 @@ SCENARIO(
100100
{
101101
}
102102
}
103+
104+
SCENARIO(
105+
"Parse methods of generic classes using inner parameters",
106+
"[core][java_bytecode][java_bytecode_parse_generics][caskjd]")
107+
{
108+
const symbol_tablet &new_symbol_table = load_java_class(
109+
"GenericClass", "./java_bytecode/java_bytecode_parse_generics");
110+
111+
std::string class_prefix = "java::GenericClass";
112+
113+
THEN("Method 1 should take a pointer to GenericClass$InnerClass")
114+
{
115+
const std::string func_name = ".method";
116+
const std::string func_descriptor = ":(LGenericClass$InnerClass;)V";
117+
const std::string process_func_name =
118+
class_prefix + func_name + func_descriptor;
119+
120+
REQUIRE(new_symbol_table.has_symbol(process_func_name));
121+
const symbolt &function_symbol =
122+
new_symbol_table.lookup_ref(process_func_name);
123+
124+
const code_typet &function_call =
125+
require_type::require_code(function_symbol.type);
126+
127+
const auto param_type =
128+
require_type::require_parameter(function_call, "input");
129+
require_type::require_pointer(
130+
param_type.type(), symbol_typet("java::GenericClass$InnerClass"));
131+
132+
THEN("The pointer should be generic")
133+
{
134+
REQUIRE(is_java_generic_type(param_type.type()));
135+
const auto &generic_variables =
136+
to_java_generic_type(param_type.type()).generic_type_variables();
137+
REQUIRE(generic_variables.size() == 1);
138+
const java_generic_parametert &generic_param = generic_variables[0];
139+
REQUIRE(
140+
generic_param.type_variable() == symbol_typet("java::GenericClass::T"));
141+
}
142+
}
143+
THEN("Method 2 should take two pointers to GenericClass$InnerClass")
144+
{
145+
const std::string func_name = ".method2";
146+
const std::string func_descriptor =
147+
":(LGenericClass$InnerClass;LGenericClass$InnerClass;)V";
148+
const std::string process_func_name =
149+
class_prefix + func_name + func_descriptor;
150+
151+
REQUIRE(new_symbol_table.has_symbol(process_func_name));
152+
const symbolt &function_symbol =
153+
new_symbol_table.lookup_ref(process_func_name);
154+
155+
const code_typet &function_call =
156+
require_type::require_code(function_symbol.type);
157+
158+
// Check param input
159+
{
160+
const auto param_type =
161+
require_type::require_parameter(function_call, "input");
162+
require_type::require_pointer(
163+
param_type.type(), symbol_typet("java::GenericClass$InnerClass"));
164+
165+
THEN("The pointer should be generic")
166+
{
167+
REQUIRE(is_java_generic_type(param_type.type()));
168+
const auto &generic_variables =
169+
to_java_generic_type(param_type.type()).generic_type_variables();
170+
REQUIRE(generic_variables.size() == 1);
171+
const java_generic_parametert &generic_param = generic_variables[0];
172+
REQUIRE(
173+
generic_param.type_variable() ==
174+
symbol_typet("java::GenericClass::T"));
175+
}
176+
}
177+
178+
// Check param input2
179+
{
180+
const auto param_type2 =
181+
require_type::require_parameter(function_call, "input2");
182+
require_type::require_pointer(
183+
param_type2.type(), symbol_typet("java::GenericClass$InnerClass"));
184+
185+
THEN("The pointer should be generic")
186+
{
187+
REQUIRE(is_java_generic_type(param_type2.type()));
188+
const auto &generic_variables =
189+
to_java_generic_type(param_type2.type()).generic_type_variables();
190+
REQUIRE(generic_variables.size() == 1);
191+
const java_generic_parametert &generic_param = generic_variables[0];
192+
REQUIRE(
193+
generic_param.type_variable() ==
194+
symbol_typet("java::GenericClass::T"));
195+
}
196+
}
197+
}
198+
THEN("Method 3 should take a pointer to GenericClass$GenericInnerClass")
199+
{
200+
const std::string func_name = ".method3";
201+
const std::string func_descriptor = ":(LGenericClass$GenericInnerClass;)V";
202+
const std::string process_func_name =
203+
class_prefix + func_name + func_descriptor;
204+
205+
REQUIRE(new_symbol_table.has_symbol(process_func_name));
206+
const symbolt &function_symbol =
207+
new_symbol_table.lookup_ref(process_func_name);
208+
209+
const code_typet &function_call =
210+
require_type::require_code(function_symbol.type);
211+
212+
const auto param_type =
213+
require_type::require_parameter(function_call, "input");
214+
require_type::require_pointer(
215+
param_type.type(), symbol_typet("java::GenericClass$GenericInnerClass"));
216+
217+
THEN("The pointer should be generic")
218+
{
219+
REQUIRE(is_java_generic_type(param_type.type()));
220+
const auto &generic_variables =
221+
to_java_generic_type(param_type.type()).generic_type_variables();
222+
REQUIRE(generic_variables.size() == 1);
223+
const java_generic_parametert &generic_param = generic_variables[0];
224+
REQUIRE(is_java_generic_inst_parameter(generic_param));
225+
REQUIRE(
226+
generic_param.type_variable() ==
227+
java_reference_type(symbol_typet("java::Foo")));
228+
}
229+
}
230+
THEN("Method 4 should take a pointer to GenericClass$GenericInnerClass")
231+
{
232+
const std::string func_name = ".method4";
233+
const std::string func_descriptor = ":(LGenericClass$GenericInnerClass;)V";
234+
const std::string process_func_name =
235+
class_prefix + func_name + func_descriptor;
236+
237+
REQUIRE(new_symbol_table.has_symbol(process_func_name));
238+
const symbolt &function_symbol =
239+
new_symbol_table.lookup_ref(process_func_name);
240+
241+
const code_typet &function_call =
242+
require_type::require_code(function_symbol.type);
243+
244+
const auto param_type =
245+
require_type::require_parameter(function_call, "input");
246+
require_type::require_pointer(
247+
param_type.type(), symbol_typet("java::GenericClass$GenericInnerClass"));
248+
}
249+
THEN("Method 5 should return a GenericClass$InnerClass")
250+
{
251+
const std::string func_name = ".method5";
252+
const std::string func_descriptor = ":()LGenericClass$InnerClass;";
253+
const std::string process_func_name =
254+
class_prefix + func_name + func_descriptor;
255+
256+
REQUIRE(new_symbol_table.has_symbol(process_func_name));
257+
const symbolt &function_symbol =
258+
new_symbol_table.lookup_ref(process_func_name);
259+
260+
const code_typet &function_call =
261+
require_type::require_code(function_symbol.type);
262+
263+
require_type::require_pointer(
264+
function_call.return_type(),
265+
symbol_typet("java::GenericClass$InnerClass"));
266+
}
267+
THEN("Method 6 should return a GenericClass$InnerClass")
268+
{
269+
const std::string func_name = ".method6";
270+
const std::string func_descriptor = ":()LGenericClass$GenericInnerClass;";
271+
const std::string process_func_name =
272+
class_prefix + func_name + func_descriptor;
273+
274+
REQUIRE(new_symbol_table.has_symbol(process_func_name));
275+
const symbolt &function_symbol =
276+
new_symbol_table.lookup_ref(process_func_name);
277+
278+
const code_typet &function_call =
279+
require_type::require_code(function_symbol.type);
280+
281+
require_type::require_pointer(
282+
function_call.return_type(),
283+
symbol_typet("java::GenericClass$GenericInnerClass"));
284+
}
285+
THEN("Method 7 should return a GenericClass$InnerClass")
286+
{
287+
const std::string func_name = ".method7";
288+
const std::string func_descriptor = ":()LGenericClass$GenericInnerClass;";
289+
const std::string process_func_name =
290+
class_prefix + func_name + func_descriptor;
291+
292+
REQUIRE(new_symbol_table.has_symbol(process_func_name));
293+
const symbolt &function_symbol =
294+
new_symbol_table.lookup_ref(process_func_name);
295+
296+
const code_typet &function_call =
297+
require_type::require_code(function_symbol.type);
298+
299+
require_type::require_pointer(
300+
function_call.return_type(),
301+
symbol_typet("java::GenericClass$GenericInnerClass"));
302+
}
303+
}

0 commit comments

Comments
 (0)