1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_cli_ure.hxx"
30 
31 #include "climaker_share.h"
32 
33 #include "rtl/string.hxx"
34 #include "rtl/ustrbuf.hxx"
35 #include "com/sun/star/reflection/XIndirectTypeDescription.hpp"
36 #include "com/sun/star/reflection/XStructTypeDescription.hpp"
37 #include "com/sun/star/reflection/XInterfaceTypeDescription2.hpp"
38 #include "com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp"
39 #include "com/sun/star/reflection/XInterfaceAttributeTypeDescription.hpp"
40 #include "com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp"
41 #include <vector>
42 
43 using namespace ::System::Reflection;
44 
45 using namespace ::rtl;
46 using namespace ::com::sun::star;
47 using namespace ::com::sun::star::uno;
48 
49 namespace climaker
50 {
51 System::String* mapUnoPolymorphicName(System::String* unoName);
52 //------------------------------------------------------------------------------
53 static inline ::System::String * to_cts_name(
54     OUString const & uno_name )
55 {
56     OUStringBuffer buf( 7 + uno_name.getLength() );
57     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("unoidl.") );
58     buf.append( uno_name );
59     return ustring_to_String( buf.makeStringAndClear() );
60 }
61 
62 //------------------------------------------------------------------------------
63 static inline ::System::Object * to_cli_constant( Any const & value )
64 {
65     switch (value.getValueTypeClass())
66     {
67     case TypeClass_CHAR:
68         return __box
69             ((::System::Char) *reinterpret_cast< sal_Unicode const * >(
70                 value.getValue() ));
71     case TypeClass_BOOLEAN:
72         return __box
73             ((::System::Boolean)
74              sal_False != *reinterpret_cast< sal_Bool const * >(
75                  value.getValue() ));
76     case TypeClass_BYTE:
77         return __box
78             ((::System::Byte) *reinterpret_cast< sal_Int8 const * >(
79                 value.getValue() ));
80     case TypeClass_SHORT:
81         return __box
82             ((::System::Int16) *reinterpret_cast< sal_Int16 const * >(
83                 value.getValue() ));
84     case TypeClass_UNSIGNED_SHORT:
85         return __box
86             ((::System::UInt16) *reinterpret_cast< sal_uInt16 const * >(
87                 value.getValue() ));
88     case TypeClass_LONG:
89         return __box
90             ((::System::Int32) *reinterpret_cast< sal_Int32 const * >(
91                 value.getValue() ));
92     case TypeClass_UNSIGNED_LONG:
93         return __box
94             ((::System::UInt32) *reinterpret_cast< sal_uInt32 const * >(
95                 value.getValue() ));
96     case TypeClass_HYPER:
97         return __box
98             ((::System::Int64) *reinterpret_cast< sal_Int64 const * >(
99                 value.getValue() ));
100     case TypeClass_UNSIGNED_HYPER:
101         return __box
102             ((::System::UInt64) *reinterpret_cast< sal_uInt64 const * >(
103                 value.getValue() ));
104     case TypeClass_FLOAT:
105         return __box
106             ((::System::Single) *reinterpret_cast< float const * >(
107                 value.getValue() ));
108     case TypeClass_DOUBLE:
109         return __box
110             ((::System::Double) *reinterpret_cast< double const * >(
111                 value.getValue() ));
112     default:
113         throw RuntimeException(
114             OUSTR("unexpected constant type ") +
115             value.getValueType().getTypeName(),
116             Reference< XInterface >() );
117     }
118 }
119 
120 //------------------------------------------------------------------------------
121 static inline void emit_ldarg( Emit::ILGenerator * code, ::System::Int32 index )
122 {
123     switch (index)
124     {
125     case 0:
126         code->Emit( Emit::OpCodes::Ldarg_0 );
127         break;
128     case 1:
129         code->Emit( Emit::OpCodes::Ldarg_1 );
130         break;
131     case 2:
132         code->Emit( Emit::OpCodes::Ldarg_2 );
133         break;
134     case 3:
135         code->Emit( Emit::OpCodes::Ldarg_3 );
136         break;
137     default:
138         if (index < 0x100)
139             code->Emit( Emit::OpCodes::Ldarg_S, (::System::Byte) index );
140         else if (index < 0x8000)
141             code->Emit( Emit::OpCodes::Ldarg_S, (::System::Int16) index );
142         else
143             code->Emit( Emit::OpCodes::Ldarg, index );
144         break;
145     }
146 }
147 
148 void polymorphicStructNameToStructName(::System::String ** sPolyName)
149 {
150     if ((*sPolyName)->EndsWith(S">") == false)
151         return;
152 
153     int index = (*sPolyName)->IndexOf('<');
154     OSL_ASSERT(index != -1);
155     *sPolyName = (*sPolyName)->Substring(0, index);
156 }
157 
158 
159 System::String* mapUnoTypeName(System::String * typeName)
160 {
161 	::System::Text::StringBuilder* buf= new System::Text::StringBuilder();
162 	::System::String * sUnoName = ::System::String::Copy(typeName);
163     //determine if the type is a sequence and its dimensions
164     int dims= 0;
165     if (typeName->StartsWith(S"["))//if (usUnoName[0] == '[')
166     {
167         int index= 1;
168         while (true)
169         {
170             if (typeName->get_Chars(index++) == ']')//if (usUnoName[index++] == ']')
171                 dims++;
172             if (typeName->get_Chars(index++) != '[')//usUnoName[index++] != '[')
173                 break;
174         }
175         sUnoName = sUnoName->Substring(index - 1);//usUnoName = usUnoName.copy(index - 1);
176     }
177 	if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoBool)))
178         buf->Append(const_cast<System::String*>(Constants::sBoolean));
179     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoChar)))
180         buf->Append(const_cast<System::String*>(Constants::sChar));
181     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoByte)))
182         buf->Append(const_cast<System::String*>(Constants::sByte));
183     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoShort)))
184         buf->Append(const_cast<System::String*>(Constants::sInt16));
185     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoUShort)))
186         buf->Append(const_cast<System::String*>(Constants::sUInt16));
187     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoLong)))
188         buf->Append(const_cast<System::String*>(Constants::sInt32));
189     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoULong)))
190         buf->Append(const_cast<System::String*>(Constants::sUInt32));
191     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoHyper)))
192         buf->Append(const_cast<System::String*>(Constants::sInt64));
193     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoUHyper)))
194         buf->Append(const_cast<System::String*>(Constants::sUInt64));
195     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoFloat)))
196         buf->Append(const_cast<System::String*>(Constants::sSingle));
197     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoDouble)))
198         buf->Append(const_cast<System::String*>(Constants::sDouble));
199     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoString)))
200         buf->Append(const_cast<System::String*>(Constants::sString));
201     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoVoid)))
202         buf->Append(const_cast<System::String*>(Constants::sVoid));
203     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoType)))
204         buf->Append(const_cast<System::String*>(Constants::sType));
205     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoXInterface)))
206         buf->Append(const_cast<System::String*>(Constants::sObject));
207     else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoAny)))
208     {
209         buf->Append(const_cast<System::String*>(Constants::sAny));
210     }
211     else
212     {
213         //put "unoidl." at the beginning
214         buf->Append(const_cast<System::String*>(Constants::sUnoidl));
215         buf->Append(mapUnoPolymorphicName(sUnoName));
216     }
217     // apend []
218     for (;dims--;)
219         buf->Append(const_cast<System::String*>(Constants::sBrackets));
220 
221     return buf->ToString();
222 }
223 
224 
225 /** For example, there is a uno type
226     com.sun.star.Foo<char, long>.
227     The values in the type list
228     are uno types and are replaced by cli types, such as System.Char,
229     System.Int32, etc.
230 
231 	Strings can be as complicated as this
232 	test.MyStruct<char,test.MyStruct<long, []string>>
233  */
234 System::String* mapUnoPolymorphicName(System::String* unoName)
235 {
236     int index = unoName->IndexOf('<');
237     if (index == -1)
238         return unoName;
239 
240     System::Text::StringBuilder * builder =
241         new System::Text::StringBuilder(unoName->Substring(0, index +1 ));
242 
243 	//Find the first occurrence of ','
244 	//If the parameter is a polymorphic struct then we neede to ignore everything
245 	//between the brackets because it can also contain commas
246     //get the type list within < and >
247 	int endIndex = unoName->Length - 1;
248 	index++;
249 	int cur = index;
250 	int countParams = 0;
251 	while (cur <= endIndex)
252 	{
253 		System::Char c = unoName->Chars[cur];
254 		if (c == ',' || c == '>')
255 		{
256 			//insert a comma if needed
257 			if (countParams != 0)
258 				builder->Append(S",");
259 			countParams++;
260 			System::String * sParam = unoName->Substring(index, cur - index);
261 			//skip the comma
262 			cur++;
263 			//the the index to the beginning of the next param
264 			index = cur;
265 			builder->Append(mapUnoTypeName(sParam));
266 		}
267 		else if (c == '<')
268 		{
269 			cur++;
270 			//continue until the matching '>'
271 			int numNested = 0;
272 			for (;;cur++)
273 			{
274 				System::Char curChar = unoName->Chars[cur];
275 				if (curChar == '<')
276 				{
277 					numNested ++;
278 				}
279 				else if (curChar == '>')
280 				{
281 					if (numNested > 0)
282 						numNested--;
283 					else
284 						break;
285 				}
286 			}
287 		}
288 		cur++;
289 	}
290 
291     builder->Append((System::Char) '>');
292     return builder->ToString();
293 }
294 
295 
296 
297 //______________________________________________________________________________
298 Assembly * TypeEmitter::type_resolve(
299     ::System::Object *, ::System::ResolveEventArgs * args )
300 {
301     ::System::String * cts_name = args->get_Name();
302     ::System::Type * ret_type = m_module_builder->GetType(
303         cts_name, false /* no exc */ );
304     if (0 == ret_type)
305     {
306         iface_entry * entry = dynamic_cast< iface_entry * >(
307             m_incomplete_ifaces->get_Item( cts_name ) );
308         if (0 != entry)
309             ret_type = entry->m_type_builder;
310     }
311     if (0 == ret_type)
312     {
313         sal_Int32 len = m_extra_assemblies->get_Length();
314         for ( sal_Int32 pos = 0; pos < len; ++pos )
315         {
316             ret_type = m_extra_assemblies[ pos ]->GetType(
317                 cts_name, false /* no exc */ );
318             if (0 != ret_type)
319             {
320                 if (g_verbose)
321                 {
322                     ::System::Console::WriteLine(
323                         "> resolving type {0} from {1}.",
324                         cts_name, ret_type->get_Assembly()->get_FullName() );
325                 }
326                 break;
327             }
328         }
329     }
330     if (0 != ret_type)
331         return ret_type->get_Assembly();
332     return 0;
333 }
334 
335 //______________________________________________________________________________
336 ::System::Type * TypeEmitter::get_type(
337     ::System::String * cts_name, bool throw_exc )
338 {
339     ::System::Type * ret_type = m_module_builder->GetType( cts_name, false );
340     //We get the type from the ModuleBuilder even if the type is not complete
341     //but have been defined.
342     //if (ret_type == 0)
343     //{
344     //    iface_entry * entry = dynamic_cast< iface_entry * >(
345     //        m_incomplete_ifaces->get_Item( cts_name ) );
346     //    if (0 != entry)
347     //        ret_type = entry->m_type_builder;
348     //}
349         //try the cli_basetypes assembly
350     if (ret_type == 0)
351     {
352         ::System::Text::StringBuilder * builder = new ::System::Text::StringBuilder(cts_name);
353         builder->Append(S",cli_basetypes");
354         ret_type = ::System::Type::GetType(builder->ToString());
355     }
356 
357     if (ret_type == 0)
358     {
359 		try
360 		{
361 			// may call on type_resolve()
362 			return ::System::Type::GetType( cts_name, throw_exc );
363 		}
364 		catch (::System::Exception* exc)
365 		{
366 			//If the type is not found one may have forgotten to specify assemblies with
367 			//additional types
368 			::System::Text::StringBuilder * sb = new ::System::Text::StringBuilder();
369 			sb->Append(new ::System::String(S"\nThe type "));
370 			sb->Append(cts_name);
371 			sb->Append(new ::System::String(S" \n could not be found. Did you forget to " \
372 				S"specify an additional assembly with the --reference option?\n"));
373 			if (throw_exc)
374 				throw new ::System::Exception(sb->ToString(), exc);
375 		}
376     }
377     else
378     {
379         return ret_type;
380     }
381 }
382 
383 //______________________________________________________________________________
384 ::System::Type * TypeEmitter::get_type_Exception()
385 {
386     if (0 == m_type_Exception)
387     {
388         m_type_Exception = get_type(
389             S"unoidl.com.sun.star.uno.Exception", false /* no exc */ );
390         if (0 == m_type_Exception)
391         {
392             // define hardcoded type unoidl.com.sun.star.uno.Exception
393             Emit::TypeBuilder * type_builder =
394                 m_module_builder->DefineType(
395                       S"unoidl.com.sun.star.uno.Exception",
396                       (TypeAttributes) (TypeAttributes::Public |
397                                         TypeAttributes::BeforeFieldInit |
398                                         TypeAttributes::AnsiClass),
399                       __typeof (::System::Exception) );
400             Emit::FieldBuilder * field_Context = type_builder->DefineField(
401                 S"Context", __typeof (::System::Object),
402                 FieldAttributes::Public );
403             // default .ctor
404             type_builder->DefineDefaultConstructor( c_ctor_method_attr );
405             // .ctor
406             ::System::Type * param_types[] =
407                   new ::System::Type *[ 2 ];
408             param_types[ 0 ] = __typeof (::System::String);
409             param_types[ 1 ] = __typeof (::System::Object);
410             Emit::ConstructorBuilder * ctor_builder =
411                 type_builder->DefineConstructor(
412                     c_ctor_method_attr, CallingConventions::Standard,
413                     param_types );
414             ctor_builder->DefineParameter(
415                 1, ParameterAttributes::In, S"Message" );
416             ctor_builder->DefineParameter(
417                 2, ParameterAttributes::In, S"Context" );
418             Emit::ILGenerator * code = ctor_builder->GetILGenerator();
419             code->Emit( Emit::OpCodes::Ldarg_0 );
420             code->Emit( Emit::OpCodes::Ldarg_1 );
421             param_types = new ::System::Type * [ 1 ];
422             param_types[ 0 ] = __typeof (::System::String);
423             code->Emit(
424                 Emit::OpCodes::Call,
425                 __typeof (::System::Exception)
426                   ->GetConstructor( param_types ) );
427             code->Emit( Emit::OpCodes::Ldarg_0 );
428             code->Emit( Emit::OpCodes::Ldarg_2 );
429             code->Emit( Emit::OpCodes::Stfld, field_Context );
430             code->Emit( Emit::OpCodes::Ret );
431 
432             if (g_verbose)
433             {
434                 ::System::Console::WriteLine(
435                     "> emitting exception type "
436                     "unoidl.com.sun.star.uno.Exception" );
437             }
438             m_type_Exception = type_builder->CreateType();
439         }
440     }
441     return m_type_Exception;
442 }
443 
444 //______________________________________________________________________________
445 ::System::Type * TypeEmitter::get_type_RuntimeException()
446 {
447     if (0 == m_type_RuntimeException)
448     {
449         m_type_RuntimeException = get_type(
450             S"unoidl.com.sun.star.uno.RuntimeException", false /* no exc */ );
451         if (0 == m_type_RuntimeException)
452         {
453             // define hardcoded type unoidl.com.sun.star.uno.RuntimeException
454             ::System::Type * type_Exception = get_type_Exception();
455             Emit::TypeBuilder * type_builder =
456                   m_module_builder->DefineType(
457                       S"unoidl.com.sun.star.uno.RuntimeException",
458                       (TypeAttributes) (TypeAttributes::Public |
459                                         TypeAttributes::BeforeFieldInit |
460                                         TypeAttributes::AnsiClass),
461                       type_Exception );
462             // default .ctor
463             type_builder->DefineDefaultConstructor( c_ctor_method_attr );
464             // .ctor
465             ::System::Type * param_types [] =
466                   new ::System::Type * [ 2 ];
467             param_types[ 0 ] = __typeof (::System::String);
468             param_types[ 1 ] = __typeof (::System::Object);
469             Emit::ConstructorBuilder * ctor_builder =
470                 type_builder->DefineConstructor(
471                     c_ctor_method_attr, CallingConventions::Standard,
472                     param_types );
473             ctor_builder->DefineParameter(
474                 1, ParameterAttributes::In, S"Message" );
475             ctor_builder->DefineParameter(
476                 2, ParameterAttributes::In, S"Context" );
477             Emit::ILGenerator * code = ctor_builder->GetILGenerator();
478             code->Emit( Emit::OpCodes::Ldarg_0 );
479             code->Emit( Emit::OpCodes::Ldarg_1 );
480             code->Emit( Emit::OpCodes::Ldarg_2 );
481             code->Emit(
482                 Emit::OpCodes::Call,
483                 type_Exception->GetConstructor( param_types ) );
484             code->Emit( Emit::OpCodes::Ret );
485 
486             if (g_verbose)
487             {
488                 ::System::Console::WriteLine(
489                     "> emitting exception type "
490                     "unoidl.com.sun.star.uno.RuntimeException" );
491             }
492             m_type_RuntimeException = type_builder->CreateType();
493         }
494     }
495     return m_type_RuntimeException;
496 }
497 
498 //______________________________________________________________________________
499 ::System::Type * TypeEmitter::get_type(
500     Reference< reflection::XConstantTypeDescription > const & xType )
501 {
502     ::System::String * cts_name = to_cts_name( xType->getName() );
503     ::System::Type * ret_type = get_type( cts_name, false /* no exc */ );
504     if (0 == ret_type)
505     {
506         Reference< reflection::XConstantTypeDescription > xConstant(
507             xType, UNO_QUERY_THROW );
508         ::System::Object * constant =
509               to_cli_constant( xConstant->getConstantValue() );
510         Emit::TypeBuilder * type_builder =
511             m_module_builder->DefineType(
512                 cts_name,
513                 (TypeAttributes) (TypeAttributes::Public |
514                                   TypeAttributes::Sealed |
515                                   TypeAttributes::BeforeFieldInit |
516                                   TypeAttributes::AnsiClass) );
517 
518         Emit::FieldBuilder * field_builder = type_builder->DefineField(
519             cts_name->Substring( cts_name->LastIndexOf( '.' ) +1 ),
520             constant->GetType(),
521             (FieldAttributes) (FieldAttributes::Public |
522                                FieldAttributes::Static |
523                                FieldAttributes::Literal) );
524         field_builder->SetConstant( constant );
525 
526         if (g_verbose)
527         {
528             ::System::Console::WriteLine(
529                 "> emitting constant type {0}", cts_name );
530         }
531         ret_type = type_builder->CreateType();
532     }
533     return ret_type;
534 }
535 
536 //______________________________________________________________________________
537 ::System::Type * TypeEmitter::get_type(
538     Reference< reflection::XConstantsTypeDescription > const & xType )
539 {
540     ::System::String * cts_name = to_cts_name( xType->getName() );
541     ::System::Type * ret_type = get_type( cts_name, false /* no exc */ );
542     if (0 == ret_type)
543     {
544         Emit::TypeBuilder * type_builder =
545             m_module_builder->DefineType(
546                 cts_name,
547                 (TypeAttributes) (TypeAttributes::Public |
548                                   TypeAttributes::Sealed |
549                                   TypeAttributes::BeforeFieldInit |
550                                   TypeAttributes::AnsiClass) );
551 
552         Sequence< Reference<
553             reflection::XConstantTypeDescription > > seq_constants(
554                 xType->getConstants() );
555         Reference< reflection::XConstantTypeDescription > const * constants =
556             seq_constants.getConstArray();
557         sal_Int32 constants_length = seq_constants.getLength();
558         for ( sal_Int32 constants_pos = 0;
559               constants_pos < constants_length; ++constants_pos )
560         {
561             Reference<
562                 reflection::XConstantTypeDescription > const & xConstant =
563                 constants[ constants_pos ];
564             ::System::Object * constant =
565                   to_cli_constant( xConstant->getConstantValue() );
566             ::System::String * uno_name =
567                   ustring_to_String( xConstant->getName() );
568             Emit::FieldBuilder * field_builder = type_builder->DefineField(
569                 uno_name->Substring( uno_name->LastIndexOf( '.' ) +1 ),
570                 constant->GetType(),
571                 (FieldAttributes) (FieldAttributes::Public |
572                                    FieldAttributes::Static |
573                                    FieldAttributes::Literal) );
574             field_builder->SetConstant( constant );
575         }
576 
577         if (g_verbose)
578         {
579             ::System::Console::WriteLine(
580                 "> emitting constants group type {0}", cts_name );
581         }
582         ret_type = type_builder->CreateType();
583     }
584     return ret_type;
585 }
586 
587 //______________________________________________________________________________
588 ::System::Type * TypeEmitter::get_type(
589     Reference< reflection::XEnumTypeDescription > const & xType )
590 {
591     ::System::String * cts_name = to_cts_name( xType->getName() );
592     ::System::Type * ret_type = get_type( cts_name, false /* no exc */ );
593     if (0 == ret_type)
594     {
595 //         Emit::EnumBuilder * enum_builder =
596 //             m_module_builder->DefineEnum(
597 //                 cts_name,
598 //                 (TypeAttributes) (TypeAttributes::Public |
599 // //                                   TypeAttributes::Sealed |
600 //                                   TypeAttributes::AnsiClass),
601 //                 __typeof (::System::Int32) );
602         // workaround enum builder bug
603         Emit::TypeBuilder * enum_builder =
604             m_module_builder->DefineType(
605                 cts_name,
606                 (TypeAttributes) (TypeAttributes::Public |
607                                   TypeAttributes::Sealed),
608                 __typeof (::System::Enum) );
609         enum_builder->DefineField(
610             S"value__", __typeof (::System::Int32),
611             (FieldAttributes) (FieldAttributes::Private |
612                                FieldAttributes::SpecialName |
613                                FieldAttributes::RTSpecialName) );
614         Sequence< OUString > seq_enum_names( xType->getEnumNames() );
615         Sequence< sal_Int32 > seq_enum_values( xType->getEnumValues() );
616         sal_Int32 enum_length = seq_enum_names.getLength();
617         OSL_ASSERT( enum_length == seq_enum_values.getLength() );
618         OUString const * enum_names = seq_enum_names.getConstArray();
619         sal_Int32 const * enum_values = seq_enum_values.getConstArray();
620         for ( sal_Int32 enum_pos = 0; enum_pos < enum_length; ++enum_pos )
621         {
622 //             enum_builder->DefineLiteral(
623 //                 ustring_to_String( enum_names[ enum_pos ] ),
624 //                 __box ((::System::Int32) enum_values[ enum_pos ]) );
625             Emit::FieldBuilder * field_builder =
626                 enum_builder->DefineField(
627                     ustring_to_String( enum_names[ enum_pos ] ),
628                     enum_builder,
629                     (FieldAttributes) (FieldAttributes::Public |
630                                        FieldAttributes::Static |
631                                        FieldAttributes::Literal) );
632             field_builder->SetConstant(
633                 __box ((::System::Int32) enum_values[ enum_pos ]) );
634         }
635 
636         if (g_verbose)
637         {
638             ::System::Console::WriteLine(
639                 "> emitting enum type {0}", cts_name );
640         }
641         ret_type = enum_builder->CreateType();
642     }
643     return ret_type;
644 }
645 
646 //______________________________________________________________________________
647 ::System::Type * TypeEmitter::get_type(
648     Reference< reflection::XCompoundTypeDescription > const & xType )
649 {
650     OUString uno_name( xType->getName() );
651     if (TypeClass_EXCEPTION == xType->getTypeClass())
652     {
653         if (uno_name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
654                                        "com.sun.star.uno.Exception") ))
655         {
656             return get_type_Exception();
657         }
658         if (uno_name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
659                                        "com.sun.star.uno.RuntimeException") ))
660         {
661             return get_type_RuntimeException();
662         }
663     }
664     ::System::String * cts_name = to_cts_name( uno_name );
665     // if the struct is an instantiated polymorpic struct then we create the simple struct name
666     // For example:
667     // void func ([in] PolyStruct<boolean> arg);
668     //PolyStruct<boolean> will be converted to PolyStruct
669     polymorphicStructNameToStructName( & cts_name);
670 
671     ::System::Type * ret_type = get_type( cts_name, false /* no exc */ );
672     if (0 == ret_type)
673     {
674         Reference< reflection::XCompoundTypeDescription > xBaseType(
675             xType->getBaseType(), UNO_QUERY );
676         ::System::Type * base_type = (xBaseType.is()
677                                       ? get_type( xBaseType )
678                                       : __typeof (::System::Object));
679         Emit::TypeBuilder * type_builder =
680             m_module_builder->DefineType(
681                 cts_name,
682                 (TypeAttributes) (TypeAttributes::Public |
683                                   TypeAttributes::BeforeFieldInit |
684                                   TypeAttributes::AnsiClass),
685                 base_type );
686 
687 
688          // insert to be completed
689         struct_entry * entry = new struct_entry();
690         xType->acquire();
691         entry->m_xType = xType.get();
692         entry->m_type_builder = type_builder;
693         entry->m_base_type = base_type;
694         m_incomplete_structs->Add( cts_name, entry );
695 
696         // type is incomplete
697         ret_type = type_builder;
698     }
699 
700     //In case of an instantiated polymorphic struct we want to return a
701     //uno.PolymorphicType (inherits Type) rather then Type. This is neaded for constructing
702     //the service code. We can only do that if the struct is completed.
703     if (m_generated_structs->get_Item(cts_name))
704     {
705         Reference< reflection::XStructTypeDescription> xStructTypeDesc(
706             xType, UNO_QUERY);
707 
708         if (xStructTypeDesc.is())
709         {
710             Sequence< Reference< reflection::XTypeDescription > > seqTypeArgs = xStructTypeDesc->getTypeArguments();
711             sal_Int32 numTypes = seqTypeArgs.getLength();
712             if (numTypes > 0)
713             {
714                 //it is an instantiated polymorphic struct
715                 ::System::String * sCliName = mapUnoTypeName(ustring_to_String(xType->getName()));
716                 ret_type = ::uno::PolymorphicType::GetType(ret_type, sCliName);
717             }
718         }
719     }
720     return ret_type;
721 }
722 
723 //______________________________________________________________________________
724 ::System::Type * TypeEmitter::get_type(
725     Reference< reflection::XInterfaceTypeDescription2 > const & xType )
726 {
727     OUString uno_name( xType->getName() );
728     if (uno_name.equalsAsciiL(
729             RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") ))
730     {
731         return __typeof (::System::Object);
732     }
733 
734     ::System::String * cts_name = to_cts_name( xType->getName() );
735     ::System::Type * ret_type = get_type( cts_name, false /* no exc */ );
736     if (0 == ret_type)
737     {
738         Emit::TypeBuilder * type_builder;
739 
740         TypeAttributes attr = (TypeAttributes) (TypeAttributes::Public |
741                                                 TypeAttributes::Interface |
742                                                 TypeAttributes::Abstract |
743                                                 TypeAttributes::AnsiClass);
744 
745         std::vector<Reference<reflection::XInterfaceTypeDescription2> > vecBaseTypes;
746         Sequence<Reference< reflection::XTypeDescription > > seqBaseTypes =
747             xType->getBaseTypes();
748         if (seqBaseTypes.getLength() > 0)
749         {
750             for (int i = 0; i < seqBaseTypes.getLength(); i++)
751             {
752                 Reference<reflection::XInterfaceTypeDescription2> xIfaceTd =
753                     resolveInterfaceTypedef(seqBaseTypes[i]);
754 
755                 if (xIfaceTd->getName().equalsAsciiL(
756                         RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") ) == sal_False)
757                 {
758                     vecBaseTypes.push_back(xIfaceTd);
759                 }
760             }
761 
762             ::System::Type * base_interfaces [] =
763                   new ::System::Type * [ vecBaseTypes.size() ];
764 
765             typedef std::vector<Reference<reflection::XInterfaceTypeDescription2> >::const_iterator it;
766             int index = 0;
767             for (it i = vecBaseTypes.begin(); i != vecBaseTypes.end(); i++, index++)
768                 base_interfaces[ index ] = get_type( *i );
769             type_builder = m_module_builder->DefineType(
770                 cts_name, attr, 0, base_interfaces );
771         }
772         else
773         {
774             ::System::Console::WriteLine(
775                 "warning: IDL interface {0} is not derived from "
776                 "com.sun.star.uno.XInterface!",
777                 ustring_to_String( uno_name ) );
778 
779             type_builder = m_module_builder->DefineType( cts_name, attr );
780         }
781 
782         // insert to be completed
783         iface_entry * entry = new iface_entry();
784         xType->acquire();
785         entry->m_xType = xType.get();
786         entry->m_type_builder = type_builder;
787         m_incomplete_ifaces->Add( cts_name, entry );
788 
789         // type is incomplete
790         ret_type = type_builder;
791     }
792     return ret_type;
793 }
794 
795 
796 //______________________________________________________________________________
797 ::System::Type * TypeEmitter::get_type(
798     Reference< reflection::XServiceTypeDescription2 > const & xType )
799 {
800     if (xType->isSingleInterfaceBased() == sal_False)
801         return NULL;
802 
803     System::String * cts_name = to_cts_name( xType->getName() );
804     System::Type * ret_type = get_type( cts_name, false /* no exc */ );
805     if (ret_type != NULL)
806         return ret_type;
807 
808     TypeAttributes attr = (TypeAttributes) (TypeAttributes::Public |
809                                             TypeAttributes::Sealed |
810                                             TypeAttributes::BeforeFieldInit |
811                                             TypeAttributes::AnsiClass);
812 
813     Emit::TypeBuilder * type_builder = m_module_builder->DefineType(
814         cts_name, attr);
815 
816     // insert to be completed
817     service_entry * entry = new service_entry();
818     xType->acquire();
819     entry->m_xType = xType.get();
820     entry->m_type_builder = type_builder;
821     m_incomplete_services->Add(cts_name,entry );
822 
823     return type_builder;
824 }
825 
826 ::System::Type * TypeEmitter::get_type(
827     Reference<reflection::XSingletonTypeDescription2 > const & xType )
828 {
829     if (xType->isInterfaceBased() == sal_False)
830         return NULL;
831 
832     ::System::String* cts_name = to_cts_name( xType->getName() );
833     ::System::Type * ret_type = get_type( cts_name, false /* no exc */ );
834     if (ret_type != NULL)
835         return ret_type;
836 
837     TypeAttributes attr = static_cast<TypeAttributes>(
838         TypeAttributes::Public |
839         TypeAttributes::Sealed |
840         TypeAttributes::BeforeFieldInit |
841         TypeAttributes::AnsiClass);
842 
843     Emit::TypeBuilder * type_builder = m_module_builder->DefineType(
844         cts_name, attr);
845 
846     // insert to be completed
847     singleton_entry * entry = new singleton_entry();
848     xType->acquire();
849     entry->m_xType = xType.get();
850     entry->m_type_builder = type_builder;
851     m_incomplete_singletons->Add(cts_name,entry );
852 
853     return type_builder;
854 
855 }
856 
857 //______________________________________________________________________________
858 ::System::Type * TypeEmitter::complete_iface_type( iface_entry * entry )
859 {
860     Emit::TypeBuilder * type_builder = entry->m_type_builder;
861     reflection::XInterfaceTypeDescription2 * xType = entry->m_xType;
862 
863     Sequence<Reference< reflection::XTypeDescription > > seqBaseTypes( xType->getBaseTypes() );
864     if (seqBaseTypes.getLength() > 0)
865     {
866         for (int i = 0; i < seqBaseTypes.getLength(); i++)
867         {
868             //make sure we get the interface rather then a typedef
869             Reference<reflection::XInterfaceTypeDescription2> aBaseType =
870                 resolveInterfaceTypedef( seqBaseTypes[i]);
871 
872             if (aBaseType->getName().equalsAsciiL(
873                     RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") ) == sal_False)
874             {
875                 ::System::String * basetype_name = to_cts_name( aBaseType->getName() );
876                 iface_entry * base_entry = dynamic_cast< iface_entry * >(
877                     m_incomplete_ifaces->get_Item( basetype_name ) );
878                 if (0 != base_entry)
879                 {
880                 // complete uncompleted base type first
881                     complete_iface_type( base_entry );
882                 }
883             }
884         }
885     }
886 
887     Sequence<
888         Reference< reflection::XInterfaceMemberTypeDescription > > seq_members(
889             xType->getMembers() );
890     Reference< reflection::XInterfaceMemberTypeDescription > const * members =
891         seq_members.getConstArray();
892     sal_Int32 members_length = seq_members.getLength();
893     for ( sal_Int32 members_pos = 0;
894           members_pos < members_length; ++members_pos )
895     {
896         Reference<
897             reflection::XInterfaceMemberTypeDescription > const & xMember =
898             members[ members_pos ];
899         Sequence< Reference< reflection::XTypeDescription > > seq_exceptions;
900         Emit::MethodBuilder * method_builder;
901 
902         const MethodAttributes c_method_attr = (MethodAttributes)
903             (MethodAttributes::Public |
904              MethodAttributes::Abstract |
905              MethodAttributes::Virtual |
906              MethodAttributes::NewSlot |
907              MethodAttributes::HideBySig);
908 //#if defined(_MSC_VER) && (_MSC_VER < 1400)
909 //             MethodAttributes::Instance);
910 //#else
911 //	     Instance);
912 //#endif
913 
914         if (TypeClass_INTERFACE_METHOD == xMember->getTypeClass())
915         {
916             Reference< reflection::XInterfaceMethodTypeDescription > xMethod(
917                 xMember, UNO_QUERY_THROW );
918 
919             Sequence<
920                 Reference< reflection::XMethodParameter > > seq_parameters(
921                     xMethod->getParameters() );
922             sal_Int32 params_length = seq_parameters.getLength();
923             ::System::Type * param_types [] =
924                   new ::System::Type * [ params_length ];
925             Reference< reflection::XMethodParameter > const * parameters =
926                 seq_parameters.getConstArray();
927             // first determine all types
928             //Make the first param type as return type
929             sal_Int32 params_pos = 0;
930             for ( ; params_pos < params_length; ++params_pos )
931             {
932                 Reference< reflection::XMethodParameter > const & xParam =
933                     parameters[ params_pos ];
934                 ::System::Type * param_type = get_type( xParam->getType() );
935                 ::System::String * param_type_name = param_type->get_FullName();
936                 if (xParam->isOut())
937                 {
938                     param_type = get_type(
939                         ::System::String::Concat(
940                             param_type_name, S"&" ), true );
941                 }
942                 param_types[ xParam->getPosition() ] = param_type;
943             }
944 
945 
946             // create method
947 //             if (tb)
948 //                 method_builder = type_builder->DefineMethod(
949 //                 ustring_to_String( xMethod->getMemberName() ),
950 //                 c_method_attr, tb,
951 //                 param_types );
952 //             else
953                 method_builder = type_builder->DefineMethod(
954                     ustring_to_String( xMethod->getMemberName() ),
955                     c_method_attr, get_type( xMethod->getReturnType() ),
956                     param_types );
957             // then define parameter infos
958             params_pos = 0;
959             for ( ; params_pos < params_length; ++params_pos )
960             {
961                 Reference< reflection::XMethodParameter > const & xParam =
962                     parameters[ params_pos ];
963                 long param_flags = 0;
964                 if (xParam->isIn())
965                     param_flags |= ParameterAttributes::In;
966                 if (xParam->isOut())
967                     param_flags |= ParameterAttributes::Out;
968                 OSL_ASSERT( 0 != param_flags );
969                 method_builder->DefineParameter(
970                     xParam->getPosition() +1 /* starts with 1 */,
971                     (ParameterAttributes) param_flags,
972                     ustring_to_String( xParam->getName() ) );
973             }
974             //Apply attribute TypeParametersAttribute to return value if it
975             //is a parameterized Type. Currently only structs can have parameters.
976             Reference<reflection::XStructTypeDescription> xReturnStruct(
977                 xMethod->getReturnType(), UNO_QUERY);
978 
979             if (xReturnStruct.is())
980             {
981                 Sequence<Reference<reflection::XTypeDescription> > seq_type_args =
982                     xReturnStruct->getTypeArguments();
983                 if (seq_type_args.getLength() != 0)
984                 {
985                     //get th ctor of the attribute
986                     ::System::Type * arCtor[] = {::System::Type::GetType(S"System.Type[]")};
987                     //Get the arguments for the attribute's ctor
988                     Reference<reflection::XTypeDescription> const * arXTypeArgs =
989                         seq_type_args.getConstArray();
990                     int numTypes = seq_type_args.getLength();
991                     ::System::Type * arCtsTypes[] = new ::System::Type*[numTypes];
992                     for (int i = 0; i < numTypes; i++)
993                         arCtsTypes[i] = get_type(arXTypeArgs[i]);
994                     ::System::Object * arArgs[] = {arCtsTypes};
995 
996 					Emit::CustomAttributeBuilder * attrBuilder =
997                         new Emit::CustomAttributeBuilder(
998                             __typeof(::uno::TypeArgumentsAttribute)
999                             ->GetConstructor( arCtor),
1000                             arArgs);
1001 
1002                     method_builder->SetCustomAttribute(attrBuilder);
1003                 }
1004             }
1005 
1006             //define UNO exception attribute (exceptions)--------------------------------------
1007             Emit::CustomAttributeBuilder* attrBuilder =
1008                 get_iface_method_exception_attribute(xMethod);
1009             if (attrBuilder != NULL)
1010                 method_builder->SetCustomAttribute(attrBuilder);
1011 
1012             // oneway attribute
1013             if (xMethod->isOneway())
1014             {
1015                 ::System::Type * arCtorOneway[] = new ::System::Type*[0];
1016                 ::System::Object * arArgs[] = new ::System::Object*[0];
1017                 Emit::CustomAttributeBuilder * attrBuilder =
1018                     new Emit::CustomAttributeBuilder(
1019                         __typeof(::uno::OnewayAttribute)->GetConstructor( arCtorOneway),
1020                         arArgs);
1021                 method_builder->SetCustomAttribute(attrBuilder);
1022             }
1023         }
1024         else // attribute
1025         {
1026             OSL_ASSERT(
1027                 TypeClass_INTERFACE_ATTRIBUTE == xMember->getTypeClass() );
1028             Reference<
1029                 reflection::XInterfaceAttributeTypeDescription2 > xAttribute(
1030                     xMember, UNO_QUERY_THROW );
1031 
1032             const MethodAttributes c_property_method_attr = (MethodAttributes)
1033                 (c_method_attr | MethodAttributes::SpecialName);
1034 
1035             ::System::Type * attribute_type = get_type( xAttribute->getType() );
1036             ::System::Type * parameters [] =
1037                   new ::System::Type * [ 0 ];
1038 
1039             Emit::PropertyBuilder * property_builder =
1040                 type_builder->DefineProperty(
1041                     ustring_to_String( xAttribute->getMemberName() ),
1042                     PropertyAttributes::None,
1043                     attribute_type, parameters );
1044 
1045             //set BoundAttribute, if necessary
1046             if (xAttribute->isBound())
1047             {
1048                 ConstructorInfo * ctorBoundAttr =
1049                     __typeof(::uno::BoundAttribute)->GetConstructor(
1050                         new System::Type*[0]);
1051                 Emit::CustomAttributeBuilder * attrBuilderBound =
1052                     new Emit::CustomAttributeBuilder(
1053                         ctorBoundAttr, new ::System::Object*[0]);
1054                 property_builder->SetCustomAttribute(attrBuilderBound);
1055             }
1056 
1057             // getter
1058             Emit::MethodBuilder * method_builder =
1059                 type_builder->DefineMethod(
1060                     ustring_to_String( OUSTR("get_") +
1061                                        xAttribute->getMemberName() ),
1062                     c_property_method_attr, attribute_type, parameters );
1063 
1064            //define UNO exception attribute (exceptions)--------------------------------------
1065             Emit::CustomAttributeBuilder* attrBuilder =
1066                 get_exception_attribute(xAttribute->getGetExceptions());
1067             if (attrBuilder != NULL)
1068                 method_builder->SetCustomAttribute(attrBuilder);
1069 
1070             property_builder->SetGetMethod( method_builder );
1071 
1072             if (! xAttribute->isReadOnly())
1073             {
1074                 // setter
1075                 parameters = new ::System::Type * [ 1 ];
1076                 parameters[ 0 ] = attribute_type;
1077                 method_builder =
1078                     type_builder->DefineMethod(
1079                         ustring_to_String( OUSTR("set_") +
1080                                            xAttribute->getMemberName() ),
1081                         c_property_method_attr, 0, parameters );
1082                 // define parameter info
1083                 method_builder->DefineParameter(
1084                     1 /* starts with 1 */, ParameterAttributes::In, S"value" );
1085                 //define UNO exception attribute (exceptions)--------------------------------------
1086                 Emit::CustomAttributeBuilder* attrBuilder =
1087                     get_exception_attribute(xAttribute->getSetExceptions());
1088                 if (attrBuilder != NULL)
1089                     method_builder->SetCustomAttribute(attrBuilder);
1090 
1091                 property_builder->SetSetMethod( method_builder );
1092             }
1093         }
1094     }
1095 
1096     // remove from incomplete types map
1097     ::System::String * cts_name = type_builder->get_FullName();
1098     m_incomplete_ifaces->Remove( cts_name );
1099     xType->release();
1100 
1101     if (g_verbose)
1102     {
1103         ::System::Console::WriteLine(
1104             "> emitting interface type {0}", cts_name );
1105     }
1106     return type_builder->CreateType();
1107 }
1108 
1109 ::System::Type * TypeEmitter::complete_struct_type( struct_entry * entry )
1110 {
1111      OSL_ASSERT(entry);
1112     ::System::String * cts_name = entry->m_type_builder->get_FullName();
1113 
1114     //Polymorphic struct, define uno.TypeParametersAttribute
1115     //A polymorphic struct cannot have a basetype.
1116     //When we create the template of the struct then we have no exact types
1117     //and the name does not contain a parameter list
1118     Sequence< OUString > seq_type_parameters;
1119     Reference< reflection::XStructTypeDescription> xStructTypeDesc(
1120         entry->m_xType, UNO_QUERY);
1121     if (xStructTypeDesc.is())
1122     {
1123         seq_type_parameters = xStructTypeDesc->getTypeParameters();
1124         int numTypes = 0;
1125         if ((numTypes = seq_type_parameters.getLength()) > 0)
1126         {
1127             ::System::Object * aArg[] = new ::System::Object*[numTypes];
1128             for (int i = 0; i < numTypes; i++)
1129                 aArg[i] = ustring_to_String(seq_type_parameters.getConstArray()[i]);
1130             ::System::Object * args[] = {aArg};
1131 
1132             ::System::Type * arTypesCtor[] =
1133             {::System::Type::GetType(S"System.String[]")};
1134             Emit::CustomAttributeBuilder * attrBuilder =
1135                 new Emit::CustomAttributeBuilder(
1136                 __typeof(::uno::TypeParametersAttribute)->GetConstructor(arTypesCtor),
1137                 args);
1138             entry->m_type_builder->SetCustomAttribute(attrBuilder);
1139         }
1140     }
1141 
1142     // optional: lookup base type whether generated entry of this session
1143     struct_entry * base_type_entry = 0;
1144     if (0 != entry->m_base_type)
1145     {
1146         //ToDo maybe get from incomplete structs
1147         base_type_entry =
1148             dynamic_cast< struct_entry * >(
1149                 m_generated_structs->get_Item(
1150                     entry->m_base_type->get_FullName() ) );
1151     }
1152 
1153         // members
1154     Sequence< Reference< reflection::XTypeDescription > > seq_members(
1155         entry->m_xType->getMemberTypes() );
1156     Sequence< OUString > seq_member_names( entry->m_xType->getMemberNames() );
1157     sal_Int32 members_length = seq_members.getLength();
1158     OSL_ASSERT( seq_member_names.getLength() == members_length );
1159 	//check if we have a XTypeDescription for every member. If not then the user may
1160 	//have forgotten to specify additional rdbs with the --extra option.
1161     Reference< reflection::XTypeDescription > const * pseq_members =
1162 	        seq_members.getConstArray();
1163     OUString const * pseq_member_names =
1164         seq_member_names.getConstArray();
1165 	for (int i = 0; i < members_length; i++)
1166 	{
1167 		const OUString sType(entry->m_xType->getName());
1168 		const OUString sMemberName(pseq_member_names[i]);
1169 		if ( ! pseq_members[i].is())
1170 			throw RuntimeException(OUSTR("Missing type description . Check if you need to " \
1171 			"specify additional RDBs with the --extra option. Type missing for: ") +  sType +
1172 			OUSTR("::") + sMemberName,0);
1173 	}
1174 
1175     sal_Int32 all_members_length = 0;
1176     sal_Int32 member_pos;
1177     sal_Int32 type_param_pos = 0;
1178 
1179     // collect base types; wrong order
1180     ::System::Collections::ArrayList * base_types_list =
1181             new ::System::Collections::ArrayList( 3 /* initial capacity */ );
1182     for (::System::Type * base_type_pos = entry->m_base_type;
1183         ! base_type_pos->Equals( __typeof (::System::Object) );
1184         base_type_pos = base_type_pos->get_BaseType() )
1185     {
1186         base_types_list->Add( base_type_pos );
1187         if (base_type_pos->Equals( __typeof (::System::Exception) ))
1188         {
1189             // special Message member
1190             all_members_length += 1;
1191             break; // don't include System.Exception base classes
1192         }
1193         else
1194         {
1195             //ensure the base type is complete. Otherwise GetFields won't work
1196             get_complete_struct(base_type_pos->get_FullName());
1197             all_members_length +=
1198                 base_type_pos->GetFields(
1199                 (BindingFlags) (BindingFlags::Instance |
1200                 BindingFlags::Public |
1201                 BindingFlags::DeclaredOnly) )
1202                 ->get_Length();
1203         }
1204     }
1205 
1206     // create all_members arrays; right order
1207     ::System::String * all_member_names[] =
1208         new ::System::String * [all_members_length + members_length ];
1209     ::System::Type * all_param_types[] =
1210         new ::System::Type * [all_members_length + members_length ];
1211     member_pos = 0;
1212     for ( sal_Int32 pos = base_types_list->get_Count(); pos--; )
1213     {
1214         ::System::Type * base_type = __try_cast< ::System::Type * >(
1215             base_types_list->get_Item( pos ) );
1216         if (base_type->Equals( __typeof (::System::Exception) ))
1217         {
1218             all_member_names[ member_pos ] = S"Message";
1219             all_param_types[ member_pos ] = __typeof (::System::String);
1220             ++member_pos;
1221         }
1222         else
1223         {
1224             ::System::String * base_type_name = base_type->get_FullName();
1225 
1226             //ToDo m_generated_structs?
1227             struct_entry * entry =
1228                 dynamic_cast< struct_entry * >(
1229                 m_generated_structs->get_Item( base_type_name ) );
1230             if (0 == entry)
1231             {
1232                 // complete type
1233                 FieldInfo * fields [] =
1234                     base_type->GetFields(
1235                     (BindingFlags) (BindingFlags::Instance |
1236                     BindingFlags::Public |
1237                     BindingFlags::DeclaredOnly) );
1238                 sal_Int32 len = fields->get_Length();
1239                 for ( sal_Int32 pos = 0; pos < len; ++pos )
1240                 {
1241                     FieldInfo * field = fields[ pos ];
1242                     all_member_names[ member_pos ] = field->get_Name();
1243                     all_param_types[ member_pos ] = field->get_FieldType();
1244                     ++member_pos;
1245                 }
1246             }
1247             else // generated during this session:
1248                 // members may be incomplete ifaces
1249             {
1250                 sal_Int32 len = entry->m_member_names->get_Length();
1251                 for ( sal_Int32 pos = 0; pos < len; ++pos )
1252                 {
1253                     all_member_names[ member_pos ] =
1254                         entry->m_member_names[ pos ];
1255                     all_param_types[ member_pos ] =
1256                         entry->m_param_types[ pos ];
1257                     ++member_pos;
1258                 }
1259             }
1260         }
1261     }
1262     OSL_ASSERT( all_members_length == member_pos );
1263 
1264     // build up entry
1265 //    struct_entry * entry = new struct_entry();
1266     entry->m_member_names = new ::System::String * [ members_length ];
1267     entry->m_param_types = new ::System::Type * [ members_length ];
1268 
1269     // add members
1270     Emit::FieldBuilder * members[] = new Emit::FieldBuilder * [ members_length ];
1271     //Reference< reflection::XTypeDescription > const * pseq_members =
1272     //    seq_members.getConstArray();
1273     //OUString const * pseq_member_names =
1274     //    seq_member_names.getConstArray();
1275 
1276     int curParamIndex = 0; //count the fields which have parameterized types
1277     for ( member_pos = 0; member_pos < members_length; ++member_pos )
1278     {
1279         ::System::String * field_name =
1280             ustring_to_String( pseq_member_names[ member_pos ] );
1281         ::System::Type * field_type;
1282         //Special handling of struct parameter types
1283         bool bParameterizedType = false;
1284         if (pseq_members[ member_pos ]->getTypeClass() == TypeClass_UNKNOWN)
1285         {
1286             bParameterizedType = true;
1287             if (type_param_pos < seq_type_parameters.getLength())
1288             {
1289                 field_type = __typeof(::System::Object);
1290                 type_param_pos++;
1291             }
1292             else
1293             {
1294                 throw RuntimeException(
1295                     OUSTR("unexpected member type in ") + entry->m_xType->getName(),
1296                     Reference< XInterface >() );
1297             }
1298         }
1299         else
1300         {
1301             field_type =
1302                 get_type( pseq_members[ member_pos ] );
1303         }
1304         members[ member_pos ] =
1305             entry->m_type_builder->DefineField(
1306             field_name, field_type, FieldAttributes::Public );
1307 
1308         //parameterized type (polymorphic struct) ?
1309         if (bParameterizedType && xStructTypeDesc.is())
1310         {
1311             //get the name
1312             OSL_ASSERT(seq_type_parameters.getLength() > curParamIndex);
1313             ::System::String* sTypeName = ustring_to_String(
1314                 seq_type_parameters.getConstArray()[curParamIndex++]);
1315             ::System::Object * args[] = {sTypeName};
1316             //set ParameterizedTypeAttribute
1317             ::System::Type * arCtorTypes[] = {__typeof(::System::String)};
1318 
1319             Emit::CustomAttributeBuilder * attrBuilder =
1320                 new Emit::CustomAttributeBuilder(
1321                 __typeof(::uno::ParameterizedTypeAttribute)
1322                 ->GetConstructor(arCtorTypes),
1323                 args);
1324 
1325             members[member_pos]->SetCustomAttribute(attrBuilder);
1326         }
1327         // add to all_members
1328         all_member_names[ all_members_length + member_pos ] = field_name;
1329         all_param_types[ all_members_length + member_pos ] = field_type;
1330         // add to entry
1331         entry->m_member_names[ member_pos ] = field_name;
1332         entry->m_param_types[ member_pos ] = field_type;
1333     }
1334     all_members_length += members_length;
1335 
1336     // default .ctor
1337     Emit::ConstructorBuilder * ctor_builder =
1338         entry->m_type_builder->DefineConstructor(
1339         c_ctor_method_attr, CallingConventions::Standard,
1340         new ::System::Type * [ 0 ] );
1341     Emit::ILGenerator * code = ctor_builder->GetILGenerator();
1342     code->Emit( Emit::OpCodes::Ldarg_0 );
1343     code->Emit(
1344         Emit::OpCodes::Call,
1345         0 == base_type_entry
1346         ? entry->m_base_type->GetConstructor( new ::System::Type * [ 0 ] )
1347         : base_type_entry->m_default_ctor );
1348     // default initialize members
1349     for ( member_pos = 0; member_pos < members_length; ++member_pos )
1350     {
1351         FieldInfo * field = members[ member_pos ];
1352         ::System::Type * field_type = field->get_FieldType();
1353         //            ::System::Type * new_field_type = m_module_builder->GetType(field_type->FullName, false);
1354         // default initialize:
1355         // string, type, enum, sequence, struct, exception, any
1356         if (field_type->Equals( __typeof (::System::String) ))
1357         {
1358             code->Emit( Emit::OpCodes::Ldarg_0 );
1359             code->Emit( Emit::OpCodes::Ldstr, S"" );
1360             code->Emit( Emit::OpCodes::Stfld, field );
1361         }
1362         else if (field_type->Equals( __typeof (::System::Type) ))
1363         {
1364             code->Emit( Emit::OpCodes::Ldarg_0 );
1365             code->Emit(
1366                 Emit::OpCodes::Ldtoken, __typeof (::System::Void) );
1367             code->Emit(
1368                 Emit::OpCodes::Call, m_method_info_Type_GetTypeFromHandle );
1369             code->Emit( Emit::OpCodes::Stfld, field );
1370         }
1371         else if (field_type->get_IsArray())
1372         {
1373             //Find the value type. In case of sequence<sequence< ... > > find the actual value type
1374             ::System::Type * value = field_type;
1375             while ((value = value->GetElementType())->get_IsArray());
1376             //If the value type is a struct then make sure it is fully created.
1377             get_complete_struct(value->get_FullName());
1378 
1379             code->Emit( Emit::OpCodes::Ldarg_0 );
1380             code->Emit( Emit::OpCodes::Ldc_I4_0 );
1381             code->Emit(
1382                 Emit::OpCodes::Newarr, field_type->GetElementType() );
1383             code->Emit( Emit::OpCodes::Stfld, field );
1384         }
1385         else if (field_type->get_IsValueType())
1386         {
1387             if (field_type->get_FullName()->Equals( S"uno.Any" ))
1388             {
1389                 code->Emit( Emit::OpCodes::Ldarg_0 );
1390                 code->Emit( Emit::OpCodes::Ldsfld, __typeof(::uno::Any)->GetField(S"VOID"));
1391                 code->Emit( Emit::OpCodes::Stfld, field );
1392             }
1393         }
1394         else if (field_type->get_IsClass())
1395         {
1396             /* may be XInterface */
1397             if (! field_type->Equals( __typeof (::System::Object) ))
1398             {
1399                 // struct, exception
1400                 //make sure the struct is already complete.
1401                 get_complete_struct(field_type->get_FullName());
1402                 code->Emit( Emit::OpCodes::Ldarg_0 );
1403                 code->Emit(
1404                     Emit::OpCodes::Newobj,
1405                     //GetConstructor requies that the member types of the object which is to be constructed are already known.
1406                     field_type->GetConstructor(
1407                     new ::System::Type * [ 0 ] ) );
1408                 code->Emit( Emit::OpCodes::Stfld, field );
1409             }
1410         }
1411     }
1412     code->Emit( Emit::OpCodes::Ret );
1413     entry->m_default_ctor = ctor_builder;
1414 
1415     // parameterized .ctor including all base members
1416     ctor_builder = entry->m_type_builder->DefineConstructor(
1417         c_ctor_method_attr, CallingConventions::Standard, all_param_types );
1418     for ( member_pos = 0; member_pos < all_members_length; ++member_pos )
1419     {
1420         ctor_builder->DefineParameter(
1421             member_pos +1 /* starts with 1 */, ParameterAttributes::In,
1422             all_member_names[ member_pos ] );
1423     }
1424     code = ctor_builder->GetILGenerator();
1425     // call base .ctor
1426     code->Emit( Emit::OpCodes::Ldarg_0 ); // push this
1427     sal_Int32 base_members_length = all_members_length - members_length;
1428     ::System::Type * param_types [] =
1429         new ::System::Type * [ base_members_length ];
1430     for ( member_pos = 0; member_pos < base_members_length; ++member_pos )
1431     {
1432         emit_ldarg( code, member_pos +1 );
1433         param_types[ member_pos ] = all_param_types[ member_pos ];
1434     }
1435     code->Emit(
1436         Emit::OpCodes::Call,
1437         0 == base_type_entry
1438         ? entry->m_base_type->GetConstructor( param_types )
1439         : base_type_entry->m_ctor );
1440     // initialize members
1441     for ( member_pos = 0; member_pos < members_length; ++member_pos )
1442     {
1443         code->Emit( Emit::OpCodes::Ldarg_0 ); // push this
1444         emit_ldarg( code, member_pos + base_members_length +1 );
1445         code->Emit( Emit::OpCodes::Stfld, members[ member_pos ] );
1446     }
1447     code->Emit( Emit::OpCodes::Ret );
1448     entry->m_ctor = ctor_builder;
1449 
1450     if (g_verbose)
1451     {
1452         ::System::Console::WriteLine(
1453             "> emitting {0} type {1}",
1454             TypeClass_STRUCT == entry->m_xType->getTypeClass()
1455             ? S"struct"
1456             : S"exception",
1457             cts_name);
1458     }
1459     // new entry
1460     m_generated_structs->Add(cts_name, entry );
1461     ::System::Type * ret_type = entry->m_type_builder->CreateType();
1462 
1463     // remove from incomplete types map
1464     m_incomplete_structs->Remove( cts_name );
1465     entry->m_xType->release();
1466 
1467     if (g_verbose)
1468     {
1469         ::System::Console::WriteLine(
1470             "> emitting struct type {0}", cts_name);
1471     }
1472     return ret_type;
1473 }
1474 
1475 //Examples of generated code
1476 // 		public static XWeak constructor1(XComponentContext ctx)
1477 // 		{
1478 // 			XMultiComponentFactory factory = ctx.getServiceManager();
1479 // 			if (factory == null)
1480 // 				throw new com.sun.star.uno.DeploymentException("bla", null);
1481 // 			return (XWeak) factory.createInstanceWithContext("service_specifier", ctx);
1482 // 		}
1483 // 		public static XWeak constructor2(XComponentContext ctx, int a, int b, Any c)
1484 // 		{
1485 // 			XMultiComponentFactory factory = ctx.getServiceManager();
1486 // 			if (factory == null)
1487 // 				throw new com.sun.star.uno.DeploymentException("bla", null);
1488 // 			Any[] arAny = new Any[3];
1489 // 			arAny[0] = new Any(typeof(int), a);
1490 // 			arAny[1] = new Any(typeof(int), b);
1491 //			arAny[2] = new Any(c.Type, c.Value);
1492 // 			return (XWeak) factory.createInstanceWithArgumentsAndContext("service_specifier", arAny, ctx);
1493 // 		}
1494 // Notice that a any parameter is NOT wrapped by another any. Instead the new any is created with the type and value
1495 // of the parameter.
1496 
1497 // 		public static XWeak constructor3(XComponentContext ctx, params Any[] c)
1498 // 		{
1499 // 			XMultiComponentFactory factory = ctx.getServiceManager();
1500 // 			if (factory == null)
1501 // 				throw new com.sun.star.uno.DeploymentException("bla", null);
1502 // 			return (XWeak) factory.createInstanceWithArgumentsAndContext("service_specifier", c, ctx);
1503 //		}
1504 ::System::Type * TypeEmitter::complete_service_type(service_entry * entry)
1505 {
1506     Emit::TypeBuilder * type_builder = entry->m_type_builder;
1507     reflection::XServiceTypeDescription2 * xServiceType = entry->m_xType;
1508 
1509     //Create the private default constructor
1510     Emit::ConstructorBuilder* ctor_builder =
1511         type_builder->DefineConstructor(
1512             (MethodAttributes) (MethodAttributes::Private |
1513                                 MethodAttributes::HideBySig |
1514                                 MethodAttributes::SpecialName |
1515                                 MethodAttributes::RTSpecialName),
1516             CallingConventions::Standard, NULL);
1517 
1518     Emit::ILGenerator* ilGen = ctor_builder->GetILGenerator();
1519     ilGen->Emit( Emit::OpCodes::Ldarg_0 ); // push this
1520     ilGen->Emit(
1521             Emit::OpCodes::Call,
1522             type_builder->BaseType->GetConstructor(new ::System::Type*[0]));
1523     ilGen->Emit( Emit::OpCodes::Ret );
1524 
1525 
1526     //Create the service constructors.
1527     //obtain the interface which makes up this service, it is the return
1528     //type of the constructor functions
1529     Reference<reflection::XInterfaceTypeDescription2> xIfaceType(
1530         xServiceType->getInterface(), UNO_QUERY);
1531     if (xIfaceType.is () == sal_False)
1532         xIfaceType = resolveInterfaceTypedef(xServiceType->getInterface());
1533     System::Type * retType = get_type(xIfaceType);
1534 
1535     //Create the ConstructorInfo for a DeploymentException
1536     ::System::Type * typeDeploymentExc =
1537           get_type(S"unoidl.com.sun.star.uno.DeploymentException", true);
1538 
1539     ::System::Type * arTypeCtor[] = {__typeof(::System::String),
1540                                          __typeof(::System::Object)};
1541     ::System::Reflection::ConstructorInfo * ctorDeploymentException  =
1542           typeDeploymentExc->GetConstructor(arTypeCtor);
1543 
1544     Sequence<Reference<reflection::XServiceConstructorDescription> >  seqCtors =
1545         xServiceType->getConstructors();
1546 
1547     ::System::Type * type_uno_exception = get_type(S"unoidl.com.sun.star.uno.Exception", true);
1548 
1549     for (int i = seqCtors.getLength() - 1; i >= 0; i--)
1550     {
1551         bool bParameterArray = false;
1552         ::System::Type * typeAny = __typeof(::uno::Any);
1553         const Reference<reflection::XServiceConstructorDescription> & ctorDes =
1554             seqCtors[i];
1555         //obtain the parameter types
1556         Sequence<Reference<reflection::XParameter> > seqParams =
1557             ctorDes->getParameters();
1558         Reference<reflection::XParameter> const * arXParams = seqParams.getConstArray();
1559         sal_Int32 cParams = seqParams.getLength();
1560         ::System::Type * arTypeParameters[] = new ::System::Type* [cParams + 1];
1561         arTypeParameters[0] = get_type(S"unoidl.com.sun.star.uno.XComponentContext", true);
1562         for (int iparam = 0; iparam != cParams; iparam++)
1563         {
1564             if (arXParams[iparam]->isRestParameter())
1565                 arTypeParameters[iparam + 1] = __typeof(::uno::Any[]);
1566             else
1567                 arTypeParameters[iparam + 1] = get_type(arXParams[iparam]->getType());
1568         }
1569         //The array arTypeParameters can contain:
1570 		//System.Type and uno.PolymorphicType.
1571 		//Passing PolymorphicType to MethodBuilder.DefineMethod will cause a problem.
1572 		//The exception will read something like no on information for parameter # d
1573 		//Maybe we need no override another Type method in PolymorphicType ...
1574 		//Until we have figured this out, we will create another array of System.Type which
1575 		//we pass on to DefineMethod.
1576 		::System::Type * arParamTypes[] = new ::System::Type * [cParams + 1];
1577 //        arParamTypes[0] = get_type(S"unoidl.com.sun.star.uno.XComponentContext", true);
1578 		for (int i = 0; i < cParams + 1; i++)
1579 		{
1580 			::uno::PolymorphicType * pT = dynamic_cast< ::uno::PolymorphicType * >(arTypeParameters[i]);
1581 			if (pT)
1582 				arParamTypes[i] = pT->OriginalType;
1583 			else
1584 				arParamTypes[i] = arTypeParameters[i];
1585 		}
1586         //define method
1587 		System::String * ctorName;
1588         if (ctorDes->isDefaultConstructor())
1589             ctorName = new ::System::String(S"create");
1590         else
1591             ctorName = ustring_to_String(ctorDes->getName());
1592         Emit::MethodBuilder* method_builder = type_builder->DefineMethod(
1593             ctorName,
1594             static_cast<MethodAttributes>(MethodAttributes::Public | MethodAttributes::HideBySig |
1595                                           MethodAttributes::Static),
1596             retType,
1597 //            arTypeParameters);
1598 			arParamTypes);
1599 
1600         //define UNO exception attribute (exceptions)--------------------------------------
1601         Emit::CustomAttributeBuilder* attrBuilder = get_service_exception_attribute(ctorDes);
1602         if (attrBuilder != NULL)
1603             method_builder->SetCustomAttribute(attrBuilder);
1604 
1605 		//-------------------------------------------------------------
1606         //define parameter attributes (paramarray), names etc.
1607         //The first parameter is the XComponentContext, which cannot be obtained
1608         //from reflection.
1609         //The context is not part of the idl description
1610         method_builder->DefineParameter(
1611             1, ParameterAttributes::In, S"the_context");
1612 
1613         Emit::ParameterBuilder * arParameterBuilder[] =
1614             new Emit::ParameterBuilder * [cParams];
1615         for (int iparam = 0; iparam != cParams; iparam++)
1616         {
1617             Reference<reflection::XParameter> const & aParam = arXParams[iparam];
1618             ::System::String * sParamName = ustring_to_String(aParam->getName());
1619 
1620             arParameterBuilder[iparam] = method_builder->DefineParameter(
1621                 iparam + 2, ParameterAttributes::In, sParamName);
1622 
1623             if (aParam->isRestParameter())
1624             {
1625                 bParameterArray = true;
1626                 //set the ParameterArrayAttribute
1627                 ::System::Reflection::ConstructorInfo* ctor_info =
1628                     __typeof(System::ParamArrayAttribute)->GetConstructor(
1629                         new ::System::Type*[0]);
1630                 Emit::CustomAttributeBuilder * attr_builder =
1631                     new Emit::CustomAttributeBuilder(ctor_info, new ::System::Object*[0]);
1632 				arParameterBuilder[iparam]->SetCustomAttribute(attr_builder);
1633                 break;
1634             }
1635         }
1636 
1637         Emit::ILGenerator * ilGen = method_builder->GetILGenerator();
1638 
1639         //Define locals ---------------------------------
1640         //XMultiComponentFactory
1641         Emit::LocalBuilder* local_factory =
1642             ilGen->DeclareLocal(
1643                 get_type(S"unoidl.com.sun.star.lang.XMultiComponentFactory", true));
1644 
1645         //The return type
1646         Emit::LocalBuilder* local_return_val =
1647             ilGen->DeclareLocal(retType);
1648 
1649         //Obtain the XMultiComponentFactory and throw an exception if we do not get one
1650         ilGen->Emit(Emit::OpCodes::Ldarg_0);
1651 
1652         ::System::Reflection::MethodInfo * methodGetServiceManager = get_type(
1653             S"unoidl.com.sun.star.uno.XComponentContext", true)
1654                 ->GetMethod(S"getServiceManager");
1655         ilGen->Emit(Emit::OpCodes::Callvirt, methodGetServiceManager);
1656         ilGen->Emit(Emit::OpCodes::Stloc, local_factory);
1657         ilGen->Emit(Emit::OpCodes::Ldloc, local_factory);
1658         Emit::Label label1 = ilGen->DefineLabel();
1659         ilGen->Emit(Emit::OpCodes::Brtrue, label1);
1660         //The string for the exception
1661         ::System::Text::StringBuilder * strbuilder = new ::System::Text::StringBuilder(256);
1662         strbuilder->Append(S"The service ");
1663         strbuilder->Append(to_cts_name(xServiceType->getName()));
1664         strbuilder->Append(S" could not be created. The context failed to supply the service manager.");
1665 
1666         ilGen->Emit(Emit::OpCodes::Ldstr, strbuilder->ToString());
1667         ilGen->Emit(Emit::OpCodes::Ldarg_0);
1668         ilGen->Emit(Emit::OpCodes::Newobj, ctorDeploymentException);
1669         ilGen->Emit(Emit::OpCodes::Throw);
1670         ilGen->MarkLabel(label1);
1671 
1672         //We create a try/ catch around the createInstanceWithContext, etc. functions
1673         //There are 3 cases
1674         //1. function do not specify exceptions. Then RuntimeExceptions are retrhown and other
1675         //   exceptions produce a DeploymentException.
1676         //2. function specify  Exception. Then all exceptions fly through
1677         //3. function specifies exceptions but no Exception. Then these are rethrown
1678         //   and other exceptions, except RuntimeException, produce a deployment exception.
1679         //In case there are no parameters we call
1680         //XMultiComponentFactory.createInstanceWithContext
1681 
1682         ::System::Collections::ArrayList * arExceptionTypes =
1683               get_service_ctor_method_exceptions_reduced(ctorDes->getExceptions());
1684         if (arExceptionTypes->Contains(
1685                 type_uno_exception) == false)
1686         {
1687             ilGen->BeginExceptionBlock();
1688         }
1689         if (cParams == 0)
1690         {
1691             ilGen->Emit(Emit::OpCodes::Ldloc, local_factory);
1692             ilGen->Emit(Emit::OpCodes::Ldstr, ustring_to_String(xServiceType->getName()));
1693             ilGen->Emit(Emit::OpCodes::Ldarg_0);
1694 
1695             ::System::Reflection::MethodInfo * methodCreate =
1696                     local_factory->get_LocalType()->GetMethod(S"createInstanceWithContext");
1697             ilGen->Emit(Emit::OpCodes::Callvirt, methodCreate);
1698         }
1699         else if(bParameterArray)
1700         {
1701             //Service constructor with parameter array
1702             ilGen->Emit(Emit::OpCodes::Ldloc, local_factory);
1703             ilGen->Emit(Emit::OpCodes::Ldstr, ustring_to_String(xServiceType->getName()));
1704             ilGen->Emit(Emit::OpCodes::Ldarg_1);
1705             ilGen->Emit(Emit::OpCodes::Ldarg_0);
1706             ::System::Reflection::MethodInfo * methodCreate =
1707                     local_factory->get_LocalType()->GetMethod(S"createInstanceWithArgumentsAndContext");
1708             ilGen->Emit(Emit::OpCodes::Callvirt, methodCreate);
1709         }
1710         else
1711         {
1712             // Any param1, Any param2, etc.
1713             // For each parameter,except the component context, and parameter array
1714             // and Any is created.
1715             Emit::LocalBuilder * arLocalAny[] = new Emit::LocalBuilder* [cParams];
1716 
1717             for (int iParam = 0; iParam < cParams; iParam ++)
1718             {
1719                 arLocalAny[iParam] = ilGen->DeclareLocal(typeAny);
1720             }
1721 
1722             //Any[]. This array is filled with the created Anys which contain the parameters
1723             //and the values contained in the parameter array
1724             Emit::LocalBuilder * local_anyParams =
1725                 ilGen->DeclareLocal(__typeof(::uno::Any[]));
1726 
1727             //Create the Any for every argument, except for the parameter array
1728             //arLocalAny contains the LocalBuilder for all these parameters.
1729             //we call the ctor Any(Type, Object)
1730 			//If the parameter is an Any then the Any is created with Any(param.Type, param.Value);
1731             ::System::Type * arTypesCtorAny[] = {__typeof(::System::Type),
1732                                                     __typeof(::System::Object)};
1733             ::System::Reflection::ConstructorInfo * ctorAny =
1734                 typeAny->GetConstructor( arTypesCtorAny);
1735 			::System::Reflection::MethodInfo * methodAnyGetType =
1736 				typeAny->GetProperty(S"Type")->GetGetMethod();
1737 			::System::Reflection::MethodInfo * methodAnyGetValue =
1738 				typeAny->GetProperty(S"Value")->GetGetMethod();
1739             for (int i = 0; i < arLocalAny->Length; i ++)
1740             {
1741 				//check if the parameter is a polymorphic struct
1742 				::uno::PolymorphicType *polyType = dynamic_cast< ::uno::PolymorphicType* >(arTypeParameters[i+1]);
1743 				//arTypeParameters[i+1] = polyType->OriginalType;
1744 				if (polyType)
1745 				{
1746 					//It is a polymorphic struct
1747 					//Load the uninitialized local Any on which we will call the ctor
1748 					ilGen->Emit(Emit::OpCodes::Ldloca, arLocalAny[i]);
1749 					// Call PolymorphicType PolymorphicType::GetType(Type t, String polyName)
1750 					// Prepare the first parameter
1751 					ilGen->Emit(Emit::OpCodes::Ldtoken, polyType->get_OriginalType());
1752 					::System::Type * arTypeParams[] = {__typeof(::System::RuntimeTypeHandle)};
1753 					ilGen->Emit(Emit::OpCodes::Call,
1754 								__typeof(::System::Type)->GetMethod(
1755 									S"GetTypeFromHandle", arTypeParams));
1756 					// Prepare the second parameter
1757 					ilGen->Emit(Emit::OpCodes::Ldstr, polyType->get_PolymorphicName());
1758 					// Make the actual call
1759 					::System::Type * arTypeParam_GetType[] = {
1760 						__typeof(::System::Type), __typeof(::System::String) };
1761 					ilGen->Emit(Emit::OpCodes::Call,
1762 					__typeof(::uno::PolymorphicType)->GetMethod(new System::String(S"GetType"),
1763 						arTypeParam_GetType));
1764 
1765 					//Stack is: localAny, PolymorphicType
1766 					//Call Any::Any(Type, Object)
1767 					//Prepare the second parameter for the any ctor
1768 					ilGen->Emit(Emit::OpCodes::Ldarg, i + 1);
1769 					// if the parameter is a value type then we need to box it, because
1770 					// the Any ctor takes an Object
1771 					if (arTypeParameters[i+1]->IsValueType)
1772 						ilGen->Emit(Emit::OpCodes::Box, arTypeParameters[i+1]);
1773 					ilGen->Emit(Emit::OpCodes::Call, ctorAny);
1774 				}
1775 				else if (arTypeParameters[i+1] == typeAny)
1776 				{
1777 					//Create the call new Any(param.Type,param,Value)
1778 					//Stack must be Any,Type,Value
1779 					//First load the Any which is to be constructed
1780 					ilGen->Emit(Emit::OpCodes::Ldloca, arLocalAny[i]);
1781 					//Load the Type, which is obtained by calling param.Type
1782 					ilGen->Emit(Emit::OpCodes::Ldarga, i + 1);
1783 					ilGen->Emit(Emit::OpCodes::Call, methodAnyGetType);
1784 					//Load the Value, which is obtained by calling param.Value
1785 					ilGen->Emit(Emit::OpCodes::Ldarga, i + 1);
1786 					ilGen->Emit(Emit::OpCodes::Call, methodAnyGetValue);
1787 					//Call the Any ctor.
1788 					ilGen->Emit(Emit::OpCodes::Call, ctorAny);
1789 				}
1790 				else
1791 				{
1792 					ilGen->Emit(Emit::OpCodes::Ldloca, arLocalAny[i]);
1793 					ilGen->Emit(Emit::OpCodes::Ldtoken, arTypeParameters[i+1]);
1794 
1795 					::System::Type * arTypeParams[] = {__typeof(::System::RuntimeTypeHandle)};
1796 					ilGen->Emit(Emit::OpCodes::Call,
1797 								__typeof(::System::Type)->GetMethod(
1798 									S"GetTypeFromHandle", arTypeParams));
1799 					ilGen->Emit(Emit::OpCodes::Ldarg, i + 1);
1800 					// if the parameter is a value type then we need to box it, because
1801 					// the Any ctor takes an Object
1802 					if (arTypeParameters[i+1]->IsValueType)
1803 						ilGen->Emit(Emit::OpCodes::Box, arTypeParameters[i+1]);
1804 					ilGen->Emit(Emit::OpCodes::Call, ctorAny);
1805 				}
1806             }
1807 
1808             //Create the Any[] that is passed to the
1809             //createInstanceWithContext[AndArguments] function
1810             ilGen->Emit(Emit::OpCodes::Ldc_I4, arLocalAny->Length);
1811             ilGen->Emit(Emit::OpCodes::Newarr, typeAny);
1812             ilGen->Emit(Emit::OpCodes::Stloc, local_anyParams);
1813 
1814             //Assign all anys created from the parameters
1815             //array to the Any[]
1816             for (int i = 0; i < arLocalAny->Length; i++)
1817             {
1818                 ilGen->Emit(Emit::OpCodes::Ldloc, local_anyParams);
1819                 ilGen->Emit(Emit::OpCodes::Ldc_I4, i);
1820                 ilGen->Emit(Emit::OpCodes::Ldelema, typeAny);
1821                 ilGen->Emit(Emit::OpCodes::Ldloc, arLocalAny[i]);
1822                 ilGen->Emit(Emit::OpCodes::Stobj, typeAny);
1823             }
1824             // call createInstanceWithContextAndArguments
1825             ilGen->Emit(Emit::OpCodes::Ldloc, local_factory);
1826             ilGen->Emit(Emit::OpCodes::Ldstr, ustring_to_String(xServiceType->getName()));
1827             ilGen->Emit(Emit::OpCodes::Ldloc, local_anyParams);
1828             ilGen->Emit(Emit::OpCodes::Ldarg_0);
1829             ::System::Reflection::MethodInfo * methodCreate =
1830                     local_factory->get_LocalType()->GetMethod(S"createInstanceWithArgumentsAndContext");
1831             ilGen->Emit(Emit::OpCodes::Callvirt, methodCreate);
1832         }
1833         //cast the object returned by the functions createInstanceWithContext or
1834         //createInstanceWithArgumentsAndContext to the interface type
1835         ilGen->Emit(Emit::OpCodes::Castclass, retType);
1836         ilGen->Emit(Emit::OpCodes::Stloc, local_return_val);
1837 
1838         //catch exceptions thrown by createInstanceWithArgumentsAndContext and createInstanceWithContext
1839         if (arExceptionTypes->Contains(type_uno_exception) == false)
1840         {
1841             // catch (unoidl.com.sun.star.uno.RuntimeException) {throw;}
1842             ilGen->BeginCatchBlock(get_type(S"unoidl.com.sun.star.uno.RuntimeException", true));
1843             ilGen->Emit(Emit::OpCodes::Pop);
1844             ilGen->Emit(Emit::OpCodes::Rethrow);
1845 
1846             //catch and rethrow all other defined Exceptions
1847             for (int i = 0; i < arExceptionTypes->Count; i++)
1848             {
1849                 ::System::Type * excType = __try_cast< ::System::Type* >(
1850                     arExceptionTypes->get_Item(i));
1851                 if (excType->IsInstanceOfType(
1852                         get_type(S"unoidl.com.sun.star.uno.RuntimeException", true)))
1853                 {// we have a catch for RuntimeException already defined
1854                     continue;
1855                 }
1856 
1857                 //catch Exception and rethrow
1858                 ilGen->BeginCatchBlock(excType);
1859                 ilGen->Emit(Emit::OpCodes::Pop);
1860                 ilGen->Emit(Emit::OpCodes::Rethrow);
1861             }
1862             //catch (unoidl.com.sun.star.uno.Exception) {throw DeploymentException...}
1863             ilGen->BeginCatchBlock(type_uno_exception);
1864 
1865             //Define the local variabe that keeps the exception
1866              Emit::LocalBuilder * local_exception = ilGen->DeclareLocal(
1867                  type_uno_exception);
1868 
1869              //Store the exception
1870              ilGen->Emit(Emit::OpCodes::Stloc, local_exception);
1871 
1872             //prepare the construction of the exception
1873              strbuilder = new ::System::Text::StringBuilder(256);
1874              strbuilder->Append(S"The context (com.sun.star.uno.XComponentContext) failed to supply the service ");
1875              strbuilder->Append(to_cts_name(xServiceType->getName()));
1876              strbuilder->Append(S": ");
1877 
1878              ilGen->Emit(Emit::OpCodes::Ldstr, strbuilder->ToString());
1879 
1880             //add to the string the Exception.Message
1881             ilGen->Emit(Emit::OpCodes::Ldloc, local_exception);
1882             ilGen->Emit(Emit::OpCodes::Callvirt,
1883                         type_uno_exception->GetProperty(S"Message")->GetGetMethod());
1884             ::System::Type * arConcatParams [] = {__typeof(System::String),
1885                                                   __typeof(System::String)};
1886             ilGen->Emit(Emit::OpCodes::Call,
1887                         __typeof(System::String)->GetMethod(S"Concat", arConcatParams));
1888             //load contex argument
1889             ilGen->Emit(Emit::OpCodes::Ldarg_0);
1890             ilGen->Emit(Emit::OpCodes::Newobj, ctorDeploymentException);
1891             ilGen->Emit(Emit::OpCodes::Throw);//Exception(typeDeploymentExc);
1892 
1893             ilGen->EndExceptionBlock();
1894         }
1895 
1896 
1897         //Check if the service instance was create and throw a exception if not.
1898         Emit::Label label_service_created = ilGen->DefineLabel();
1899         ilGen->Emit(Emit::OpCodes::Ldloc, local_return_val);
1900         ilGen->Emit(Emit::OpCodes::Brtrue_S, label_service_created);
1901 
1902         strbuilder = new ::System::Text::StringBuilder(256);
1903         strbuilder->Append(S"The context (com.sun.star.uno.XComponentContext) failed to supply the service ");
1904         strbuilder->Append(to_cts_name(xServiceType->getName()));
1905         strbuilder->Append(S".");
1906         ilGen->Emit(Emit::OpCodes::Ldstr, strbuilder->ToString());
1907         ilGen->Emit(Emit::OpCodes::Ldarg_0);
1908         ilGen->Emit(Emit::OpCodes::Newobj, ctorDeploymentException);
1909         ilGen->Emit(Emit::OpCodes::Throw);//Exception(typeDeploymentExc);
1910 
1911         ilGen->MarkLabel(label_service_created);
1912         ilGen->Emit(Emit::OpCodes::Ldloc, local_return_val);
1913         ilGen->Emit(Emit::OpCodes::Ret);
1914 
1915     }
1916     // remove from incomplete types map
1917     ::System::String * cts_name = type_builder->get_FullName();
1918     m_incomplete_services->Remove( cts_name );
1919     xServiceType->release();
1920     if (g_verbose)
1921     {
1922         ::System::Console::WriteLine(
1923             "> emitting service type {0}", cts_name );
1924     }
1925     return type_builder->CreateType();
1926 }
1927 
1928 
1929 Emit::CustomAttributeBuilder* TypeEmitter::get_service_exception_attribute(
1930     const Reference<reflection::XServiceConstructorDescription> & ctorDes  )
1931 {
1932     return get_exception_attribute(ctorDes->getExceptions());
1933 }
1934 
1935 Emit::CustomAttributeBuilder* TypeEmitter::get_iface_method_exception_attribute(
1936     const Reference< reflection::XInterfaceMethodTypeDescription >& xMethod )
1937 {
1938 
1939     const Sequence<Reference<reflection::XTypeDescription> > seqTD = xMethod->getExceptions();
1940     int len = seqTD.getLength();
1941     Sequence<Reference<reflection::XCompoundTypeDescription> > seqCTD(len);
1942     Reference<reflection::XCompoundTypeDescription> * arCTD = seqCTD.getArray();
1943     for (int i = 0; i < len; i++)
1944         arCTD[i] = Reference<reflection::XCompoundTypeDescription>(seqTD[i], UNO_QUERY_THROW);
1945     return get_exception_attribute(seqCTD);
1946 }
1947 
1948 Emit::CustomAttributeBuilder* TypeEmitter::get_exception_attribute(
1949 
1950     const Sequence<Reference< reflection::XCompoundTypeDescription > >& seq_exceptionsTd )
1951 {
1952     Emit::CustomAttributeBuilder * attr_builder = NULL;
1953 
1954     Reference< reflection::XCompoundTypeDescription > const * exceptions =
1955         seq_exceptionsTd.getConstArray();
1956 
1957     ::System::Type * arTypesCtor[] = {::System::Type::GetType(S"System.Type[]")};
1958     ConstructorInfo * ctor_ExceptionAttribute =
1959         __typeof(::uno::ExceptionAttribute)->GetConstructor(arTypesCtor);
1960 
1961     sal_Int32 exc_length = seq_exceptionsTd.getLength();
1962     if (exc_length != 0) // opt
1963     {
1964         ::System::Type * exception_types [] =
1965               new ::System::Type * [ exc_length ];
1966         for ( sal_Int32 exc_pos = 0; exc_pos < exc_length; ++exc_pos )
1967         {
1968             Reference< reflection::XCompoundTypeDescription > const & xExc =
1969                 exceptions[ exc_pos ];
1970             exception_types[ exc_pos ] = get_type( xExc );
1971         }
1972         ::System::Object * args [] = {exception_types};
1973         attr_builder = new Emit::CustomAttributeBuilder(
1974             ctor_ExceptionAttribute, args );
1975     }
1976     return attr_builder;
1977 }
1978 
1979 
1980 ::System::Type * TypeEmitter::complete_singleton_type(singleton_entry * entry)
1981 {
1982     Emit::TypeBuilder * type_builder = entry->m_type_builder;
1983     reflection::XSingletonTypeDescription2 * xSingletonType = entry->m_xType;
1984     ::System::String* sSingletonName = to_cts_name(xSingletonType->getName());
1985 
1986     //Create the private default constructor
1987     Emit::ConstructorBuilder* ctor_builder =
1988         type_builder->DefineConstructor(
1989             static_cast<MethodAttributes>(MethodAttributes::Private |
1990                                           MethodAttributes::HideBySig |
1991                                           MethodAttributes::SpecialName |
1992                                           MethodAttributes::RTSpecialName),
1993             CallingConventions::Standard, NULL);
1994 
1995     Emit::ILGenerator* ilGen = ctor_builder->GetILGenerator();
1996     ilGen->Emit( Emit::OpCodes::Ldarg_0 ); // push this
1997     ilGen->Emit(
1998             Emit::OpCodes::Call,
1999             type_builder->BaseType->GetConstructor(new ::System::Type*[0]));
2000     ilGen->Emit( Emit::OpCodes::Ret );
2001 
2002 
2003     //obtain the interface which makes up this service, it is the return
2004     //type of the constructor functions
2005     Reference<reflection::XInterfaceTypeDescription2> xIfaceType(
2006         xSingletonType->getInterface(), UNO_QUERY);
2007     if (xIfaceType.is () == sal_False)
2008         xIfaceType = resolveInterfaceTypedef(xSingletonType->getInterface());
2009     System::Type * retType = get_type(xIfaceType);
2010 
2011     //define method
2012     ::System::Type * arTypeParameters[] = {get_type(S"unoidl.com.sun.star.uno.XComponentContext", true)};
2013     Emit::MethodBuilder* method_builder = type_builder->DefineMethod(
2014         new System::String(S"get"),
2015         static_cast<MethodAttributes>(MethodAttributes::Public | MethodAttributes::HideBySig |
2016                                       MethodAttributes::Static),
2017         retType,
2018         arTypeParameters);
2019 
2020 
2021 //         method_builder->SetCustomAttribute(get_service_ctor_method_attribute(ctorDes));
2022 
2023     //The first parameter is the XComponentContext, which cannot be obtained
2024     //from reflection.
2025     //The context is not part of the idl description
2026     method_builder->DefineParameter(1, ParameterAttributes::In, S"the_context");
2027 
2028 
2029     ilGen = method_builder->GetILGenerator();
2030     //Define locals ---------------------------------
2031 	// Any, returned by XComponentContext.getValueByName
2032 	Emit::LocalBuilder* local_any =
2033 		ilGen->DeclareLocal(__typeof(::uno::Any));
2034 
2035     //Call XContext::getValueByName
2036     ilGen->Emit(Emit::OpCodes::Ldarg_0);
2037     // build the singleton name : /singleton/unoidl.com.sun.star.XXX
2038     ::System::Text::StringBuilder* sBuilder =
2039           new ::System::Text::StringBuilder(S"/singletons/");
2040     sBuilder->Append(sSingletonName);
2041     ilGen->Emit(Emit::OpCodes::Ldstr, sBuilder->ToString());
2042 
2043     ::System::Reflection::MethodInfo * methodGetValueByName =
2044           get_type(S"unoidl.com.sun.star.uno.XComponentContext", true)->GetMethod(S"getValueByName");
2045     ilGen->Emit(Emit::OpCodes::Callvirt, methodGetValueByName);
2046     ilGen->Emit(Emit::OpCodes::Stloc_0);
2047 
2048     //Contains the returned Any a value?
2049     ilGen->Emit(Emit::OpCodes::Ldloca_S, local_any);
2050     ::System::Reflection::MethodInfo * methodHasValue =
2051           __typeof(::uno::Any)->GetMethod(S"hasValue");
2052     ilGen->Emit(Emit::OpCodes::Call, methodHasValue);
2053 
2054     //If not, then throw an DeploymentException
2055     Emit::Label label_singleton_exists = ilGen->DefineLabel();
2056     ilGen->Emit(Emit::OpCodes::Brtrue_S, label_singleton_exists);
2057     sBuilder = new ::System::Text::StringBuilder(
2058         S"Component context fails to supply singleton ");
2059     sBuilder->Append(sSingletonName);
2060     sBuilder->Append(S" of type ");
2061     sBuilder->Append(retType->FullName);
2062     sBuilder->Append(S".");
2063     ilGen->Emit(Emit::OpCodes::Ldstr, sBuilder->ToString());
2064     ilGen->Emit(Emit::OpCodes::Ldarg_0);
2065     ::System::Type * arTypesCtorDeploymentException[] = {
2066         __typeof(::System::String), __typeof(::System::Object)};
2067     ilGen->Emit(Emit::OpCodes::Newobj,
2068                 get_type(S"unoidl.com.sun.star.uno.DeploymentException",true)
2069                 ->GetConstructor(arTypesCtorDeploymentException));
2070     ilGen->Emit(Emit::OpCodes::Throw);
2071     ilGen->MarkLabel(label_singleton_exists);
2072 
2073     //Cast the singleton contained in the Any to the expected interface and return it.
2074     ilGen->Emit(Emit::OpCodes::Ldloca_S, local_any);
2075     ilGen->Emit(Emit::OpCodes::Call,  __typeof(::uno::Any)->GetProperty(S"Value")->GetGetMethod());
2076     ilGen->Emit(Emit::OpCodes::Castclass, retType);
2077     ilGen->Emit(Emit::OpCodes::Ret);
2078 
2079     // remove from incomplete types map
2080     ::System::String * cts_name = type_builder->get_FullName();
2081     m_incomplete_singletons->Remove( cts_name );
2082     xSingletonType->release();
2083     if (g_verbose)
2084     {
2085         ::System::Console::WriteLine(
2086             "> emitting singleton type {0}", cts_name );
2087     }
2088     return type_builder->CreateType();
2089 }
2090 
2091 
2092 //______________________________________________________________________________
2093 ::System::Type * TypeEmitter::get_type(
2094     Reference< reflection::XTypeDescription > const & xType )
2095 {
2096     switch (xType->getTypeClass())
2097     {
2098     case TypeClass_VOID:
2099         return __typeof (::System::Void);
2100     case TypeClass_CHAR:
2101         return __typeof (::System::Char);
2102     case TypeClass_BOOLEAN:
2103         return __typeof (::System::Boolean);
2104     case TypeClass_BYTE:
2105         return __typeof (::System::Byte);
2106     case TypeClass_SHORT:
2107         return __typeof (::System::Int16);
2108     case TypeClass_UNSIGNED_SHORT:
2109         return __typeof (::System::UInt16);
2110     case TypeClass_LONG:
2111         return __typeof (::System::Int32);
2112     case TypeClass_UNSIGNED_LONG:
2113         return __typeof (::System::UInt32);
2114     case TypeClass_HYPER:
2115         return __typeof (::System::Int64);
2116     case TypeClass_UNSIGNED_HYPER:
2117         return __typeof (::System::UInt64);
2118     case TypeClass_FLOAT:
2119         return __typeof (::System::Single);
2120     case TypeClass_DOUBLE:
2121         return __typeof (::System::Double);
2122     case TypeClass_STRING:
2123         return __typeof (::System::String);
2124     case TypeClass_TYPE:
2125         return __typeof (::System::Type);
2126     case TypeClass_ANY:
2127         return __typeof(::uno::Any);
2128     case TypeClass_ENUM:
2129         return get_type( Reference< reflection::XEnumTypeDescription >(
2130                              xType, UNO_QUERY_THROW ) );
2131     case TypeClass_TYPEDEF:
2132         // unwind typedefs
2133         return get_type(
2134             Reference< reflection::XIndirectTypeDescription >(
2135                 xType, UNO_QUERY_THROW )->getReferencedType() );
2136     case TypeClass_STRUCT:
2137     case TypeClass_EXCEPTION:
2138         return get_type(
2139             Reference< reflection::XCompoundTypeDescription >(
2140                 xType, UNO_QUERY_THROW ) );
2141     case TypeClass_SEQUENCE:
2142     {
2143         ::System::Type * element_type = get_type(
2144             Reference< reflection::XIndirectTypeDescription >(
2145                 xType, UNO_QUERY_THROW )->getReferencedType() );
2146 		::System::Type * retType = get_type(
2147             ::System::String::Concat(
2148                 element_type->get_FullName(), S"[]" ), true );
2149 
2150 		::uno::PolymorphicType * pt = dynamic_cast< ::uno::PolymorphicType * >(element_type);
2151 		if (pt)
2152 		{
2153 			::System::String * sName = ::System::String::Concat(pt->PolymorphicName, S"[]");
2154 			retType = ::uno::PolymorphicType::GetType(retType, sName);
2155 		}
2156         return retType;
2157     }
2158     case TypeClass_INTERFACE:
2159         return get_type(
2160             Reference< reflection::XInterfaceTypeDescription2 >(
2161                 xType, UNO_QUERY_THROW ) );
2162     case TypeClass_CONSTANT:
2163         return get_type(
2164             Reference< reflection::XConstantTypeDescription >(
2165                 xType, UNO_QUERY_THROW ) );
2166     case TypeClass_CONSTANTS:
2167         return get_type(
2168             Reference< reflection::XConstantsTypeDescription >(
2169                 xType, UNO_QUERY_THROW ) );
2170     case TypeClass_SERVICE:
2171 		return get_type(
2172 			Reference< reflection::XServiceTypeDescription2 >(
2173 				xType, UNO_QUERY_THROW) );
2174     case TypeClass_SINGLETON:
2175 		return get_type(
2176 			Reference< reflection::XSingletonTypeDescription2 >(
2177 				xType, UNO_QUERY_THROW) );
2178     case TypeClass_MODULE:
2179         // ignore these
2180         return 0;
2181     default:
2182         throw RuntimeException(
2183             OUSTR("unexpected type ") + xType->getName(),
2184             Reference< XInterface >() );
2185     }
2186 }
2187 
2188 //______________________________________________________________________________
2189 ::System::Type * TypeEmitter::get_complete_struct( ::System::String * sName)
2190 {
2191     struct_entry * pStruct = __try_cast< struct_entry *>(
2192         m_incomplete_structs->get_Item(sName));
2193     if (pStruct)
2194     {
2195         complete_struct_type(pStruct);
2196     }
2197     //get_type will asked the module builder for the type or otherwise all known assemblies.
2198     return get_type(sName, true);
2199 }
2200 void TypeEmitter::Dispose()
2201 {
2202     while (true)
2203     {
2204         ::System::Collections::IDictionaryEnumerator * enumerator =
2205               m_incomplete_ifaces->GetEnumerator();
2206         if (! enumerator->MoveNext())
2207             break;
2208         complete_iface_type(
2209             __try_cast< iface_entry * >( enumerator->get_Value() ) );
2210     }
2211 
2212     while (true)
2213     {
2214         ::System::Collections::IDictionaryEnumerator * enumerator =
2215               m_incomplete_structs->GetEnumerator();
2216         if (! enumerator->MoveNext())
2217             break;
2218         complete_struct_type(
2219             __try_cast< struct_entry * >( enumerator->get_Value() ) );
2220     }
2221 
2222 
2223     while (true)
2224     {
2225         ::System::Collections::IDictionaryEnumerator * enumerator =
2226               m_incomplete_services->GetEnumerator();
2227         if (! enumerator->MoveNext())
2228             break;
2229         complete_service_type(
2230             __try_cast< service_entry * >( enumerator->get_Value() ) );
2231     }
2232 
2233     while (true)
2234     {
2235         ::System::Collections::IDictionaryEnumerator * enumerator =
2236               m_incomplete_singletons->GetEnumerator();
2237         if (! enumerator->MoveNext())
2238             break;
2239         complete_singleton_type(
2240             __try_cast< singleton_entry * >( enumerator->get_Value() ) );
2241     }
2242 }
2243 //______________________________________________________________________________
2244 TypeEmitter::TypeEmitter(
2245     ::System::Reflection::Emit::ModuleBuilder * module_builder,
2246     ::System::Reflection::Assembly * extra_assemblies [] )
2247     : m_module_builder( module_builder ),
2248       m_extra_assemblies( extra_assemblies ),
2249       m_method_info_Type_GetTypeFromHandle( 0 ),
2250       m_type_Exception( 0 ),
2251       m_type_RuntimeException( 0 ),
2252       m_incomplete_ifaces( new ::System::Collections::Hashtable() ),
2253       m_incomplete_structs( new ::System::Collections::Hashtable() ),
2254       m_incomplete_services(new ::System::Collections::Hashtable() ),
2255       m_incomplete_singletons(new ::System::Collections::Hashtable() ),
2256       m_generated_structs( new ::System::Collections::Hashtable() )
2257 {
2258     ::System::Type * param_types[] = new ::System::Type * [ 1 ];
2259     param_types[ 0 ] = __typeof (::System::RuntimeTypeHandle);
2260     m_method_info_Type_GetTypeFromHandle =
2261         __typeof (::System::Type)
2262           ->GetMethod( "GetTypeFromHandle", param_types );
2263 }
2264 
2265 ::System::Collections::ArrayList * TypeEmitter::get_service_ctor_method_exceptions_reduced(
2266     const Sequence<Reference<reflection::XCompoundTypeDescription> > & seqExceptionsTd)
2267 {
2268     if (seqExceptionsTd.getLength() == 0)
2269         return new ::System::Collections::ArrayList();
2270 
2271     ::System::Collections::ArrayList * arTypes = new ::System::Collections::ArrayList();
2272     for (int i = 0; i < seqExceptionsTd.getLength(); i++)
2273         arTypes->Add(get_type(to_cts_name(seqExceptionsTd[i]->getName()), true));
2274 
2275     int start = 0;
2276     while (true)
2277     {
2278         bool bRemove = false;
2279         for (int i = start; i < arTypes->Count; i++)
2280         {
2281             ::System::Type * t = __try_cast< ::System::Type* >(arTypes->get_Item(i));
2282             for (int j = 0; j < arTypes->Count; j++)
2283             {
2284                 if (t->IsSubclassOf(__try_cast< ::System::Type* >(arTypes->get_Item(j))))
2285                 {
2286                     arTypes->RemoveAt(i);
2287                     bRemove = true;
2288                     break;
2289                 }
2290             }
2291             if (bRemove)
2292                 break;
2293             start++;
2294         }
2295 
2296         if (bRemove == false)
2297             break;
2298     }
2299     return arTypes;
2300 }
2301 
2302 
2303 css::uno::Reference< css::reflection::XInterfaceTypeDescription2 >
2304 resolveInterfaceTypedef(
2305     const css::uno::Reference<css::reflection::XTypeDescription>& type)
2306 {
2307     Reference<reflection::XInterfaceTypeDescription2>
2308         xIfaceTd(type, UNO_QUERY);
2309 
2310     if (xIfaceTd.is())
2311         return xIfaceTd;
2312 
2313     Reference<reflection::XIndirectTypeDescription> xIndTd(
2314         type, UNO_QUERY);
2315     if (xIndTd.is() == sal_False)
2316         throw css::uno::Exception(
2317             OUSTR("resolveInterfaceTypedef was called with an invalid argument"), 0);
2318 
2319     return resolveInterfaceTypedef(xIndTd->getReferencedType());
2320 }
2321 
2322 
2323 }
2324