📄 ifr_adding_visitor.cpp
字号:
/* -*- c++ -*- */
// ifr_adding_visitor.cpp,v 1.44 2003/12/12 17:39:32 parsons Exp
#include "ast_argument.h"
#include "ast_array.h"
#include "ast_attribute.h"
#include "ast_component.h"
#include "ast_component_fwd.h"
#include "ast_constant.h"
#include "ast_enum.h"
#include "ast_eventtype.h"
#include "ast_eventtype_fwd.h"
#include "ast_exception.h"
#include "ast_expression.h"
#include "ast_factory.h"
#include "ast_field.h"
#include "ast_home.h"
#include "ast_interface.h"
#include "ast_interface_fwd.h"
#include "ast_module.h"
#include "ast_native.h"
#include "ast_operation.h"
#include "ast_predefined_type.h"
#include "ast_root.h"
#include "ast_sequence.h"
#include "ast_string.h"
#include "ast_structure.h"
#include "ast_union.h"
#include "ast_valuetype.h"
#include "ast_valuetype_fwd.h"
#include "utl_identifier.h"
#include "utl_string.h"
#include "utl_exceptlist.h"
#include "nr_extern.h"
#include "ifr_adding_visitor.h"
#include "ifr_adding_visitor_operation.h"
#include "ifr_adding_visitor_structure.h"
#include "ifr_adding_visitor_exception.h"
#include "ifr_adding_visitor_union.h"
#include "tao/IFR_Client/IFR_ComponentsC.h"
#include "ace/Vector_T.h"
ACE_RCSID (IFR_Service,
ifr_adding_visitor,
"ifr_adding_visitor.cpp,v 1.44 2003/12/12 17:39:32 parsons Exp")
ifr_adding_visitor::ifr_adding_visitor (AST_Decl *scope,
CORBA::Boolean in_reopened)
: scope_ (scope),
in_reopened_ (in_reopened)
{
}
ifr_adding_visitor::~ifr_adding_visitor (void)
{
}
int
ifr_adding_visitor::visit_scope (UTL_Scope *node)
{
// Proceed if the number of members in our scope is greater than 0.
if (node->nmembers () > 0)
{
// Initialize an iterator to iterate over our scope.
UTL_ScopeActiveIterator si (node,
UTL_Scope::IK_decls);
AST_Decl *d = 0;
// Continue until each element is visited.
while (!si.is_done ())
{
d = si.item ();
if (d == 0)
{
ACE_ERROR_RETURN ((
LM_ERROR,
ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_scope -")
ACE_TEXT (" bad node in this scope\n")
),
-1
);
}
// These are created at startup in the repository, and
// need not be dealt with here.
if (d->node_type () == AST_Decl::NT_pre_defined)
{
si.next ();
continue;
}
if (d->ast_accept (this) == -1)
{
ACE_ERROR_RETURN ((
LM_ERROR,
ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_scope -")
ACE_TEXT (" failed to accept visitor\n")
),
-1
);
}
si.next ();
}
}
return 0;
}
int
ifr_adding_visitor::visit_predefined_type (AST_PredefinedType *node)
{
ACE_TRY_NEW_ENV
{
this->ir_current_ =
be_global->repository ()->get_primitive (
this->predefined_type_to_pkind (node)
ACE_ENV_ARG_PARAMETER
);
ACE_TRY_CHECK;
}
ACE_CATCHANY
{
ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
ACE_TEXT ("visit_predefined_type"));
return -1;
}
ACE_ENDTRY;
return 0;
}
int
ifr_adding_visitor::visit_module (AST_Module *node)
{
if (node->imported () && !be_global->do_included_files ())
{
return 0;
}
CORBA::Container_var new_def;
ACE_DECLARE_NEW_CORBA_ENV;
ACE_TRY
{
// If this module been opened before, it will already be in
// the repository.
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 ()))
{
// New module.
CORBA::Container_ptr container =
CORBA::Container::_nil ();
if (be_global->ifr_scopes ().top (container) == 0)
{
new_def = container->create_module (
node->repoID (),
node->local_name ()->get_string (),
node->version ()
ACE_ENV_ARG_PARAMETER
);
ACE_TRY_CHECK;
}
else
{
ACE_ERROR_RETURN ((
LM_ERROR,
ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_module -")
ACE_TEXT (" scope stack is empty\n")
),
-1
);
}
}
else
{
CORBA::DefinitionKind kind =
prev_def->def_kind (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_TRY_CHECK;
// If the line below is true, we are clobbering a previous
// entry from another IDL file. In that
// case we do what other ORB vendors do, and destroy the
// original entry, create the new one, and let the user beware.
if (kind != CORBA::dk_Module)
{
prev_def->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_TRY_CHECK;
// This call will take the brach where prev_def.in() is 0.
return this->visit_module (node);
}
else
{
// We are either in a reopened module, are processing an IDL
// IDL file for the second time, or are in a module whose
// name already exists by coincidence - there is no way to
// tell the difference. So any members whose repository ID
// already exists in this case will be skipped.
this->in_reopened_ = 1;
new_def =
CORBA::ComponentIR::Container::_narrow (prev_def.in ()
ACE_ENV_ARG_PARAMETER);
ACE_TRY_CHECK;
}
}
if (be_global->ifr_scopes ().push (new_def.in ()) != 0)
{
ACE_ERROR_RETURN ((
LM_ERROR,
ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_module -")
ACE_TEXT (" scope push failed\n")
),
-1
);
}
if (this->visit_scope (node) == -1)
{
ACE_ERROR_RETURN ((
LM_ERROR,
ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_module -")
ACE_TEXT (" visit_scope failed\n")
),
-1
);
}
this->in_reopened_ = 0;
CORBA::Container_ptr tmp =
CORBA::Container::_nil ();
if (be_global->ifr_scopes ().pop (tmp) != 0)
{
ACE_ERROR_RETURN ((
LM_ERROR,
ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_module -")
ACE_TEXT (" scope pop failed\n")
),
-1
);
}
}
ACE_CATCHANY
{
ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
ACE_TEXT ("visit_module"));
return -1;
}
ACE_ENDTRY;
return 0;
}
int
ifr_adding_visitor::visit_interface (AST_Interface *node)
{
if (node->imported () && !be_global->do_included_files ())
{
return 0;
}
ACE_DECLARE_NEW_CORBA_ENV;
ACE_TRY
{
// Is this interface already in the respository?
CORBA::Contained_var prev_def =
be_global->repository ()->lookup_id (node->repoID ()
ACE_ENV_ARG_PARAMETER);
ACE_TRY_CHECK;
// If not, create a new entry.
if (CORBA::is_nil (prev_def.in ()))
{
int status = this->create_interface_def (node
ACE_ENV_ARG_PARAMETER);
ACE_TRY_CHECK;
return status;
}
else
{
// There is already an entry in the repository. If the interface is
// defined and has not already been populated, we do so
// now. If it is not yet defined or the full definition has already
// been added to the repository, we just update the current IR object
// holder.
if (node->is_defined ()
&& node->ifr_added () == 0
&& this->in_reopened_ == 0)
{
// If we are here and the line below is true, then either
// 1. We are defining an undefined forward declared interface
// from a previously processed IDL file, or
// 2. We are clobbering a previous definition, either of an
// interface or of some other type.
// 3. We are inside a module that has a previous entry.
// If prev_def would narrow successfully to an InterfaceDef, we
// have NO WAY of knowing if we are defining or clobbering. So
// we destroy the contents of the previous entry (we don't want
// to destroy the entry itself, since it may have already been
// made a member of some other entry, and destroying it would
// make the containing entry's section key invalid) and repopulate.
// On the other hand, if prev_def is NOT an interface, we can
// safely destroy it, since we know we are not redefining a
// previous entry, forward declared or not.
// If we are inside a module that was seen before, we could be
// just processing an IDL file a second time, in which case we
// again just update ir_current_.
if (node->ifr_fwd_added () == 0)
{
CORBA::DefinitionKind kind =
prev_def->def_kind (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_TRY_CHECK;
if (kind == CORBA::dk_Interface)
{
CORBA::InterfaceDef_var iface =
CORBA::InterfaceDef::_narrow (prev_def.in ()
ACE_ENV_ARG_PARAMETER);
ACE_TRY_CHECK;
CORBA::ContainedSeq_var contents =
iface->contents (CORBA::dk_all,
1
ACE_ENV_ARG_PARAMETER);
ACE_TRY_CHECK;
CORBA::ULong length = contents->length ();
for (CORBA::ULong i = 0; i < length; ++i)
{
contents[i]->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_TRY_CHECK;
}
}
else
{
prev_def->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_TRY_CHECK;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -