Skip to content

Commit 823f2a7

Browse files
author
svorenova
committed
Adding a unit test for lambda method handles in class symbol
1 parent 8b172b4 commit 823f2a7

File tree

2 files changed

+264
-0
lines changed

2 files changed

+264
-0
lines changed

unit/Makefile

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ SRC += unit_tests.cpp \
2323
java_bytecode/java_bytecode_convert_class/convert_abstract_class.cpp \
2424
java_bytecode/java_bytecode_parse_generics/parse_generic_class.cpp \
2525
java_bytecode/java_object_factory/gen_nondet_string_init.cpp \
26+
java_bytecode/java_bytecode_parser/java_bytecode_parse_lambda_method_table.cpp \
27+
java_bytecode/java_bytecode_parser/java_bytecode_convert_class_lambda_method_handles.cpp \
2628
miniBDD_new.cpp \
2729
java_bytecode/java_string_library_preprocess/convert_exprt_to_string_exprt.cpp \
2830
java_bytecode/java_utils_test.cpp \
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
/*******************************************************************\
2+
3+
Module: Unit tests for parsing generic classes
4+
5+
Author: Diffblue Ltd.
6+
7+
\*******************************************************************/
8+
9+
#include <algorithm>
10+
11+
#include <testing-utils/catch.hpp>
12+
#include <testing-utils/load_java_class.h>
13+
#include <testing-utils/run_test_with_compilers.h>
14+
#include <testing-utils/require_type.h>
15+
16+
SCENARIO(
17+
"Static lambdas in class symbol",
18+
"[core][java_bytecode][java_bytecode_convert_class_lambda_method_handles]")
19+
{
20+
// NOLINTNEXTLINE(whitespace/braces)
21+
run_test_with_compilers([](const std::string &compiler) {
22+
GIVEN(
23+
"A class with static lambda variables from " + compiler + " compiler.")
24+
{
25+
const symbol_tablet &new_symbol_table = load_java_class(
26+
"StaticLambdas",
27+
"./java_bytecode/java_bytecode_parser/lambda_examples/" + compiler +
28+
"_classes/");
29+
30+
std::string class_prefix = "java::StaticLambdas";
31+
REQUIRE(new_symbol_table.has_symbol(class_prefix));
32+
33+
const symbolt &class_symbol = new_symbol_table.lookup_ref(class_prefix);
34+
35+
THEN("The class has the correct list of lambda method handles")
36+
{
37+
std::vector<std::string> lambda_identifiers;
38+
if(compiler == "eclipse")
39+
{
40+
// NOLINTNEXTLINE(whitespace/braces)
41+
lambda_identifiers = {
42+
"java::StaticLambdas.lambda$0:()V",
43+
"java::StaticLambdas.lambda$1:(ILjava/lang/Object;LDummyGeneric;)V",
44+
"java::StaticLambdas.lambda$2:([I[Ljava/lang/"
45+
"Object;[LDummyGeneric;)V",
46+
"java::StaticLambdas.lambda$3:()I",
47+
"java::StaticLambdas.lambda$4:()Ljava/lang/Object;",
48+
"java::StaticLambdas.lambda$5:()LDummyGeneric;",
49+
"java::StaticLambdas.lambda$6:()[I",
50+
"java::StaticLambdas.lambda$7:()[Ljava/lang/Object;",
51+
"java::StaticLambdas.lambda$8:()[LDummyGeneric;",
52+
"java::StaticLambdas.lambda$9:()I",
53+
"java::StaticLambdas.lambda$10:()Ljava/lang/Object;",
54+
"java::StaticLambdas.lambda$11:()LDummyGeneric;"};
55+
}
56+
else
57+
{
58+
// NOLINTNEXTLINE(whitespace/braces)
59+
lambda_identifiers = {
60+
"java::StaticLambdas.lambda$static$0:()V",
61+
"java::StaticLambdas.lambda$static$1:(ILjava/lang/"
62+
"Object;LDummyGeneric;)V",
63+
"java::StaticLambdas.lambda$static$2:([I[Ljava/lang/"
64+
"Object;[LDummyGeneric;)V",
65+
"java::StaticLambdas.lambda$static$3:()I",
66+
"java::StaticLambdas.lambda$static$4:()Ljava/lang/Object;",
67+
"java::StaticLambdas.lambda$static$5:()LDummyGeneric;",
68+
"java::StaticLambdas.lambda$static$6:()[I",
69+
"java::StaticLambdas.lambda$static$7:()[Ljava/lang/Object;",
70+
"java::StaticLambdas.lambda$static$8:()[LDummyGeneric;",
71+
"java::StaticLambdas.lambda$static$9:()I",
72+
"java::StaticLambdas.lambda$static$10:()Ljava/lang/Object;",
73+
"java::StaticLambdas.lambda$static$11:()LDummyGeneric;"};
74+
}
75+
require_type::require_lambda_method_handles(
76+
to_java_class_type(class_symbol.type), lambda_identifiers);
77+
}
78+
}
79+
});
80+
}
81+
82+
SCENARIO(
83+
"Local lambdas in class symbol",
84+
"[core][java_bytecode][java_bytecode_convert_class_lambda_method_handles]")
85+
{
86+
// NOLINTNEXTLINE(whitespace/braces)
87+
run_test_with_compilers([](const std::string &compiler) {
88+
GIVEN(
89+
"A class with static lambda variables from " + compiler + " compiler.")
90+
{
91+
const symbol_tablet &new_symbol_table = load_java_class(
92+
"LocalLambdas",
93+
"./java_bytecode/java_bytecode_parser/lambda_examples/" + compiler +
94+
"_classes/");
95+
96+
std::string class_prefix = "java::LocalLambdas";
97+
REQUIRE(new_symbol_table.has_symbol(class_prefix));
98+
99+
const symbolt &class_symbol = new_symbol_table.lookup_ref(class_prefix);
100+
101+
THEN("The class has the correct list of lambda method handles")
102+
{
103+
std::vector<std::string> lambda_identifiers;
104+
if(compiler == "eclipse")
105+
{
106+
// NOLINTNEXTLINE(whitespace/braces)
107+
lambda_identifiers = {
108+
"java::LocalLambdas.lambda$0:()V",
109+
"java::LocalLambdas.lambda$1:(ILjava/lang/Object;"
110+
"LDummyGeneric;)V",
111+
"java::LocalLambdas.lambda$2:([I[Ljava/lang/Object;"
112+
"[LDummyGeneric;)V",
113+
"java::LocalLambdas.lambda$3:()I",
114+
"java::LocalLambdas.lambda$4:()Ljava/lang/Object;",
115+
"java::LocalLambdas.lambda$5:()LDummyGeneric;",
116+
"java::LocalLambdas.lambda$6:()[I",
117+
"java::LocalLambdas.lambda$7:()[Ljava/lang/Object;",
118+
"java::LocalLambdas.lambda$8:()[LDummyGeneric;",
119+
"java::LocalLambdas.lambda$9:(I)I",
120+
"java::LocalLambdas.lambda$10:(Ljava/lang/Object;)"
121+
"Ljava/lang/Object;",
122+
"java::LocalLambdas.lambda$11:(LDummyGeneric;)"
123+
"LDummyGeneric;"};
124+
}
125+
else
126+
{
127+
// NOLINTNEXTLINE(whitespace/braces)
128+
lambda_identifiers = {
129+
"java::LocalLambdas.lambda$test$0:()V",
130+
"java::LocalLambdas.lambda$test$1:(ILjava/lang/Object;"
131+
"LDummyGeneric;)V",
132+
"java::LocalLambdas.lambda$test$2:([I[Ljava/lang/Object;"
133+
"[LDummyGeneric;)V",
134+
"java::LocalLambdas.lambda$test$3:()I",
135+
"java::LocalLambdas.lambda$test$4:()Ljava/lang/Object;",
136+
"java::LocalLambdas.lambda$test$5:()LDummyGeneric;",
137+
"java::LocalLambdas.lambda$test$6:()[I",
138+
"java::LocalLambdas.lambda$test$7:()[Ljava/lang/Object;",
139+
"java::LocalLambdas.lambda$test$8:()[LDummyGeneric;",
140+
"java::LocalLambdas.lambda$test$9:(I)I",
141+
"java::LocalLambdas.lambda$test$10:(Ljava/lang/Object;)"
142+
"Ljava/lang/Object;",
143+
"java::LocalLambdas.lambda$test$11:(LDummyGeneric;)"
144+
"LDummyGeneric;"};
145+
}
146+
require_type::require_lambda_method_handles(
147+
to_java_class_type(class_symbol.type), lambda_identifiers);
148+
}
149+
}
150+
});
151+
}
152+
153+
SCENARIO(
154+
"Member lambdas in class symbol",
155+
"[core][java_bytecode][java_bytecode_convert_class_lambda_method_handles]")
156+
{
157+
// NOLINTNEXTLINE(whitespace/braces)
158+
run_test_with_compilers([](const std::string &compiler) {
159+
GIVEN(
160+
"A class with static lambda variables from " + compiler + " compiler.")
161+
{
162+
const symbol_tablet &new_symbol_table = load_java_class(
163+
"MemberLambdas",
164+
"./java_bytecode/java_bytecode_parser/lambda_examples/" + compiler +
165+
"_classes/");
166+
167+
std::string class_prefix = "java::MemberLambdas";
168+
REQUIRE(new_symbol_table.has_symbol(class_prefix));
169+
170+
const symbolt &class_symbol = new_symbol_table.lookup_ref(class_prefix);
171+
172+
THEN("The class has the correct list of lambda method handles")
173+
{
174+
std::vector<std::string> lambda_identifiers;
175+
if(compiler == "eclipse")
176+
{
177+
// NOLINTNEXTLINE(whitespace/braces)
178+
lambda_identifiers = {
179+
"java::MemberLambdas.lambda$0:()V",
180+
"java::MemberLambdas.lambda$1:(ILjava/lang/Object;LDummyGeneric;)V",
181+
"java::MemberLambdas.lambda$2:([I[Ljava/lang/"
182+
"Object;[LDummyGeneric;)V",
183+
"java::MemberLambdas.lambda$3:()I",
184+
"java::MemberLambdas.lambda$4:()Ljava/lang/Object;",
185+
"java::MemberLambdas.lambda$5:()LDummyGeneric;",
186+
"java::MemberLambdas.lambda$6:()[I",
187+
"java::MemberLambdas.lambda$7:()[Ljava/lang/Object;",
188+
"java::MemberLambdas.lambda$8:()[LDummyGeneric;",
189+
"java::MemberLambdas.lambda$9:()I",
190+
"java::MemberLambdas.lambda$10:()Ljava/lang/Object;",
191+
"java::MemberLambdas.lambda$11:()LDummyGeneric;"};
192+
}
193+
else
194+
{
195+
// NOLINTNEXTLINE(whitespace/braces)
196+
lambda_identifiers = {
197+
"java::MemberLambdas.lambda$new$0:()V",
198+
"java::MemberLambdas.lambda$new$1:(ILjava/lang/"
199+
"Object;LDummyGeneric;)V",
200+
"java::MemberLambdas.lambda$new$2:([I[Ljava/lang/"
201+
"Object;[LDummyGeneric;)V",
202+
"java::MemberLambdas.lambda$new$3:()I",
203+
"java::MemberLambdas.lambda$new$4:()Ljava/lang/Object;",
204+
"java::MemberLambdas.lambda$new$5:()LDummyGeneric;",
205+
"java::MemberLambdas.lambda$new$6:()[I",
206+
"java::MemberLambdas.lambda$new$7:()[Ljava/lang/Object;",
207+
"java::MemberLambdas.lambda$new$8:()[LDummyGeneric;",
208+
"java::MemberLambdas.lambda$new$9:()I",
209+
"java::MemberLambdas.lambda$new$10:()Ljava/lang/Object;",
210+
"java::MemberLambdas.lambda$new$11:()LDummyGeneric;"};
211+
}
212+
require_type::require_lambda_method_handles(
213+
to_java_class_type(class_symbol.type), lambda_identifiers);
214+
}
215+
}
216+
});
217+
}
218+
219+
SCENARIO(
220+
"Member lambdas capturing outer class variables in class symbol",
221+
"[core][java_bytecode][java_bytecode_convert_class_lambda_method_handles]")
222+
{
223+
// NOLINTNEXTLINE(whitespace/braces)
224+
run_test_with_compilers([](const std::string &compiler) {
225+
GIVEN(
226+
"A class with static lambda variables from " + compiler + " compiler.")
227+
{
228+
const symbol_tablet &new_symbol_table = load_java_class(
229+
"OuterMemberLambdas$Inner",
230+
"./java_bytecode/java_bytecode_parser/lambda_examples/" + compiler +
231+
"_classes/");
232+
233+
std::string class_prefix = "java::OuterMemberLambdas$Inner";
234+
REQUIRE(new_symbol_table.has_symbol(class_prefix));
235+
236+
const symbolt &class_symbol = new_symbol_table.lookup_ref(class_prefix);
237+
238+
THEN("The class has the correct list of lambda method handles")
239+
{
240+
std::vector<std::string> lambda_identifiers;
241+
if(compiler == "eclipse")
242+
{
243+
// NOLINTNEXTLINE(whitespace/braces)
244+
lambda_identifiers = {
245+
"java::OuterMemberLambdas$Inner.lambda$0:()I",
246+
"java::OuterMemberLambdas$Inner.lambda$1:()Ljava/lang/Object;",
247+
"java::OuterMemberLambdas$Inner.lambda$2:()LDummyGeneric;"};
248+
}
249+
else
250+
{
251+
// NOLINTNEXTLINE(whitespace/braces)
252+
lambda_identifiers = {
253+
"java::OuterMemberLambdas$Inner.lambda$new$0:()I",
254+
"java::OuterMemberLambdas$Inner.lambda$new$1:()Ljava/lang/Object;",
255+
"java::OuterMemberLambdas$Inner.lambda$new$2:()LDummyGeneric;"};
256+
}
257+
require_type::require_lambda_method_handles(
258+
to_java_class_type(class_symbol.type), lambda_identifiers);
259+
}
260+
}
261+
});
262+
}

0 commit comments

Comments
 (0)