Skip to content

Commit b28562b

Browse files
Adds unit test for parsing inner classes.
1 parent c336455 commit b28562b

27 files changed

+385
-0
lines changed

jbmc/unit/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ SRC += java_bytecode/goto-programs/class_hierarchy_output.cpp \
1212
java_bytecode/java_bytecode_convert_class/convert_java_annotations.cpp \
1313
java_bytecode/java_bytecode_convert_method/convert_invoke_dynamic.cpp \
1414
java_bytecode/java_bytecode_parse_generics/parse_generic_class.cpp \
15+
java_bytecode/java_bytecode_parser/parse_java_attributes.cpp \
1516
java_bytecode/java_object_factory/gen_nondet_string_init.cpp \
1617
java_bytecode/java_bytecode_parse_lambdas/java_bytecode_parse_lambda_method_table.cpp \
1718
java_bytecode/java_bytecode_parse_lambdas/java_bytecode_convert_class_lambda_method_handles.cpp \
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
public class InnerClasses {
2+
public class PublicInnerClass {
3+
public int i;
4+
public PublicInnerClass(int i) {
5+
this.i = i;
6+
}
7+
}
8+
class DefaultInnerClass {
9+
int i;
10+
DefaultInnerClass(int i) {
11+
this.i = i;
12+
}
13+
}
14+
protected class ProtectedInnerClass {
15+
protected int i;
16+
protected ProtectedInnerClass(int i) {
17+
this.i = i;
18+
}
19+
}
20+
private class PrivateInnerClass {
21+
private int i;
22+
private PrivateInnerClass(int i) {
23+
this.i = i;
24+
}
25+
}
26+
}
27+
28+
class InnerClassesDefault {
29+
public class PublicInnerClass {
30+
public int i;
31+
public PublicInnerClass(int i) {
32+
this.i = i;
33+
}
34+
}
35+
class DefaultInnerClass {
36+
int i;
37+
DefaultInnerClass(int i) {
38+
this.i = i;
39+
}
40+
}
41+
protected class ProtectedInnerClass {
42+
protected int i;
43+
protected ProtectedInnerClass(int i) {
44+
this.i = i;
45+
}
46+
}
47+
private class PrivateInnerClass {
48+
private int i;
49+
private PrivateInnerClass(int i) {
50+
this.i = i;
51+
}
52+
}
53+
}
54+
55+
class InnerClassesDeeplyNested {
56+
class SinglyNestedClass {
57+
int i;
58+
SinglyNestedClass(int i) {
59+
this.i = i;
60+
}
61+
public class PublicDoublyNestedInnerClass {
62+
public int i;
63+
public PublicDoublyNestedInnerClass(int i) {
64+
this.i = i;
65+
}
66+
}
67+
class DefaultDoublyNestedInnerClass {
68+
int i;
69+
DefaultDoublyNestedInnerClass(int i) {
70+
this.i = i;
71+
}
72+
}
73+
protected class ProtectedDoublyNestedInnerClass {
74+
protected int i;
75+
protected ProtectedDoublyNestedInnerClass(int i) {
76+
this.i = i;
77+
}
78+
}
79+
private class PrivateDoublyNestedInnerClass {
80+
private int i;
81+
private PrivateDoublyNestedInnerClass(int i) {
82+
this.i = i;
83+
}
84+
}
85+
}
86+
}
87+
88+
class ContainsAnonymousClass {
89+
interface InnerInterface {
90+
int i = 0;
91+
}
92+
public InnerInterface anonymousPublic = new InnerInterface() {
93+
int i = 1;
94+
};
95+
InnerInterface anonymousDefault = new InnerInterface() {
96+
int i = 2;
97+
};
98+
protected InnerInterface anonymousProtected = new InnerInterface() {
99+
int i = 3;
100+
};
101+
private InnerInterface anonymousPrivate = new InnerInterface() {
102+
int i = 4;
103+
};
104+
}
105+
106+
class ContainsLocalClass {
107+
public void test() {
108+
class LocalClass {
109+
int i = 55;
110+
LocalClass(int i) {
111+
this.i = i;
112+
}
113+
}
114+
}
115+
}
Binary file not shown.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
/*******************************************************************\
2+
3+
Module: Unit tests for converting annotations
4+
5+
Author: Diffblue Ltd.
6+
7+
\*******************************************************************/
8+
9+
#include <java-testing-utils/load_java_class.h>
10+
#include <java_bytecode/java_bytecode_convert_class.h>
11+
#include <java_bytecode/java_bytecode_parse_tree.h>
12+
#include <java_bytecode/java_types.h>
13+
#include <testing-utils/catch.hpp>
14+
15+
SCENARIO(
16+
"java_bytecode_parse_attributes",
17+
"[core][java_bytecode][java_bytecode_parser]")
18+
{
19+
GIVEN("Some public class files in the class path with inner classes")
20+
{
21+
const symbol_tablet &new_symbol_table =
22+
load_java_class("InnerClasses", "./java_bytecode/java_bytecode_parser");
23+
WHEN("Parsing the InnerClasses attribute for a public inner class")
24+
{
25+
THEN("The class should be marked as public")
26+
{
27+
const symbolt &class_symbol =
28+
new_symbol_table.lookup_ref("java::InnerClasses$PublicInnerClass");
29+
const java_class_typet java_class =
30+
to_java_class_type(class_symbol.type);
31+
REQUIRE(java_class.get_is_inner_class());
32+
REQUIRE(java_class.get_access() == ID_public);
33+
}
34+
}
35+
WHEN("Parsing the InnerClasses attribute for a package private inner class")
36+
{
37+
THEN("The class should be marked as default")
38+
{
39+
const symbolt &class_symbol =
40+
new_symbol_table.lookup_ref("java::InnerClasses$DefaultInnerClass");
41+
const java_class_typet java_class =
42+
to_java_class_type(class_symbol.type);
43+
REQUIRE(java_class.get_is_inner_class());
44+
REQUIRE(java_class.get_access() == ID_default);
45+
}
46+
}
47+
WHEN("Parsing the InnerClasses attribute for a protected inner class")
48+
{
49+
THEN("The class should be marked as protected")
50+
{
51+
const symbolt &class_symbol =
52+
new_symbol_table.lookup_ref("java::InnerClasses$ProtectedInnerClass");
53+
const java_class_typet java_class =
54+
to_java_class_type(class_symbol.type);
55+
REQUIRE(java_class.get_is_inner_class());
56+
REQUIRE(java_class.get_access() == ID_protected);
57+
}
58+
}
59+
WHEN("Parsing the InnerClasses attribute for a private inner class")
60+
{
61+
THEN("The class should be marked as private")
62+
{
63+
const symbolt &class_symbol =
64+
new_symbol_table.lookup_ref("java::InnerClasses$PrivateInnerClass");
65+
const java_class_typet java_class =
66+
to_java_class_type(class_symbol.type);
67+
REQUIRE(java_class.get_is_inner_class());
68+
REQUIRE(java_class.get_access() == ID_private);
69+
}
70+
}
71+
}
72+
GIVEN("Some package-private class files in the class path with inner classes")
73+
{
74+
const symbol_tablet &new_symbol_table = load_java_class(
75+
"InnerClassesDefault", "./java_bytecode/java_bytecode_parser");
76+
WHEN("Parsing the InnerClasses attribute for a public inner class")
77+
{
78+
THEN("The class should be marked as public")
79+
{
80+
const symbolt &class_symbol = new_symbol_table.lookup_ref(
81+
"java::InnerClassesDefault$PublicInnerClass");
82+
const java_class_typet java_class =
83+
to_java_class_type(class_symbol.type);
84+
REQUIRE(java_class.get_is_inner_class());
85+
REQUIRE(java_class.get_access() == ID_public);
86+
}
87+
}
88+
WHEN("Parsing the InnerClasses attribute for a package private inner class")
89+
{
90+
THEN("The class should be marked as default")
91+
{
92+
const symbolt &class_symbol = new_symbol_table.lookup_ref(
93+
"java::InnerClassesDefault$DefaultInnerClass");
94+
const java_class_typet java_class =
95+
to_java_class_type(class_symbol.type);
96+
REQUIRE(java_class.get_is_inner_class());
97+
REQUIRE(java_class.get_access() == ID_default);
98+
}
99+
}
100+
WHEN("Parsing the InnerClasses attribute for a protected inner class")
101+
{
102+
THEN("The class should be marked as protected")
103+
{
104+
const symbolt &class_symbol = new_symbol_table.lookup_ref(
105+
"java::InnerClassesDefault$ProtectedInnerClass");
106+
const java_class_typet java_class =
107+
to_java_class_type(class_symbol.type);
108+
REQUIRE(java_class.get_is_inner_class());
109+
REQUIRE(java_class.get_access() == ID_protected);
110+
}
111+
}
112+
WHEN("Parsing the InnerClasses attribute for a private inner class")
113+
{
114+
THEN("The class should be marked as private")
115+
{
116+
const symbolt &class_symbol = new_symbol_table.lookup_ref(
117+
"java::InnerClassesDefault$PrivateInnerClass");
118+
const java_class_typet java_class =
119+
to_java_class_type(class_symbol.type);
120+
REQUIRE(java_class.get_is_inner_class());
121+
REQUIRE(java_class.get_access() == ID_private);
122+
}
123+
}
124+
}
125+
126+
GIVEN(
127+
"Some package-private class files in the class path with deeply nested "
128+
"inner classes")
129+
{
130+
const symbol_tablet &new_symbol_table = load_java_class(
131+
"InnerClassesDeeplyNested", "./java_bytecode/java_bytecode_parser");
132+
WHEN(
133+
"Parsing the InnerClasses attribute for a public doubly-nested inner "
134+
"class")
135+
{
136+
THEN("The class should be marked as public")
137+
{
138+
const symbolt &class_symbol = new_symbol_table.lookup_ref(
139+
"java::InnerClassesDeeplyNested$SinglyNestedClass$"
140+
"PublicDoublyNestedInnerClass");
141+
const java_class_typet java_class =
142+
to_java_class_type(class_symbol.type);
143+
REQUIRE(java_class.get_is_inner_class());
144+
REQUIRE(java_class.get_access() == ID_public);
145+
}
146+
}
147+
WHEN(
148+
"Parsing the InnerClasses attribute for a package private doubly-nested "
149+
"inner class")
150+
{
151+
THEN("The class should be marked as default")
152+
{
153+
const symbolt &class_symbol = new_symbol_table.lookup_ref(
154+
"java::InnerClassesDeeplyNested$SinglyNestedClass$"
155+
"DefaultDoublyNestedInnerClass");
156+
const java_class_typet java_class =
157+
to_java_class_type(class_symbol.type);
158+
REQUIRE(java_class.get_is_inner_class());
159+
REQUIRE(java_class.get_access() == ID_default);
160+
}
161+
}
162+
WHEN(
163+
"Parsing the InnerClasses attribute for a protected doubly-nested inner "
164+
"class")
165+
{
166+
THEN("The class should be marked as protected")
167+
{
168+
const symbolt &class_symbol = new_symbol_table.lookup_ref(
169+
"java::InnerClassesDeeplyNested$SinglyNestedClass$"
170+
"ProtectedDoublyNestedInnerClass");
171+
const java_class_typet java_class =
172+
to_java_class_type(class_symbol.type);
173+
REQUIRE(java_class.get_is_inner_class());
174+
REQUIRE(java_class.get_access() == ID_protected);
175+
}
176+
}
177+
WHEN(
178+
"Parsing the InnerClasses attribute for a private doubly-nested inner "
179+
"class")
180+
{
181+
THEN("The class should be marked as private")
182+
{
183+
const symbolt &class_symbol = new_symbol_table.lookup_ref(
184+
"java::InnerClassesDeeplyNested$SinglyNestedClass$"
185+
"PrivateDoublyNestedInnerClass");
186+
const java_class_typet java_class =
187+
to_java_class_type(class_symbol.type);
188+
REQUIRE(java_class.get_is_inner_class());
189+
REQUIRE(java_class.get_access() == ID_private);
190+
}
191+
}
192+
}
193+
194+
GIVEN(
195+
"Some package-private class files in the class path with anonymous classes")
196+
{
197+
const symbol_tablet &new_symbol_table = load_java_class(
198+
"ContainsAnonymousClass", "./java_bytecode/java_bytecode_parser");
199+
WHEN("Parsing the InnerClasses attribute for a public anonymous class")
200+
{
201+
THEN("The class should be marked as public")
202+
{
203+
const symbolt &class_symbol =
204+
new_symbol_table.lookup_ref("java::ContainsAnonymousClass$1");
205+
const java_class_typet java_class =
206+
to_java_class_type(class_symbol.type);
207+
REQUIRE_FALSE(java_class.get_is_inner_class());
208+
REQUIRE(java_class.get_access() == ID_private);
209+
}
210+
}
211+
WHEN(
212+
"Parsing the InnerClasses attribute for a package-private anonymous "
213+
"class")
214+
{
215+
THEN("The class should be marked as default")
216+
{
217+
const symbolt &class_symbol =
218+
new_symbol_table.lookup_ref("java::ContainsAnonymousClass$2");
219+
const java_class_typet java_class =
220+
to_java_class_type(class_symbol.type);
221+
REQUIRE_FALSE(java_class.get_is_inner_class());
222+
REQUIRE(java_class.get_access() == ID_private);
223+
}
224+
}
225+
WHEN("Parsing the InnerClasses attribute for a protected anonymous class")
226+
{
227+
THEN("The class should be marked as protected")
228+
{
229+
const symbolt &class_symbol =
230+
new_symbol_table.lookup_ref("java::ContainsAnonymousClass$3");
231+
const java_class_typet java_class =
232+
to_java_class_type(class_symbol.type);
233+
REQUIRE_FALSE(java_class.get_is_inner_class());
234+
REQUIRE(java_class.get_access() == ID_private);
235+
}
236+
}
237+
WHEN("Parsing the InnerClasses attribute for a private anonymous class")
238+
{
239+
THEN("The class should be marked as private")
240+
{
241+
const symbolt &class_symbol =
242+
new_symbol_table.lookup_ref("java::ContainsAnonymousClass$4");
243+
const java_class_typet java_class =
244+
to_java_class_type(class_symbol.type);
245+
REQUIRE_FALSE(java_class.get_is_inner_class());
246+
REQUIRE(java_class.get_access() == ID_private);
247+
}
248+
}
249+
}
250+
251+
GIVEN(
252+
"Some package-private class files in the class path with local classes ")
253+
{
254+
const symbol_tablet &new_symbol_table = load_java_class(
255+
"ContainsLocalClass", "./java_bytecode/java_bytecode_parser");
256+
WHEN("Parsing the InnerClasses attribute for a package-private class ")
257+
{
258+
THEN("The class should be marked as package-private")
259+
{
260+
const symbolt &class_symbol =
261+
new_symbol_table.lookup_ref("java::ContainsLocalClass$1LocalClass");
262+
const java_class_typet java_class =
263+
to_java_class_type(class_symbol.type);
264+
REQUIRE(java_class.get_is_inner_class());
265+
REQUIRE(java_class.get_access() == ID_private);
266+
}
267+
}
268+
}
269+
}

0 commit comments

Comments
 (0)