Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / TAO / tests / IDLv4 / annotations / annotation_tests.cpp
blob35bcc728a83a4a4910c56ed07b6f5114a376a356
1 #include "Annotation_Test.h"
3 #include <ast_valuetype.h>
4 #include <ast_porttype.h>
5 #include <ast_eventtype.h>
6 #include <ast_component.h>
7 #include <ast_union_branch.h>
8 #include <ast_union_label.h>
9 #include <ast_expression.h>
10 #include <string>
12 namespace {
14 void assert_node_has_annotation (
15 Annotation_Test &t, const char *node_name, AST_Annotation_Decl *annotation)
17 AST_Decl *node = t.assert_node (node_name);
18 t.assert_annotation_appl_count (node, 1);
19 t.assert_annotation_appl (node, 0, annotation);
22 /**
23 * Common Test IDL for what the IDL4 grammer calls "attr_dcl"
25 const std::string common_attr_dcl_idl =
26 " @test_annotation_1\n"
27 " attribute short rw_attribute;\n"
28 " @test_annotation_1\n"
29 " readonly attribute short ro_attribute;\n";
31 void assert_common_attr_dcl_idl (
32 Annotation_Test &t, AST_Annotation_Decl *test_annotation_1)
34 assert_node_has_annotation (t, "rw_attribute", test_annotation_1);
35 assert_node_has_annotation (t, "ro_attribute", test_annotation_1);
38 /**
39 * Common Test IDL for what the IDL4 grammer calls "export"
41 const std::string common_export_idl =
42 // op_dcl
43 " @test_annotation_1\n"
44 " void operation();\n"
45 // attr_decl
46 + common_attr_dcl_idl +
47 // type_dcl
48 " @test_annotation_1\n"
49 " struct struct_in_export {\n"
50 " short value;\n"
51 " };\n"
52 // const_dcl
53 " @test_annotation_1\n"
54 " const short const_value = 3;\n"
55 // except_dcl
56 " @test_annotation_1\n"
57 " exception exception_in_export {\n"
58 " short value;\n"
59 " };\n"
60 // Use expection
61 " @test_annotation_1\n"
62 " void operation_with_exception() raises (exception_in_export);\n"
63 // type_id_dcl (Doesn't work)
64 // type_prefix_dcl (No grammar issues, but a type_prefix isn't something
65 // that's part of the AST, so I'm not sure how this would work).
66 // " @test_annotation_1\n"
67 // " typeprefix struct_in_export \"electric_plants\";\n"
68 // import_dcl (TAO_IDL has import as a keyword, but doesn't support it in the grammer)
69 // op_oneway_dcl
70 " @test_annotation_1\n"
71 " oneway void oneway_op();\n";
73 void assert_common_export_idl (
74 Annotation_Test &t, AST_Annotation_Decl *test_annotation_1)
76 assert_node_has_annotation (t, "operation", test_annotation_1);
77 assert_common_attr_dcl_idl (t, test_annotation_1);
78 assert_node_has_annotation (t, "struct_in_export", test_annotation_1);
79 assert_node_has_annotation (t, "const_value", test_annotation_1);
80 assert_node_has_annotation (t, "exception_in_export", test_annotation_1);
81 assert_node_has_annotation (t, "operation_with_exception", test_annotation_1);
82 assert_node_has_annotation (t, "oneway_op", test_annotation_1);
85 /**
86 * Common Test IDL for what the IDL4 grammer calls "value_element"
88 const std::string common_value_element_idl =
89 // export
90 common_export_idl +
92 // state_member
93 " @test_annotation_1\n"
94 " public short public_state_member;\n"
95 " @test_annotation_1\n"
96 " private short private_state_member;\n"
98 // init_dcl
99 " @test_annotation_1\n"
100 " factory factory_thing();\n";
102 void assert_common_value_element_idl (
103 Annotation_Test &t, AST_Annotation_Decl *test_annotation_1)
105 assert_common_export_idl (t, test_annotation_1);
106 assert_node_has_annotation (t, "public_state_member", test_annotation_1);
107 assert_node_has_annotation (t, "private_state_member", test_annotation_1);
108 assert_node_has_annotation (t, "factory_thing", test_annotation_1);
113 * Notes About These Tests
114 * =========================================================================
116 * - They are in the same IDL namespace, so they can conflict with each
117 * other.
119 * - You can't test for a syntax error really because tao_idl throws an
120 * exception for them. Even if the exception was caught, the AST might be
121 * in an invalid state afterwards.
123 * - Annotations local names internally start with @ so that they don't
124 * conflict with other non-annotation names. See below for examples.
126 * - Some of these tests intentionally cause errors.
129 void
130 annotation_tests ()
132 /* -------------------------------------------------------------------------
133 * Annotations Declarations
134 * -------------------------------------------------------------------------
135 * These tests assert that annotations can be declared.
138 AST_Annotation_Decl *test_annotation_1 = 0;
139 try {
140 Annotation_Test t ("Annotation Declaration with No Members");
141 test_annotation_1 = t.run (
142 "@annotation test_annotation_1 {\n"
143 "};\n"
144 ).assert_annotation_decl ("::@test_annotation_1");
145 t.assert_annotation_member_count (test_annotation_1, 0);
146 } catch (Failed const &) {}
148 try {
149 Annotation_Test t ("Annotation Declaration with Members");
150 AST_Annotation_Decl *test_annotation_2 = t.run (
151 "@annotation test_annotation_2 {\n"
152 " short short_value;\n"
153 " char char_value;\n"
154 " long long_value;\n"
155 " boolean boolean_value;\n"
156 "};\n"
157 ).assert_annotation_decl ("::@test_annotation_2");
158 t.assert_annotation_member_count (test_annotation_2, 4);
160 AST_Annotation_Member *short_value =
161 t.get_annotation_member (test_annotation_2, "short_value");
162 t.assert_annotation_member_type (short_value, AST_Expression::EV_short);
163 t.assert_annotation_member_no_value (short_value);
165 AST_Annotation_Member *char_value =
166 t.get_annotation_member (test_annotation_2, "char_value");
167 t.assert_annotation_member_type (char_value, AST_Expression::EV_char);
168 t.assert_annotation_member_no_value (char_value);
170 AST_Annotation_Member *long_value =
171 t.get_annotation_member (test_annotation_2, "long_value");
172 t.assert_annotation_member_type (long_value, AST_Expression::EV_long);
173 t.assert_annotation_member_no_value (long_value);
175 AST_Annotation_Member *boolean_value =
176 t.get_annotation_member (test_annotation_2, "boolean_value");
177 t.assert_annotation_member_type (boolean_value, AST_Expression::EV_bool);
178 t.assert_annotation_member_no_value (boolean_value);
179 } catch (Failed const &) {}
181 try {
182 Annotation_Test t ("Annotation Declaration with Defaulted Members");
183 AST_Annotation_Decl *test_annotation_3 = t.run (
184 "@annotation test_annotation_3 {\n"
185 " short short_value default 1;\n"
186 " char char_value default '&';\n"
187 " long long_value default -1;\n"
188 " boolean boolean_value default FALSE;\n"
189 "};\n"
190 ).assert_annotation_decl ("::@test_annotation_3");
191 t.assert_annotation_member_count (test_annotation_3, 4);
193 AST_Annotation_Member *short_value =
194 t.get_annotation_member (test_annotation_3, "short_value");
195 t.assert_annotation_member_type (short_value, AST_Expression::EV_short);
196 t.assert_annotation_member_value<short, ACE_CDR::Short> (short_value, 1);
198 AST_Annotation_Member *char_value =
199 t.get_annotation_member (test_annotation_3, "char_value");
200 t.assert_annotation_member_type (char_value, AST_Expression::EV_char);
201 t.assert_annotation_member_value<char, ACE_CDR::Char> (char_value, '&');
203 AST_Annotation_Member *long_value =
204 t.get_annotation_member (test_annotation_3, "long_value");
205 t.assert_annotation_member_type (long_value, AST_Expression::EV_long);
206 t.assert_annotation_member_value<int, ACE_CDR::Long> (long_value, -1);
208 AST_Annotation_Member *boolean_value =
209 t.get_annotation_member (test_annotation_3, "boolean_value");
210 t.assert_annotation_member_type (boolean_value, AST_Expression::EV_bool);
211 t.assert_annotation_member_value<bool, ACE_CDR::Boolean> (boolean_value, false);
212 } catch (Failed const &) {}
214 AST_Annotation_Decl *test_annotation_4 = 0;
215 try {
216 Annotation_Test t ("Annotation Declaration with Mixed Members");
217 test_annotation_4 = t.run (
218 "@annotation test_annotation_4 {\n"
219 " short x;\n"
220 " short y default 0;\n"
221 "};\n"
222 ).assert_annotation_decl ("::@test_annotation_4");
223 t.assert_annotation_member_count (test_annotation_4, 2);
225 AST_Annotation_Member *x =
226 t.get_annotation_member (test_annotation_4, "x");
227 t.assert_annotation_member_type (x, AST_Expression::EV_short);
228 t.assert_annotation_member_no_value (x);
230 AST_Annotation_Member *y =
231 t.get_annotation_member (test_annotation_4, "y");
232 t.assert_annotation_member_type (y, AST_Expression::EV_short);
233 t.assert_annotation_member_value<short, ACE_CDR::Short> (y, 0);
234 } catch (Failed const &) {}
236 AST_Annotation_Decl *test_annotation_in_module = 0;
237 try {
238 Annotation_Test t ("Annotation Declaration In Module");
239 test_annotation_in_module = t.run (
240 "module module_with_annotation_decl {\n"
241 " @annotation test_annotation {\n"
242 " };\n"
243 "};\n"
244 ).assert_annotation_decl (
245 "::module_with_annotation_decl::@test_annotation");
246 t.assert_annotation_member_count (test_annotation_in_module, 0);
247 } catch (Failed const &) {}
249 AST_Annotation_Decl *enum_annotation = 0;
250 AST_Expression *enum_annotation_a = 0;
251 AST_Expression *enum_annotation_b = 0;
252 AST_Expression *enum_annotation_c = 0;
253 try {
254 Annotation_Test t ("Annotation Declaration with Enum");
255 enum_annotation = t.run (
256 "@annotation enum_annotation {\n"
257 " enum Enum_t {\n"
258 " A,\n"
259 " B,\n"
260 " C\n"
261 " };\n"
262 " Enum_t value default A;\n"
263 "};\n"
264 ).assert_annotation_decl ("@enum_annotation");
265 t.assert_annotation_member_count (enum_annotation, 1);
266 t.set_scope (enum_annotation);
267 AST_Annotation_Member *value =
268 t.get_annotation_member (enum_annotation, "value");
270 AST_EnumVal *a = t.assert_node<AST_EnumVal> ("A");
271 enum_annotation_a = a->constant_value ();
273 AST_EnumVal *b = t.assert_node<AST_EnumVal> ("B");
274 enum_annotation_b = b->constant_value ();
276 AST_EnumVal *c = t.assert_node<AST_EnumVal> ("C");
277 enum_annotation_c = c->constant_value ();
279 t.assert_annotation_member_value (value, enum_annotation_a);
280 } catch (Failed const &) {}
282 AST_Annotation_Decl *string_annotation = 0;
283 try {
284 Annotation_Test t ("Annotation Declaration with String");
285 string_annotation = t.run (
286 "@annotation string_annotation {\n"
287 " string value default \"This is some text\";\n"
288 "};\n"
289 ).assert_annotation_decl ("@string_annotation");
290 t.assert_annotation_member_count (string_annotation, 1);
291 AST_Annotation_Member *value =
292 t.get_annotation_member (string_annotation, "value");
294 UTL_String test_string ("This is some text");
295 t.assert_annotation_member_value<UTL_String*, UTL_String*>
296 (value, &test_string);
297 } catch (Failed const &) {}
299 AST_Expression *constant_annotation_x = 0;
300 AST_Expression *constant_annotation_y = 0;
301 AST_Annotation_Decl *constant_annotation = 0;
302 try {
303 Annotation_Test t ("Annotation Declaration with Constant");
304 constant_annotation = t.run (
305 "@annotation constant_annotation {\n"
306 " const short X = 4;\n"
307 " const short Y = 5;\n"
308 " short value default X;\n"
309 "};\n"
310 ).assert_annotation_decl ("@constant_annotation");
311 t.assert_annotation_member_count (constant_annotation, 1);
312 t.set_scope (constant_annotation);
313 AST_Annotation_Member *value =
314 t.get_annotation_member (constant_annotation, "value");
316 constant_annotation_x = t.assert_node<AST_Constant> ("X")->constant_value ();
317 constant_annotation_y = t.assert_node<AST_Constant> ("Y")->constant_value ();
319 t.assert_annotation_member_value (value, constant_annotation_x);
320 } catch (Failed const &) {}
322 AST_Annotation_Decl *boolean_annotation = 0;
323 try {
324 Annotation_Test t ("Annotation Declaration with Single Boolean");
325 boolean_annotation = t.run (
326 "@annotation boolean_annotation {\n"
327 " boolean value default TRUE;\n"
328 "};\n"
329 ).assert_annotation_decl ("@boolean_annotation");
330 t.assert_annotation_member_count (boolean_annotation, 1);
331 AST_Annotation_Member *value =
332 t.get_annotation_member (boolean_annotation, "value");
333 t.assert_annotation_member_type (value, AST_Expression::EV_bool);
334 t.assert_annotation_member_value<bool, ACE_CDR::Boolean> (value, true);
335 } catch (Failed const &) {}
337 /* -------------------------------------------------------------------------
338 * Annotations Applications
339 * -------------------------------------------------------------------------
340 * These tests assert that annotations can be applied to various IDL
341 * constructs.
344 try {
345 Annotation_Test t ("Module Annotation Application");
346 AST_Decl *module1 = t.run (
347 "@test_annotation_1\n"
348 "module module1 {\n"
349 " struct struct_in_module1 {\n"
350 " short member;\n"
351 " };\n"
352 "};\n"
353 ).assert_node ("::module1");
354 t.assert_annotation_appl_count (module1, 1);
355 t.assert_annotation_appl (module1, 0, test_annotation_1);
356 } catch (Failed const &) {}
358 try {
359 Annotation_Test t ("Struct Annotation Application");
360 AST_Decl *struct1 = t.run (
361 "@test_annotation_1\n"
362 "struct struct1 {\n"
363 " short member;\n"
364 "};\n"
365 ).assert_node ("::struct1");
366 t.assert_annotation_appl_count (struct1, 1);
367 t.assert_annotation_appl (struct1, 0, test_annotation_1);
368 } catch (Failed const &) {}
370 try {
371 Annotation_Test t ("Typedef Annotation Application");
372 t.run (
373 "@enum_annotation\n"
374 "typedef short short_int;\n"
375 "@string_annotation\n"
376 "typedef short_int small_int;\n"
377 "@test_annotation_1\n"
378 "typedef small_int i16;\n"
379 "struct struct6 {\n"
380 " i16 member;\n"
381 "};\n"
384 // Assert short_int has enum_annotation
385 AST_Decl *short_int = t.assert_node ("short_int");
386 t.assert_annotation_appl_count (short_int, 1);
387 t.assert_annotation_appl (short_int, 0, enum_annotation);
389 // Get type of member
390 AST_Field *member= t.assert_node<AST_Field> ("struct6::member");
391 AST_Type* type = member->field_type ();
393 // Assert type has enum_annotation, string_annotation, and
394 // test_annotation_1.
395 t.assert_annotation_appl_count (type, 3);
396 t.assert_annotation_appl (type, 0, enum_annotation);
397 t.assert_annotation_appl (type, 1, string_annotation);
398 t.assert_annotation_appl (type, 2, test_annotation_1);
399 } catch (Failed const &) {}
401 try {
402 Annotation_Test t ("Sequence Type Parameter Annotation Application");
403 AST_Field *value = t.run (
404 "typedef sequence<@test_annotation_1 short, 5> test_seq_t;\n"
405 "struct struct7 {\n"
406 " test_seq_t value;\n"
407 "};\n"
408 ).assert_node<AST_Field> ("::struct7::value");
410 // Get Sequence
411 AST_Typedef *typedef_node = dynamic_cast<AST_Typedef *> (value->field_type ());
412 if (!typedef_node) t.failed ("Could not get AST_Typedef");
413 AST_Sequence *seq = dynamic_cast<AST_Sequence *> (typedef_node->base_type ());
414 if (!seq) t.failed ("Could get AST_Sequence");
416 // Verify Annotation on Base Type
417 AST_Annotation_Appls &annotations = seq->base_type_annotations ();
418 size_t count = annotations.size ();
419 if (count != 1)
421 ACE_ERROR ((LM_ERROR, ACE_TEXT ("Annotation Test Error: %C:\n")
422 ACE_TEXT ("expected one annotation on test_seq_t base type, ")
423 ACE_TEXT ("it has %d annotations!\n"),
424 t.name_.c_str (), count));
425 t.failed ();
427 AST_Annotation_Appl *annotation = annotations[0];
428 if (!annotation)
430 t.failed ("annotation for test_seq_t base type is null!");
432 if (annotation->annotation_decl () != test_annotation_1)
434 UTL_ScopedName *scopedname = annotation->name ();
435 const char *name = scopedname ?
436 scopedname-> get_string_copy () : "UNKNOWN";
437 ACE_ERROR ((LM_ERROR, ACE_TEXT ("Annotation Test Error: %C:\n")
438 ACE_TEXT ("expected annotation for test_seq_t base type to be ")
439 ACE_TEXT ("test_annotation_1, but it was %C\n"),
440 t.name_.c_str (), name));
441 if (scopedname)
443 delete [] name;
445 t.failed ();
447 } catch (Failed const &) {}
449 try {
450 Annotation_Test t ("Constant Declarations Annotation Application");
451 AST_Decl *test_const = t.run (
452 "@test_annotation_1\n"
453 "const short test_const = 5;\n"
454 ).assert_node ("test_const");
455 t.assert_annotation_appl_count (test_const, 1);
456 t.assert_annotation_appl (test_const, 0, test_annotation_1);
457 } catch (Failed const &) {}
459 try {
460 Annotation_Test t ("Multiple Annotation Applications");
461 AST_Decl *struct3 = t.run (
462 "@test_annotation_1\n"
463 "@test_annotation_1\n"
464 "struct struct3 {\n"
465 " short test_member_1;\n"
466 "};\n"
467 ).assert_node ("struct3");
468 t.assert_annotation_appl_count (struct3, 2);
469 t.assert_annotation_appl (struct3, 0, test_annotation_1);
470 t.assert_annotation_appl (struct3, 1, test_annotation_1);
471 } catch (Failed const &) {}
473 try {
474 Annotation_Test t ("Annotation Application with a Single Parameter");
475 AST_Decl *struct4 = t.run (
476 "@test_annotation_4 (100)\n"
477 "struct struct4 {\n"
478 " short test_member_1;\n"
479 "};\n"
480 ).assert_node ("struct4");
481 t.assert_annotation_appl_count (struct4, 1);
482 AST_Annotation_Appl *appl =
483 t.assert_annotation_appl (struct4, 0, test_annotation_4);
484 t.assert_annotation_member_count (appl, 2);
486 AST_Annotation_Member *x = t.get_annotation_member (appl, "x");
487 t.assert_annotation_member_value<short, ACE_CDR::Short> (x, 100);
489 AST_Annotation_Member *y = t.get_annotation_member (appl, "y");
490 t.assert_annotation_member_value<short, ACE_CDR::Short> (y, 0);
491 } catch (Failed const &) {}
493 try {
494 Annotation_Test t ("Annotation Application with Named Parameters");
495 AST_Decl *struct2 = t.run (
496 "@test_annotation_4 (x = 101, y = 102)\n"
497 "struct struct2 {\n"
498 " short test_member_1;\n"
499 "};\n"
500 ).assert_node ("struct2");
501 t.assert_annotation_appl_count (struct2, 1);
502 AST_Annotation_Appl *appl =
503 t.assert_annotation_appl (struct2, 0, test_annotation_4);
504 t.assert_annotation_member_count (appl, 2);
506 AST_Annotation_Member *x = t.get_annotation_member (appl, "x");
507 t.assert_annotation_member_value<short, ACE_CDR::Short> (x, 101);
509 AST_Annotation_Member *y = t.get_annotation_member (appl, "y");
510 t.assert_annotation_member_value<short, ACE_CDR::Short> (y, 102);
511 } catch (Failed const &) {}
513 try {
514 Annotation_Test t ("Annotation Applications with Scoped Names");
515 AST_Decl *struct5 = t.run (
516 "@module_with_annotation_decl::test_annotation\n"
517 "@::module_with_annotation_decl::test_annotation\n"
518 "struct struct5 {\n"
519 " short test_member_1;\n"
520 "};\n"
521 ).assert_node ("struct5");
522 t.assert_annotation_appl_count (struct5, 2);
523 t.assert_annotation_appl (struct5, 0, test_annotation_in_module);
524 t.assert_annotation_appl (struct5, 1, test_annotation_in_module);
525 } catch (Failed const &) {}
527 try {
528 Annotation_Test t ("Annotation Applications on/in Unions");
529 AST_Union *test_union = t.run (
530 /* Annotations on the union and the discriminator */
531 "@test_annotation_1\n"
532 "union test_union switch (@test_annotation_1 short) {\n"
533 "case 0:\n"
534 "case 1:\n"
535 /* Annotation on a Union Member */
536 " @test_annotation_1 short union_member_1;\n"
537 "default:\n"
538 " short union_member_2;\n"
539 "};\n"
540 ).assert_node<AST_Union> ("test_union");
542 // Annotation On Union
543 t.assert_annotation_appl_count (test_union, 1);
544 t.assert_annotation_appl (test_union, 0, test_annotation_1);
546 // Annotation On Discriminator
547 AST_Annotation_Appls &annotations = test_union->disc_annotations ();
548 size_t count = annotations.size ();
549 if (count != 1)
551 ACE_ERROR ((LM_ERROR, ACE_TEXT ("Annotation Test Error: %C:\n")
552 ACE_TEXT ("expected one annotation on test_union discriminator, ")
553 ACE_TEXT ("it has %d annotations!\n"),
554 t.name_.c_str (), count));
555 t.failed ();
557 AST_Annotation_Appl *annotation = annotations[0];
558 if (!annotation)
560 t.failed ("annotation for test_seq_t base type is null!");
562 if (annotation->annotation_decl () != test_annotation_1)
564 UTL_ScopedName *scopedname = annotation->name ();
565 const char *name = scopedname ?
566 scopedname-> get_string_copy () : "UNKNOWN";
567 ACE_ERROR ((LM_ERROR, ACE_TEXT ("Annotation Test Error: %C:\n")
568 ACE_TEXT ("expected annotation for test_union discriminator to be ")
569 ACE_TEXT ("test_annotation_1, but it was %C\n"),
570 t.name_.c_str (), name));
571 if (scopedname)
573 delete [] name;
575 t.failed ();
578 // Annotation on Union Member
579 AST_Decl *union_member_1 =
580 t.assert_node ("test_union::union_member_1");
581 t.assert_annotation_appl_count (union_member_1, 1);
582 t.assert_annotation_appl (union_member_1, 0, test_annotation_1);
583 } catch (Failed const &) {}
585 try {
586 Annotation_Test t ("Annotation Applications on/in Enums");
587 AST_Decl *Test_Enum = t.run (
588 /* Annotation on the enum */
589 "@test_annotation_1\n"
590 "enum Test_Enum {\n"
591 " TEST_ENUM_MEMBER_1,\n"
592 /* Annotation on a enumerator */
593 " @test_annotation_1 TEST_ENUM_MEMBER_2,\n"
594 " TEST_ENUM_MEMBER_3\n"
595 "};\n"
596 ).assert_node ("Test_Enum");
598 // Annotation on Enum
599 t.assert_annotation_appl_count (Test_Enum, 1);
600 t.assert_annotation_appl (Test_Enum, 0, test_annotation_1);
602 // Annotation on Enum Member
603 AST_Decl *TEST_ENUM_MEMBER_2 =
604 t.assert_node ("Test_Enum::TEST_ENUM_MEMBER_2");
605 t.assert_annotation_appl_count (TEST_ENUM_MEMBER_2, 1);
606 t.assert_annotation_appl (TEST_ENUM_MEMBER_2, 0, test_annotation_1);
607 } catch (Failed const &) {}
609 try {
610 Annotation_Test t ("By Default, Unknown Annotation Application Causes Warning");
611 t.last_warning (UTL_Error::EIDL_LOOKUP_ERROR);
612 t.disable_output ();
613 t.run (
614 "struct struct11 {\n"
615 " @fake_annotation(fake_param=FAKE_CONSTANT)\n"
616 " short member;\n"
617 "};\n"
619 } catch (Failed const &) {}
621 try {
622 idl_global->unknown_annotations_ =
623 IDL_GlobalData::UNKNOWN_ANNOTATIONS_ERROR;
624 Annotation_Test t ("Optionally, Unknown Annotation Application Causes Err0r");
625 // Any mention of "Error" will be picked up by scoreboard ^^^
626 t.last_error (UTL_Error::EIDL_LOOKUP_ERROR).error_count (1);
627 t.disable_output ();
628 t.run (
629 "struct struct10 {\n"
630 " @fake_annotation(fake_param=FAKE_CONSTANT)\n"
631 " short member;\n"
632 "};\n"
634 // Restore Default Behaivor
635 idl_global->unknown_annotations_ =
636 IDL_GlobalData::UNKNOWN_ANNOTATIONS_WARN_ONCE;
637 } catch (Failed const &) {}
639 try {
640 Annotation_Test t ("Annotation Application with Enum");
641 AST_Decl *value = t.run (
642 "struct struct8 {\n"
643 " @enum_annotation\n" // A
644 " @enum_annotation(B)\n"
645 " @enum_annotation(value=C)\n"
646 " short value;\n"
647 "};\n"
648 ).assert_node ("struct8::value");
649 t.assert_annotation_appl_count (value, 3);
650 AST_Annotation_Member *member;
652 AST_Annotation_Appl *first =
653 t.assert_annotation_appl (value, 0, enum_annotation);
654 member = t.get_annotation_member (first, "value");
655 t.assert_annotation_member_value (member, enum_annotation_a);
657 AST_Annotation_Appl *second =
658 t.assert_annotation_appl (value, 1, enum_annotation);
659 member = t.get_annotation_member (second, "value");
660 t.assert_annotation_member_value (member, enum_annotation_b);
662 AST_Annotation_Appl *third =
663 t.assert_annotation_appl (value, 2, enum_annotation);
664 member = t.get_annotation_member (third, "value");
665 t.assert_annotation_member_value (member, enum_annotation_c);
666 } catch (Failed const &) {}
668 try {
669 Annotation_Test t ("Annotation Application with String");
670 AST_Decl *value = t.run (
671 "struct struct9 {\n"
672 " @string_annotation\n" // A
673 " @string_annotation(\"Something else\")\n"
674 " @string_annotation(value=\"One last thing\")\n"
675 " short value;\n"
676 "};\n"
677 ).assert_node ("struct9::value");
678 t.assert_annotation_appl_count (value, 3);
679 AST_Annotation_Member *member;
680 AST_Annotation_Appl *annotation;
682 UTL_String first_string ("This is some text");
683 annotation = t.assert_annotation_appl (value, 0, string_annotation);
684 member = t.get_annotation_member (annotation, "value");
685 t.assert_annotation_member_value <UTL_String *, UTL_String *>
686 (member, &first_string);
688 UTL_String second_string ("Something else");
689 annotation = t.assert_annotation_appl (value, 1, string_annotation);
690 member = t.get_annotation_member (annotation, "value");
691 t.assert_annotation_member_value <UTL_String *, UTL_String *>
692 (member, &second_string);
694 UTL_String third_string ("One last thing");
695 annotation = t.assert_annotation_appl (value, 2, string_annotation);
696 member = t.get_annotation_member (annotation, "value");
697 t.assert_annotation_member_value <UTL_String *, UTL_String *>
698 (member, &third_string);
699 } catch (Failed const &) {}
701 try {
702 Annotation_Test t ("Annotation Application with Constant");
703 AST_Decl *value = t.run (
704 "struct struct12 {\n"
705 " @constant_annotation\n" // A
706 " @constant_annotation(Y)\n"
707 " @constant_annotation(100)\n"
708 " short value;\n"
709 "};\n"
710 ).assert_node ("struct12::value");
711 t.assert_annotation_appl_count (value, 3);
712 AST_Annotation_Member *member;
713 AST_Annotation_Appl *annotation;
715 annotation = t.assert_annotation_appl (value, 0, constant_annotation);
716 member = t.get_annotation_member (annotation, "value");
717 t.assert_annotation_member_value (member, constant_annotation_x);
719 annotation = t.assert_annotation_appl (value, 1, constant_annotation);
720 member = t.get_annotation_member (annotation, "value");
721 t.assert_annotation_member_value (member, constant_annotation_y);
723 annotation = t.assert_annotation_appl (value, 2, constant_annotation);
724 member = t.get_annotation_member (annotation, "value");
725 t.assert_annotation_member_value<short, ACE_CDR::Short> (member, 100);
726 } catch (Failed const &) {}
728 try {
729 Annotation_Test t ("Annotate Array Base Type");
730 AST_Typedef *thetypedef = t.run (
731 "typedef struct12 struct12Array @test_annotation_1 [12];\n"
732 ).assert_node<AST_Typedef> ("::struct12Array");
733 AST_Array *struct12Array =
734 dynamic_cast<AST_Array *> (thetypedef->base_type ());
735 if (!struct12Array) t.failed ("Could not get AST_Array");
737 // Verify Annotation on Base Type
738 AST_Annotation_Appls &annotations =
739 struct12Array->base_type_annotations ();
740 size_t count = annotations.size ();
741 if (count != 1)
743 ACE_ERROR ((LM_ERROR, ACE_TEXT ("Annotation Test Error: %C:\n")
744 ACE_TEXT ("expected one annotation on struct12Array base type, ")
745 ACE_TEXT ("it has %d annotations!\n"),
746 t.name_.c_str (), count));
747 t.failed ();
749 AST_Annotation_Appl *annotation = annotations[0];
750 if (!annotation)
752 t.failed ("annotation for struct12Array base type is null!");
754 if (annotation->annotation_decl () != test_annotation_1)
756 UTL_ScopedName *scopedname = annotation->name ();
757 const char *name = scopedname ?
758 scopedname-> get_string_copy () : "UNKNOWN";
759 ACE_ERROR ((LM_ERROR, ACE_TEXT ("Annotation Test Error: %C:\n")
760 ACE_TEXT ("expected annotation for struct12Array base type to be ")
761 ACE_TEXT ("test_annotation_1, but it was %C\n"),
762 t.name_.c_str (), name));
763 if (scopedname)
765 delete [] name;
767 t.failed ();
769 } catch (Failed const &) {}
771 try {
772 Annotation_Test t ("Annotation Application with Single Boolean");
773 t.run (
774 "struct struct13 {\n"
775 " @boolean_annotation\n"
776 " short test_member_1;\n"
777 " @boolean_annotation (TRUE)\n"
778 " short test_member_2;\n"
779 " @boolean_annotation (FALSE)\n"
780 " short test_member_3;\n"
781 " @boolean_annotation (value = TRUE)\n"
782 " short test_member_4;\n"
783 " @boolean_annotation (value = FALSE)\n"
784 " short test_member_5;\n"
785 "};\n"
788 AST_Decl *struct_member = 0;
789 AST_Annotation_Appl *appl = 0;
791 struct_member = t.assert_node ("struct13::test_member_1");
792 t.assert_annotation_appl_count (struct_member, 1);
793 appl = t.assert_annotation_appl (struct_member, 0, boolean_annotation);
794 t.assert_annotation_member_count (appl, 1);
795 t.assert_annotation_member_value<bool, ACE_CDR::Boolean> (
796 t.get_annotation_member (appl, "value"), true);
798 struct_member = t.assert_node ("struct13::test_member_2");
799 t.assert_annotation_appl_count (struct_member, 1);
800 appl = t.assert_annotation_appl (struct_member, 0, boolean_annotation);
801 t.assert_annotation_member_count (appl, 1);
802 t.assert_annotation_member_value<bool, ACE_CDR::Boolean> (
803 t.get_annotation_member (appl, "value"), true);
805 struct_member = t.assert_node ("struct13::test_member_3");
806 t.assert_annotation_appl_count (struct_member, 1);
807 appl = t.assert_annotation_appl (struct_member, 0, boolean_annotation);
808 t.assert_annotation_member_count (appl, 1);
809 t.assert_annotation_member_value<bool, ACE_CDR::Boolean> (
810 t.get_annotation_member (appl, "value"), false);
812 struct_member = t.assert_node ("struct13::test_member_4");
813 t.assert_annotation_appl_count (struct_member, 1);
814 appl = t.assert_annotation_appl (struct_member, 0, boolean_annotation);
815 t.assert_annotation_member_count (appl, 1);
816 t.assert_annotation_member_value<bool, ACE_CDR::Boolean> (
817 t.get_annotation_member (appl, "value"), true);
819 struct_member = t.assert_node ("struct13::test_member_5");
820 t.assert_annotation_appl_count (struct_member, 1);
821 appl = t.assert_annotation_appl (struct_member, 0, boolean_annotation);
822 t.assert_annotation_member_count (appl, 1);
823 t.assert_annotation_member_value<bool, ACE_CDR::Boolean> (
824 t.get_annotation_member (appl, "value"), false);
825 } catch (Failed const &) {}
827 try {
828 Annotation_Test t ("Annotations on and in Interfaces");
829 t.run ((std::string () +
830 "@test_annotation_1\n"
831 "interface interface1 {\n"
832 // export
833 + common_export_idl +
834 "};\n"
835 ).c_str ());
837 AST_Interface *interface1 = t.assert_node<AST_Interface> ("interface1");
838 t.assert_annotation_appl_count (interface1, 1);
839 t.assert_annotation_appl (interface1, 0, test_annotation_1);
840 t.set_scope (interface1);
841 assert_common_export_idl (t, test_annotation_1);
842 } catch (Failed const &) {}
844 try {
845 Annotation_Test t ("Annotations on and in Valuetypes");
846 t.run ((std::string () +
847 "@test_annotation_1\n"
848 "valuetype valuetype1 {\n"
849 // value_element
850 + common_value_element_idl +
851 "};\n"
852 ).c_str ());
854 AST_ValueType *valuetype1 = t.assert_node<AST_ValueType> ("valuetype1");
855 t.assert_annotation_appl_count (valuetype1, 1);
856 t.assert_annotation_appl (valuetype1, 0, test_annotation_1);
857 t.set_scope (valuetype1);
858 assert_common_value_element_idl (t, test_annotation_1);
859 } catch (Failed const &) {}
861 try {
862 Annotation_Test t ("Annotations on and in Porttypes");
863 t.run ((std::string () +
864 "@test_annotation_1\n"
865 "porttype port_with_provides {\n"
866 // port_ref
867 " @test_annotation_1\n"
868 " provides interface1 provides_value;\n"
869 // port_export
870 + common_attr_dcl_idl +
871 "};\n"
872 "\n"
873 "@test_annotation_1\n"
874 "porttype port_with_uses {\n"
875 // port_ref
876 " @test_annotation_1\n"
877 " uses interface1 uses_value;\n"
878 // port_export
879 + common_attr_dcl_idl +
880 "};\n"
881 ).c_str ());
883 AST_PortType *port_with_provides =
884 t.assert_node<AST_PortType> ("port_with_provides");
885 t.assert_annotation_appl_count (port_with_provides, 1);
886 t.assert_annotation_appl (port_with_provides, 0, test_annotation_1);
887 t.set_scope (port_with_provides);
888 assert_node_has_annotation (t, "provides_value", test_annotation_1);
889 assert_common_attr_dcl_idl (t, test_annotation_1);
891 AST_PortType *port_with_uses =
892 t.assert_node<AST_PortType> ("port_with_uses");
893 t.assert_annotation_appl_count (port_with_uses, 1);
894 t.assert_annotation_appl (port_with_uses, 0, test_annotation_1);
895 t.set_scope (port_with_uses);
896 assert_node_has_annotation (t, "uses_value", test_annotation_1);
897 assert_common_attr_dcl_idl (t, test_annotation_1);
898 } catch (Failed const &) {}
900 try {
901 Annotation_Test t ("Annotations on and in Eventtypes");
902 t.run ((std::string () +
903 "@test_annotation_1\n"
904 "eventtype event1 {\n"
905 + common_value_element_idl +
906 "};\n"
907 ).c_str ());
908 AST_EventType *event1 = t.assert_node<AST_EventType> ("event1");
909 t.assert_annotation_appl_count (event1, 1);
910 t.assert_annotation_appl (event1, 0, test_annotation_1);
911 t.set_scope (event1);
912 assert_common_value_element_idl (t, test_annotation_1);
913 } catch (Failed const &) {}
915 try {
916 Annotation_Test t ("Annotations on and in Components");
917 t.run ((std::string () +
918 "@test_annotation_1\n"
919 "component component1 {\n"
920 // provides_dcl
921 " @test_annotation_1\n"
922 " provides interface1 provides_value;\n"
923 // uses_dcl
924 " @test_annotation_1\n"
925 " uses interface1 uses_value;\n"
926 // attr_dcl
927 + common_attr_dcl_idl +
928 // port_dcl
929 " @test_annotation_1\n"
930 " port port_with_uses port_value;\n"
931 // emits_dcl
932 " @test_annotation_1\n"
933 " emits event1 emits_value;\n"
934 // publishes_dcl
935 " @test_annotation_1\n"
936 " publishes event1 publishes_value;\n"
937 // consumes_dcl
938 " @test_annotation_1\n"
939 " consumes event1 consumes_value;\n"
940 "};\n"
941 ).c_str ());
942 AST_Component *component1 = t.assert_node<AST_Component> ("component1");
943 t.assert_annotation_appl_count (component1, 1);
944 t.assert_annotation_appl (component1, 0, test_annotation_1);
945 t.set_scope (component1);
946 assert_node_has_annotation (t, "provides_value", test_annotation_1);
947 assert_node_has_annotation (t, "uses_value", test_annotation_1);
948 assert_common_attr_dcl_idl (t, test_annotation_1);
949 assert_node_has_annotation (t, "port_value", test_annotation_1);
950 assert_node_has_annotation (t, "emits_value", test_annotation_1);
951 assert_node_has_annotation (t, "publishes_value", test_annotation_1);
952 assert_node_has_annotation (t, "consumes_value", test_annotation_1);
953 } catch (Failed const &) {}
956 * Test for https://github.com/DOCGroup/ACE_TAO/issues/997
958 * When the original annotation work (https://github.com/DOCGroup/ACE_TAO/pull/723)
959 * was done it was assumed that when annotations didn't define the symbol
960 * being used, the lookup would go up the scope stack to the current scope.
961 * This turned out not the case, so this functionality was implemented just
962 * for annotation parameters.
964 try {
965 Annotation_Test t ("Passing Constant from Module");
966 t.run (
967 "@annotation range_test_annotation {\n"
968 " float min;\n"
969 " float max;\n"
970 "};\n"
971 "\n"
972 "module range_test_annoation_module {\n"
973 " const float f1 = 1.;\n"
974 " const float f2 = 2.;\n"
975 "\n"
976 " @range_test_annotation(min = f1, max = f2)\n"
977 " @range_test_annotation(\n"
978 " min = range_test_annoation_module::f1,\n"
979 " max = range_test_annoation_module::f2)\n"
980 " @range_test_annotation(\n"
981 " min = ::range_test_annoation_module::f1,\n"
982 " max = ::range_test_annoation_module::f2)\n"
983 " typedef float RangedFloat;\n"
984 "};\n"
987 AST_Annotation_Decl *range_like_test_annotation =
988 t.assert_annotation_decl ("::@range_test_annotation");
989 AST_Decl *RangedFloat = t.assert_node (
990 "::range_test_annoation_module::RangedFloat");
991 t.assert_annotation_appl_count (RangedFloat, 3);
992 t.assert_annotation_appl (RangedFloat, 0, range_like_test_annotation);
993 t.assert_annotation_appl (RangedFloat, 1, range_like_test_annotation);
994 t.assert_annotation_appl (RangedFloat, 2, range_like_test_annotation);
995 } catch (Failed const &) {}
997 /* -------------------------------------------------------------------------
998 * Annotation Names
999 * -------------------------------------------------------------------------
1000 * These tests assert various aspects of how annotations work in regards to
1001 * naming.
1004 try {
1005 Annotation_Test t ("Annotation and Non-Annotation Names Can't Clash");
1006 t.run (
1007 "@annotation samename {\n"
1008 "};\n"
1009 "struct samename {\n"
1010 " short member;\n"
1011 "};"
1013 } catch (Failed const &) {}
1015 try {
1016 Annotation_Test t ("Annotation Names Can't Be \"annotation\"");
1017 t.last_error (UTL_Error::EIDL_MISC).error_count (1);
1018 t.disable_output ();
1019 t.run (
1020 "@annotation annotation {\n"
1021 "};\n"
1023 } catch (Failed const &) {}
1025 try {
1026 Annotation_Test t ("Annotation Names Can Start with \"annotation\"");
1027 t.run (
1028 "@annotation annotationannotation {\n"
1029 "};\n"
1030 "@annotationannotation\n"
1031 "struct annotationannotation_struct {\n"
1032 " short member;\n"
1033 "};\n"
1034 ).assert_annotation_decl ("::@annotationannotation");
1035 } catch (Failed const &) {}
1037 /* -------------------------------------------------------------------------
1038 * Struct Field Visibility Must be vis_NA
1039 * -------------------------------------------------------------------------
1040 * Test for: https://github.com/DOCGroup/ACE_TAO/issues/784
1042 * In the bison file, visibility for valuetype state members (which are the
1043 * same class as normal fields) was being passed through the bison stack.
1044 * When adding support for annotations, the grammar was changed and it was
1045 * broken, causing bogus data to be passed to regular struct field as their
1046 * visibility.
1048 * This is a test to assert that struct fields have vis_NA. This can't be put
1049 * anywhere else at the moment because this is the only test that's an
1050 * instance of the idl compiler.
1052 try {
1053 Annotation_Test t ("Struct Field Visibility Must be vis_NA");
1054 AST_Field *member = t.assert_node<AST_Field> ("struct1::member");
1055 if (member->visibility () != AST_Field::vis_NA)
1057 char buffer[100];
1058 ACE_OS::snprintf (&buffer[0], 100,
1059 "struct field visibility is %u, which is not equal to vis_NA",
1060 static_cast<unsigned> (member->visibility ()));
1061 t.failed (&buffer[0]);
1063 } catch (Failed const &) {}
1065 /* -------------------------------------------------------------------------
1066 * Empty union cases aliasing the default case must always be evaluated
1067 * -------------------------------------------------------------------------
1068 * When the union has an enum discriminator, and one or more empty cases
1069 * acting as an alias to the default case the IDL compiler was failing to
1070 * resolve the ordinal value for these empty labels and this causes trouble
1071 * for at least OpenDDS.
1073 * This test is designed to verify that the condition is corrected by
1074 * parsing a specially crafted union and validating the value of the
1075 * label aliasing the default case.
1077 try {
1078 Annotation_Test t ("empty union branch label");
1079 AST_Union *test_union = t.run (
1080 "enum disc {A, B, C};\n"
1081 "union empty_union switch (disc) {\n"
1082 "case A: long along;\n"
1083 "case B: short bshort;\n"
1084 "case C:\n"
1085 "default: float cfloat;\n"
1086 "};\n").assert_node<AST_Union>("::empty_union");
1087 AST_Field **af = 0;
1088 test_union->field(af, 2);
1089 AST_UnionBranch *ub = dynamic_cast<AST_UnionBranch *>(*af);
1090 AST_UnionLabel *ul = ub->label ();
1091 if (ul->label_val()->ev()->u.ulval != 2)
1093 t.failed("did not get the correct label value");
1095 } catch (Failed const &) {}
1097 // Done, Print Overall Results
1098 Annotation_Test::results ();