Skip to content

Commit 34a3d85

Browse files
Merge pull request #2247 from antlechner/antonia/annotation-conversion
Additional functions for processing Java annotations
2 parents 70da606 + 3a7135a commit 34a3d85

16 files changed

+157
-24
lines changed

jbmc/src/java_bytecode/java_bytecode_convert_class.cpp

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -875,8 +875,9 @@ void java_bytecode_convert_classt::add_array_types(symbol_tablet &symbol_table)
875875

876876
bool java_bytecode_convert_classt::is_overlay_method(const methodt &method)
877877
{
878-
return java_bytecode_parse_treet::does_annotation_exist(
879-
method.annotations, ID_overlay_method);
878+
return java_bytecode_parse_treet::find_annotation(
879+
method.annotations, ID_overlay_method)
880+
.has_value();
880881
}
881882

882883
bool java_bytecode_convert_class(
@@ -1015,24 +1016,48 @@ static void find_and_replace_parameters(
10151016
/// \param annotations: The java_annotationt collection to populate
10161017
void convert_annotations(
10171018
const java_bytecode_parse_treet::annotationst &parsed_annotations,
1018-
std::vector<java_annotationt> &annotations)
1019+
std::vector<java_annotationt> &java_annotations)
10191020
{
10201021
for(const auto &annotation : parsed_annotations)
10211022
{
1022-
annotations.emplace_back(annotation.type);
1023+
java_annotations.emplace_back(annotation.type);
10231024
std::vector<java_annotationt::valuet> &values =
1024-
annotations.back().get_values();
1025+
java_annotations.back().get_values();
10251026
std::transform(
10261027
annotation.element_value_pairs.begin(),
10271028
annotation.element_value_pairs.end(),
10281029
std::back_inserter(values),
1029-
[](const decltype(annotation.element_value_pairs)::value_type &value)
1030-
{
1030+
[](const decltype(annotation.element_value_pairs)::value_type &value) {
10311031
return java_annotationt::valuet(value.element_name, value.value);
10321032
});
10331033
}
10341034
}
10351035

1036+
/// Convert java annotations, e.g. as retrieved from the symbol table, back
1037+
/// to type annotationt (inverse of convert_annotations())
1038+
/// \param java_annotations: The java_annotationt collection to convert
1039+
/// \param annotations: The annotationt collection to populate
1040+
void convert_java_annotations(
1041+
const std::vector<java_annotationt> &java_annotations,
1042+
java_bytecode_parse_treet::annotationst &annotations)
1043+
{
1044+
for(const auto &java_annotation : java_annotations)
1045+
{
1046+
annotations.emplace_back(java_bytecode_parse_treet::annotationt());
1047+
auto &annotation = annotations.back();
1048+
annotation.type = java_annotation.get_type();
1049+
1050+
std::transform(
1051+
java_annotation.get_values().begin(),
1052+
java_annotation.get_values().end(),
1053+
std::back_inserter(annotation.element_value_pairs),
1054+
[](const java_annotationt::valuet &value)
1055+
-> java_bytecode_parse_treet::annotationt::element_value_pairt {
1056+
return {value.get_name(), value.get_value()};
1057+
});
1058+
}
1059+
}
1060+
10361061
/// Checks if the class is implicitly generic, i.e., it is an inner class of
10371062
/// any generic class. All uses of the implicit generic type parameters within
10381063
/// the inner class are updated to point to the type parameters of the

jbmc/src/java_bytecode/java_bytecode_convert_class.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ void convert_annotations(
3333
const java_bytecode_parse_treet::annotationst &parsed_annotations,
3434
std::vector<java_annotationt> &annotations);
3535

36+
void convert_java_annotations(
37+
const std::vector<java_annotationt> &java_annotations,
38+
java_bytecode_parse_treet::annotationst &annotations);
39+
3640
void mark_java_implicitly_generic_class_type(
3741
const irep_idt &class_name,
3842
symbol_tablet &symbol_table);

jbmc/src/java_bytecode/java_bytecode_parse_tree.cpp

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -99,23 +99,30 @@ void java_bytecode_parse_treet::annotationt::element_value_pairt::output(
9999
out << expr2java(value, ns);
100100
}
101101

102-
bool java_bytecode_parse_treet::does_annotation_exist(
102+
/// Find an annotation given its name
103+
/// \param annotations: A vector of annotationt
104+
/// \param annotation_type_name: An irep_idt representing the name of the
105+
/// annotation class, e.g. java::java.lang.SuppressWarnings
106+
/// \return The first annotation with the given name in annotations if one
107+
/// exists, an empty optionalt otherwise.
108+
optionalt<java_bytecode_parse_treet::annotationt>
109+
java_bytecode_parse_treet::find_annotation(
103110
const annotationst &annotations,
104111
const irep_idt &annotation_type_name)
105112
{
106-
return
107-
std::find_if(
108-
annotations.begin(),
109-
annotations.end(),
110-
[&annotation_type_name](const annotationt &annotation)
111-
{
112-
if(annotation.type.id() != ID_pointer)
113-
return false;
114-
typet type = annotation.type.subtype();
115-
return
116-
type.id() == ID_symbol
117-
&& to_symbol_type(type).get_identifier() == annotation_type_name;
118-
}) != annotations.end();
113+
const auto annotation_it = std::find_if(
114+
annotations.begin(),
115+
annotations.end(),
116+
[&annotation_type_name](const annotationt &annotation) {
117+
if(annotation.type.id() != ID_pointer)
118+
return false;
119+
const typet &type = annotation.type.subtype();
120+
return type.id() == ID_symbol &&
121+
to_symbol_type(type).get_identifier() == annotation_type_name;
122+
});
123+
if(annotation_it == annotations.end())
124+
return {};
125+
return *annotation_it;
119126
}
120127

121128
void java_bytecode_parse_treet::methodt::output(std::ostream &out) const

jbmc/src/java_bytecode/java_bytecode_parse_tree.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class java_bytecode_parse_treet
5454

5555
typedef std::vector<annotationt> annotationst;
5656

57-
static bool does_annotation_exist(
57+
static optionalt<annotationt> find_annotation(
5858
const annotationst &annotations,
5959
const irep_idt &annotation_type_name);
6060

jbmc/src/java_bytecode/java_class_loader.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,9 @@ optionalt<java_bytecode_parse_treet> java_class_loadert::get_class_from_jar(
103103

104104
static bool is_overlay_class(const java_bytecode_parse_treet::classt &c)
105105
{
106-
return java_bytecode_parse_treet::does_annotation_exist(
107-
c.annotations, ID_overlay_class);
106+
return java_bytecode_parse_treet::find_annotation(
107+
c.annotations, ID_overlay_class)
108+
.has_value();
108109
}
109110

110111
/// Check through all the places class parse trees can appear and returns the

jbmc/unit/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ SRC += java_bytecode/goto-programs/class_hierarchy_output.cpp \
99
java_bytecode/goto-programs/class_hierarchy_graph.cpp \
1010
java_bytecode/goto-programs/remove_virtual_functions_without_fallback.cpp \
1111
java_bytecode/java_bytecode_convert_class/convert_abstract_class.cpp \
12+
java_bytecode/java_bytecode_convert_class/convert_java_annotations.cpp \
1213
java_bytecode/java_bytecode_convert_method/convert_invoke_dynamic.cpp \
1314
java_bytecode/java_bytecode_parse_generics/parse_generic_class.cpp \
1415
java_bytecode/java_object_factory/gen_nondet_string_init.cpp \
Binary file not shown.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@MyClassAnnotation(6)
2+
public class ClassWithClassAnnotation {
3+
}
Binary file not shown.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
public class ClassWithMethodAnnotation {
2+
3+
@MyMethodAnnotation(methodValue = 11)
4+
public void myMethod() {
5+
}
6+
7+
}

0 commit comments

Comments
 (0)