Skip to content

Commit c9a3716

Browse files
author
svorenova
committed
Adding unit test for functions with generics
1 parent 9db9947 commit c9a3716

File tree

4 files changed

+375
-0
lines changed

4 files changed

+375
-0
lines changed
Binary file not shown.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
public class FunctionsWithGenerics
2+
{
3+
4+
class Inner
5+
{
6+
public Generic<Integer> x;
7+
}
8+
9+
public static Generic<Integer> processReturnSame(Generic<Integer> x)
10+
{
11+
return x;
12+
}
13+
14+
public static Generic<Integer> processReturnDifferent(Generic<String> s)
15+
{
16+
Generic<Integer> x = new Generic<Integer>();
17+
return x;
18+
}
19+
20+
public static Generic<Integer> processReturnMultipleSame(Generic<Integer> x, Generic<Integer> y)
21+
{
22+
return x;
23+
}
24+
25+
public static Generic<Integer> processReturnMultipleDifferent(Generic<String> s, Generic<Boolean> b)
26+
{
27+
Generic<Integer> x = new Generic<Integer>();
28+
return x;
29+
}
30+
31+
public Generic<Integer> returnInnerField(Inner inner)
32+
{
33+
return inner.x;
34+
}
35+
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,339 @@
1+
/*******************************************************************\
2+
3+
Module: Unit tests for parsing generic classes
4+
5+
Author: DiffBlue Limited. All rights reserved.
6+
7+
\*******************************************************************/
8+
9+
#include <testing-utils/catch.hpp>
10+
11+
#include <util/config.h>
12+
#include <util/cmdline.h>
13+
#include <util/language.h>
14+
#include <util/prefix.h>
15+
16+
#include <java_bytecode/java_bytecode_language.h>
17+
18+
#include <iostream>
19+
#include <testing-utils/load_java_class.h>
20+
#include <testing-utils/require_type.h>
21+
22+
SCENARIO(
23+
"java_bytecode_parse_functions_with_generics",
24+
"[core][java_bytecode][java_bytecode_parse_generics]")
25+
{
26+
const symbol_tablet &new_symbol_table = load_java_class(
27+
"FunctionsWithGenerics", "./java_bytecode/java_bytecode_parse_generics");
28+
29+
std::string class_prefix = "java::FunctionsWithGenerics";
30+
31+
WHEN("Parsing processReturnSame")
32+
{
33+
THEN("There should be a symbol for the function")
34+
{
35+
const std::string func_name = ".processReturnSame";
36+
const std::string func_descriptor = ":(LGeneric;)LGeneric;";
37+
const std::string process_func_name =
38+
class_prefix + func_name + func_descriptor;
39+
40+
REQUIRE(new_symbol_table.has_symbol(process_func_name));
41+
42+
const symbolt func_symbol =
43+
new_symbol_table.lookup_ref(process_func_name);
44+
const code_typet func_code = to_code_type(func_symbol.type);
45+
46+
THEN("It has parameter x pointing to Generic")
47+
{
48+
code_typet::parametert param_x =
49+
require_type::require_parameter(func_code, "x");
50+
require_type::require_pointer(
51+
param_x.type(), symbol_typet("java::Generic"));
52+
53+
THEN("x is generic with parameter pointing to java.lang.Integer")
54+
{
55+
REQUIRE(is_java_generic_type(param_x.type()));
56+
57+
const java_generic_typet generic_x =
58+
to_java_generic_type(param_x.type());
59+
const java_generic_parametert generic_param_x =
60+
generic_x.generic_type_variables().front();
61+
require_type::require_pointer(
62+
generic_param_x, symbol_typet("java::java.lang.Integer"));
63+
}
64+
}
65+
66+
THEN("It has return type pointing to Generic")
67+
{
68+
const typet return_type = func_code.return_type();
69+
require_type::require_pointer(
70+
return_type, symbol_typet("java::Generic"));
71+
72+
THEN("It is generic with parameter pointing to java.lang.Integer")
73+
{
74+
REQUIRE(is_java_generic_type(return_type));
75+
76+
const java_generic_typet generic_return_type =
77+
to_java_generic_type(return_type);
78+
const java_generic_parametert generic_return_param =
79+
generic_return_type.generic_type_variables().front();
80+
require_type::require_pointer(
81+
generic_return_param, symbol_typet("java::java.lang.Integer"));
82+
}
83+
}
84+
}
85+
}
86+
87+
WHEN("Parsing processReturnDifferent")
88+
{
89+
THEN("There should be a symbol for the function")
90+
{
91+
const std::string func_name = ".processReturnDifferent";
92+
const std::string func_descriptor = ":(LGeneric;)LGeneric;";
93+
const std::string process_func_name =
94+
class_prefix + func_name + func_descriptor;
95+
96+
REQUIRE(new_symbol_table.has_symbol(process_func_name));
97+
98+
const symbolt func_symbol =
99+
new_symbol_table.lookup_ref(process_func_name);
100+
const code_typet func_code = to_code_type(func_symbol.type);
101+
102+
THEN("It has parameter s pointing to Generic")
103+
{
104+
code_typet::parametert param_s =
105+
require_type::require_parameter(func_code, "s");
106+
require_type::require_pointer(
107+
param_s.type(), symbol_typet("java::Generic"));
108+
109+
THEN("s is generic with parameter pointing to java.lang.String")
110+
{
111+
REQUIRE(is_java_generic_type(param_s.type()));
112+
113+
const java_generic_typet generic_s =
114+
to_java_generic_type(param_s.type());
115+
const java_generic_parametert generic_param_s =
116+
generic_s.generic_type_variables().front();
117+
require_type::require_pointer(
118+
generic_param_s, symbol_typet("java::java.lang.String"));
119+
}
120+
}
121+
122+
THEN("It has return type pointing to Generic")
123+
{
124+
const typet return_type = func_code.return_type();
125+
require_type::require_pointer(
126+
return_type, symbol_typet("java::Generic"));
127+
128+
THEN("It is generic with parameter pointing to java.lang.Integer")
129+
{
130+
REQUIRE(is_java_generic_type(return_type));
131+
132+
const java_generic_typet generic_return_type =
133+
to_java_generic_type(return_type);
134+
const java_generic_parametert generic_return_param =
135+
generic_return_type.generic_type_variables().front();
136+
require_type::require_pointer(
137+
generic_return_param, symbol_typet("java::java.lang.Integer"));
138+
}
139+
}
140+
}
141+
}
142+
143+
WHEN("Parsing processReturnMultipleSame")
144+
{
145+
THEN("There should be a symbol for the function")
146+
{
147+
const std::string func_name = ".processReturnMultipleSame";
148+
const std::string func_descriptor = ":(LGeneric;LGeneric;)LGeneric;";
149+
const std::string process_func_name =
150+
class_prefix + func_name + func_descriptor;
151+
152+
REQUIRE(new_symbol_table.has_symbol(process_func_name));
153+
154+
const symbolt func_symbol =
155+
new_symbol_table.lookup_ref(process_func_name);
156+
const code_typet func_code = to_code_type(func_symbol.type);
157+
158+
THEN("It has parameter x pointing to Generic")
159+
{
160+
code_typet::parametert param_x =
161+
require_type::require_parameter(func_code, "x");
162+
require_type::require_pointer(
163+
param_x.type(), symbol_typet("java::Generic"));
164+
165+
THEN("x is generic with parameter pointing to java.lang.Integer")
166+
{
167+
REQUIRE(is_java_generic_type(param_x.type()));
168+
169+
const java_generic_typet generic_x =
170+
to_java_generic_type(param_x.type());
171+
const java_generic_parametert generic_param_x =
172+
generic_x.generic_type_variables().front();
173+
require_type::require_pointer(
174+
generic_param_x, symbol_typet("java::java.lang.Integer"));
175+
}
176+
}
177+
178+
THEN("It has parameter y pointing to Generic")
179+
{
180+
code_typet::parametert param_y =
181+
require_type::require_parameter(func_code, "y");
182+
require_type::require_pointer(
183+
param_y.type(), symbol_typet("java::Generic"));
184+
185+
THEN("y is generic with parameter pointing to java.lang.Integer")
186+
{
187+
REQUIRE(is_java_generic_type(param_y.type()));
188+
189+
const java_generic_typet generic_y =
190+
to_java_generic_type(param_y.type());
191+
const java_generic_parametert generic_param_y =
192+
generic_y.generic_type_variables().front();
193+
require_type::require_pointer(
194+
generic_param_y, symbol_typet("java::java.lang.Integer"));
195+
}
196+
}
197+
198+
THEN("It has return type pointing to Generic")
199+
{
200+
const typet return_type = func_code.return_type();
201+
require_type::require_pointer(
202+
return_type, symbol_typet("java::Generic"));
203+
204+
THEN("It is generic with parameter pointing to java.lang.Integer")
205+
{
206+
REQUIRE(is_java_generic_type(return_type));
207+
208+
const java_generic_typet generic_return_type =
209+
to_java_generic_type(return_type);
210+
const java_generic_parametert generic_return_param =
211+
generic_return_type.generic_type_variables().front();
212+
require_type::require_pointer(
213+
generic_return_param, symbol_typet("java::java.lang.Integer"));
214+
}
215+
}
216+
}
217+
}
218+
219+
WHEN("Parsing processReturnMultipleDifferent")
220+
{
221+
THEN("There should be a symbol for the function")
222+
{
223+
const std::string func_name = ".processReturnMultipleDifferent";
224+
const std::string func_descriptor = ":(LGeneric;LGeneric;)LGeneric;";
225+
const std::string process_func_name =
226+
class_prefix + func_name + func_descriptor;
227+
228+
REQUIRE(new_symbol_table.has_symbol(process_func_name));
229+
230+
const symbolt func_symbol =
231+
new_symbol_table.lookup_ref(process_func_name);
232+
const code_typet func_code = to_code_type(func_symbol.type);
233+
234+
THEN("It has parameter s pointing to Generic")
235+
{
236+
code_typet::parametert param_s =
237+
require_type::require_parameter(func_code, "s");
238+
require_type::require_pointer(
239+
param_s.type(), symbol_typet("java::Generic"));
240+
241+
THEN("s is generic with parameter pointing to java.lang.String")
242+
{
243+
REQUIRE(is_java_generic_type(param_s.type()));
244+
245+
const java_generic_typet generic_s =
246+
to_java_generic_type(param_s.type());
247+
const java_generic_parametert generic_param_s =
248+
generic_s.generic_type_variables().front();
249+
require_type::require_pointer(
250+
generic_param_s, symbol_typet("java::java.lang.String"));
251+
}
252+
}
253+
254+
THEN("It has parameter b pointing to Generic")
255+
{
256+
code_typet::parametert param_b =
257+
require_type::require_parameter(func_code, "b");
258+
require_type::require_pointer(
259+
param_b.type(), symbol_typet("java::Generic"));
260+
261+
THEN("b is generic with parameter pointing to java.lang.Boolean")
262+
{
263+
REQUIRE(is_java_generic_type(param_b.type()));
264+
265+
const java_generic_typet generic_b =
266+
to_java_generic_type(param_b.type());
267+
const java_generic_parametert generic_param_b =
268+
generic_b.generic_type_variables().front();
269+
require_type::require_pointer(
270+
generic_param_b, symbol_typet("java::java.lang.Boolean"));
271+
}
272+
}
273+
274+
THEN("It has return type pointing to Generic")
275+
{
276+
const typet return_type = func_code.return_type();
277+
require_type::require_pointer(
278+
return_type, symbol_typet("java::Generic"));
279+
280+
THEN("It is generic with parameter pointing to java.lang.Integer")
281+
{
282+
REQUIRE(is_java_generic_type(return_type));
283+
284+
const java_generic_typet generic_return_type =
285+
to_java_generic_type(return_type);
286+
const java_generic_parametert generic_return_param =
287+
generic_return_type.generic_type_variables().front();
288+
require_type::require_pointer(
289+
generic_return_param, symbol_typet("java::java.lang.Integer"));
290+
}
291+
}
292+
}
293+
}
294+
295+
WHEN("Parsing returnInnerField")
296+
{
297+
THEN("There should be a symbol for the function")
298+
{
299+
const std::string func_name = ".returnInnerField";
300+
const std::string func_descriptor =
301+
":(LFunctionsWithGenerics$Inner;)LGeneric;";
302+
const std::string process_func_name =
303+
class_prefix + func_name + func_descriptor;
304+
305+
REQUIRE(new_symbol_table.has_symbol(process_func_name));
306+
307+
const symbolt func_symbol =
308+
new_symbol_table.lookup_ref(process_func_name);
309+
const code_typet func_code = to_code_type(func_symbol.type);
310+
311+
THEN("It has parameter inner pointing to Inner")
312+
{
313+
code_typet::parametert param_inner =
314+
require_type::require_parameter(func_code, "inner");
315+
require_type::require_pointer(
316+
param_inner.type(), symbol_typet(class_prefix + "$Inner"));
317+
}
318+
319+
THEN("It has return type pointing to Generic")
320+
{
321+
const typet return_type = func_code.return_type();
322+
require_type::require_pointer(
323+
return_type, symbol_typet("java::Generic"));
324+
325+
THEN("It is generic with parameter pointing to java.lang.Integer")
326+
{
327+
REQUIRE(is_java_generic_type(return_type));
328+
329+
const java_generic_typet generic_return_type =
330+
to_java_generic_type(return_type);
331+
const java_generic_parametert generic_return_param =
332+
generic_return_type.generic_type_variables().front();
333+
require_type::require_pointer(
334+
generic_return_param, symbol_typet("java::java.lang.Integer"));
335+
}
336+
}
337+
}
338+
}
339+
}

0 commit comments

Comments
 (0)