be_visitor_amh_pre_proc.cpp

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

CPP
937
字号
    }

  // Set the proper strategy
  be_operation_amh_strategy *strategy = 0;
  ACE_NEW_RETURN (strategy,
                  be_operation_amh_strategy (node),
                  -1);

  be_operation_strategy *old_strategy = node->set_strategy (strategy);

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

  return 0;
}

int
be_visitor_amh_pre_proc::visit_attribute (be_attribute *node)
{
  // Temporarily generate the set operation.
  be_operation *set_operation = this->generate_set_operation (node);

  this->visit_operation (set_operation);

  // Retrieve the strategy set by the visit operation.
  be_operation_default_strategy *default_strategy = 0;
  ACE_NEW_RETURN (default_strategy,
                  be_operation_default_strategy (set_operation),
                  -1);

  be_operation_strategy *set_operation_strategy =
    set_operation->set_strategy (default_strategy);

  // Assign it to the attribute as set_operation strategy.
  if (set_operation_strategy)
    {
      be_operation_strategy *sos =
        node->set_set_strategy (set_operation_strategy);
      delete sos;
      sos = 0;
    }

  // Temporerily generate the get operation.
  be_operation *get_operation = this->generate_get_operation (node);

  this->visit_operation (get_operation);

  ACE_NEW_RETURN (default_strategy,
                  be_operation_default_strategy (get_operation),
                  -1);

  be_operation_strategy *get_operation_strategy =
    get_operation->set_strategy (default_strategy);

  if (get_operation_strategy)
    {
      be_operation_strategy *gos =
        node->set_get_strategy (get_operation_strategy);
      delete gos;
      gos = 0;
    }


  return 0;
}

int
be_visitor_amh_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;
              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;
              ACE_ERROR_RETURN ((LM_ERROR,
                                 "(%N:%l) be_visitor_scope::visit_scope - "
                                 "codegen for scope failed\n"),
                                -1);

            }
        } // end of while loop

      delete [] elements;
    } // end of if

  return 0;
}

be_valuetype *
be_visitor_amh_pre_proc::create_exception_holder (be_interface *node)
{
  // AMH exception holders require both of these.
  ACE_SET_BITS (idl_global->decls_seen_info_,
                idl_global->decls_seen_masks.valuetype_seen_);

  ACE_SET_BITS (idl_global->decls_seen_info_,
                idl_global->decls_seen_masks.valuefactory_seen_);

  const int inherit_count = 0;
  AST_Interface **p_intf = 0;

  UTL_ScopedName *excep_holder_name =
    node->compute_name ("AMH_", 
                        "ExceptionHolder");

  be_valuetype *excep_holder = 0;
  ACE_NEW_RETURN (excep_holder,
                  be_valuetype (excep_holder_name,
                                p_intf,
                                inherit_count,
                                0,
                                0,
                                0,
                                0,
                                0,
                                0,
                                0,
                                0,
                                0),
                  0);

  excep_holder->set_name (excep_holder_name);
  excep_holder->set_defined_in (node->defined_in ());
  excep_holder->gen_fwd_helper_name ();

  // Now our customized valuetype is created, we have to
  // add now the operations and attributes to the scope.

  // initialize an iterator to iterate thru our scope
  for (UTL_ScopeActiveIterator si (node, UTL_Scope::IK_decls);
       !si.is_done ();
       si.next ())
    {
      AST_Decl *d = si.item ();

      if (d == 0)
        {
          ACE_ERROR_RETURN ((LM_ERROR,
                             "(%N:%l) be_visitor_amh_pre_proc::"
                             "visit_interface - "
                             "bad node in this scope\n"),
                            0);
        }

      be_decl *op = be_decl::narrow_from_decl (d);
      AST_Decl::NodeType nt = d->node_type ();

      if (nt == AST_Decl::NT_attr)
        {
          AST_Attribute *attribute = AST_Attribute::narrow_from_decl (d);

          if (attribute == 0)
            {
              return 0;
            }

          this->create_raise_operation (op,
                                        excep_holder,
                                        GET_OPERATION);

          if (!attribute->readonly ())
            {
              this->create_raise_operation (op,
                                            excep_holder,
                                            SET_OPERATION);
            }
        }
      else if (nt == AST_Decl::NT_op)
        {
          this->create_raise_operation (op,
                                        excep_holder,
                                        NORMAL);
        }
      else
        {
          continue;
        }
    }

  return excep_holder;
}

int
be_visitor_amh_pre_proc::create_raise_operation (
    be_decl *node,
    be_valuetype *excep_holder,
    Operation_Kind operation_kind
  )
{
  Identifier *id = 0;
  UTL_ScopedName *sn = 0;
  be_operation *orig_op = 0;

  if (operation_kind == NORMAL)
    {
      orig_op = be_operation::narrow_from_decl (node);

      if (orig_op)
        {
          // @@ Mayur, we do want to generate code for oneways!  This is
          // needed to support reliable oneways with the SYNC_WITH_TARGET
          // policy, the user can raise system exceptions here.
          if (orig_op->flags () == AST_Operation::OP_oneway)
            {
              // We do nothing for oneways!
              return 0;
            }
        }
    }
  
  // Create the return type, which is "void"

  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);

  // Name the operation properly
  UTL_ScopedName *op_name = ACE_static_cast (UTL_ScopedName *,
                                             excep_holder->name ()->copy ());

  ACE_CString new_local_name ("raise_");

  if (operation_kind == SET_OPERATION)
    {
      new_local_name += "set_";
    }
  else if (operation_kind == GET_OPERATION)
    {
      new_local_name += "get_";
    }

  new_local_name += node->name ()->last_component ()->get_string ();

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

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

  op_name->nconc (sn);

  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->set_defined_in (excep_holder);

  if (operation_kind == NORMAL)
    {
      if (orig_op)
        {
          // Copy the exceptions.
          if (orig_op->exceptions ())
            {
              UTL_ExceptList *exceptions = orig_op->exceptions ();
              operation->be_add_exceptions (exceptions);
            }
        }
    }

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

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

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

  // After having generated the operation we insert it into the
  // exceptionholder valuetype.
  excep_holder->be_add_operation (operation);

  return 0;
}


int
be_visitor_amh_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_amh_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,
                                1,
                                0),
                  0);

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

  return operation;
}

be_operation *
be_visitor_amh_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 ());

  Identifier *id = 0;
  UTL_ScopedName *sn = 0;

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

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

  // The return type  is "void".
  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;
}

⌨️ 快捷键说明

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