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