ifr_adding_visitor_exception.cpp

Go to the documentation of this file.
00001 /* -*- c++ -*- */
00002 // $Id: ifr_adding_visitor_exception.cpp 78850 2007-07-12 10:50:02Z parsons $
00003 
00004 #include "ast_enum.h"
00005 #include "ast_exception.h"
00006 #include "ast_expression.h"
00007 #include "ast_field.h"
00008 #include "ast_union.h"
00009 #include "utl_identifier.h"
00010 
00011 #include "ifr_adding_visitor_exception.h"
00012 #include "ifr_adding_visitor_structure.h"
00013 #include "ifr_adding_visitor_union.h"
00014 
00015 ACE_RCSID (IFR_Service,
00016            ifr_adding_visitor_exception,
00017            "$Id: ifr_adding_visitor_exception.cpp 78850 2007-07-12 10:50:02Z parsons $")
00018 
00019 ifr_adding_visitor_exception::ifr_adding_visitor_exception (
00020     AST_Decl *scope,
00021     bool in_reopened
00022   )
00023   : ifr_adding_visitor (scope,
00024                         in_reopened)
00025 {
00026 }
00027 
00028 ifr_adding_visitor_exception::~ifr_adding_visitor_exception (void)
00029 {
00030 }
00031 
00032 // Specialized visit_scope method for exceptions only.
00033 int
00034 ifr_adding_visitor_exception::visit_scope (UTL_Scope *node)
00035 {
00036   // If the exception has members that are scopes but not exceptions,
00037   // the regular visit_scope method should be called instead.
00038   if (node->scope_node_type () != AST_Decl::NT_except)
00039     {
00040       return ifr_adding_visitor::visit_scope (node);
00041     }
00042 
00043   AST_Exception *e = AST_Exception::narrow_from_scope (node);
00044 
00045   CORBA::ULong nfields = static_cast<CORBA::ULong> (e->nfields ());
00046 
00047   this->members_.length (nfields);
00048 
00049   AST_Field **f = 0;
00050 
00051   try
00052     {
00053       // Visit each field.
00054       for (CORBA::ULong i = 0; i < nfields; ++i)
00055         {
00056           if (e->field (f, i) != 0)
00057             {
00058               ACE_ERROR_RETURN ((
00059                   LM_ERROR,
00060                   ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::")
00061                   ACE_TEXT ("visit_scope -")
00062                   ACE_TEXT (" field node access failed\n")
00063                 ),
00064                 -1
00065               );
00066             }
00067 
00068           AST_Type *ft = (*f)->field_type ();
00069 
00070           bool defined_here = ft->is_child (this->scope_);
00071 
00072           // If the struct member is defined in the struct, we have to
00073           // do some visiting - otherwise we can just look up the entry.
00074           if (defined_here)
00075             {
00076               if (ft->ast_accept (this) == -1)
00077                 {
00078                   ACE_ERROR_RETURN ((
00079                       LM_ERROR,
00080                       ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::")
00081                       ACE_TEXT ("visit_scope -")
00082                       ACE_TEXT (" failed to accept visitor\n")
00083                     ),
00084                     -1
00085                   );
00086                 }
00087             }
00088           else
00089             {
00090               // Updates ir_current_.
00091               this->get_referenced_type (ft);
00092             }
00093 
00094           this->members_[i].name =
00095             CORBA::string_dup ((*f)->local_name ()->get_string ());
00096 
00097           // IfR method create_exception does not use this - it just needs
00098           // to be non-zero for marshaling.
00099           this->members_[i].type =
00100             CORBA::TypeCode::_duplicate (CORBA::_tc_void);
00101 
00102           this->members_[i].type_def =
00103             CORBA::IDLType::_duplicate (this->ir_current_.in ());
00104         }
00105     }
00106   catch (const CORBA::Exception& ex)
00107     {
00108       ex._tao_print_exception (
00109         ACE_TEXT (
00110           "ifr_adding_visitor_structure::visit_scope"));
00111 
00112       return -1;
00113     }
00114 
00115   return 0;
00116 }
00117 
00118 int
00119 ifr_adding_visitor_exception::visit_structure (AST_Structure *node)
00120 {
00121   try
00122     {
00123       // Is this union already in the respository?
00124       CORBA::Contained_var prev_def =
00125         be_global->repository ()->lookup_id (node->repoID ());
00126 
00127       // If not, create a new entry.
00128       if (CORBA::is_nil (prev_def.in ()))
00129         {
00130           ifr_adding_visitor_structure visitor (node, true);
00131 
00132           int retval = visitor.visit_structure (node);
00133 
00134           if (retval == 0)
00135             {
00136               // Get the result of the visit.
00137               this->ir_current_ =
00138                 CORBA::IDLType::_duplicate (visitor.ir_current ());
00139 
00140               CORBA::Contained_ptr tmp =
00141                 CORBA::Contained::_narrow (visitor.ir_current ());
00142 
00143               // Since the enclosing ExceptionDef hasn't been created
00144               // yet, we don't have a scope, so this nested StructDef
00145               // (which was created at global scope) goes on the
00146               // queue to be moved later.
00147               this->move_queue_.enqueue_tail (tmp);
00148             }
00149 
00150           return retval;
00151         }
00152       else
00153         {
00154           // If the line below is true, we are clobbering a previous
00155           // entry (from another IDL file) of another type. In that
00156           // case we do what other ORB vendors do, and destroy the
00157           // original entry, create the new one, and let the user beware.
00158           if (!node->ifr_added ())
00159             {
00160               prev_def->destroy ();
00161 
00162               // This call will take the other branch.
00163               return this->visit_structure (node);
00164             }
00165 
00166           this->ir_current_ =
00167             CORBA::IDLType::_narrow (prev_def.in ());
00168         }
00169     }
00170   catch (const CORBA::Exception& ex)
00171     {
00172       ex._tao_print_exception (
00173         ACE_TEXT (
00174           "ifr_adding_visitor_exception::visit_structure"));
00175 
00176       return -1;
00177     }
00178 
00179   return 0;
00180 }
00181 
00182 int
00183 ifr_adding_visitor_exception::visit_exception (AST_Exception *node)
00184 {
00185   try
00186     {
00187       CORBA::Contained_var prev_def =
00188         be_global->repository ()->lookup_id (node->repoID ());
00189 
00190       if (!CORBA::is_nil (prev_def.in ()))
00191         {
00192           // If we and our enclosing module are both already in the
00193           // repository, we are probably processing the same IDL file
00194           // a second time. If it is just a name clash, there is no
00195           // way to detect it.
00196           if (this->in_reopened_)
00197             {
00198               return 0;
00199             }
00200 
00201           // If the line below is true, we are clobbering a previous
00202           // entry (from another IDL file) of another type. In that
00203           // case we do what other ORB vendors do, and destroy the
00204           // original entry, create the new one, and let the user beware.
00205           if (!node->ifr_added ())
00206             {
00207               prev_def->destroy ();
00208 
00209               // This call will create a new ExceptionDef entry.
00210               return this->visit_exception (node);
00211             }
00212           else
00213             {
00214               // The node is being referenced in an operation, no action.
00215               return 0;
00216             }
00217         }
00218 
00219       if (this->visit_scope (node) == -1)
00220         {
00221           ACE_ERROR_RETURN ((
00222               LM_ERROR,
00223               ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::")
00224               ACE_TEXT ("visit_exception -")
00225               ACE_TEXT (" visit_scope failed\n")
00226             ),
00227             -1
00228           );
00229         }
00230 
00231       CORBA::Container_ptr current_scope =
00232         CORBA::Container::_nil ();
00233 
00234       if (be_global->ifr_scopes ().top (current_scope) != 0)
00235         {
00236           ACE_ERROR_RETURN ((
00237               LM_ERROR,
00238               ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::")
00239               ACE_TEXT ("visit_exception -")
00240               ACE_TEXT (" scope stack is empty\n")
00241             ),
00242             -1
00243           );
00244         }
00245 
00246       CORBA::ExceptionDef_var new_def =
00247         current_scope->create_exception (node->repoID (),
00248                                          node->local_name ()->get_string (),
00249                                          node->version (),
00250                                          this->members_);
00251 
00252 
00253       size_t size = this->move_queue_.size ();
00254 
00255       if (size > 0)
00256         {
00257           CORBA::Contained_var traveller;
00258 
00259           CORBA::Container_var new_container =
00260             CORBA::Container::_narrow (new_def.in ());
00261 
00262           for (size_t i = 0; i < size; ++i)
00263             {
00264               this->move_queue_.dequeue_head (traveller);
00265 
00266               CORBA::String_var name =
00267                 traveller->name ();
00268 
00269               CORBA::String_var version =
00270                 traveller->version ();
00271 
00272               traveller->move (new_container.in (),
00273                                name.in (),
00274                                version.in ());
00275             }
00276         }
00277 
00278       node->ifr_added (true);
00279     }
00280   catch (const CORBA::Exception& ex)
00281     {
00282       ex._tao_print_exception (
00283         ACE_TEXT (
00284           "ifr_adding_visitor_exception::visit_exception"));
00285 
00286       return -1;
00287     }
00288 
00289   return 0;
00290 }
00291 
00292 int
00293 ifr_adding_visitor_exception::visit_enum (AST_Enum *node)
00294 {
00295   try
00296     {
00297       // Is this enum already in the respository?
00298       CORBA::Contained_var prev_def =
00299         be_global->repository ()->lookup_id (node->repoID ());
00300 
00301       // If not, create a new entry.
00302       if (CORBA::is_nil (prev_def.in ()))
00303         {
00304           CORBA::ULong member_count = static_cast<CORBA::ULong> (node->member_count ());
00305 
00306           CORBA::EnumMemberSeq members (member_count);
00307           members.length (member_count);
00308 
00309           UTL_ScopedName *member_name = 0;
00310 
00311           // Get a list of the member names.
00312           for (CORBA::ULong i = 0; i < member_count; ++i)
00313             {
00314               member_name = node->value_to_name (i);
00315 
00316               members[i] =
00317                 CORBA::string_dup (
00318                     member_name->last_component ()->get_string ()
00319                   );
00320             }
00321 
00322           this->ir_current_ =
00323             be_global->repository ()->create_enum (
00324                                           node->repoID (),
00325                                           node->local_name ()->get_string (),
00326                                           node->version (),
00327                                           members
00328                                         );
00329 
00330           CORBA::Contained_ptr tmp =
00331             CORBA::Contained::_narrow (this->ir_current_.in ());
00332 
00333           this->move_queue_.enqueue_tail (tmp);
00334 
00335           node->ifr_added (true);
00336         }
00337       else
00338         {
00339           // If the line below is true, we are clobbering a previous
00340           // entry (from another IDL file) of another type. In that
00341           // case we do what other ORB vendors do, and destroy the
00342           // original entry, create the new one, and let the user beware.
00343           if (!node->ifr_added ())
00344             {
00345               prev_def->destroy ();
00346 
00347               // This call will take the other branch.
00348               return this->visit_enum (node);
00349             }
00350 
00351           this->ir_current_ =
00352             CORBA::IDLType::_narrow (prev_def.in ());
00353         }
00354     }
00355   catch (const CORBA::Exception& ex)
00356     {
00357       ex._tao_print_exception (
00358         ACE_TEXT (
00359           "ifr_adding_visitor_exception::visit_enum"));
00360 
00361       return -1;
00362     }
00363 
00364   return 0;
00365 }
00366 
00367 int
00368 ifr_adding_visitor_exception::visit_union (AST_Union *node)
00369 {
00370   try
00371     {
00372       // Is this union already in the respository?
00373       CORBA::Contained_var prev_def =
00374         be_global->repository ()->lookup_id (node->repoID ());
00375 
00376       // If not, create a new entry.
00377       if (CORBA::is_nil (prev_def.in ()))
00378         {
00379           ifr_adding_visitor_union visitor (node, true);
00380 
00381           int retval = visitor.visit_union (node);
00382 
00383           if (retval == 0)
00384             {
00385               // Get the result of the visit.
00386               this->ir_current_ =
00387                 CORBA::IDLType::_duplicate (visitor.ir_current ());
00388 
00389               CORBA::Contained_ptr tmp =
00390                 CORBA::Contained::_narrow (visitor.ir_current ());
00391 
00392               // Since the enclosing ExceptionDef hasn't been created
00393               // yet, we don't have a scope, so this nested UnionDef
00394               // (which was created at global scope) goes on the
00395               // queue to be moved later.
00396               this->move_queue_.enqueue_tail (tmp);
00397             }
00398 
00399           return retval;
00400         }
00401       else
00402         {
00403           // If the line below is true, we are clobbering a previous
00404           // entry (from another IDL file) of another type. In that
00405           // case we do what other ORB vendors do, and destroy the
00406           // original entry, create the new one, and let the user beware.
00407           if (!node->ifr_added ())
00408             {
00409               prev_def->destroy ();
00410 
00411               // This call will take the other branch.
00412               return this->visit_union (node);
00413             }
00414 
00415           this->ir_current_ =
00416             CORBA::IDLType::_narrow (prev_def.in ());
00417         }
00418     }
00419   catch (const CORBA::Exception& ex)
00420     {
00421       ex._tao_print_exception (
00422         ACE_TEXT (
00423           "ifr_adding_visitor_exception::visit_union"));
00424 
00425       return -1;
00426     }
00427 
00428   return 0;
00429 }
00430 
00431 CORBA::IDLType_ptr
00432 ifr_adding_visitor_exception::ir_current (void) const
00433 {
00434   return this->ir_current_.in ();
00435 }

Generated on Sun Jan 27 16:31:52 2008 for TAO_IFR by doxygen 1.3.6