summaryrefslogtreecommitdiff
path: root/modules/CIAO/tools/IDL3_to_IDL2/idl3_to_idl2_visitor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/CIAO/tools/IDL3_to_IDL2/idl3_to_idl2_visitor.cpp')
-rw-r--r--modules/CIAO/tools/IDL3_to_IDL2/idl3_to_idl2_visitor.cpp730
1 files changed, 730 insertions, 0 deletions
diff --git a/modules/CIAO/tools/IDL3_to_IDL2/idl3_to_idl2_visitor.cpp b/modules/CIAO/tools/IDL3_to_IDL2/idl3_to_idl2_visitor.cpp
new file mode 100644
index 00000000000..5cafe1e1467
--- /dev/null
+++ b/modules/CIAO/tools/IDL3_to_IDL2/idl3_to_idl2_visitor.cpp
@@ -0,0 +1,730 @@
+/* -*- c++ -*- */
+// $Id$
+
+#include "idl3_to_idl2_visitor.h"
+#include "identifier_helper.h"
+#include "be_sunsoft.h"
+#include "be_extern.h"
+
+#include "ast_component.h"
+#include "ast_component_fwd.h"
+#include "ast_provides.h"
+#include "ast_uses.h"
+#include "ast_publishes.h"
+#include "ast_emits.h"
+#include "ast_consumes.h"
+#include "ast_eventtype.h"
+#include "ast_eventtype_fwd.h"
+#include "ast_home.h"
+#include "ast_finder.h"
+#include "ast_operation.h"
+#include "ast_root.h"
+
+#include "utl_exceptlist.h"
+#include "utl_identifier.h"
+#include "global_extern.h"
+#include "nr_extern.h"
+
+idl3_to_idl2_visitor::idl3_to_idl2_visitor (void)
+ : basic_visitor (),
+ home_ (0)
+{
+}
+
+idl3_to_idl2_visitor::~idl3_to_idl2_visitor (void)
+{
+}
+
+int
+idl3_to_idl2_visitor::visit_module (AST_Module *node)
+{
+ if (node->imported ())
+ {
+ return 0;
+ }
+
+ *os << be_nl << be_nl;
+
+ ACE_CString name =
+ IdentifierHelper::try_escape (node->original_local_name ());
+
+ *os << "module " << name.c_str () << be_nl
+ << "{" << be_idt;
+
+ this->check_id_and_version (node);
+ this->check_prefix (node);
+
+ if (this->visit_scope (node) != 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "idl3_to_idl2_visitor::visit_module - "
+ "codegen for scope failed\n"),
+ -1);
+ }
+
+ *os << be_uidt_nl
+ << "}; // end of module " << name.c_str ();
+
+ return 0;
+}
+
+int
+idl3_to_idl2_visitor::visit_interface (AST_Interface *node)
+{
+ if (node->imported ())
+ {
+ return 0;
+ }
+
+ *os << be_nl << be_nl;
+
+ if (node->is_local ())
+ {
+ *os << "local ";
+ }
+
+ if (node->is_abstract ())
+ {
+ *os << "abstract ";
+ }
+
+ *os << "interface "
+ << IdentifierHelper::try_escape (node->original_local_name ()).c_str ();
+
+ AST_Type **parents = node->inherits ();
+
+ for (long i = 0; i < node->n_inherits (); ++i)
+ {
+ if (i == 0)
+ {
+ *os << " : ";
+ }
+ else
+ {
+ *os << ", ";
+ }
+
+ *os << IdentifierHelper::orig_sn (parents[i]->name ()).c_str ();
+ }
+
+ *os << be_nl
+ << "{" << be_idt;
+
+ this->check_id_and_version (node);
+ this->check_prefix (node);
+
+ if (this->visit_scope (node) != 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "idl3_to_idl2_visitor::visit_interface - "
+ "codegen for scope failed\n"),
+ -1);
+ }
+
+ *os << be_uidt_nl
+ << "};";
+
+ return 0;
+}
+
+int
+idl3_to_idl2_visitor::visit_component (AST_Component *node)
+{
+ if (node->imported ())
+ {
+ return 0;
+ }
+
+ *os << be_nl << be_nl
+ << "interface "
+ << IdentifierHelper::try_escape (node->original_local_name ()).c_str ();
+
+ AST_Component *base = node->base_component ();
+ long nsupports = node->n_supports ();
+
+ *os << " : "
+ << (base != 0
+ ? IdentifierHelper::orig_sn (base->name ()).c_str ()
+ : "Components::CCMObject");
+
+ for (long i = 0; i < nsupports; ++i)
+ {
+ *os << ", "
+ << IdentifierHelper::orig_sn (node->supports ()[i]->name ()).c_str ();
+ }
+
+ *os << be_nl
+ << "{" << be_idt;
+
+ this->check_id_and_version (node);
+
+ if (this->visit_scope (node) != 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "idl3_to_idl2_visitor::visit_component - "
+ "codegen for scope failed\n"),
+ -1);
+ }
+
+ *os << be_uidt_nl
+ << "};";
+
+ return 0;
+}
+
+int
+idl3_to_idl2_visitor::visit_component_fwd (AST_ComponentFwd *node)
+{
+ if (node->imported ())
+ {
+ return 0;
+ }
+
+ *os << be_nl << be_nl
+ << "component "
+ << IdentifierHelper::try_escape (node->original_local_name ()).c_str ()
+ << ";";
+
+ return 0;
+}
+
+int
+idl3_to_idl2_visitor::visit_provides (AST_Provides *node)
+{
+ Identifier *orig_id =
+ IdentifierHelper::original_local_name (node->local_name ());
+
+ UTL_ScopedName *n = node->provides_type ()->name ();
+ ACE_CString impl_name =
+ IdentifierHelper::orig_sn (n);
+
+ *os << be_nl << be_nl
+ << impl_name.c_str () << " provide_" << orig_id << " ();";
+
+ orig_id->destroy ();
+ delete orig_id;
+ orig_id = 0;
+
+ return 0;
+}
+
+int
+idl3_to_idl2_visitor::visit_uses (AST_Uses *node)
+{
+ *os << be_nl << be_nl;
+
+ Identifier *orig_id =
+ IdentifierHelper::original_local_name (node->local_name ());
+
+ UTL_ScopedName *n = node->uses_type ()->name ();
+ ACE_CString impl_name =
+ IdentifierHelper::orig_sn (n);
+
+ if (node->is_multiple ())
+ {
+ *os << "struct " << orig_id << "Connection" << be_nl
+ << "{" << be_idt_nl
+ << impl_name.c_str () << " objref;" << be_nl
+ << "Components::Cookie ck;" << be_uidt_nl
+ << "};" << be_nl << be_nl
+ << "typedef sequence<" << orig_id << "Connection> "
+ << orig_id << "Connections;"
+ << be_nl << be_nl
+ << "Components::Cookie connect_" << orig_id << " (in "
+ << impl_name.c_str () << " connection)" << be_idt_nl
+ << "raises (Components::ExceededConnectionLimit, "
+ << "Components::InvalidConnection);" << be_uidt_nl << be_nl
+ << impl_name.c_str () << " disconnect_" << orig_id
+ << " (in Components::Cookie ck)" << be_idt_nl
+ << "raises (Components::InvalidConnection);"
+ << be_uidt_nl << be_nl
+ << orig_id << "Connections get_connections_" << orig_id
+ << " ();";
+ }
+ else
+ {
+ *os << "void connect_" << orig_id << " (in "
+ << impl_name.c_str () << " conxn)" << be_idt_nl
+ << "raises (Components::AlreadyConnected, "
+ << "Components::InvalidConnection);" << be_uidt_nl << be_nl
+ << impl_name.c_str () << " disconnect_" << orig_id
+ << " ()" << be_idt_nl
+ << "raises (Components::NoConnection);" << be_uidt_nl << be_nl
+ << impl_name.c_str () << " get_connection_" << orig_id
+ << " ();";
+ }
+
+ orig_id->destroy ();
+ delete orig_id;
+ orig_id = 0;
+
+ return 0;
+}
+
+int
+idl3_to_idl2_visitor::visit_publishes (AST_Publishes *node)
+{
+ Identifier *orig_id =
+ IdentifierHelper::original_local_name (node->local_name ());
+
+ UTL_ScopedName *n = node->publishes_type ()->name ();
+ ACE_CString impl_name =
+ IdentifierHelper::orig_sn (n, true);
+
+ *os << be_nl << be_nl
+ << "Components::Cookie subscribe_" << orig_id
+ << " (in "
+ << impl_name.c_str () << "Consumer consumer)"
+ << be_idt_nl
+ << "raises (Components::ExceededConnectionLimit);"
+ << be_uidt_nl << be_nl
+ << impl_name.c_str () << "Consumer unsubscribe_" << orig_id
+ << " (in Components::Cookie ck)" << be_idt_nl
+ << "raises (Components::InvalidConnection);" << be_uidt;
+
+ orig_id->destroy ();
+ delete orig_id;
+ orig_id = 0;
+
+ return 0;
+}
+
+int
+idl3_to_idl2_visitor::visit_emits (AST_Emits *node)
+{
+ Identifier *orig_id =
+ IdentifierHelper::original_local_name (node->local_name ());
+
+ UTL_ScopedName *n = node->emits_type ()->name ();
+ ACE_CString impl_name =
+ IdentifierHelper::orig_sn (n, true);
+
+ *os << be_nl << be_nl
+ << "void connect_" << orig_id
+ << " (in "
+ << impl_name.c_str () << "Consumer consumer)" << be_idt_nl
+ << "raises (Components::AlreadyConnected);"
+ << be_uidt_nl << be_nl
+ << impl_name.c_str () << "Consumer disconnect_" << orig_id
+ << " ()" << be_idt_nl
+ << "raises (Components::NoConnection);" << be_uidt;
+
+ orig_id->destroy ();
+ delete orig_id;
+ orig_id = 0;
+
+ return 0;
+}
+
+int
+idl3_to_idl2_visitor::visit_consumes (AST_Consumes *node)
+{
+ Identifier *orig_id =
+ IdentifierHelper::original_local_name (node->local_name ());
+
+ UTL_ScopedName *n = node->consumes_type ()->name ();
+ ACE_CString impl_name =
+ IdentifierHelper::orig_sn (n, true);
+
+ *os << be_nl << be_nl
+ << impl_name.c_str () << "Consumer get_consumer_" << orig_id
+ << " ();";
+
+ orig_id->destroy ();
+ delete orig_id;
+ orig_id = 0;
+
+ return 0;
+}
+
+int
+idl3_to_idl2_visitor::visit_extended_port (AST_Extended_Port *)
+{
+ return 0;
+}
+
+int
+idl3_to_idl2_visitor::visit_mirror_port (AST_Mirror_Port *)
+{
+ return 0;
+}
+
+int
+idl3_to_idl2_visitor::visit_connector (AST_Connector *)
+{
+ return 0;
+}
+
+int
+idl3_to_idl2_visitor::visit_param_holder (AST_Param_Holder *)
+{
+ return 0;
+}
+
+int
+idl3_to_idl2_visitor::visit_eventtype (AST_EventType *node)
+{
+ if (node->imported ())
+ {
+ return 0;
+ }
+
+ if (this->visit_valuetype (node) != 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "idl3_to_idl2_visitor::visit_eventtype - "
+ "codegen for valuetype failed\n"),
+ -1);
+ }
+
+ *os << be_nl << be_nl
+ << "interface " << node->original_local_name () << "Consumer : ";
+
+ AST_Type *parent = 0;
+ AST_Decl::NodeType nt = AST_Decl::NT_native;
+
+ if (node->n_inherits () > 0)
+ {
+ parent = node->inherits ()[0];
+ AST_Type *ut = parent->unaliased_type ();
+ nt = ut->node_type ();
+ }
+
+ if (node->n_inherits () == 0 || nt == AST_Decl::NT_valuetype)
+ {
+ *os << "Components::EventConsumerBase";
+ }
+ else
+ {
+ *os << IdentifierHelper::orig_sn (node->inherits ()[0]->name (), true).c_str ()
+ << "Consumer";
+ }
+
+ *os << be_nl
+ << "{" << be_idt_nl
+ << "void push_" << node->original_local_name () << " (in "
+ << IdentifierHelper::try_escape (node->original_local_name ()).c_str ()
+ << " the_"
+ << node->original_local_name () << ");" << be_uidt_nl
+ << "};";
+
+ return 0;
+}
+
+int
+idl3_to_idl2_visitor::visit_eventtype_fwd (AST_EventTypeFwd *node)
+{
+ if (node->imported ())
+ {
+ return 0;
+ }
+
+ if (this->visit_valuetype_fwd (node) != 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "idl3_to_idl2_visitor::visit_eventtype_fwd - "
+ "codegen for valuetype_fwd failed\n"),
+ -1);
+ }
+
+ *os << be_nl
+ << "interface " << node->original_local_name () << "Consumer;";
+
+ return 0;
+}
+
+int
+idl3_to_idl2_visitor::visit_home (AST_Home *node)
+{
+ if (node->imported ())
+ {
+ return 0;
+ }
+
+ this->home_ = node;
+
+ ACE_CString explicit_name = node->original_local_name ()->get_string ();
+ explicit_name += "Explicit";
+
+ *os << be_nl << be_nl
+ << "interface " << explicit_name.c_str () << " : ";
+
+ AST_Home *base = node->base_home ();
+
+ if (base == 0)
+ {
+ *os << "Components::CCMHome";
+ }
+ else
+ {
+ *os << IdentifierHelper::orig_sn (base->name (), true).c_str ()
+ << "Explicit";
+ }
+
+ *os << be_nl
+ << "{" << be_idt;
+
+ this->check_id_and_version (node);
+
+ // Create a temporary interface node corresponding to the one we
+ // just generated above for the home explicit interface.
+ UTL_ScopedName *sn =
+ this->create_scoped_name (0,
+ explicit_name.c_str (),
+ 0,
+ ScopeAsDecl (node->defined_in ()));
+
+ AST_Interface xplicit (sn,
+ 0,
+ 0,
+ 0,
+ 0,
+ false,
+ false);
+ xplicit.set_defined_in (node->defined_in ());
+
+ // Reset the home's decls to be defined in the explicit home interface.
+ this->tranfer_scope_elements (node, xplicit);
+
+ *os << be_uidt_nl
+ << "};" << be_nl << be_nl;
+
+ xplicit.destroy ();
+ sn->destroy ();
+ delete sn;
+ sn = 0;
+
+ AST_Type *key = node->primary_key ();
+ ACE_CString mng_name =
+ IdentifierHelper::orig_sn (node->managed_component ()->name ());
+ ACE_CString key_name;
+
+ // Generate the implicit home interface and its operations.
+ *os << "interface " << node->original_local_name () << "Implicit"
+ << (key == 0 ? " : Components::KeylessCCMHome" : "") << be_nl
+ << "{" << be_idt_nl
+ << mng_name.c_str () << " create (";
+
+ if (key != 0)
+ {
+ key_name =
+ IdentifierHelper::orig_sn (key->name ());
+
+ *os << "in " << key_name.c_str () << " key";
+ }
+
+ *os << ")" << be_idt_nl
+ << "raises (Components::CreateFailure";
+
+ if (key != 0)
+ {
+ *os << ", Components::InvalidKey, Components::DuplicateKeyValue";
+ }
+
+ *os << ");" << be_uidt;
+
+ if (key != 0)
+ {
+ *os << be_nl << be_nl
+ << mng_name.c_str ()
+ << " find_by_primary_key (in " << key_name.c_str ()
+ << " key)" << be_idt_nl
+ << "raises (Components::InvalidKey, Components::UnknownKeyValue, "
+ << "Components::FinderFailure);" << be_uidt;
+
+ *os << be_nl << be_nl
+ << "void remove (in " << key_name.c_str () << " key)" << be_idt_nl
+ << "raises (Components::InvalidKey, Components::UnknownKeyValue, "
+ << "Components::RemoveFailure);" << be_uidt;
+
+ *os << be_nl << be_nl
+ << key_name.c_str () << " get_primary_key (in "
+ << mng_name.c_str () << " comp);";
+ }
+
+ *os << be_uidt_nl
+ << "};";
+
+ // Create equivalent interface.
+ *os << be_nl << be_nl
+ << "interface "
+ << IdentifierHelper::try_escape (node->original_local_name ()).c_str ()
+ << " : "
+ << node->original_local_name () << "Explicit, "
+ << node->original_local_name () << "Implicit" << be_nl
+ << "{" << be_nl
+ << "};";
+
+ return 0;
+}
+
+int
+idl3_to_idl2_visitor::visit_factory (AST_Factory *node)
+{
+ Identifier *id = node->original_local_name ();
+
+ *os << be_nl << be_nl;
+
+ if (this->home_ == 0)
+ {
+ *os << "factory ";
+ }
+ else
+ {
+ AST_Component *c = this->home_->managed_component ();
+
+ *os << IdentifierHelper::orig_sn (c->name ()).c_str ()
+ << " ";
+ }
+
+ *os << IdentifierHelper::try_escape (id).c_str ()
+ << " (";
+
+ this->gen_params (node, node->argument_count ());
+
+ *os << ")";
+
+ this->gen_exception_list (node->exceptions ());
+
+ *os << ";";
+
+ return 0;
+}
+
+int
+idl3_to_idl2_visitor::visit_finder (AST_Finder *node)
+{
+ return this->visit_factory (node);
+}
+
+int
+idl3_to_idl2_visitor::visit_root (AST_Root *node)
+{
+ int status = be_global->outfile_init (this->os,
+ "",
+ "_IDL2.idl",
+ "_TAO_IDL_",
+ "_IDL_");
+
+ if (status == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("idl3_to_idl2_visitor::visit_root - ")
+ ACE_TEXT ("failed to initialize output file\n")),
+ -1);
+ }
+
+ ACE_CString filename;
+
+ for (size_t i = 0; i < idl_global->n_included_idl_files (); ++i)
+ {
+ if (i == 0)
+ {
+ *os << be_nl;
+ }
+
+ ACE_CString raw_filename = idl_global->included_idl_files ()[i];
+ bool excluded_file_found =
+ this->match_excluded_file (raw_filename.c_str ());
+
+ if (raw_filename.find (".pidl") != ACE_CString::npos
+ || raw_filename == "orb.idl"
+ || raw_filename == "Components.idl"
+ || excluded_file_found)
+ {
+ filename = raw_filename;
+ }
+ else
+ {
+ filename =
+ raw_filename.substr (0, raw_filename.rfind ('.')) + "_IDL2.idl";
+ }
+
+ *os << be_nl
+ << "#include \"" << filename.c_str () << "\"";
+ }
+
+ const char *pfix = node->prefix ();
+
+ if (ACE_OS::strcmp (pfix, "") != 0)
+ {
+ *os << be_nl << be_nl
+ << "#pragma prefix \"" << pfix << "\"";
+ }
+
+ if (this->visit_scope (node) != 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("idl3_to_idl2_visitor::visit_root - ")
+ ACE_TEXT ("codegen for scope failed\n")),
+ -1);
+ }
+
+ *os << be_nl << be_nl
+ << "#endif /* ifndef */" << be_nl << be_nl;
+
+ return 0;
+}
+
+UTL_ScopedName *
+idl3_to_idl2_visitor::create_scoped_name (const char *prefix,
+ const char *local_name,
+ const char *suffix,
+ AST_Decl *parent)
+{
+ ACE_CString local_string (prefix,
+ 0,
+ false);
+ local_string += local_name;
+ local_string += suffix;
+ Identifier *local_id = 0;
+ ACE_NEW_RETURN (local_id,
+ Identifier (local_string.fast_rep ()),
+ 0);
+ UTL_ScopedName *last_segment = 0;
+ ACE_NEW_RETURN (last_segment,
+ UTL_ScopedName (local_id,
+ 0),
+ 0);
+ UTL_ScopedName *full_name =
+ static_cast<UTL_ScopedName *> (parent->name ()->copy ());
+ full_name->nconc (last_segment);
+ return full_name;
+}
+
+void
+idl3_to_idl2_visitor::tranfer_scope_elements (AST_Home *src,
+ AST_Interface &dst)
+{
+ // Transfer the elements of the home's scope to the temporary
+ // explicit home interface.
+ for (UTL_ScopeActiveIterator src_iter (src, UTL_Scope::IK_decls);
+ ! src_iter.is_done ();
+ src_iter.next ())
+ {
+ AST_Decl *d = src_iter.item ();
+ d->set_defined_in (&dst);
+ UTL_ScopedName *new_name =
+ this->create_scoped_name (0,
+ d->local_name ()->get_string (),
+ 0,
+ &dst);
+ d->set_name (new_name);
+ dst.add_to_scope (d);
+ }
+
+ // Visit the transferred scope elements normally to generate the IDL.
+ // This way referenced items will have the interface's name in the
+ // scoped name instead of the home's name.
+ for (UTL_ScopeActiveIterator dst_iter (&dst, UTL_Scope::IK_decls);
+ ! dst_iter.is_done ();
+ dst_iter.next ())
+ {
+ if (dst_iter.item ()->ast_accept (this) != 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "idl3_to_idl2_visitor::tranfer_scope_elements - "
+ "codegen for destination scope failed\n"));
+ }
+ }
+}