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