Skip to content

Commit d20a12e

Browse files
author
Matthias Güdemann
authored
Merge pull request diffblue#2517 from jeannielynnmoulton/jeannie/InnerStaticClasses
Captures static inner class information
2 parents 6409eae + fe73955 commit d20a12e

14 files changed

+136
-0
lines changed

jbmc/src/java_bytecode/java_bytecode_convert_class.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ void java_bytecode_convert_classt::convert(
277277
class_type.set(ID_synthetic, c.is_synthetic);
278278
class_type.set_final(c.is_final);
279279
class_type.set_is_inner_class(c.is_inner_class);
280+
class_type.set_is_static_class(c.is_static_class);
280281
if(c.is_enum)
281282
{
282283
if(max_array_length != 0 && c.enum_elements > max_array_length)

jbmc/src/java_bytecode/java_bytecode_parse_tree.h

+1
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ class java_bytecode_parse_treet
218218
bool is_synthetic = false;
219219
bool is_annotation = false;
220220
bool is_inner_class = false;
221+
bool is_static_class = false;
221222
bool attribute_bootstrapmethods_read = false;
222223
size_t enum_elements=0;
223224

jbmc/src/java_bytecode/java_bytecode_parser.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -1622,6 +1622,7 @@ void java_bytecode_parsert::rinner_classes_attribute(
16221622
bool is_private = (inner_class_access_flags & ACC_PRIVATE) != 0;
16231623
bool is_public = (inner_class_access_flags & ACC_PUBLIC) != 0;
16241624
bool is_protected = (inner_class_access_flags & ACC_PROTECTED) != 0;
1625+
bool is_static = (inner_class_access_flags & ACC_STATIC) != 0;
16251626

16261627
// If the original parsed class name matches the inner class name,
16271628
// the parsed class is an inner class, so overwrite the parsed class'
@@ -1632,6 +1633,7 @@ void java_bytecode_parsert::rinner_classes_attribute(
16321633
parsed_class.is_inner_class = is_inner_class;
16331634
if(!is_inner_class)
16341635
continue;
1636+
parsed_class.is_static_class = is_static;
16351637
// Note that if outer_class_info_index == 0, the inner class is an anonymous
16361638
// or local class, and is treated as private.
16371639
if(outer_class_info_index == 0)

jbmc/src/java_bytecode/java_types.h

+11
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,17 @@ class java_class_typet:public class_typet
121121
return set(ID_is_inner_class, is_inner_class);
122122
}
123123

124+
const bool get_is_static_class() const
125+
{
126+
return get_bool(ID_is_static);
127+
}
128+
129+
void set_is_static_class(const bool &is_static_class)
130+
{
131+
return set(ID_is_static, is_static_class);
132+
}
133+
134+
124135
bool get_final()
125136
{
126137
return get_bool(ID_final);
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,33 @@
1+
public class StaticInnerClass {
2+
public static interface SomeInterface {
3+
public int i = 0;
4+
}
5+
public static class PublicStaticInnerClass {
6+
public int i;
7+
public PublicStaticInnerClass(int i) {
8+
this.i = i;
9+
}
10+
}
11+
public class PublicNonStaticInnerClass {
12+
public int i;
13+
public PublicNonStaticInnerClass(int i) {
14+
this.i = i;
15+
}
16+
}
17+
public static SomeInterface staticAnonymousClass = new SomeInterface() {
18+
public int i = 50;
19+
};
20+
public SomeInterface anonymousClass = new SomeInterface() {
21+
public int i = 25;
22+
};
23+
public void testNonStatic() {
24+
class LocalClassInNonStatic {
25+
public int i = 1;
26+
}
27+
}
28+
public static void testStatic() {
29+
class LocalClassInStatic {
30+
public int i = 2;
31+
}
32+
}
33+
}

jbmc/unit/java_bytecode/java_bytecode_parser/parse_java_attributes.cpp

+88
Original file line numberDiff line numberDiff line change
@@ -266,4 +266,92 @@ SCENARIO(
266266
}
267267
}
268268
}
269+
270+
const symbol_tablet &new_symbol_table =
271+
load_java_class("StaticInnerClass", "./java_bytecode/java_bytecode_parser");
272+
GIVEN("Some class with a static inner class")
273+
{
274+
WHEN("Parsing the InnerClasses attribute for a static inner class ")
275+
{
276+
THEN("The class should be marked as static")
277+
{
278+
const symbolt &class_symbol = new_symbol_table.lookup_ref(
279+
"java::StaticInnerClass$PublicStaticInnerClass");
280+
const java_class_typet java_class =
281+
to_java_class_type(class_symbol.type);
282+
REQUIRE(java_class.get_is_inner_class());
283+
REQUIRE(java_class.get_is_static_class());
284+
}
285+
}
286+
WHEN("Parsing the InnerClasses attribute for a non-static inner class ")
287+
{
288+
THEN("The class should not be marked as static")
289+
{
290+
const symbolt &class_symbol = new_symbol_table.lookup_ref(
291+
"java::StaticInnerClass$PublicNonStaticInnerClass");
292+
const java_class_typet java_class =
293+
to_java_class_type(class_symbol.type);
294+
REQUIRE(java_class.get_is_inner_class());
295+
REQUIRE_FALSE(java_class.get_is_static_class());
296+
}
297+
}
298+
}
299+
GIVEN("Some class with a static anonymous class")
300+
{
301+
WHEN("Parsing the InnerClasses attribute for a static anonymous class ")
302+
{
303+
THEN("The class should be marked as static")
304+
{
305+
const symbolt &class_symbol =
306+
new_symbol_table.lookup_ref("java::StaticInnerClass$1");
307+
const java_class_typet java_class =
308+
to_java_class_type(class_symbol.type);
309+
REQUIRE(java_class.get_is_inner_class());
310+
REQUIRE(java_class.get_is_static_class());
311+
}
312+
}
313+
WHEN("Parsing the InnerClasses attribute for a non-static anonymous class ")
314+
{
315+
THEN("The class should not be marked as static")
316+
{
317+
const symbolt &class_symbol =
318+
new_symbol_table.lookup_ref("java::StaticInnerClass$2");
319+
const java_class_typet java_class =
320+
to_java_class_type(class_symbol.type);
321+
REQUIRE(java_class.get_is_inner_class());
322+
REQUIRE_FALSE(java_class.get_is_static_class());
323+
}
324+
}
325+
}
326+
GIVEN("Some method containing a local class")
327+
{
328+
WHEN(
329+
"Parsing the InnerClasses attribute for a local class in a static "
330+
"method ")
331+
{
332+
THEN("The local class should be marked as static")
333+
{
334+
const symbolt &class_symbol = new_symbol_table.lookup_ref(
335+
"java::StaticInnerClass$1LocalClassInStatic");
336+
const java_class_typet java_class =
337+
to_java_class_type(class_symbol.type);
338+
REQUIRE(java_class.get_is_inner_class());
339+
REQUIRE_FALSE(java_class.get_is_static_class());
340+
}
341+
}
342+
WHEN(
343+
"Parsing the InnerClasses attribute for a local class in a non-static "
344+
"method ")
345+
{
346+
THEN("The local class should not be marked as static")
347+
{
348+
const symbolt &class_symbol = new_symbol_table.lookup_ref(
349+
"java::StaticInnerClass$1LocalClassInNonStatic");
350+
const java_class_typet java_class =
351+
to_java_class_type(class_symbol.type);
352+
REQUIRE(java_class.get_is_inner_class());
353+
REQUIRE_FALSE(java_class.get_is_static_class());
354+
}
355+
}
356+
}
269357
}

0 commit comments

Comments
 (0)