|
11 | 11 | #include <java_bytecode/java_bytecode_parse_tree.h>
|
12 | 12 | #include <java_bytecode/java_types.h>
|
13 | 13 | #include <testing-utils/catch.hpp>
|
| 14 | +#include <testing-utils/free_form_cmdline.h> |
| 15 | +#include <testing-utils/message.h> |
| 16 | + |
| 17 | +class test_java_bytecode_languaget : public java_bytecode_languaget |
| 18 | +{ |
| 19 | +public: |
| 20 | + std::vector<irep_idt> get_parsed_class_names() |
| 21 | + { |
| 22 | + std::vector<irep_idt> parsed_class_names; |
| 23 | + for(const auto &named_class |
| 24 | + : java_class_loader.get_class_with_overlays_map()) |
| 25 | + { |
| 26 | + parsed_class_names.push_back(named_class.first); |
| 27 | + } |
| 28 | + return parsed_class_names; |
| 29 | + } |
| 30 | + |
| 31 | + java_class_loadert::parse_tree_with_overlayst &get_parse_trees_for_class( |
| 32 | + const irep_idt &class_name) |
| 33 | + { |
| 34 | + //return java_class_loader(class_name); |
| 35 | + return java_class_loader.get_class_with_overlays_map().at(class_name); |
| 36 | + } |
| 37 | +}; |
14 | 38 |
|
15 | 39 | // See
|
16 | 40 | // https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.16.1
|
@@ -91,5 +115,91 @@ SCENARIO(
|
91 | 115 | REQUIRE(java_type == void_type());
|
92 | 116 | }
|
93 | 117 | }
|
| 118 | + WHEN("Parsing a class with annotations everywhere") |
| 119 | + { |
| 120 | + free_form_cmdlinet command_line; |
| 121 | + command_line.add_flag("no-lazy-methods"); |
| 122 | + command_line.add_flag("no-refine-strings"); |
| 123 | + test_java_bytecode_languaget language; |
| 124 | + language.set_message_handler(null_message_handler); |
| 125 | + language.get_language_options(command_line); |
| 126 | + |
| 127 | + std::istringstream java_code_stream("ignored"); |
| 128 | + language.parse(java_code_stream, "AnnotationsEverywhere.class"); |
| 129 | + const java_class_loadert::parse_tree_with_overlayst &parse_trees = |
| 130 | + language.get_parse_trees_for_class("AnnotationsEverywhere"); |
| 131 | + REQUIRE(parse_trees.size() == 1); |
| 132 | + const java_bytecode_parse_treet::classt &parsed_class = |
| 133 | + parse_trees.front().parsed_class; |
| 134 | + auto method_it = std::find_if( |
| 135 | + parsed_class.methods.begin(), |
| 136 | + parsed_class.methods.end(), |
| 137 | + [] (const java_bytecode_parse_treet::methodt &method) |
| 138 | + { |
| 139 | + return method.name == "foo"; |
| 140 | + }); |
| 141 | + REQUIRE(method_it != parsed_class.methods.end()); |
| 142 | + const java_bytecode_parse_treet::methodt &method = *method_it; |
| 143 | + |
| 144 | + THEN("Only the correct annotation should be on the class") |
| 145 | + { |
| 146 | + const java_bytecode_parse_treet::annotationst &annotations = |
| 147 | + parsed_class.annotations; |
| 148 | + REQUIRE(annotations.size() == 1); |
| 149 | + const java_bytecode_parse_treet::annotationt &annotation = |
| 150 | + annotations.front(); |
| 151 | + INVARIANT( |
| 152 | + annotation.type.id() == ID_pointer, |
| 153 | + "Annotation type should be pointer."); |
| 154 | + REQUIRE( |
| 155 | + annotation.type.subtype().get(ID_C_base_name) == "ClassAnnotation"); |
| 156 | + } |
| 157 | + |
| 158 | + THEN("Only the correct annotation should be on the field") |
| 159 | + { |
| 160 | + REQUIRE(parsed_class.fields.size() == 1); |
| 161 | + const java_bytecode_parse_treet::fieldt &field = parsed_class.fields.front(); |
| 162 | + const java_bytecode_parse_treet::annotationst &annotations = |
| 163 | + field.annotations; |
| 164 | + REQUIRE(annotations.size() == 1); |
| 165 | + const java_bytecode_parse_treet::annotationt &annotation = |
| 166 | + annotations.front(); |
| 167 | + INVARIANT( |
| 168 | + annotation.type.id() == ID_pointer, |
| 169 | + "Annotation type should be pointer."); |
| 170 | + REQUIRE( |
| 171 | + annotation.type.subtype().get(ID_C_base_name) == "FieldAnnotation"); |
| 172 | + } |
| 173 | + |
| 174 | + THEN("Only the correct annotation should be on the method") |
| 175 | + { |
| 176 | + const java_bytecode_parse_treet::annotationst &annotations = |
| 177 | + method.annotations; |
| 178 | + REQUIRE(annotations.size() == 1); |
| 179 | + const java_bytecode_parse_treet::annotationt &annotation = |
| 180 | + annotations.front(); |
| 181 | + INVARIANT( |
| 182 | + annotation.type.id() == ID_pointer, |
| 183 | + "Annotation type should be pointer."); |
| 184 | + REQUIRE( |
| 185 | + annotation.type.subtype().get(ID_C_base_name) == "MethodAnnotation"); |
| 186 | + } |
| 187 | + |
| 188 | + THEN("Only the correct annotation should be on the parameter") |
| 189 | + { |
| 190 | + REQUIRE(method.parameter_annotations.size() == 1); |
| 191 | + const java_bytecode_parse_treet::annotationst &annotations = |
| 192 | + method.parameter_annotations.front(); |
| 193 | + REQUIRE(annotations.size() == 1); |
| 194 | + const java_bytecode_parse_treet::annotationt &annotation = |
| 195 | + annotations.front(); |
| 196 | + INVARIANT( |
| 197 | + annotation.type.id() == ID_pointer, |
| 198 | + "Annotation type should be pointer."); |
| 199 | + REQUIRE( |
| 200 | + annotation.type.subtype().get(ID_C_base_name) == |
| 201 | + "ParameterAnnotation"); |
| 202 | + } |
| 203 | + } |
94 | 204 | }
|
95 | 205 | }
|
0 commit comments