// $Id: reopened_modules.idl 91816 2010-09-17 08:35:56Z johnnyw $

// ============================================================================
//
// = LIBRARY
//    TAO/tests/IDL_Test
//
// = FILENAME
//    reopened_modules.idl
//
// = DESCRIPTION
//    This file contains examples of IDL code that has
//    caused problems in the past for the TAO IDL
//    compiler. This test is to make sure the problems
//    stay fixed.
//
// = AUTHORS
//    Jeff Parsons <parsons@cs.wustl.edu> and TAO users.
//
// ============================================================================

// These examples test the lookup abilities of the
// TAO IDL compiler, with reopened modules.

// Tests lookup function when modules are reopened by
// a chain of inclusions.
#include "reopen_include2.idl"

module AA
{
  module BB
  {
    interface x1 {};
  };
};

module AA
{
  module BB
  {
    module CC
    {
      interface x2
      {
        // 'AA::BB::' should be implicit
        void op1 (in x1 obj);
        // 'AA::' should be implicit
        void op2 (in BB::x1 obj);
        // Just for reference
        void op3 (in AA::BB::x1 obj);
      };
    };
  };
};

// Each occurrence of Party and Person should be
// recognized as being in the same scope as the
// previous occurrence(s).

module dot
{
  interface Party;

  interface Person
    {
      attribute Party someParty;
    };
};

module dot
{
  interface Party
    {
      attribute Person somePerson;
    };
};

// Should be no problem in lookup of all the
// arguments in Operation.

module Outside
{
  module Reopened
    {
      typedef short Tricky;
    };

  typedef long Tricky;

  module Reopened
    {
      typedef float Newdef;
    };
};

interface OpHolder
  {
    void  Operation (in ::Outside::Tricky p1,
                     out ::Outside::Reopened::Tricky p2,
                     inout ::Outside::Reopened::Newdef p3);
  };

// This particular combination used to cause IDL compiler
// to go into an infinite loop looking for return type to
// getInfo(). Partial solution got rid of infinite loop,
// but erroneously returned ::com from lookup.

module com
{
  module mr
    {
      typedef short info;
    };
};

module com
{
  interface IFace
    {
      com::mr::info getInfo ();
    };
};

// Modules X and Y are also included from reopene_include2.idl.
// There were problems with the lookup of Y::Z and X::Ex.

module Y
{
   interface Z {};
};

module X
{
   exception Ex {};

   interface BI : Y::Z
   {
     void method () raises (X::Ex);
   };
};

// Reopened from reopen_include2.idl inclusion. There
// was a problem with the inheritance lookup.

module XX
{
  interface blah_intfc;

  interface blah_intfc
  {
    void op1 ();
  };

  interface blah0 : blah_intfc
  {
    void op0 ();
  };
};

// Had lookup problems with the operation args and
// return type.

module frag
{
  interface frag_iface {};
};

module frag
{
  typedef long ret_long;
};

interface gather
{
  frag::ret_long op (in frag::dub_seq inarg,
                     inout frag::pug inoutarg,
                     out frag::frag_iface outarg);
};

// Had problems with second opening of module using
// types declared between the openings.

module foo
{
  typedef long longdef;
};

typedef long longdef2;

struct bar {short s;};

module foo
{
  struct foo_struct
  {
    longdef longval;
    longdef2 longval2;
  };

  interface obj
  {
    void op (in bar inarg);
  };
};

module A
{
  module B
  {
    typedef sequence<X2> X2Seq;

    interface X3 : X1, X2
    {
      X2Seq getSeqOfX2 ();
      string getX3 ();
    };
  };
};

// Interface B was not getting redefined, so
// definition of C would cause an error.

module mB
{
  interface B;
};

module mA
{
  interface A
  {
    attribute ::mB::B theB;
  };
};

module mB
{
  interface B : ::mA::A
  {
    attribute ::mA::A theA;
  };
};

module mC
{
  interface C : ::mB::B
  {
  };
};

// The example below uncovered errors in the logic of
// AST_Module::fe_add_interface_fwd() and
// AST_Module::add_to_previous() that were causing
// AST_Module::look_in_previous() (and thus lookup_by_name)
// to fail on the last line.
module Schmoik
{
  interface foo
  {
    typedef string foo_type;
  };
};

module Schmoik
{
  interface foo;
};

module Schmoik
{
  struct bar
  {
    foo::foo_type member;
  };
};

// Tests forward declared interface as element type.
// Had to override visit_interface_fwd()
// for the be_visitor_sequence_base_template_args
// visitor to fix this. Also had to separate calls
// to nested_type_name() into individual insertions
// into the code generating stream, because of side
// effects.
module Thwoik
{
  interface TestType;
};

module Thwoik
{
  typedef sequence<TestType> ub_TestTypeSeq;
  typedef sequence<TestType, 3> bd_TestTypeSeq;
};

module Thwoik
{
  interface TestType {};
};

// We had a problem with the inheritance list
// in the declaration of A_mod::B_mod::Foo, in
// both stub and skeleton files.
module A_mod
{
  interface Foo {};

  module B_mod
  {
    interface Foo : A_mod::Foo {};
  };
};

/// Similar to example at the top of this file,
/// but with more openings and deeper nesting.
module m1
{
  module m2
  {
    module m3a
    {
      module m4a
      {
        const unsigned short FRED = 123;
      };
    };
  };
};

module m1
{
  module m2
  {
    module m3a
    {
      module m4b
      {
        const unsigned short JIM = 240;
      };
    };
  };
};

module m1
{
  module m2
  {
    module m3b
    {
      typedef string < ::m1::m2::m3a::m4b::JIM> StringJIM;
      typedef string <m1::m2::m3a::m4b::JIM> StringJIM_0;
      typedef string <m2::m3a::m4b::JIM> StringJIM_1;
      typedef string <m3a::m4b::JIM> StringJIM_2;
    };
  };
};
