be_visitor_ami_pre_proc.cpp

来自「这是广泛使用的通信开源项目,对于大容量,高并发的通讯要求完全能够胜任,他广泛可用」· C++ 代码 · 共 1,431 行 · 第 1/3 页

CPP
1,431
字号
            {
              ACE_ERROR_RETURN ((LM_ERROR,
                                 "(%N:%l) be_visitor_ami_pre_proc::"
                                 "create_reply_handler_operation - "
                                 "bad node in this scope\n"),
                                -1);

            }

          AST_Argument *original_arg = AST_Argument::narrow_from_decl (d);

          if (original_arg->direction () == AST_Argument::dir_INOUT ||
              original_arg->direction () == AST_Argument::dir_OUT)
            {
              // Create the argument.
              be_argument *arg = 0;
              ACE_NEW_RETURN (arg,
                              be_argument (AST_Argument::dir_IN,
                                           original_arg->field_type (),
                                           original_arg->name ()),
                              -1);

              operation->be_add_argument (arg);
            }
        } // end of while loop
    } // end of if

  // Set the proper strategy.
  be_operation_ami_handler_reply_stub_strategy *boahrss = 0;
  ACE_NEW_RETURN (boahrss,
                  be_operation_ami_handler_reply_stub_strategy (operation),
                  -1);

  be_operation_strategy *old_strategy = operation->set_strategy (boahrss);

  if (old_strategy)
    {
      delete old_strategy;
      old_strategy = 0;
    }

  operation->set_defined_in (reply_handler);

  // We do not copy the exceptions because the exceptions
  // are delivered by the excep methods.

  // After having generated the operation we insert it into the
  // reply handler interface.
  reply_handler->be_add_operation (operation);

  return 0;
}

int
be_visitor_ami_pre_proc::create_excep_operation (be_operation *node,
                                                 be_interface *reply_handler,
                                                 be_valuetype *excep_holder)
{
  if (!node)
    {
      return -1;
    }

  if (node->flags () == AST_Operation::OP_oneway)
    {
      // We do nothing for oneways!
      return 0;
    }

  // Create the return type, which is "void".
  Identifier *id = 0;
  UTL_ScopedName *sn = 0;

  ACE_NEW_RETURN (id,
                  Identifier ("void"),
                  -1);

  ACE_NEW_RETURN (sn,
                  UTL_ScopedName (id,
                                  0),
                  -1);

  be_predefined_type *rt = 0;
  ACE_NEW_RETURN (rt,
                  be_predefined_type (AST_PredefinedType::PT_void,
                                      sn),
                  -1);

  // Create the argument.
  ACE_NEW_RETURN (id,
                  Identifier ("excep_holder"),
                  -1);

  ACE_NEW_RETURN (sn,
                  UTL_ScopedName (id,
                                  0),
                  -1);

  be_argument *arg = 0;
  ACE_NEW_RETURN (arg,
                  be_argument (AST_Argument::dir_IN,
                               excep_holder, // is also a valuetype
                               sn),
                  -1);

  // Create the new name
  // Append _execp to the name of the operation
  ACE_CString original_op_name (
                  node->name ()->last_component ()->get_string ()
                );
  ACE_CString new_op_name = original_op_name + ACE_CString ("_excep");

  UTL_ScopedName *op_name =
    ACE_static_cast (UTL_ScopedName *, reply_handler->name ()->copy ());

  ACE_NEW_RETURN (id,
                  Identifier (new_op_name.rep ()),
                  -1);

  ACE_NEW_RETURN (sn,
                  UTL_ScopedName (id,
                                  0),
                  -1);

  op_name->nconc (sn);

  // Create the operation.
  be_operation *operation = 0;
  ACE_NEW_RETURN (operation,
                  be_operation (rt,
                                AST_Operation::OP_noflags,
                                op_name,
                                0,
                                0),
                  -1);

  operation->set_name (op_name);
  operation->be_add_argument (arg);

  operation->set_defined_in (reply_handler);

  // We do not copy the exceptions because the exceptions
  // are delivered by the excep methods.

  // After having generated the operation we insert it into the
  // reply handler interface.
  reply_handler->be_add_operation (operation);

  return 0;
}

// Visit the scope and its elements.
int
be_visitor_ami_pre_proc::visit_scope (be_scope *node)
{
  // proceed if the number of members in our scope is greater than 0
  if (node->nmembers () > 0)
    {
      int number_of_elements = 0;

      {
        // initialize an iterator to iterate thru our scope
        for (UTL_ScopeActiveIterator si (node, UTL_Scope::IK_decls);
             !si.is_done ();
             si.next ())
          {
            ++number_of_elements;
          }
      }

      AST_Decl **elements;
      ACE_NEW_RETURN (elements,
                      AST_Decl *[number_of_elements],
                      -1);

      {
        int position = 0;

        // Initialize an iterator to iterate thru our scope.
        for (UTL_ScopeActiveIterator si (node, UTL_Scope::IK_decls);
             !si.is_done ();
             si.next ())
          {
            elements[position++] = si.item ();
          }
      }


      int elem_number = 0;

      // Continue until each element is visited.
      while (elem_number < number_of_elements)
        {
          AST_Decl *d = elements[elem_number];

          if (!d)
            {
              delete [] elements;
              elements = 0;
              ACE_ERROR_RETURN ((LM_ERROR,
                                 "(%N:%l) be_visitor_scope::visit_scope - "
                                 "bad node in this scope\n"),
                                -1);

            }

          be_decl *bd = be_decl::narrow_from_decl (d);

          // Set the scope node as "node" in which the code is being
          // generated so that elements in the node's scope can use it
          // for code generation.
          this->ctx_->scope (node->decl ());

          // Set the node to be visited.
          this->ctx_->node (bd);
          ++elem_number;


          // Send the visitor.
          if (bd == 0 ||  bd->accept (this) == -1)
            {
              delete [] elements;
              elements = 0;
              ACE_ERROR_RETURN ((LM_ERROR,
                                 "(%N:%l) be_visitor_scope::visit_scope - "
                                 "codegen for scope failed\n"),
                                -1);
            }
        } // end of while loop

      delete [] elements;
      elements = 0;
    } // end of if

  return 0;
}

// Helper methods

int
be_visitor_ami_pre_proc::generate_name (ACE_CString &destination,
                                        const char *prefix,
                                        const char *middle_name,
                                        const char *suffix)
{
  destination = prefix;
  destination += middle_name;
  destination += suffix;
  return 0;
}

be_operation *
be_visitor_ami_pre_proc::generate_get_operation (be_attribute *node)
{
  ACE_CString original_op_name (
                  node->name ()->last_component ()->get_string ()
                );
  ACE_CString new_op_name = ACE_CString ("get_") + original_op_name;

  UTL_ScopedName *get_name = ACE_static_cast (UTL_ScopedName *,
                                              node->name ()->copy ());
  get_name->last_component ()->replace_string (new_op_name.rep ());

  be_operation *operation = 0;
  ACE_NEW_RETURN (operation,
                  be_operation (node->field_type (),
                                AST_Operation::OP_noflags,
                                get_name,
                                0,
                                0),
                  0);

  operation->set_name (get_name);
  operation->set_defined_in (node->defined_in ());

  return operation;
}

be_operation *
be_visitor_ami_pre_proc::generate_set_operation (be_attribute *node)
{
  ACE_CString original_op_name (
                  node->name ()->last_component ()->get_string ()
                );
  ACE_CString new_op_name = ACE_CString ("set_") + original_op_name;

  UTL_ScopedName *set_name = ACE_static_cast (UTL_ScopedName *,
                                              node->name ()-> copy ());
  set_name->last_component ()->replace_string (new_op_name.rep ());

  // The return type  is "void".
  Identifier *id = 0;
  UTL_ScopedName *sn = 0;

  ACE_NEW_RETURN (id,
                  Identifier ("void"),
                  0);

  ACE_NEW_RETURN (sn,
                  UTL_ScopedName (id,
                                  0),
                  0);

  be_predefined_type *rt = 0;
  ACE_NEW_RETURN (rt,
                  be_predefined_type (AST_PredefinedType::PT_void,
                                      sn),
                  0);

  // Argument type is the same as the attribute type.
  be_argument *arg = 0;
  ACE_NEW_RETURN (arg,
                  be_argument (AST_Argument::dir_IN,
                               node->field_type (),
                               set_name),
                  0);

  arg->set_name (node->name ());

  // Create the operation.
  be_operation *operation = 0;
  ACE_NEW_RETURN (operation,
                  be_operation (rt,
                                AST_Operation::OP_noflags,
                                set_name,
                                0,
                                0),
                  0);

  operation->set_name (set_name);
  operation->set_defined_in (node->defined_in ());
  operation->be_add_argument (arg);

  return operation;
}

be_visitor_ami_pre_proc::AST_Interface_ptr *
be_visitor_ami_pre_proc::create_inheritance_list (be_interface *node,
                                                  long &n_rh_parents)
{
  AST_Interface_ptr *retval = 0;

  long n_parents = node->n_inherits ();
  AST_Interface **parents = node->inherits ();
  AST_Interface *parent = 0;
  UTL_ScopedName *sn = 0;
  Identifier *id = 0;

  for (long i = 0; i < n_parents; ++i)
    {
      parent = parents[i];

      if (parent->is_abstract ())
        {
          continue;
        }

      ++n_rh_parents;
    }

  if (n_rh_parents == 0)
    {
      // Create a virtual module named "Messaging" and an interface "ReplyHandler"
      // from which we inherit.
      ACE_NEW_RETURN (id,
                      Identifier ("Messaging"),
                      0);

      UTL_ScopedName *inherit_name = 0;
      ACE_NEW_RETURN (inherit_name,
                      UTL_ScopedName (id,
                                      0),
                      0);

      ACE_NEW_RETURN (id,
                      Identifier ("ReplyHandler"),
                      0);

      ACE_NEW_RETURN (sn,
                      UTL_ScopedName (id,
                                      0),
                      0);

      inherit_name->nconc (sn);

      be_interface *inherit_intf = 0;
      ACE_NEW_RETURN (inherit_intf,
                      be_interface (inherit_name,
                                    0,  // inherited interfaces
                                    0,  // number of inherited interfaces
                                    0,  // ancestors
                                    0,  // number of ancestors
                                    0,  // not local
                                    0), // not abstract
                      0);

      inherit_intf->set_name (inherit_name);

      ACE_NEW_RETURN (id,
                      Identifier ("Messaging"),
                      0);

      ACE_NEW_RETURN (sn,
                      UTL_ScopedName (id,
                                      0),
                      0);

      be_module *msg = 0;
      ACE_NEW_RETURN (msg,
                      be_module (sn),
                      0);

      // Notice the interface "ReplyHandler" that it is defined in the
      // "Messaging" module.
      inherit_intf->set_defined_in (msg);

      ACE_NEW_RETURN (retval,
                      AST_Interface_ptr[1],
                      0);

      retval[0] = inherit_intf;
      n_rh_parents = 1;
    }
  else
    {
      ACE_NEW_RETURN (retval,
                      AST_Interface_ptr[n_rh_parents],
                      0);

      ACE_CString prefix ("AMI_");
      ACE_CString suffix ("Handler");
      long index = 0;

      for (long j = 0; j < n_parents; ++j)
        {
          parent = parents[j];

          if (parent->is_abstract ())
            {
              continue;
            }

          ACE_CString rh_local_name = 
            prefix + parent->local_name ()->get_string () + suffix;

          UTL_ScopedName *rh_parent_name = 
            ACE_static_cast (UTL_ScopedName *, parent->name ()->copy ());

          rh_parent_name->last_component ()->replace_string (
                                                 rh_local_name.fast_rep ()
                                               );

          AST_Decl *d = 
            node->defined_in ()->lookup_by_name (rh_parent_name,
                                                 1);

          if (d != 0)
            {
              retval[index++] = AST_Interface::narrow_from_decl (d);
            }

          rh_parent_name->destroy ();
        }

      // Just a sanity check until we're sure this works in all use cases.
      if (n_rh_parents != index)
        {
          ACE_ERROR_RETURN ((LM_ERROR,
                             "reply handler parent iteration mismatch\n"),
                            0);
        }
    }

  return retval;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?