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