Skip to content

Commit 44153b7

Browse files
author
thk123
committed
Adding unit tests verifying initalizsers are correctly labelled
1 parent 80a439d commit 44153b7

8 files changed

+343
-0
lines changed
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
class ClassWithConstructors {
2+
public ClassWithConstructors() {
3+
4+
}
5+
6+
public ClassWithConstructors(int primitiveParam, Object referenceParam, OpaqueClass opaqueParam) {
7+
8+
}
9+
}
10+
11+
class ClassWithoutConstructors {
12+
13+
}
14+
15+
class ClassWithStaticConstructor {
16+
static int primitiveA = 4;
17+
static int primitiveB;
18+
static int primitiveC;
19+
static Object referenceA = new Object();
20+
static Object referenceB;
21+
static Object referenceC;
22+
23+
static {
24+
primitiveB = 5;
25+
referenceB = new Object();
26+
}
27+
28+
public ClassWithStaticConstructor() {
29+
30+
}
31+
32+
public ClassWithStaticConstructor(int primitiveParam, Object referenceParam, OpaqueClass opaqueParam) {
33+
34+
}
35+
}
36+
37+
class StaticClassUsingOpaqueStaticConstructor {
38+
static int primitiveA = OpaqueClass.primitiveA;
39+
static int primitiveB = OpaqueClass.primitiveB;
40+
static int primitiveC = OpaqueClass.primitiveC;
41+
static Object referenceA = OpaqueClass.referenceA;
42+
static Object referenceB = OpaqueClass.referenceB;
43+
static Object referenceC = OpaqueClass.referenceC;
44+
}
45+
46+
class ClassUsingOpaqueStaticConstructor {
47+
int primitiveA;
48+
int primitiveB;
49+
int primitiveC;
50+
Object referenceA;
51+
Object referenceB;
52+
Object referenceC;
53+
54+
public ClassUsingOpaqueStaticConstructor(){
55+
primitiveA = OpaqueClass.primitiveA;
56+
primitiveB = OpaqueClass.primitiveB;
57+
primitiveC = OpaqueClass.primitiveC;
58+
referenceA = OpaqueClass.referenceA;
59+
referenceB = OpaqueClass.referenceB;
60+
referenceC = OpaqueClass.referenceC;
61+
}
62+
}
63+
64+
class DummyClassLoadingOpaqueClass {
65+
DummyClassLoadingOpaqueClass() {
66+
OpaqueClass o = new OpaqueClass();
67+
int primitiveA = OpaqueClass.primitiveA;
68+
int primitiveB = OpaqueClass.primitiveB;
69+
int primitiveC = OpaqueClass.primitiveC;
70+
Object referenceA = OpaqueClass.referenceA;
71+
Object referenceB = OpaqueClass.referenceB;
72+
Object referenceC = OpaqueClass.referenceC;
73+
74+
}
75+
}
76+
77+
class OpaqueClass {
78+
static int primitiveA = 4;
79+
static int primitiveB;
80+
static int primitiveC;
81+
static Object referenceA = new Object();
82+
static Object referenceB;
83+
static Object referenceC;
84+
85+
static {
86+
primitiveB = 5;
87+
referenceB = new Object();
88+
}
89+
90+
public OpaqueClass() {
91+
// opaque constructor
92+
}
93+
}
Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
/*******************************************************************\
2+
3+
Module: Unit tests for converting abstract classes
4+
5+
Author: DiffBlue Limited. All rights reserved.
6+
7+
\*******************************************************************/
8+
9+
#include <testing-utils/catch.hpp>
10+
11+
#include <memory>
12+
13+
#include <util/config.h>
14+
#include <util/symbol_table.h>
15+
16+
#include <java_bytecode/java_bytecode_language.h>
17+
18+
#include <testing-utils/load_java_class.h>
19+
#include <testing-utils/require_type.h>
20+
21+
struct test_datat
22+
{
23+
symbol_tablet symbol_table;
24+
std::string constructor_descriptor;
25+
};
26+
27+
/// Verify that a given descriptor is marked as a constructor in the symbol
28+
/// table
29+
/// \param test_data The data to run the test on
30+
void require_is_constructor(const test_datat &test_data)
31+
{
32+
33+
const symbolt &constructor =
34+
test_data.symbol_table.lookup_ref(test_data.constructor_descriptor);
35+
THEN("The constructor should be marked as a constructor")
36+
{
37+
code_typet constructor_type = require_type::require_code(constructor.type);
38+
REQUIRE(constructor_type.get_is_constructor());
39+
}
40+
}
41+
42+
/// Verify that a given descriptor is not marked as a constructor in the symbol
43+
/// table
44+
/// \param test_data The data to run the test on
45+
void require_is_static_initalizer(const test_datat &test_data)
46+
{
47+
const symbolt &constructor =
48+
test_data.symbol_table.lookup_ref(test_data.constructor_descriptor);
49+
THEN("The constructor should be marked as a constructor")
50+
{
51+
code_typet constructor_type = require_type::require_code(constructor.type);
52+
REQUIRE_FALSE(constructor_type.get_is_constructor());
53+
}
54+
}
55+
56+
SCENARIO(
57+
"java_bytecode_convert_initalizers",
58+
"[core][java_bytecode][java_bytecode_convert_method]")
59+
{
60+
GIVEN("A class with some constructors")
61+
{
62+
const symbol_tablet symbol_table = load_java_class(
63+
"ClassWithConstructors", "./java_bytecode/java_bytecode_convert_method");
64+
std::string base_constructor_name = "java::ClassWithConstructors.<init>";
65+
WHEN("Looking at the parameterless constructor")
66+
{
67+
require_is_constructor([&]() {
68+
test_datat data;
69+
data.constructor_descriptor = base_constructor_name + ":()V";
70+
data.symbol_table = symbol_table;
71+
return data;
72+
}());
73+
}
74+
WHEN("Looking at the parametered constructor")
75+
{
76+
require_is_constructor([&]() {
77+
test_datat data;
78+
data.constructor_descriptor =
79+
base_constructor_name + ":(ILjava/lang/Object;LOpaqueClass;)V";
80+
data.symbol_table = symbol_table;
81+
return data;
82+
}());
83+
}
84+
}
85+
GIVEN("A class without any constructors")
86+
{
87+
const symbol_tablet symbol_table = load_java_class(
88+
"ClassWithoutConstructors",
89+
"./java_bytecode/java_bytecode_convert_method");
90+
std::string base_constructor_name = "java::ClassWithoutConstructors.<init>";
91+
WHEN("Looking at the default constructor")
92+
{
93+
require_is_constructor([&]() {
94+
test_datat data;
95+
data.constructor_descriptor = base_constructor_name + ":()V";
96+
data.symbol_table = symbol_table;
97+
return data;
98+
}());
99+
}
100+
}
101+
GIVEN("A class with both constructors and static initalisers")
102+
{
103+
const symbol_tablet symbol_table = load_java_class(
104+
"ClassWithStaticConstructor",
105+
"./java_bytecode/java_bytecode_convert_method");
106+
std::string base_class_name = "java::ClassWithStaticConstructor.";
107+
std::string base_constructor_name = base_class_name + "<init>";
108+
WHEN("Looking at the parameterless constructor")
109+
{
110+
require_is_constructor([&]() {
111+
test_datat data;
112+
data.constructor_descriptor = base_constructor_name + ":()V";
113+
data.symbol_table = symbol_table;
114+
return data;
115+
}());
116+
}
117+
WHEN("Looking at the parametered constructor")
118+
{
119+
require_is_constructor([&]() {
120+
test_datat data;
121+
data.constructor_descriptor =
122+
base_constructor_name + ":(ILjava/lang/Object;LOpaqueClass;)V";
123+
data.symbol_table = symbol_table;
124+
return data;
125+
}());
126+
}
127+
WHEN("Looking at the static initalizer")
128+
{
129+
THEN("The static init should not be marked as a constructor")
130+
{
131+
require_is_static_initalizer([&]() {
132+
test_datat data;
133+
data.constructor_descriptor = base_class_name + "<clinit>:()V";
134+
data.symbol_table = symbol_table;
135+
return data;
136+
}());
137+
}
138+
}
139+
}
140+
GIVEN("A class with a static initalizer calling an opaque static initalizer")
141+
{
142+
const symbol_tablet symbol_table = load_java_class(
143+
"StaticClassUsingOpaqueStaticConstructor",
144+
"./java_bytecode/java_bytecode_convert_method");
145+
146+
std::string base_class_name =
147+
"java::StaticClassUsingOpaqueStaticConstructor.";
148+
std::string base_constructor_name = base_class_name + "<init>";
149+
150+
WHEN("Looking at the default constructor")
151+
{
152+
require_is_constructor([&]() {
153+
test_datat data;
154+
data.constructor_descriptor = base_constructor_name + ":()V";
155+
data.symbol_table = symbol_table;
156+
return data;
157+
}());
158+
}
159+
WHEN("Looking at the static initalizer")
160+
{
161+
THEN("The static init should not be marked as a constructor")
162+
{
163+
require_is_static_initalizer([&]() {
164+
test_datat data;
165+
data.constructor_descriptor = base_class_name + "<clinit>:()V";
166+
data.symbol_table = symbol_table;
167+
return data;
168+
}());
169+
}
170+
}
171+
}
172+
GIVEN("A class with a constructor calling opaque static initalizer")
173+
{
174+
const symbol_tablet symbol_table = load_java_class(
175+
"ClassUsingOpaqueStaticConstructor",
176+
"./java_bytecode/java_bytecode_convert_method");
177+
178+
std::string base_class_name = "java::ClassUsingOpaqueStaticConstructor.";
179+
std::string base_constructor_name = base_class_name + "<init>";
180+
181+
WHEN("Looking at the parameterless constructor")
182+
{
183+
require_is_constructor([&]() {
184+
test_datat data;
185+
data.constructor_descriptor = base_constructor_name + ":()V";
186+
data.symbol_table = symbol_table;
187+
return data;
188+
}());
189+
}
190+
WHEN("Looking at the static initalizer for the opaque class")
191+
{
192+
THEN("The static init should not be marked as a constructor")
193+
{
194+
require_is_static_initalizer([&]() {
195+
test_datat data;
196+
data.constructor_descriptor = "java::OpaqueClass.<clinit>:()V";
197+
data.symbol_table = symbol_table;
198+
return data;
199+
}());
200+
}
201+
}
202+
}
203+
GIVEN("A class with a constructor calling opaque constructor")
204+
{
205+
const symbol_tablet symbol_table = load_java_class(
206+
"DummyClassLoadingOpaqueClass",
207+
"./java_bytecode/java_bytecode_convert_method");
208+
209+
std::string base_class_name = "java::DummyClassLoadingOpaqueClass.";
210+
std::string base_constructor_name = base_class_name + "<init>";
211+
212+
const symbolt &opaque_class_symbol =
213+
symbol_table.lookup_ref("java::OpaqueClass");
214+
REQUIRE(opaque_class_symbol.type.get_bool(ID_incomplete_class));
215+
216+
WHEN("Looking at the parameterless constructor")
217+
{
218+
require_is_constructor([&]() {
219+
test_datat data;
220+
data.constructor_descriptor = base_constructor_name + ":()V";
221+
data.symbol_table = symbol_table;
222+
return data;
223+
}());
224+
}
225+
WHEN("Looking at the static initalizer for the opaque class")
226+
{
227+
THEN("The static init should not be marked as a constructor")
228+
{
229+
require_is_static_initalizer([&]() {
230+
test_datat data;
231+
data.constructor_descriptor = "java::OpaqueClass.<clinit>:()V";
232+
data.symbol_table = symbol_table;
233+
return data;
234+
}());
235+
}
236+
}
237+
WHEN("Looking at the constructor for the opaque class")
238+
{
239+
THEN("The static init should not be marked as a constructor")
240+
{
241+
require_is_constructor([&]() {
242+
test_datat data;
243+
data.constructor_descriptor = "java::OpaqueClass.<init>:()V";
244+
data.symbol_table = symbol_table;
245+
return data;
246+
}());
247+
}
248+
}
249+
}
250+
}

0 commit comments

Comments
 (0)