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 	// append []
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 an 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 need 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 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 needed 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 requires 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 variable 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 context 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 created 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 ask 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