Skip to content

Commit f90f7c4

Browse files
Add annotations to java_class_typet, its methods and fields
Add the annotations parsed from the byte code to classes/fields/methods and static fields (globals) in the symbol table
1 parent 08ad919 commit f90f7c4

File tree

5 files changed

+134
-1
lines changed

5 files changed

+134
-1
lines changed

src/java_bytecode/java_bytecode_convert_class.cpp

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ class java_bytecode_convert_classt:public messaget
6868

6969
typedef java_bytecode_parse_treet::classt classt;
7070
typedef java_bytecode_parse_treet::fieldt fieldt;
71+
typedef java_bytecode_parse_treet::annotationt annotationt;
7172

7273
protected:
7374
symbol_tablet &symbol_table;
@@ -306,6 +307,10 @@ void java_bytecode_convert_classt::convert(const classt &c)
306307
}
307308
}
308309

310+
// Load annotations
311+
if(!c.annotations.empty())
312+
convert_annotations(c.annotations, class_type.get_annotations());
313+
309314
// produce class symbol
310315
symbolt new_symbol;
311316
new_symbol.base_name=c.name;
@@ -441,6 +446,14 @@ void java_bytecode_convert_classt::convert(
441446
ns,
442447
get_message_handler());
443448

449+
// Load annotations
450+
if(!f.annotations.empty())
451+
{
452+
convert_annotations(
453+
f.annotations,
454+
static_cast<annotated_typet &>(new_symbol.type).get_annotations());
455+
}
456+
444457
// Do we have the static field symbol already?
445458
const auto s_it=symbol_table.symbols.find(new_symbol.name);
446459
if(s_it!=symbol_table.symbols.end())
@@ -453,7 +466,7 @@ void java_bytecode_convert_classt::convert(
453466
{
454467
class_typet &class_type=to_class_type(class_symbol.type);
455468

456-
class_type.components().push_back(class_typet::componentt());
469+
class_type.components().emplace_back();
457470
class_typet::componentt &component=class_type.components().back();
458471

459472
component.set_name(f.name);
@@ -469,6 +482,14 @@ void java_bytecode_convert_classt::convert(
469482
component.set_access(ID_public);
470483
else
471484
component.set_access(ID_default);
485+
486+
// Load annotations
487+
if(!f.annotations.empty())
488+
{
489+
convert_annotations(
490+
f.annotations,
491+
static_cast<annotated_typet &>(component.type()).get_annotations());
492+
}
472493
}
473494
}
474495

@@ -774,6 +795,29 @@ static void find_and_replace_parameters(
774795
}
775796
}
776797

798+
/// Convert parsed annotations into the symbol table
799+
/// \param parsed_annotations: The parsed annotations to convert
800+
/// \param annotations: The java_annotationt collection to populate
801+
void convert_annotations(
802+
const java_bytecode_parse_treet::annotationst &parsed_annotations,
803+
std::vector<java_annotationt> &annotations)
804+
{
805+
for(const auto &annotation : parsed_annotations)
806+
{
807+
annotations.emplace_back(annotation.type);
808+
std::vector<java_annotationt::valuet> &values =
809+
annotations.back().get_values();
810+
std::transform(
811+
annotation.element_value_pairs.begin(),
812+
annotation.element_value_pairs.end(),
813+
std::back_inserter(values),
814+
[](const decltype(annotation.element_value_pairs)::value_type &value)
815+
{
816+
return java_annotationt::valuet(value.element_name, value.value);
817+
});
818+
}
819+
}
820+
777821
/// Checks if the class is implicitly generic, i.e., it is an inner class of
778822
/// any generic class. All uses of the implicit generic type parameters within
779823
/// the inner class are updated to point to the type parameters of the

src/java_bytecode/java_bytecode_convert_class.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ bool java_bytecode_convert_class(
2727
method_bytecodet &,
2828
java_string_library_preprocesst &string_preprocess);
2929

30+
void convert_annotations(
31+
const java_bytecode_parse_treet::annotationst &parsed_annotations,
32+
std::vector<java_annotationt> &annotations);
33+
3034
void mark_java_implicitly_generic_class_type(
3135
const irep_idt &class_name,
3236
symbol_tablet &symbol_table);

src/java_bytecode/java_bytecode_convert_method.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,15 @@ void java_bytecode_convert_method_lazy(
366366
parameters.insert(parameters.begin(), this_p);
367367
}
368368

369+
// Load annotations
370+
if(!m.annotations.empty())
371+
{
372+
convert_annotations(
373+
m.annotations,
374+
static_cast<annotated_typet &>(static_cast<typet &>(member_type))
375+
.get_annotations());
376+
}
377+
369378
method_symbol.type=member_type;
370379
symbol_table.add(method_symbol);
371380
}

src/java_bytecode/java_types.h

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,69 @@ Author: Daniel Kroening, kroening@kroening.com
1818
#include <util/c_types.h>
1919
#include <util/optional.h>
2020

21+
class java_annotationt : public irept
22+
{
23+
public:
24+
class valuet : public irept
25+
{
26+
public:
27+
valuet(irep_idt name, const exprt &value) : irept(name)
28+
{
29+
get_sub().push_back(value);
30+
}
31+
32+
const irep_idt &get_name() const
33+
{
34+
return id();
35+
}
36+
37+
const exprt &get_value() const
38+
{
39+
return static_cast<const exprt &>(get_sub().front());
40+
}
41+
};
42+
43+
explicit java_annotationt(const typet &type)
44+
{
45+
set(ID_type, type);
46+
}
47+
48+
const typet &get_type() const
49+
{
50+
return static_cast<const typet &>(find(ID_type));
51+
}
52+
53+
const std::vector<valuet> &get_values() const
54+
{
55+
// This cast should be safe as valuet doesn't add data to irept
56+
return reinterpret_cast<const std::vector<valuet> &>(get_sub());
57+
}
58+
59+
std::vector<valuet> &get_values()
60+
{
61+
// This cast should be safe as valuet doesn't add data to irept
62+
return reinterpret_cast<std::vector<valuet> &>(get_sub());
63+
}
64+
};
65+
66+
class annotated_typet : public typet
67+
{
68+
public:
69+
const std::vector<java_annotationt> &get_annotations() const
70+
{
71+
// This cast should be safe as java_annotationt doesn't add data to irept
72+
return reinterpret_cast<const std::vector<java_annotationt> &>(
73+
find(ID_annotations).get_sub());
74+
}
75+
76+
std::vector<java_annotationt> &get_annotations()
77+
{
78+
// This cast should be safe as java_annotationt doesn't add data to irept
79+
return reinterpret_cast<std::vector<java_annotationt> &>(
80+
add(ID_annotations).get_sub());
81+
}
82+
};
83+
2184
class java_class_typet:public class_typet
2285
{
2386
public:
@@ -30,6 +93,18 @@ class java_class_typet:public class_typet
3093
{
3194
return set(ID_access, access);
3295
}
96+
97+
const std::vector<java_annotationt> &get_annotations() const
98+
{
99+
return static_cast<const annotated_typet &>(
100+
static_cast<const typet &>(*this)).get_annotations();
101+
}
102+
103+
std::vector<java_annotationt> &get_annotations()
104+
{
105+
return static_cast<annotated_typet &>(
106+
static_cast<typet &>(*this)).get_annotations();
107+
}
33108
};
34109

35110
inline const java_class_typet &to_java_class_type(const typet &type)

src/util/irep_ids.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,7 @@ IREP_ID_TWO(type_variables, #type_variables)
839839
IREP_ID_ONE(havoc_object)
840840
IREP_ID_TWO(overflow_shl, overflow-shl)
841841
IREP_ID_TWO(C_no_initialization_required, #no_initialization_required)
842+
IREP_ID_ONE(annotations)
842843

843844
#undef IREP_ID_ONE
844845
#undef IREP_ID_TWO

0 commit comments

Comments
 (0)