OpenDDS  Snapshot(2023/04/28-20:55)
dds_visitor.cpp
Go to the documentation of this file.
1 /*
2  * Distributed under the OpenDDS License.
3  * See: http://www.opendds.org/license.html
4  */
5 
6 #include "dds_visitor.h"
7 
8 #include "metaclass_generator.h"
9 #include "ts_generator.h"
10 #include "marshal_generator.h"
11 #include "keys_generator.h"
12 #include "itl_generator.h"
13 #include "langmap_generator.h"
14 #include "value_reader_generator.h"
15 #include "value_writer_generator.h"
16 #include "topic_keys.h"
17 #include "typeobject_generator.h"
19 
20 #include <ast_argument.h>
21 #include <ast_attribute.h>
22 #include <ast_component_fwd.h>
23 #include <ast_enum.h>
24 #include <ast_enum_val.h>
25 #include <ast_eventtype.h>
26 #include <ast_eventtype_fwd.h>
27 #include <ast_exception.h>
28 #include <ast_factory.h>
29 #include <ast_home.h>
30 #include <ast_interface.h>
31 #include <ast_module.h>
32 #include <ast_native.h>
33 #include <ast_operation.h>
34 #include <ast_predefined_type.h>
35 #include <ast_root.h>
36 #include <ast_sequence.h>
37 #include <ast_structure.h>
38 #include <ast_union.h>
39 #include <ast_valuetype.h>
40 #include <ast_valuetype_fwd.h>
41 #include <utl_identifier.h>
42 #include <utl_string.h>
43 #include <utl_exceptlist.h>
44 #include <utl_err.h>
45 #include <nr_extern.h>
46 
47 #include <iostream>
48 #include <vector>
49 #include <fstream>
50 #include <string>
51 #include <set>
52 
53 using namespace std;
54 
55 namespace {
56  marshal_generator mar_gen_;
57  keys_generator key_gen_;
58  ts_generator ts_gen_;
59  metaclass_generator mc_gen_;
60  itl_generator itl_gen_;
61  langmap_generator lm_gen_;
62  typeobject_generator to_gen_;
63  value_reader_generator value_reader_generator_;
64  value_writer_generator value_writer_generator_;
65  dynamic_data_adapter_generator dynamic_data_adapter_generator_;
66 } // namespace
67 
68 dds_visitor::dds_visitor(AST_Decl* scope, bool java_ts_only)
69  : scope_(scope), error_(false), java_ts_only_(java_ts_only)
70 {
71  if (!be_global->no_default_gen()) {
72  gen_target_.add_generator(&to_gen_);
73  const bool generate_xtypes = !be_global->suppress_xtypes() && !java_ts_only;
74  to_gen_.produce_output(generate_xtypes);
75  to_gen_.produce_xtypes_complete(generate_xtypes && be_global->xtypes_complete());
76  if (generate_xtypes && be_global->old_typeobject_encoding()) {
77  to_gen_.use_old_typeobject_encoding();
78  }
79 
80  if (be_global->value_reader_writer()) {
81  gen_target_.add_generator(&value_reader_generator_);
82  gen_target_.add_generator(&value_writer_generator_);
83  }
84 
85  gen_target_.add_generator(&mar_gen_);
86  gen_target_.add_generator(&key_gen_);
87  gen_target_.add_generator(&ts_gen_);
88  gen_target_.add_generator(&mc_gen_);
89  gen_target_.add_generator(&dynamic_data_adapter_generator_);
90  }
91  if (be_global->itl()) {
92  gen_target_.add_generator(&itl_gen_);
93  }
94  if (be_global->language_mapping() != BE_GlobalData::LANGMAP_NONE) {
95  gen_target_.add_generator(&lm_gen_);
96  lm_gen_.init();
97  }
98 }
99 
101 {
102 }
103 
104 //visit_* functions
105 
106 int
107 dds_visitor::visit_root(AST_Root* node)
108 {
109  error_ = false;
110 
112  if (this->visit_scope(node) == -1) {
114  ACE_TEXT("(%N:%l) dds_visitor::visit_root -")
115  ACE_TEXT(" visit_scope failed\n")), -1);
116  }
118 
119  return (error_) ? -1 : 0;
120 }
121 
122 int
123 dds_visitor::visit_scope(UTL_Scope* node)
124 {
125  if (node->nmembers() > 0) {
126  UTL_ScopeActiveIterator si(node, UTL_Scope::IK_decls);
127  AST_Decl* d = 0;
128 
129  while (!si.is_done()) {
130  d = si.item();
131 
132  if (d == 0) {
134  ACE_TEXT("(%N:%l) dds_visitor::visit_")
135  ACE_TEXT("scope - bad node in this scope\n")), -1);
136  }
137 
138  if (d->node_type() == AST_Decl::NT_pre_defined) {
139  si.next();
140  continue;
141  }
142 
143  if (d->ast_accept(this) == -1) {
145  ACE_TEXT("(%N:%l) dds_visitor::visit_")
146  ACE_TEXT("scope - failed to accept visitor\n")), -1);
147  }
148 
149  si.next();
150  }
151  }
152 
153  return 0;
154 }
155 
156 int
157 dds_visitor::visit_module(AST_Module* node)
158 {
159  // Modules for builtin annotations seem to be showing up here. Ignore them.
160  if (node->builtin()) {
161  return 0;
162  }
163 
164  const char* name = node->local_name()->get_string();
165 
166  BE_Comment_Guard g("MODULE", name);
167 
168  ACE_UNUSED_ARG(g);
169 
170  if (this->visit_scope(node) == -1) {
172  ACE_TEXT("(%N:%l) dds_visitor::visit_module -")
173  ACE_TEXT(" visit_scope failed\n")), -1);
174  }
175 
176  return 0;
177 }
178 
179 int
180 dds_visitor::visit_interface(AST_Interface* node)
181 {
182  const char* name = node->local_name()->get_string();
183 
184  BE_Comment_Guard g("INTERFACE", name);
185 
186  ACE_UNUSED_ARG(g);
187 
188  vector<AST_Interface*> inherits(node->n_inherits());
189  for (int i = 0; i < node->n_inherits(); ++i) {
190  inherits[i] = dynamic_cast<AST_Interface*>(node->inherits()[i]);
191  }
192 
193  vector<AST_Interface*> inherits_flat(node->inherits_flat(),
194  node->inherits_flat()
195  + node->n_inherits_flat());
196 
197  vector<AST_Attribute*> attrs;
198 
199  scope2vector(attrs, node, AST_Decl::NT_attr);
200 
201  vector<AST_Operation*> ops;
202 
203  scope2vector(ops, node, AST_Decl::NT_op);
204 
205  if (!java_ts_only_) {
206  error_ |= !gen_target_.gen_interf(node, node->name(), node->is_local(),
207  inherits, inherits_flat, attrs, ops,
208  node->repoID());
209  }
210 
211  if (this->visit_scope(node) == -1) {
213  ACE_TEXT("(%N:%l) dds_visitor::visit_interface ")
214  ACE_TEXT("- visit_scope failed\n")), -1);
215  }
216 
217  return 0;
218 }
219 
220 int
221 dds_visitor::visit_structure(AST_Structure* node)
222 {
223  const char* name = node->local_name()->get_string();
224 
225  BE_Comment_Guard g("STRUCT", name);
226  ACE_UNUSED_ARG(g);
227 
228  // Check That Sample Keys Are Valid
229  TopicKeys topic_keys(node);
230  try {
231  topic_keys.count();
232  } catch (TopicKeys::Error& error) {
233  idl_global->err()->misc_error(error.what(), error.node());
234  return -1;
235  }
236 
237  IDL_GlobalData::DCPS_Data_Type_Info* info = idl_global->is_dcps_type(node->name());
238  if (info) {
239  if (be_global->warn_about_dcps_data_type()) {
240  idl_global->err()->misc_warning("\n"
241  " DCPS_DATA_TYPE and DCPS_DATA_KEY pragma statements are deprecated; please use\n"
242  " topic type annotations instead.\n"
243  " See docs/migrating_to_topic_type_annotations.md in the OpenDDS source code for\n"
244  " more information.", node);
245  }
246 
247  /*
248  * If the struct is declared a topic type using both the older and newer
249  * styles, warn if the keys are inconsistent.
250  */
251  if (be_global->is_topic_type(node)) {
252  set<string> topic_type_keys, dcps_data_type_keys;
253 
254  TopicKeys::Iterator finished = topic_keys.end();
255  for (TopicKeys::Iterator i = topic_keys.begin(); i != finished; ++i) {
256  topic_type_keys.insert(i.path());
257  }
258 
259  IDL_GlobalData::DCPS_Data_Type_Info_Iter iter(info->key_list_);
260  for (ACE_TString* kp = 0; iter.next(kp) != 0; iter.advance()) {
261  dcps_data_type_keys.insert(ACE_TEXT_ALWAYS_CHAR(kp->c_str()));
262  }
263 
264  if (topic_type_keys != dcps_data_type_keys) {
265  string message = "\n"
266  " The keys are inconsistent on this struct declared to be a topic type using\n"
267  " both a DCPS_DATA_TYPE pragma and the annotation-based system.";
268 
269  bool header = false;
270  for (set<string>::iterator i = topic_type_keys.begin();
271  i != topic_type_keys.end(); ++i) {
272  if (dcps_data_type_keys.find(*i) == dcps_data_type_keys.end()) {
273  if (!header) {
274  message += "\n\n"
275  " The following keys were declared using @key, but not DCPS_DATA_KEY:";
276  header = true;
277  }
278  message += "\n " + *i;
279  }
280  }
281 
282  header = false;
283  for (set<string>::iterator i = dcps_data_type_keys.begin();
284  i != dcps_data_type_keys.end(); ++i) {
285  if (topic_type_keys.find(*i) == topic_type_keys.end()) {
286  if (!header) {
287  message += "\n\n"
288  " The following keys were declared using DCPS_DATA_KEY, but not @key:";
289  header = true;
290  }
291  message += "\n " + *i;
292  }
293  }
294 
295  message += "\n\n"
296  " DCPS_DATA_TYPE and DCPS_DATA_KEY are deprecated, so the annotation-based keys\n"
297  " will be used.";
298 
299  idl_global->err()->misc_warning(message.c_str(), node);
300  }
301  }
302  }
303 
304  vector<AST_Field*> field_vec;
305  field_vec.reserve(node->nfields());
306  const Fields fields(node);
307  const Fields::Iterator fields_end = fields.end();
308  for (Fields::Iterator i = fields.begin(); i != fields_end; ++i) {
309  field_vec.push_back(*i);
310  }
311 
312  if (!java_ts_only_) {
313  error_ |= !gen_target_.gen_struct(node, node->name(), field_vec,
314  node->size_type(), node->repoID());
315  }
316 
317  if (!node->imported() && be_global->java()) {
319  }
320 
321  return 0;
322 }
323 
324 int
325 dds_visitor::visit_exception(AST_Exception* node)
326 {
327  if (node->imported()) {
328  return 0;
329  }
330 
331  const char* name = node->local_name()->get_string();
332 
333  BE_Comment_Guard g("EXCEPTION", name);
334 
335  ACE_UNUSED_ARG(g);
336 
337  return 0;
338 }
339 
340 int
341 dds_visitor::visit_typedef(AST_Typedef* node)
342 {
343  const char* name = node->local_name()->get_string();
344 
345  BE_Comment_Guard g("TYPEDEF", name);
346 
347  ACE_UNUSED_ARG(g);
348 
349  if (!java_ts_only_) {
350  error_ |= !gen_target_.gen_typedef(node, node->name(), node->base_type(),
351  node->repoID());
352  }
353 
354  return 0;
355 }
356 
357 int
358 dds_visitor::visit_enum(AST_Enum* node)
359 {
360  const char* name = node->local_name()->get_string();
361 
362  BE_Comment_Guard g("ENUM", name);
363 
364  ACE_UNUSED_ARG(g);
365 
366  vector<AST_EnumVal*> contents;
367 
368  scope2vector(contents, node, AST_Decl::NT_enum_val);
369 
370  if (!java_ts_only_) {
371  error_ |= !gen_target_.gen_enum(node, node->name(), contents, node->repoID());
372  }
373 
374  return 0;
375 }
376 
377 int
378 dds_visitor::visit_interface_fwd(AST_InterfaceFwd* node)
379 {
380  const char* name = node->local_name()->get_string();
381  BE_Comment_Guard g("INTERFACE-FWD", name);
382  ACE_UNUSED_ARG(g);
383 
384  if (!java_ts_only_) {
385  error_ |= !gen_target_.gen_interf_fwd(node->name());
386  }
387 
388  return 0;
389 }
390 
391 int
392 dds_visitor::visit_structure_fwd(AST_StructureFwd* node)
393 {
394  const char* name = node->local_name()->get_string();
395  BE_Comment_Guard g("STRUCT-FWD", name);
396 
397  if (!java_ts_only_) {
398  error_ |= !gen_target_.gen_struct_fwd(node->name(), node->size_type());
399  }
400 
401  return 0;
402 }
403 
404 int
405 dds_visitor::visit_constant(AST_Constant* node)
406 {
407  const char* name = node->local_name()->get_string();
408 
409  BE_Comment_Guard g("CONST", name);
410 
411  ACE_UNUSED_ARG(g);
412 
413  AST_Decl* d = ScopeAsDecl(node->defined_in());
414 
415  bool nested = d && (d->node_type() == AST_Decl::NT_interface);
416 
417  if (!java_ts_only_) {
418  error_ |= !gen_target_.gen_const(node->name(), nested, node);
419  }
420 
421  return 0;
422 }
423 
424 int
425 dds_visitor::visit_native(AST_Native* node)
426 {
427  const char* name = node->local_name()->get_string();
428 
429  BE_Comment_Guard g("NATIVE", name);
430 
431  ACE_UNUSED_ARG(g);
432 
433  if (!java_ts_only_) {
434  error_ |= !gen_target_.gen_native(node, node->name(), node->repoID());
435  }
436 
437  return 0;
438 }
439 
440 int
441 dds_visitor::visit_union(AST_Union* node)
442 {
443  const char* name = node->local_name()->get_string();
444 
445  BE_Comment_Guard g("UNION", name);
446  ACE_UNUSED_ARG(g);
447 
448  vector<AST_UnionBranch*> branches;
449  branches.reserve(node->nfields());
450  const Fields fields(node);
451  const Fields::Iterator fields_end = fields.end();
452  for (Fields::Iterator i = fields.begin(); i != fields_end; ++i) {
453  AST_UnionBranch* ub = dynamic_cast<AST_UnionBranch*>(*i);
454  if (!ub) {
455  idl_global->err()->misc_error("expected union to only contain UnionBranches", ub);
456  error_ = true;
457  return -1;
458  }
459  branches.push_back(ub);
460  }
461 
462  if (!java_ts_only_) {
463  error_ |= !gen_target_.gen_union(node, node->name(), branches, node->disc_type(),
464  node->repoID());
465  }
466 
467  return 0;
468 }
469 
470 // *** All methods below here are unimplemented (or trivially implemented) ***
471 
472 int
474 {
475  //sequences always appear as typedefs, see visit_typedef ()
476  return 0;
477 }
478 
479 int
481 {
482  // operations are taken care of by visit_interface()
483  return 0;
484 }
485 
486 int
488 {
489  // fields are taken care of by visit_interface() for arguments and attributes
490  return 0;
491 }
492 
493 int
495 {
496  // attributes are taken care of by visit_interface ()
497  return 0;
498 }
499 
500 int
502 {
503  //arrays always appear as typedefs, see visit_typedef ()
504  return 0;
505 }
506 
507 //begin IDL syntactic elements that are not currently supported
508 
509 int
511 {
512  return 0;
513 }
514 
515 int
517 {
518  return 0;
519 }
520 
521 int
523 {
524  return 0;
525 }
526 
527 int
529 {
530  return 0;
531 }
532 
533 int
535 {
536  return 0;
537 }
538 
539 int
541 {
542  return 0;
543 }
544 
545 int
547 {
548  return 0;
549 }
550 
551 int
553 {
554  return 0;
555 }
556 
557 //no need to implement these at this level
558 
559 int
561 {
562  return 0;
563 }
564 
565 int
567 {
568  return 0;
569 }
570 
571 int
572 dds_visitor::visit_union_fwd(AST_UnionFwd* node)
573 {
574  const char* name = node->local_name()->get_string();
575  BE_Comment_Guard g("UNION-FWD", name);
576 
577  if (!java_ts_only_) {
578  error_ |= !gen_target_.gen_union_fwd(node, node->name(), node->size_type());
579  }
580 
581  return 0;
582 }
583 
584 int dds_visitor::visit_union_branch(AST_UnionBranch*)
585 {
586  return 0;
587 }
588 
589 int dds_visitor::visit_union_label(AST_UnionLabel*)
590 {
591  return 0;
592 }
593 
595 {
596  return 0;
597 }
598 
599 int dds_visitor::visit_expression(AST_Expression*)
600 {
601  return 0;
602 }
603 
605 {
606  return 0;
607 }
608 
609 int dds_visitor::visit_argument(AST_Argument*)
610 {
611  return 0;
612 }
613 
615 {
616  return 0;
617 }
618 
619 int dds_visitor::visit_valuebox(AST_ValueBox*)
620 {
621  return 0;
622 }
623 
624 int
626 {
627  return 0;
628 }
629 
630 int
631 dds_visitor::visit_template_module_inst (AST_Template_Module_Inst*)
632 {
633  return 0;
634 }
635 
636 int
637 dds_visitor::visit_template_module_ref (AST_Template_Module_Ref*)
638 {
639  return 0;
640 }
641 
642 int
644 {
645  return 0;
646 }
647 
648 int dds_visitor::visit_porttype(AST_PortType*)
649 {
650  return 0;
651 }
652 
653 int dds_visitor::visit_provides(AST_Provides*)
654 {
655  return 0;
656 }
657 
659 {
660  return 0;
661 }
662 
663 int dds_visitor::visit_publishes(AST_Publishes*)
664 {
665  return 0;
666 }
667 
669 {
670  return 0;
671 }
672 
673 int dds_visitor::visit_consumes(AST_Consumes*)
674 {
675  return 0;
676 }
677 
678 int dds_visitor::visit_extended_port(AST_Extended_Port*)
679 {
680  return 0;
681 }
682 
683 int dds_visitor::visit_mirror_port(AST_Mirror_Port*)
684 {
685  return 0;
686 }
687 
688 int dds_visitor::visit_connector(AST_Connector*)
689 {
690  return 0;
691 }
692 
694 {
695  return 0;
696 }
virtual int visit_scope(UTL_Scope *node)
void scope2vector(std::vector< T *> &v, UTL_Scope *s, AST_Decl::NodeType nt)
Definition: dds_visitor.h:141
Iterator end()
Definition: topic_keys.cpp:500
virtual int visit_eventtype(AST_EventType *node)
virtual int visit_string(AST_String *node)
virtual int visit_component(AST_Component *node)
virtual int visit_connector(AST_Connector *node)
virtual int visit_interface_fwd(AST_InterfaceFwd *node)
virtual int visit_typedef(AST_Typedef *node)
Iterator begin() const
virtual int visit_extended_port(AST_Extended_Port *node)
virtual int visit_param_holder(AST_Param_Holder *node)
virtual int visit_valuebox(AST_ValueBox *node)
virtual int visit_operation(AST_Operation *node)
virtual int visit_array(AST_Array *node)
bool gen_union(AST_Union *node, UTL_ScopedName *name, const std::vector< AST_UnionBranch *> &branches, AST_Type *discriminator, const char *repoid)
virtual int visit_component_fwd(AST_ComponentFwd *node)
virtual int visit_attribute(AST_Attribute *node)
#define ACE_TEXT_ALWAYS_CHAR(STRING)
bool gen_const(UTL_ScopedName *name, bool nestedInInteface, AST_Constant *constant)
virtual const char * what() const
Definition: topic_keys.cpp:61
virtual int visit_enum(AST_Enum *node)
bool gen_interf_fwd(UTL_ScopedName *name)
bool gen_native(AST_Native *node, UTL_ScopedName *name, const char *repoid)
bool gen_interf(AST_Interface *node, UTL_ScopedName *name, bool local, const std::vector< AST_Interface *> &inherits, const std::vector< AST_Interface *> &inherits_flat, const std::vector< AST_Attribute *> &attrs, const std::vector< AST_Operation *> &ops, const char *repoid)
virtual int visit_sequence(AST_Sequence *node)
virtual int visit_predefined_type(AST_PredefinedType *node)
composite_generator gen_target_
Definition: dds_visitor.h:137
virtual int visit_factory(AST_Factory *node)
virtual int visit_field(AST_Field *node)
virtual int visit_valuetype(AST_ValueType *node)
virtual int visit_consumes(AST_Consumes *node)
virtual int visit_native(AST_Native *node)
dds_visitor(AST_Decl *scope, bool java_ts_only)
Definition: dds_visitor.cpp:68
virtual int visit_type(AST_Type *node)
virtual int visit_template_module(AST_Template_Module *node)
virtual int visit_structure(AST_Structure *node)
virtual int visit_valuetype_fwd(AST_ValueTypeFwd *node)
Christopher Diggins *renamed files *fixing compilation errors *adding Visual C project file *removed make Max Lybbert *removed references to missing and unused header
Definition: CHANGELOG.txt:8
virtual int visit_constant(AST_Constant *node)
virtual int visit_exception(AST_Exception *node)
Iterator end() const
virtual int visit_union(AST_Union *node)
virtual int visit_uses(AST_Uses *node)
STL namespace.
size_t count()
Definition: topic_keys.cpp:515
virtual int visit_porttype(AST_PortType *node)
bool gen_typedef(AST_Typedef *node, UTL_ScopedName *name, AST_Type *base, const char *repoid)
virtual int visit_enum_val(AST_EnumVal *node)
bool java_ts_only_
Definition: dds_visitor.h:136
virtual int visit_union_branch(AST_UnionBranch *node)
virtual int visit_interface(AST_Interface *node)
virtual ~dds_visitor()
const char *const name
Definition: debug.cpp:60
ACE_TEXT("TCP_Factory")
virtual int visit_mirror_port(AST_Mirror_Port *node)
virtual int visit_expression(AST_Expression *node)
virtual int visit_union_label(AST_UnionLabel *node)
AST_Decl * node()
Definition: topic_keys.cpp:66
virtual int visit_argument(AST_Argument *node)
virtual int visit_eventtype_fwd(AST_EventTypeFwd *node)
virtual int visit_template_module_ref(AST_Template_Module_Ref *node)
Iterator begin()
Definition: topic_keys.cpp:495
void add_generator(dds_generator *gen)
BE_GlobalData * be_global
Definition: be_global.cpp:44
virtual int visit_template_module_inst(AST_Template_Module_Inst *node)
virtual int visit_structure_fwd(AST_StructureFwd *node)
virtual int visit_publishes(AST_Publishes *node)
bool gen_struct_fwd(UTL_ScopedName *name, AST_Type::SIZE_TYPE size)
virtual int visit_emits(AST_Emits *node)
#define ACE_ERROR_RETURN(X, Y)
virtual int visit_root(AST_Root *node)
virtual int visit_finder(AST_Finder *node)
virtual int visit_module(AST_Module *node)
virtual int visit_union_fwd(AST_UnionFwd *node)
LM_ERROR
bool gen_union_fwd(AST_UnionFwd *, UTL_ScopedName *name, AST_Type::SIZE_TYPE size)
virtual int visit_provides(AST_Provides *node)
virtual int visit_decl(AST_Decl *d)
bool gen_struct(AST_Structure *node, UTL_ScopedName *name, const std::vector< AST_Field *> &fields, AST_Type::SIZE_TYPE size, const char *repoid)
void generate(AST_Structure *node)
called directly by dds_visitor::visit_structure() if -Wb,java
bool gen_enum(AST_Enum *node, UTL_ScopedName *name, const std::vector< AST_EnumVal *> &contents, const char *repoid)
virtual int visit_home(AST_Home *node)