1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: climaker_emit.cxx,v $
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"
46 using namespace ::System::Reflection
;
48 using namespace ::rtl
;
49 using namespace ::com::sun::star
;
50 using namespace ::com::sun::star::uno
;
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())
72 ((::System::Char
) *reinterpret_cast< sal_Unicode
const * >(
74 case TypeClass_BOOLEAN
:
77 sal_False
!= *reinterpret_cast< sal_Bool
const * >(
81 ((::System::Byte
) *reinterpret_cast< sal_Int8
const * >(
85 ((::System::Int16
) *reinterpret_cast< sal_Int16
const * >(
87 case TypeClass_UNSIGNED_SHORT
:
89 ((::System::UInt16
) *reinterpret_cast< sal_uInt16
const * >(
93 ((::System::Int32
) *reinterpret_cast< sal_Int32
const * >(
95 case TypeClass_UNSIGNED_LONG
:
97 ((::System::UInt32
) *reinterpret_cast< sal_uInt32
const * >(
101 ((::System::Int64
) *reinterpret_cast< sal_Int64
const * >(
103 case TypeClass_UNSIGNED_HYPER
:
105 ((::System::UInt64
) *reinterpret_cast< sal_uInt64
const * >(
107 case TypeClass_FLOAT
:
109 ((::System::Single
) *reinterpret_cast< float const * >(
111 case TypeClass_DOUBLE
:
113 ((::System::Double
) *reinterpret_cast< double const * >(
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
)
129 code
->Emit( Emit::OpCodes::Ldarg_0
);
132 code
->Emit( Emit::OpCodes::Ldarg_1
);
135 code
->Emit( Emit::OpCodes::Ldarg_2
);
138 code
->Emit( Emit::OpCodes::Ldarg_3
);
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
);
146 code
->Emit( Emit::OpCodes::Ldarg
, index
);
151 void polymorphicStructNameToStructName(::System::String
** sPolyName
)
153 if ((*sPolyName
)->EndsWith(S
">") == false)
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
168 if (typeName
->StartsWith(S
"["))//if (usUnoName[0] == '[')
173 if (typeName
->get_Chars(index
++) == ']')//if (usUnoName[index++] == ']')
175 if (typeName
->get_Chars(index
++) != '[')//usUnoName[index++] != '[')
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
));
216 //put "unoidl." at the beginning
217 buf
->Append(const_cast<System::String
*>(Constants::sUnoidl
));
218 buf
->Append(mapUnoPolymorphicName(sUnoName
));
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,
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('<');
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;
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
",");
263 System::String
* sParam
= unoName
->Substring(index
, cur
- index
);
266 //the the index to the beginning of the next param
268 builder
->Append(mapUnoTypeName(sParam
));
273 //continue until the matching '>'
277 System::Char curChar
= unoName
->Chars
[cur
];
282 else if (curChar
== '>')
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 */ );
309 iface_entry
* entry
= dynamic_cast< iface_entry
* >(
310 m_incomplete_ifaces
->get_Item( cts_name
) );
312 ret_type
= entry
->m_type_builder
;
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 */ );
325 ::System::Console::WriteLine(
326 "> resolving type {0} from {1}.",
327 cts_name
, ret_type
->get_Assembly()->get_FullName() );
334 return ret_type
->get_Assembly();
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.
347 // iface_entry * entry = dynamic_cast< iface_entry * >(
348 // m_incomplete_ifaces->get_Item( cts_name ) );
350 // ret_type = entry->m_type_builder;
352 //try the cli_basetypes assembly
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());
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
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"));
377 throw new ::System::Exception(sb
->ToString(), exc
);
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
);
407 type_builder
->DefineDefaultConstructor( c_ctor_method_attr
);
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
,
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
);
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
);
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
),
466 type_builder
->DefineDefaultConstructor( c_ctor_method_attr
);
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
,
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
);
486 type_Exception
->GetConstructor( param_types
) );
487 code
->Emit( Emit::OpCodes::Ret
);
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 */ );
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(
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 ),
524 (FieldAttributes
) (FieldAttributes::Public
|
525 FieldAttributes::Static
|
526 FieldAttributes::Literal
) );
527 field_builder
->SetConstant( constant
);
531 ::System::Console::WriteLine(
532 "> emitting constant type {0}", cts_name
);
534 ret_type
= type_builder
->CreateType();
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 */ );
547 Emit::TypeBuilder
* type_builder
=
548 m_module_builder
->DefineType(
550 (TypeAttributes
) (TypeAttributes::Public
|
551 TypeAttributes::Sealed
|
552 TypeAttributes::BeforeFieldInit
|
553 TypeAttributes::AnsiClass
) );
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
)
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 ),
574 (FieldAttributes
) (FieldAttributes::Public
|
575 FieldAttributes::Static
|
576 FieldAttributes::Literal
) );
577 field_builder
->SetConstant( constant
);
582 ::System::Console::WriteLine(
583 "> emitting constants group type {0}", cts_name
);
585 ret_type
= type_builder
->CreateType();
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 */ );
598 // Emit::EnumBuilder * enum_builder =
599 // m_module_builder->DefineEnum(
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(
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
] ),
632 (FieldAttributes
) (FieldAttributes::Public
|
633 FieldAttributes::Static
|
634 FieldAttributes::Literal
) );
635 field_builder
->SetConstant(
636 __box ((::System::Int32
) enum_values
[ enum_pos
]) );
641 ::System::Console::WriteLine(
642 "> emitting enum type {0}", cts_name
);
644 ret_type
= enum_builder
->CreateType();
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
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 */ );
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(
685 (TypeAttributes
) (TypeAttributes::Public
|
686 TypeAttributes::BeforeFieldInit
|
687 TypeAttributes::AnsiClass
),
691 // insert to be completed
692 struct_entry
* entry
= new struct_entry();
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(
711 if (xStructTypeDesc
.is())
713 Sequence
< Reference
< reflection::XTypeDescription
> > seqTypeArgs
= xStructTypeDesc
->getTypeArguments();
714 sal_Int32 numTypes
= seqTypeArgs
.getLength();
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
);
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 */ );
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
;
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
);
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();
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
;
799 //______________________________________________________________________________
800 ::System::Type
* TypeEmitter::get_type(
801 Reference
< reflection::XServiceTypeDescription2
> const & xType
)
803 if (xType
->isSingleInterfaceBased() == sal_False
)
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
)
811 TypeAttributes attr
= (TypeAttributes
) (TypeAttributes::Public
|
812 TypeAttributes::Sealed
|
813 TypeAttributes::BeforeFieldInit
|
814 TypeAttributes::AnsiClass
);
816 Emit::TypeBuilder
* type_builder
= m_module_builder
->DefineType(
819 // insert to be completed
820 service_entry
* entry
= new service_entry();
822 entry
->m_xType
= xType
.get();
823 entry
->m_type_builder
= type_builder
;
824 m_incomplete_services
->Add(cts_name
,entry
);
829 ::System::Type
* TypeEmitter::get_type(
830 Reference
<reflection::XSingletonTypeDescription2
> const & xType
)
832 if (xType
->isInterfaceBased() == sal_False
)
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
)
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(
849 // insert to be completed
850 singleton_entry
* entry
= new singleton_entry();
852 entry
->m_xType
= xType
.get();
853 entry
->m_type_builder
= type_builder
;
854 m_incomplete_singletons
->Add(cts_name
,entry
);
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
) );
883 // complete uncompleted base type first
884 complete_iface_type( base_entry
);
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
)
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);
917 if (TypeClass_INTERFACE_METHOD
== xMember
->getTypeClass())
919 Reference
< reflection::XInterfaceMethodTypeDescription
> xMethod(
920 xMember
, UNO_QUERY_THROW
);
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();
941 param_type
= get_type(
942 ::System::String::Concat(
943 param_type_name
, S
"&" ), true );
945 param_types
[ xParam
->getPosition() ] = param_type
;
951 // method_builder = type_builder->DefineMethod(
952 // ustring_to_String( xMethod->getMemberName() ),
953 // c_method_attr, tb,
956 method_builder
= type_builder
->DefineMethod(
957 ustring_to_String( xMethod
->getMemberName() ),
958 c_method_attr
, get_type( xMethod
->getReturnType() ),
960 // then define parameter infos
962 for ( ; params_pos
< params_length
; ++params_pos
)
964 Reference
< reflection::XMethodParameter
> const & xParam
=
965 parameters
[ params_pos
];
966 long param_flags
= 0;
968 param_flags
|= ParameterAttributes::In
;
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
),
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
);
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
),
1024 method_builder
->SetCustomAttribute(attrBuilder
);
1030 TypeClass_INTERFACE_ATTRIBUTE
== xMember
->getTypeClass() );
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
);
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())
1078 parameters
= new ::System::Type
* [ 1 ];
1079 parameters
[ 0 ] = attribute_type
;
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
);
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
)
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();
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
),
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
1151 dynamic_cast< struct_entry
* >(
1152 m_generated_structs
->get_Item(
1153 entry
->m_base_type
->get_FullName() ) );
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
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
) )
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
];
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
);
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
) );
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();
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
];
1265 OSL_ASSERT( all_members_length
== member_pos
);
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
];
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
);
1297 throw RuntimeException(
1298 OUSTR("unexpected member type in ") + entry
->m_xType
->getName(),
1299 Reference
< XInterface
>() );
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())
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
),
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
;
1334 entry
->m_member_names
[ member_pos
] = field_name
;
1335 entry
->m_param_types
[ member_pos
] = field_type
;
1337 all_members_length
+= members_length
;
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
);
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
);
1369 Emit::OpCodes::Ldtoken
, __typeof (::System::Void
) );
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
);
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
);
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();
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
];
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
;
1455 ::System::Console::WriteLine(
1456 "> emitting {0} type {1}",
1457 TypeClass_STRUCT
== entry
->m_xType
->getTypeClass()
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();
1472 ::System::Console::WriteLine(
1473 "> emitting struct type {0}", cts_name
);
1478 //Examples of generated code
1479 // public static XWeak constructor1(XComponentContext ctx)
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);
1486 // public static XWeak constructor2(XComponentContext ctx, int a, int b, Any c)
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);
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)
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);
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
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
=
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
[]);
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
]);
1585 arParamTypes
[i
] = pT
->OriginalType
;
1587 arParamTypes
[i
] = arTypeParameters
[i
];
1590 System::String
* ctorName
;
1591 if (ctorDes
->isDefaultConstructor())
1592 ctorName
= new ::System::String(S
"create");
1594 ctorName
= ustring_to_String(ctorDes
->getName());
1595 Emit::MethodBuilder
* method_builder
= type_builder
->DefineMethod(
1597 static_cast<MethodAttributes
>(MethodAttributes::Public
| MethodAttributes::HideBySig
|
1598 MethodAttributes::Static
),
1600 // arTypeParameters);
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
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
);
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));
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
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();
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
);
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;
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
);
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
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();
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
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
);
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
),
2024 // method_builder->SetCustomAttribute(get_service_ctor_method_attribute(ctorDes));
2026 //The first parameter is the XComponentContext, which cannot be obtained
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();
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
);
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
:
2137 Reference
< reflection::XIndirectTypeDescription
>(
2138 xType
, UNO_QUERY_THROW
)->getReferencedType() );
2139 case TypeClass_STRUCT
:
2140 case TypeClass_EXCEPTION
:
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
);
2156 ::System::String
* sName
= ::System::String::Concat(pt
->PolymorphicName
, S
"[]");
2157 retType
= ::uno::PolymorphicType::GetType(retType
, sName
);
2161 case TypeClass_INTERFACE
:
2163 Reference
< reflection::XInterfaceTypeDescription2
>(
2164 xType
, UNO_QUERY_THROW
) );
2165 case TypeClass_CONSTANT
:
2167 Reference
< reflection::XConstantTypeDescription
>(
2168 xType
, UNO_QUERY_THROW
) );
2169 case TypeClass_CONSTANTS
:
2171 Reference
< reflection::XConstantsTypeDescription
>(
2172 xType
, UNO_QUERY_THROW
) );
2173 case TypeClass_SERVICE
:
2175 Reference
< reflection::XServiceTypeDescription2
>(
2176 xType
, UNO_QUERY_THROW
) );
2177 case TypeClass_SINGLETON
:
2179 Reference
< reflection::XSingletonTypeDescription2
>(
2180 xType
, UNO_QUERY_THROW
) );
2181 case TypeClass_MODULE
:
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
));
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()
2207 ::System::Collections::IDictionaryEnumerator
* enumerator
=
2208 m_incomplete_ifaces
->GetEnumerator();
2209 if (! enumerator
->MoveNext())
2211 complete_iface_type(
2212 __try_cast
< iface_entry
* >( enumerator
->get_Value() ) );
2217 ::System::Collections::IDictionaryEnumerator
* enumerator
=
2218 m_incomplete_structs
->GetEnumerator();
2219 if (! enumerator
->MoveNext())
2221 complete_struct_type(
2222 __try_cast
< struct_entry
* >( enumerator
->get_Value() ) );
2228 ::System::Collections::IDictionaryEnumerator
* enumerator
=
2229 m_incomplete_services
->GetEnumerator();
2230 if (! enumerator
->MoveNext())
2232 complete_service_type(
2233 __try_cast
< service_entry
* >( enumerator
->get_Value() ) );
2238 ::System::Collections::IDictionaryEnumerator
* enumerator
=
2239 m_incomplete_singletons
->GetEnumerator();
2240 if (! enumerator
->MoveNext())
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));
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
);
2299 if (bRemove
== false)
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
);
2316 Reference
<reflection::XIndirectTypeDescription
> xIndTd(
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());