Skip to content

Commit 808a6ad

Browse files
thk123NlightNFotis
thk123
authored andcommitted
Created basic class for creating new java instantiations of classes
1 parent 691e9fb commit 808a6ad

File tree

4 files changed

+179
-0
lines changed

4 files changed

+179
-0
lines changed

src/java_bytecode/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ SRC = bytecode_info.cpp \
2525
java_string_library_preprocess.cpp \
2626
java_types.cpp \
2727
java_utils.cpp \
28+
generate_java_generic_type.cpp \
2829
mz_zip_archive.cpp \
2930
select_pointer_type.cpp \
3031
# Empty last line
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*******************************************************************\
2+
3+
Module: MODULE NAME
4+
5+
Author: DiffBlue Limited. All rights reserved.
6+
7+
\*******************************************************************/
8+
#include "generate_java_generic_type.h"
9+
#include <util/namespace.h>
10+
#include <java_bytecode/java_types.h>
11+
#include <java_bytecode/java_utils.h>
12+
13+
#include <iostream>
14+
#include <sstream>
15+
16+
generate_java_generic_typet::generate_java_generic_typet(
17+
symbol_tablet &symbol_table,
18+
message_handlert &message_handler):
19+
symbol_table(symbol_table),
20+
message_handler(message_handler)
21+
{}
22+
23+
symbolt generate_java_generic_typet::operator()(
24+
const java_type_with_generic_typet &existing_generic_type)
25+
{
26+
namespacet ns(symbol_table);
27+
28+
const typet &pointer_subtype=ns.follow(existing_generic_type.subtype());
29+
30+
INVARIANT(
31+
pointer_subtype.id()==ID_struct, "Only pointers to classes in java");
32+
33+
const java_class_typet &java_class=to_java_class_type(pointer_subtype);
34+
35+
java_class_typet replacement_type=java_class;
36+
replacement_type.components().clear();
37+
38+
const irep_idt new_tag=build_generic_tag(existing_generic_type, java_class);
39+
replacement_type.set_tag(new_tag);
40+
41+
for(const struct_union_typet::componentt &component_type :
42+
java_class.components())
43+
{
44+
if(!is_java_generic_type(component_type.type()))
45+
{
46+
replacement_type.components().push_back(component_type);
47+
continue;
48+
}
49+
50+
INVARIANT(
51+
existing_generic_type.type_parameters.size()==1,
52+
"Must have a type parameter");
53+
54+
struct_union_typet::componentt replacement_comp=component_type;
55+
replacement_comp.type()=existing_generic_type.type_parameters[0];
56+
57+
replacement_type.components().push_back(replacement_comp);
58+
59+
}
60+
INVARIANT(
61+
replacement_type.components().size()==java_class.components().size(),
62+
"All components in the original class should be in the new class");
63+
64+
generate_class_stub(new_tag, symbol_table, message_handler);
65+
INVARIANT(symbol_table.has_symbol("java::"+id2string(new_tag)), "New class not created");
66+
return symbol_table.lookup("java::"+id2string(new_tag));
67+
}
68+
69+
irep_idt generate_java_generic_typet::build_generic_tag(
70+
const java_type_with_generic_typet &existing_generic_type,
71+
const java_class_typet &original_class)
72+
{
73+
std::ostringstream new_tag_buffer;
74+
new_tag_buffer << original_class.get_tag();
75+
new_tag_buffer << "<";
76+
bool first=true;
77+
for(const typet &param : existing_generic_type.type_parameters)
78+
{
79+
if(!first)
80+
new_tag_buffer << ", ";
81+
first=false;
82+
83+
INVARIANT(
84+
is_java_inst_generic_type(param),
85+
"Only create full concretized generic types");
86+
new_tag_buffer << param.subtype().get(ID_identifier);
87+
}
88+
89+
new_tag_buffer << ">";
90+
91+
return new_tag_buffer.str();
92+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*******************************************************************\
2+
3+
Module: MODULE NAME
4+
5+
Author: DiffBlue Limited. All rights reserved.
6+
7+
\*******************************************************************/
8+
#ifndef GENERATE_JAVA_GENERIC_TYPE_H
9+
#define GENERATE_JAVA_GENERIC_TYPE_H
10+
11+
#include <util/message.h>
12+
#include <util/symbol_table.h>
13+
#include <util/std_types.h>
14+
#include <java_bytecode/java_types.h>
15+
16+
class generate_java_generic_typet
17+
{
18+
public:
19+
generate_java_generic_typet(
20+
symbol_tablet &symbol_table,
21+
message_handlert &message_handler);
22+
23+
symbolt operator()(
24+
const java_type_with_generic_typet &existing_generic_type);
25+
private:
26+
irep_idt build_generic_tag(
27+
const java_type_with_generic_typet &existing_generic_type,
28+
const java_class_typet &original_class);
29+
30+
symbol_tablet &symbol_table;
31+
32+
message_handlert &message_handler;
33+
34+
};
35+
36+
#endif // GENERATE_JAVA_GENERIC_TYPE_H
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*******************************************************************\
2+
3+
Module: Unit tests for generating new type with generic parameters
4+
substitued for concrete types
5+
6+
Author: DiffBlue Limited. All rights reserved.
7+
8+
\*******************************************************************/
9+
10+
#include <catch.hpp>
11+
12+
#include <util/symbol_table.h>
13+
14+
#include <java_bytecode/generate_java_generic_type.h>
15+
#include <java_bytecode/java_types.h>
16+
17+
SCENARIO(
18+
"generate_java_generic_type",
19+
"[CORE][java_bytecode][generate_java_generic_type")
20+
{
21+
GIVEN("A generic java type and a concrete substitution")
22+
{
23+
symbol_tablet symbol_table;
24+
25+
26+
null_message_handlert message_handler;
27+
generate_java_generic_typet type_generator(symbol_table, message_handler);
28+
29+
30+
const reference_typet &boxed_integer_type=to_reference_type(java_type_from_string("Ljava/lang/Integer;"));
31+
32+
java_type_with_generic_typet generic_type;
33+
generic_type.type_parameters.push_back(java_inst_generic_typet(boxed_integer_type));
34+
35+
struct_typet base_class;
36+
base_class.components().push_back(struct_union_typet::componentt("a", java_generic_typet("T")));
37+
base_class.set_tag("UserClass");
38+
39+
generic_type.subtype()=base_class;
40+
41+
const symbolt &new_symbol=type_generator(generic_type);
42+
REQUIRE(new_symbol.is_type);
43+
44+
45+
46+
REQUIRE(new_symbol.base_name=="UserClass<Integer>");
47+
REQUIRE(new_symbol.type.id()==ID_pointer);
48+
49+
}
50+
}

0 commit comments

Comments
 (0)