summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_operation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/orbsvcs/IFR_Service/ifr_adding_visitor_operation.cpp')
-rw-r--r--TAO/orbsvcs/IFR_Service/ifr_adding_visitor_operation.cpp280
1 files changed, 280 insertions, 0 deletions
diff --git a/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_operation.cpp b/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_operation.cpp
new file mode 100644
index 00000000000..63ff0eaefbf
--- /dev/null
+++ b/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_operation.cpp
@@ -0,0 +1,280 @@
+/* -*- c++ -*- */
+// $Id$
+
+#include "ast_argument.h"
+#include "ast_exception.h"
+#include "ast_expression.h"
+#include "ast_operation.h"
+#include "utl_identifier.h"
+#include "utl_string.h"
+
+#include "ifr_adding_visitor_operation.h"
+#include "utl_exceptlist.h"
+#include "utl_strlist.h"
+#include "nr_extern.h"
+
+ACE_RCSID (IFR_Service,
+ ifr_adding_visitor_operation,
+ "$Id$")
+
+ifr_adding_visitor_operation::ifr_adding_visitor_operation (AST_Decl *scope)
+ : ifr_adding_visitor (scope),
+ index_ (0)
+{
+}
+
+ifr_adding_visitor_operation::~ifr_adding_visitor_operation (void)
+{
+}
+
+int
+ifr_adding_visitor_operation::visit_operation (AST_Operation *node)
+{
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ // If this operation is already in the repository (for example, if
+ // we are processing the IDL file a second time inadvertently), we
+ // just return 0. The IDL file must be legal, otherwise the IDL
+ // compiler front end would have told us.
+
+ CORBA::Contained_var prev_def =
+ be_global->repository ()->lookup_id (node->repoID ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (!CORBA::is_nil (prev_def.in ()))
+ {
+ return 0;
+ }
+
+ // Build the parameter list. Our overridden version of visit_argument
+ // will look up each parameter and add its repository entry to
+ // our params_ member.
+
+ CORBA::ULong length = static_cast<CORBA::ULong> (node->argument_count ());
+
+ this->params_.length (length);
+
+ if (this->visit_scope (node) == -1)
+ {
+ ACE_ERROR_RETURN ((
+ LM_ERROR,
+ ACE_TEXT ("(%N:%l) ifr_adding_visitor_operation::")
+ ACE_TEXT ("visit_operation -")
+ ACE_TEXT (" visit_scope failed\n")
+ ),
+ -1
+ );
+ }
+
+ this->index_ = 0;
+
+ // Build the exception list.
+
+ UTL_ExceptList *excepts = node->exceptions ();
+
+ if (excepts != 0)
+ {
+ length = static_cast<CORBA::ULong> (excepts->length ());
+ }
+ else
+ {
+ length = 0;
+ }
+
+ CORBA::ExceptionDefSeq exceptions (length);
+ exceptions.length (length);
+
+ AST_Exception *ex = 0;
+ CORBA::ULong i = 0;
+
+ for (UTL_ExceptlistActiveIterator ex_iter (excepts);
+ !ex_iter.is_done ();
+ ex_iter.next (), ++i)
+ {
+ ex = ex_iter.item ();
+
+ prev_def =
+ be_global->repository ()->lookup_id (ex->repoID ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ exceptions[i] =
+ CORBA::ExceptionDef::_narrow (prev_def.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+
+ // Build the context list.
+
+ UTL_StrList *ctx_list = node->context ();
+
+ if (ctx_list != 0)
+ {
+ length = static_cast<CORBA::ULong> (ctx_list->length ());
+ }
+ else
+ {
+ length = 0;
+ }
+
+ CORBA::ContextIdSeq contexts (length);
+ contexts.length (length);
+
+ UTL_StrlistActiveIterator ctx_iter (ctx_list);
+ UTL_String *str = 0;
+ i = 0;
+
+ while (!ctx_iter.is_done ())
+ {
+ str = ctx_iter.item ();
+
+ contexts[i++] = str->get_string ();
+
+ ctx_iter.next ();
+ }
+
+ // Get the return type.
+
+ AST_Type *return_type = node->return_type ();
+
+ // Updates ir_current_.
+ this->get_referenced_type (return_type
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Is the operation oneway?
+ CORBA::OperationMode mode = node->flags () == AST_Operation::OP_oneway
+ ? CORBA::OP_ONEWAY
+ : CORBA::OP_NORMAL;
+
+ // Create the repository entry.
+
+ CORBA::Container_ptr current_scope =
+ CORBA::Container::_nil ();
+
+ if (be_global->ifr_scopes ().top (current_scope) == 0)
+ {
+ AST_Decl *op_scope = ScopeAsDecl (node->defined_in ());
+ AST_Decl::NodeType nt = op_scope->node_type ();
+
+ if (nt == AST_Decl::NT_interface)
+ {
+ CORBA::InterfaceDef_var iface =
+ CORBA::InterfaceDef::_narrow (current_scope
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ CORBA::OperationDef_var new_def =
+ iface->create_operation (node->repoID (),
+ node->local_name ()->get_string (),
+ node->version (),
+ this->ir_current_.in (),
+ mode,
+ this->params_,
+ exceptions,
+ contexts
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ else
+ {
+ CORBA::ValueDef_var vtype =
+ CORBA::ValueDef::_narrow (current_scope
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ CORBA::OperationDef_var new_def =
+ vtype->create_operation (node->repoID (),
+ node->local_name ()->get_string (),
+ node->version (),
+ this->ir_current_.in (),
+ mode,
+ this->params_,
+ exceptions,
+ contexts
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ }
+ else
+ {
+ ACE_ERROR_RETURN ((
+ LM_ERROR,
+ ACE_TEXT ("(%N:%l) ifr_adding_visitor_operation::")
+ ACE_TEXT ("visit_operation -")
+ ACE_TEXT (" scope stack is empty\n")
+ ),
+ -1
+ );
+ }
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (
+ ACE_ANY_EXCEPTION,
+ ACE_TEXT ("ifr_adding_visitor_operation::visit_operation")
+ );
+
+ return -1;
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}
+
+int
+ifr_adding_visitor_operation::visit_argument (AST_Argument *node)
+{
+ // Get the parameter's name.
+ this->params_[this->index_].name =
+ CORBA::string_dup (node->local_name ()->get_string ());
+
+ AST_Type *arg_type = node->field_type ();
+
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ // Updates ir_current_.
+ this->get_referenced_type (arg_type
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ this->params_[this->index_].type_def =
+ CORBA::IDLType::_duplicate (this->ir_current_.in ());
+
+
+ switch (node->direction ())
+ {
+ case AST_Argument::dir_IN:
+ this->params_[this->index_].mode = CORBA::PARAM_IN;
+ break;
+ case AST_Argument::dir_OUT:
+ this->params_[this->index_].mode = CORBA::PARAM_OUT;
+ break;
+ case AST_Argument::dir_INOUT:
+ this->params_[this->index_].mode = CORBA::PARAM_INOUT;
+ break;
+ }
+
+ // IfR method create_operation does not use this - it just needs
+ // to be non-zero for marshaling.
+ this->params_[this->index_].type =
+ CORBA::TypeCode::_duplicate (CORBA::_tc_void);
+
+ ++this->index_;
+ }
+ ACE_CATCHANY
+ {
+ ACE_PRINT_EXCEPTION (
+ ACE_ANY_EXCEPTION,
+ ACE_TEXT ("ifr_adding_visitor_operation::visit_argument")
+ );
+
+ return -1;
+ }
+ ACE_ENDTRY;
+
+ return 0;
+}