1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "climaker_share.h"
22 #include "rtl/string.hxx"
23 #include "rtl/ustrbuf.hxx"
24 #include "com/sun/star/reflection/XIndirectTypeDescription.hpp"
25 #include "com/sun/star/reflection/XStructTypeDescription.hpp"
26 #include "com/sun/star/reflection/XInterfaceTypeDescription2.hpp"
27 #include "com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp"
28 #include "com/sun/star/reflection/XInterfaceAttributeTypeDescription.hpp"
29 #include "com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp"
32 using namespace ::System::Reflection
;
34 using namespace ::com::sun::star
;
35 using namespace ::com::sun::star::uno
;
39 System::String
^ mapUnoPolymorphicName(System::String
^ unoName
);
41 static inline ::System::String
^ to_cts_name(
42 OUString
const & uno_name
)
44 return ustring_to_String("unoidl." + uno_name
);
48 static inline ::System::Object
^ to_cli_constant( Any
const & value
)
50 switch (value
.getValueTypeClass())
53 return ((::System::Char
) *reinterpret_cast< sal_Unicode
const * >(
55 case TypeClass_BOOLEAN
:
56 return ((::System::Boolean
)
57 sal_False
!= *reinterpret_cast< sal_Bool
const * >(
60 return ((::System::Byte
) *reinterpret_cast< sal_Int8
const * >(
63 return ((::System::Int16
) *reinterpret_cast< sal_Int16
const * >(
65 case TypeClass_UNSIGNED_SHORT
:
66 return ((::System::UInt16
) *reinterpret_cast< sal_uInt16
const * >(
69 return ((::System::Int32
) *reinterpret_cast< sal_Int32
const * >(
71 case TypeClass_UNSIGNED_LONG
:
72 return ((::System::UInt32
) *reinterpret_cast< sal_uInt32
const * >(
75 return ((::System::Int64
) *reinterpret_cast< sal_Int64
const * >(
77 case TypeClass_UNSIGNED_HYPER
:
78 return ((::System::UInt64
) *reinterpret_cast< sal_uInt64
const * >(
81 return ((::System::Single
) *reinterpret_cast< float const * >(
83 case TypeClass_DOUBLE
:
84 return ((::System::Double
) *reinterpret_cast< double const * >(
87 throw RuntimeException(
88 "unexpected constant type " +
89 value
.getValueType().getTypeName() );
94 static inline void emit_ldarg( Emit::ILGenerator
^ code
, ::System::Int32 index
)
99 #pragma warning (push)
100 #pragma warning (disable: 4538)
101 code
->Emit( Emit::OpCodes::Ldarg_0
);
102 #pragma warning (pop)
105 code
->Emit( Emit::OpCodes::Ldarg_1
);
108 code
->Emit( Emit::OpCodes::Ldarg_2
);
111 code
->Emit( Emit::OpCodes::Ldarg_3
);
115 code
->Emit( Emit::OpCodes::Ldarg_S
, (::System::Byte
) index
);
116 else if (index
< 0x8000)
117 code
->Emit( Emit::OpCodes::Ldarg_S
, (::System::Int16
) index
);
119 code
->Emit( Emit::OpCodes::Ldarg
, index
);
124 void polymorphicStructNameToStructName(::System::String
^* sPolyName
)
126 if ((*sPolyName
)->EndsWith(">") == false)
129 int index
= (*sPolyName
)->IndexOf('<');
130 OSL_ASSERT(index
!= -1);
131 *sPolyName
= (*sPolyName
)->Substring(0, index
);
135 System::String
^ mapUnoTypeName(System::String
^ typeName
)
137 ::System::Text::StringBuilder
^ buf
= gcnew
System::Text::StringBuilder();
138 ::System::String
^ sUnoName
= ::System::String::Copy(typeName
);
139 //determine if the type is a sequence and its dimensions
141 if (typeName
->StartsWith("["))//if (usUnoName[0] == '[')
146 if (typeName
[index
++] == ']')//if (usUnoName[index++] == ']')
148 if (typeName
[index
++] != '[')//usUnoName[index++] != '[')
151 sUnoName
= sUnoName
->Substring(index
- 1);//usUnoName = usUnoName.copy(index - 1);
153 if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoBool
)))
154 buf
->Append(const_cast<System::String
^>(Constants::sBoolean
));
155 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoChar
)))
156 buf
->Append(const_cast<System::String
^>(Constants::sChar
));
157 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoByte
)))
158 buf
->Append(const_cast<System::String
^>(Constants::sByte
));
159 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoShort
)))
160 buf
->Append(const_cast<System::String
^>(Constants::sInt16
));
161 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoUShort
)))
162 buf
->Append(const_cast<System::String
^>(Constants::sUInt16
));
163 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoLong
)))
164 buf
->Append(const_cast<System::String
^>(Constants::sInt32
));
165 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoULong
)))
166 buf
->Append(const_cast<System::String
^>(Constants::sUInt32
));
167 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoHyper
)))
168 buf
->Append(const_cast<System::String
^>(Constants::sInt64
));
169 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoUHyper
)))
170 buf
->Append(const_cast<System::String
^>(Constants::sUInt64
));
171 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoFloat
)))
172 buf
->Append(const_cast<System::String
^>(Constants::sSingle
));
173 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoDouble
)))
174 buf
->Append(const_cast<System::String
^>(Constants::sDouble
));
175 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoString
)))
176 buf
->Append(const_cast<System::String
^>(Constants::sString
));
177 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoVoid
)))
178 buf
->Append(const_cast<System::String
^>(Constants::sVoid
));
179 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoType
)))
180 buf
->Append(const_cast<System::String
^>(Constants::sType
));
181 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoXInterface
)))
182 buf
->Append(const_cast<System::String
^>(Constants::sObject
));
183 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoAny
)))
185 buf
->Append(const_cast<System::String
^>(Constants::sAny
));
189 //put "unoidl." at the beginning
190 buf
->Append(const_cast<System::String
^>(Constants::sUnoidl
));
191 buf
->Append(mapUnoPolymorphicName(sUnoName
));
195 buf
->Append(const_cast<System::String
^>(Constants::sBrackets
));
197 return buf
->ToString();
201 /** For example, there is a uno type
202 com.sun.star.Foo<char, long>.
203 The values in the type list
204 are uno types and are replaced by cli types, such as System.Char,
207 Strings can be as complicated as this
208 test.MyStruct<char,test.MyStruct<long, []string>>
210 System::String
^ mapUnoPolymorphicName(System::String
^ unoName
)
212 int index
= unoName
->IndexOf('<');
216 System::Text::StringBuilder
^ builder
=
217 gcnew
System::Text::StringBuilder(unoName
->Substring(0, index
+1 ));
219 //Find the first occurrence of ','
220 //If the parameter is a polymorphic struct then we neede to ignore everything
221 //between the brackets because it can also contain commas
222 //get the type list within < and >
223 int endIndex
= unoName
->Length
- 1;
227 while (cur
<= endIndex
)
229 System::Char c
= unoName
[cur
];
230 if (c
== ',' || c
== '>')
232 //insert a comma if needed
233 if (countParams
!= 0)
234 builder
->Append(",");
236 System::String
^ sParam
= unoName
->Substring(index
, cur
- index
);
239 //the index to the beginning of the next param
241 builder
->Append(mapUnoTypeName(sParam
));
246 //continue until the matching '>'
250 System::Char curChar
= unoName
[cur
];
255 else if (curChar
== '>')
267 builder
->Append((System::Char
) '>');
268 return builder
->ToString();
274 Assembly
^ TypeEmitter::type_resolve(
275 ::System::Object
^, ::System::ResolveEventArgs
^ args
)
277 ::System::String
^ cts_name
= args
->Name
;
278 ::System::Type
^ ret_type
;
280 iface_entry
^ entry
= dynamic_cast< iface_entry
^ >(m_incomplete_ifaces
[cts_name
] );
281 if (nullptr != entry
)
282 ret_type
= entry
->m_type_builder
;
284 if (nullptr == ret_type
)
286 sal_Int32 len
= m_extra_assemblies
->Length
;
287 for ( sal_Int32 pos
= 0; pos
< len
; ++pos
)
289 ret_type
= m_extra_assemblies
[ pos
]->GetType(
290 cts_name
, false /* no exc */ );
291 if (nullptr != ret_type
)
295 ::System::Console::WriteLine(
296 "> resolving type {0} from {1}.",
297 cts_name
, ret_type
->Assembly
->FullName
);
303 if (nullptr != ret_type
)
304 return ret_type
->Assembly
;
309 ::System::Type
^ TypeEmitter::get_type(
310 ::System::String
^ cts_name
, bool throw_exc
)
312 ::System::Type
^ ret_type
= m_module_builder
->GetType( cts_name
, false );
313 //We get the type from the ModuleBuilder even if the type is not complete
314 //but have been defined.
317 // iface_entry * entry = dynamic_cast< iface_entry * >(
318 // m_incomplete_ifaces->get_Item( cts_name ) );
320 // ret_type = entry->m_type_builder;
322 //try the cli_basetypes assembly
323 if (ret_type
== nullptr)
325 ::System::Text::StringBuilder
^ builder
= gcnew ::System::Text::StringBuilder(cts_name
);
326 builder
->Append(",cli_basetypes");
327 ret_type
= ::System::Type::GetType(builder
->ToString());
330 if (ret_type
== nullptr)
334 // may call on type_resolve()
335 return ::System::Type::GetType( cts_name
, throw_exc
);
337 catch (::System::Exception
^ exc
)
339 //If the type is not found one may have forgotten to specify assemblies with
341 ::System::Text::StringBuilder
^ sb
= gcnew ::System::Text::StringBuilder();
342 sb
->Append(gcnew ::System::String("\nThe type "));
343 sb
->Append(cts_name
);
344 sb
->Append(gcnew ::System::String(" \n could not be found. Did you forget to " \
345 "specify an additional assembly with the --reference option?\n"));
347 throw gcnew ::System::Exception(sb
->ToString(), exc
);
357 ::System::Type
^ TypeEmitter::get_type_Exception()
359 if (nullptr == m_type_Exception
)
361 m_type_Exception
= get_type(
362 "unoidl.com.sun.star.uno.Exception", false /* no exc */ );
363 if (nullptr == m_type_Exception
)
365 // define hardcoded type unoidl.com.sun.star.uno.Exception
366 Emit::TypeBuilder
^ type_builder
=
367 m_module_builder
->DefineType(
368 "unoidl.com.sun.star.uno.Exception",
369 (TypeAttributes
) (TypeAttributes::Public
|
370 TypeAttributes::BeforeFieldInit
|
371 TypeAttributes::AnsiClass
),
372 (::System::Exception::typeid) );
373 Emit::FieldBuilder
^ field_Context
= type_builder
->DefineField(
374 "Context", (::System::Object::typeid),
375 FieldAttributes::Public
);
377 type_builder
->DefineDefaultConstructor( c_ctor_method_attr
);
379 array
< ::System::Type
^>^ param_types
=
380 gcnew array
< ::System::Type
^>(2);
381 param_types
[ 0 ] = ::System::String::typeid;
382 param_types
[ 1 ] = ::System::Object::typeid;
383 Emit::ConstructorBuilder
^ ctor_builder
=
384 type_builder
->DefineConstructor(
385 c_ctor_method_attr
, CallingConventions::Standard
,
387 ctor_builder
->DefineParameter(
388 1, ParameterAttributes::In
, "Message" );
389 ctor_builder
->DefineParameter(
390 2, ParameterAttributes::In
, "Context" );
391 Emit::ILGenerator
^ code
= ctor_builder
->GetILGenerator();
392 code
->Emit( Emit::OpCodes::Ldarg_0
);
393 code
->Emit( Emit::OpCodes::Ldarg_1
);
394 param_types
= gcnew array
< ::System::Type
^>(1);
395 param_types
[ 0 ] = ::System::String::typeid;
398 (::System::Exception::typeid)
399 ->GetConstructor( param_types
) );
400 code
->Emit( Emit::OpCodes::Ldarg_0
);
401 code
->Emit( Emit::OpCodes::Ldarg_2
);
402 code
->Emit( Emit::OpCodes::Stfld
, field_Context
);
403 code
->Emit( Emit::OpCodes::Ret
);
407 ::System::Console::WriteLine(
408 "> emitting exception type "
409 "unoidl.com.sun.star.uno.Exception" );
411 m_type_Exception
= type_builder
->CreateType();
414 return m_type_Exception
;
418 ::System::Type
^ TypeEmitter::get_type_RuntimeException()
420 if (nullptr == m_type_RuntimeException
)
422 m_type_RuntimeException
= get_type(
423 "unoidl.com.sun.star.uno.RuntimeException", false /* no exc */ );
424 if (nullptr == m_type_RuntimeException
)
426 // define hardcoded type unoidl.com.sun.star.uno.RuntimeException
427 ::System::Type
^ type_Exception
= get_type_Exception();
428 Emit::TypeBuilder
^ type_builder
=
429 m_module_builder
->DefineType(
430 "unoidl.com.sun.star.uno.RuntimeException",
431 (TypeAttributes
) (TypeAttributes::Public
|
432 TypeAttributes::BeforeFieldInit
|
433 TypeAttributes::AnsiClass
),
436 type_builder
->DefineDefaultConstructor( c_ctor_method_attr
);
438 array
< ::System::Type
^>^ param_types
=
439 gcnew array
< ::System::Type
^>(2);
440 param_types
[ 0 ] = ::System::String::typeid;
441 param_types
[ 1 ] = ::System::Object::typeid;
442 Emit::ConstructorBuilder
^ ctor_builder
=
443 type_builder
->DefineConstructor(
444 c_ctor_method_attr
, CallingConventions::Standard
,
446 ctor_builder
->DefineParameter(
447 1, ParameterAttributes::In
, "Message" );
448 ctor_builder
->DefineParameter(
449 2, ParameterAttributes::In
, "Context" );
450 Emit::ILGenerator
^ code
= ctor_builder
->GetILGenerator();
451 code
->Emit( Emit::OpCodes::Ldarg_0
);
452 code
->Emit( Emit::OpCodes::Ldarg_1
);
453 code
->Emit( Emit::OpCodes::Ldarg_2
);
456 type_Exception
->GetConstructor( param_types
) );
457 code
->Emit( Emit::OpCodes::Ret
);
461 ::System::Console::WriteLine(
462 "> emitting exception type "
463 "unoidl.com.sun.star.uno.RuntimeException" );
465 m_type_RuntimeException
= type_builder
->CreateType();
468 return m_type_RuntimeException
;
472 ::System::Type
^ TypeEmitter::get_type(
473 Reference
< reflection::XConstantTypeDescription
> const & xType
)
475 ::System::String
^ cts_name
= to_cts_name( xType
->getName() );
476 ::System::Type
^ ret_type
= get_type( cts_name
, false /* no exc */ );
477 if (nullptr == ret_type
)
479 Reference
< reflection::XConstantTypeDescription
> xConstant(
480 xType
, UNO_QUERY_THROW
);
481 ::System::Object
^ constant
=
482 to_cli_constant( xConstant
->getConstantValue() );
483 Emit::TypeBuilder
^ type_builder
=
484 m_module_builder
->DefineType(
486 (TypeAttributes
) (TypeAttributes::Public
|
487 TypeAttributes::Sealed
|
488 TypeAttributes::BeforeFieldInit
|
489 TypeAttributes::AnsiClass
) );
491 Emit::FieldBuilder
^ field_builder
= type_builder
->DefineField(
492 cts_name
->Substring( cts_name
->LastIndexOf( '.' ) +1 ),
494 (FieldAttributes
) (FieldAttributes::Public
|
495 FieldAttributes::Static
|
496 FieldAttributes::Literal
) );
497 field_builder
->SetConstant( constant
);
501 ::System::Console::WriteLine(
502 "> emitting constant type {0}", cts_name
);
504 ret_type
= type_builder
->CreateType();
510 ::System::Type
^ TypeEmitter::get_type(
511 Reference
< reflection::XConstantsTypeDescription
> const & xType
)
513 ::System::String
^ cts_name
= to_cts_name( xType
->getName() );
514 ::System::Type
^ ret_type
= get_type( cts_name
, false /* no exc */ );
515 if (nullptr == ret_type
)
517 Emit::TypeBuilder
^ type_builder
=
518 m_module_builder
->DefineType(
520 (TypeAttributes
) (TypeAttributes::Public
|
521 TypeAttributes::Sealed
|
522 TypeAttributes::BeforeFieldInit
|
523 TypeAttributes::AnsiClass
) );
526 reflection::XConstantTypeDescription
> > seq_constants(
527 xType
->getConstants() );
528 Reference
< reflection::XConstantTypeDescription
> const * constants
=
529 seq_constants
.getConstArray();
530 sal_Int32 constants_length
= seq_constants
.getLength();
531 for ( sal_Int32 constants_pos
= 0;
532 constants_pos
< constants_length
; ++constants_pos
)
535 reflection::XConstantTypeDescription
> const & xConstant
=
536 constants
[ constants_pos
];
537 ::System::Object
^ constant
=
538 to_cli_constant( xConstant
->getConstantValue() );
539 ::System::String
^ uno_name
=
540 ustring_to_String( xConstant
->getName() );
541 Emit::FieldBuilder
^ field_builder
= type_builder
->DefineField(
542 uno_name
->Substring( uno_name
->LastIndexOf( '.' ) +1 ),
544 (FieldAttributes
) (FieldAttributes::Public
|
545 FieldAttributes::Static
|
546 FieldAttributes::Literal
) );
547 field_builder
->SetConstant( constant
);
552 ::System::Console::WriteLine(
553 "> emitting constants group type {0}", cts_name
);
555 ret_type
= type_builder
->CreateType();
561 ::System::Type
^ TypeEmitter::get_type(
562 Reference
< reflection::XEnumTypeDescription
> const & xType
)
564 ::System::String
^ cts_name
= to_cts_name( xType
->getName() );
565 ::System::Type
^ ret_type
= get_type( cts_name
, false /* no exc */ );
566 if (nullptr == ret_type
)
568 // Emit::EnumBuilder * enum_builder =
569 // m_module_builder->DefineEnum(
571 // (TypeAttributes) (TypeAttributes::Public |
572 // // TypeAttributes::Sealed |
573 // TypeAttributes::AnsiClass),
574 // __typeof (::System::Int32) );
575 // workaround enum builder bug
576 Emit::TypeBuilder
^ enum_builder
=
577 m_module_builder
->DefineType(
579 (TypeAttributes
) (TypeAttributes::Public
|
580 TypeAttributes::Sealed
),
581 ::System::Enum::typeid );
582 enum_builder
->DefineField(
583 "value__", ::System::Int32::typeid,
584 (FieldAttributes
) (FieldAttributes::Private
|
585 FieldAttributes::SpecialName
|
586 FieldAttributes::RTSpecialName
) );
587 Sequence
< OUString
> seq_enum_names( xType
->getEnumNames() );
588 Sequence
< sal_Int32
> seq_enum_values( xType
->getEnumValues() );
589 sal_Int32 enum_length
= seq_enum_names
.getLength();
590 OSL_ASSERT( enum_length
== seq_enum_values
.getLength() );
591 OUString
const * enum_names
= seq_enum_names
.getConstArray();
592 sal_Int32
const * enum_values
= seq_enum_values
.getConstArray();
593 for ( sal_Int32 enum_pos
= 0; enum_pos
< enum_length
; ++enum_pos
)
595 // enum_builder->DefineLiteral(
596 // ustring_to_String( enum_names[ enum_pos ] ),
597 // __box ((::System::Int32) enum_values[ enum_pos ]) );
598 Emit::FieldBuilder
^ field_builder
=
599 enum_builder
->DefineField(
600 ustring_to_String( enum_names
[ enum_pos
] ),
602 (FieldAttributes
) (FieldAttributes::Public
|
603 FieldAttributes::Static
|
604 FieldAttributes::Literal
) );
605 field_builder
->SetConstant(
606 ((::System::Int32
) enum_values
[ enum_pos
]) );
611 ::System::Console::WriteLine(
612 "> emitting enum type {0}", cts_name
);
614 ret_type
= enum_builder
->CreateType();
620 ::System::Type
^ TypeEmitter::get_type(
621 Reference
< reflection::XCompoundTypeDescription
> const & xType
)
623 OUString
uno_name( xType
->getName() );
624 if (TypeClass_EXCEPTION
== xType
->getTypeClass())
626 if ( uno_name
== "com.sun.star.uno.Exception" )
628 return get_type_Exception();
630 if ( uno_name
== "com.sun.star.uno.RuntimeException" )
632 return get_type_RuntimeException();
635 ::System::String
^ cts_name
= to_cts_name( uno_name
);
636 // if the struct is an instantiated polymorpic struct then we create the simple struct name
638 // void func ([in] PolyStruct<boolean> arg);
639 //PolyStruct<boolean> will be converted to PolyStruct
640 polymorphicStructNameToStructName( & cts_name
);
642 ::System::Type
^ ret_type
= get_type( cts_name
, false /* no exc */ );
643 if (nullptr == ret_type
)
645 Reference
< reflection::XCompoundTypeDescription
> xBaseType(
646 xType
->getBaseType(), UNO_QUERY
);
647 ::System::Type
^ base_type
= (xBaseType
.is()
648 ? get_type( xBaseType
)
649 : ::System::Object::typeid);
650 Emit::TypeBuilder
^ type_builder
=
651 m_module_builder
->DefineType(
653 (TypeAttributes
) (TypeAttributes::Public
|
654 TypeAttributes::BeforeFieldInit
|
655 TypeAttributes::AnsiClass
),
659 // insert to be completed
660 struct_entry
^ entry
= gcnew
struct_entry();
662 entry
->m_xType
= xType
.get();
663 entry
->m_type_builder
= type_builder
;
664 entry
->m_base_type
= base_type
;
665 m_incomplete_structs
->Add( cts_name
, entry
);
667 // type is incomplete
668 ret_type
= type_builder
;
671 //In case of an instantiated polymorphic struct we want to return a
672 //uno.PolymorphicType (inherits Type) rather then Type. This is neaded for constructing
673 //the service code. We can only do that if the struct is completed.
674 if (m_generated_structs
[cts_name
])
676 Reference
< reflection::XStructTypeDescription
> xStructTypeDesc(
679 if (xStructTypeDesc
.is())
681 Sequence
< Reference
< reflection::XTypeDescription
> > seqTypeArgs
= xStructTypeDesc
->getTypeArguments();
682 sal_Int32 numTypes
= seqTypeArgs
.getLength();
685 //it is an instantiated polymorphic struct
686 ::System::String
^ sCliName
= mapUnoTypeName(ustring_to_String(xType
->getName()));
687 ret_type
= ::uno::PolymorphicType::GetType(ret_type
, sCliName
);
695 ::System::Type
^ TypeEmitter::get_type(
696 Reference
< reflection::XInterfaceTypeDescription2
> const & xType
)
698 OUString
uno_name( xType
->getName() );
699 if ( uno_name
== "com.sun.star.uno.XInterface" )
701 return ::System::Object::typeid;
704 ::System::String
^ cts_name
= to_cts_name( xType
->getName() );
705 ::System::Type
^ ret_type
= get_type( cts_name
, false /* no exc */ );
706 if (nullptr == ret_type
)
708 Emit::TypeBuilder
^ type_builder
;
710 TypeAttributes attr
= (TypeAttributes
) (TypeAttributes::Public
|
711 TypeAttributes::Interface
|
712 TypeAttributes::Abstract
|
713 TypeAttributes::AnsiClass
);
715 std::vector
<Reference
<reflection::XInterfaceTypeDescription2
> > vecBaseTypes
;
716 Sequence
<Reference
< reflection::XTypeDescription
> > seqBaseTypes
=
717 xType
->getBaseTypes();
718 if (seqBaseTypes
.getLength() > 0)
720 for (int i
= 0; i
< seqBaseTypes
.getLength(); i
++)
722 Reference
<reflection::XInterfaceTypeDescription2
> xIfaceTd
=
723 resolveInterfaceTypedef(seqBaseTypes
[i
]);
725 if ( xIfaceTd
->getName() != "com.sun.star.uno.XInterface" )
727 vecBaseTypes
.push_back(xIfaceTd
);
731 array
< ::System::Type
^>^ base_interfaces
=
732 gcnew array
< ::System::Type
^>( vecBaseTypes
.size() );
734 typedef std::vector
<Reference
<reflection::XInterfaceTypeDescription2
> >::const_iterator it
;
736 for (it i
= vecBaseTypes
.begin(); i
!= vecBaseTypes
.end(); ++i
, ++index
)
737 base_interfaces
[ index
] = get_type( *i
);
738 type_builder
= m_module_builder
->DefineType(
739 cts_name
, attr
, nullptr, base_interfaces
);
743 ::System::Console::WriteLine(
744 "warning: IDL interface {0} is not derived from "
745 "com.sun.star.uno.XInterface!",
746 ustring_to_String( uno_name
) );
748 type_builder
= m_module_builder
->DefineType( cts_name
, attr
);
751 // insert to be completed
752 iface_entry
^ entry
= gcnew
iface_entry();
754 entry
->m_xType
= xType
.get();
755 entry
->m_type_builder
= type_builder
;
756 m_incomplete_ifaces
->Add( cts_name
, entry
);
758 // type is incomplete
759 ret_type
= type_builder
;
766 ::System::Type
^ TypeEmitter::get_type(
767 Reference
< reflection::XServiceTypeDescription2
> const & xType
)
769 if (xType
->isSingleInterfaceBased() == sal_False
)
772 System::String
^ cts_name
= to_cts_name( xType
->getName() );
773 System::Type
^ ret_type
= get_type( cts_name
, false /* no exc */ );
774 if (ret_type
!= nullptr)
777 TypeAttributes attr
= (TypeAttributes
) (TypeAttributes::Public
|
778 TypeAttributes::Sealed
|
779 TypeAttributes::BeforeFieldInit
|
780 TypeAttributes::AnsiClass
);
782 Emit::TypeBuilder
^ type_builder
= m_module_builder
->DefineType(
785 // insert to be completed
786 service_entry
^ entry
= gcnew
service_entry();
788 entry
->m_xType
= xType
.get();
789 entry
->m_type_builder
= type_builder
;
790 m_incomplete_services
->Add(cts_name
,entry
);
795 ::System::Type
^ TypeEmitter::get_type(
796 Reference
<reflection::XSingletonTypeDescription2
> const & xType
)
798 if (xType
->isInterfaceBased() == sal_False
)
801 ::System::String
^ cts_name
= to_cts_name( xType
->getName() );
802 ::System::Type
^ ret_type
= get_type( cts_name
, false /* no exc */ );
803 if (ret_type
!= nullptr)
806 TypeAttributes attr
= static_cast<TypeAttributes
>(
807 TypeAttributes::Public
|
808 TypeAttributes::Sealed
|
809 TypeAttributes::BeforeFieldInit
|
810 TypeAttributes::AnsiClass
);
812 Emit::TypeBuilder
^ type_builder
= m_module_builder
->DefineType(
815 // insert to be completed
816 singleton_entry
^ entry
= gcnew
singleton_entry();
818 entry
->m_xType
= xType
.get();
819 entry
->m_type_builder
= type_builder
;
820 m_incomplete_singletons
->Add(cts_name
,entry
);
827 ::System::Type
^ TypeEmitter::complete_iface_type( iface_entry
^ entry
)
829 Emit::TypeBuilder
^ type_builder
= entry
->m_type_builder
;
830 reflection::XInterfaceTypeDescription2
* xType
= entry
->m_xType
;
832 Sequence
<Reference
< reflection::XTypeDescription
> > seqBaseTypes( xType
->getBaseTypes() );
833 if (seqBaseTypes
.getLength() > 0)
835 for (int i
= 0; i
< seqBaseTypes
.getLength(); i
++)
837 //make sure we get the interface rather then a typedef
838 Reference
<reflection::XInterfaceTypeDescription2
> aBaseType
=
839 resolveInterfaceTypedef( seqBaseTypes
[i
]);
841 if ( aBaseType
->getName() != "com.sun.star.uno.XInterface" )
843 ::System::String
^ basetype_name
= to_cts_name( aBaseType
->getName() );
844 iface_entry
^ base_entry
= dynamic_cast< iface_entry
^ >(
845 m_incomplete_ifaces
[basetype_name
] );
846 if (nullptr != base_entry
)
848 // complete uncompleted base type first
849 complete_iface_type( base_entry
);
856 Reference
< reflection::XInterfaceMemberTypeDescription
> > seq_members(
857 xType
->getMembers() );
858 Reference
< reflection::XInterfaceMemberTypeDescription
> const * members
=
859 seq_members
.getConstArray();
860 sal_Int32 members_length
= seq_members
.getLength();
861 for ( sal_Int32 members_pos
= 0;
862 members_pos
< members_length
; ++members_pos
)
865 reflection::XInterfaceMemberTypeDescription
> const & xMember
=
866 members
[ members_pos
];
867 Sequence
< Reference
< reflection::XTypeDescription
> > seq_exceptions
;
868 Emit::MethodBuilder
^ method_builder
;
870 MethodAttributes c_method_attr
= (MethodAttributes
)
871 (MethodAttributes::Public
|
872 MethodAttributes::Abstract
|
873 MethodAttributes::Virtual
|
874 MethodAttributes::NewSlot
|
875 MethodAttributes::HideBySig
);
877 if (TypeClass_INTERFACE_METHOD
== xMember
->getTypeClass())
879 Reference
< reflection::XInterfaceMethodTypeDescription
> xMethod(
880 xMember
, UNO_QUERY_THROW
);
883 Reference
< reflection::XMethodParameter
> > seq_parameters(
884 xMethod
->getParameters() );
885 sal_Int32 params_length
= seq_parameters
.getLength();
886 array
< ::System::Type
^>^ param_types
=
887 gcnew array
< ::System::Type
^>( params_length
);
888 Reference
< reflection::XMethodParameter
> const * parameters
=
889 seq_parameters
.getConstArray();
890 // first determine all types
891 //Make the first param type as return type
892 sal_Int32 params_pos
= 0;
893 for ( ; params_pos
< params_length
; ++params_pos
)
895 Reference
< reflection::XMethodParameter
> const & xParam
=
896 parameters
[ params_pos
];
897 ::System::Type
^ param_type
= get_type( xParam
->getType() );
898 ::System::String
^ param_type_name
= param_type
->FullName
;
901 param_type
= get_type(
902 ::System::String::Concat(
903 param_type_name
, "&" ), true );
905 param_types
[ xParam
->getPosition() ] = param_type
;
911 // method_builder = type_builder->DefineMethod(
912 // ustring_to_String( xMethod->getMemberName() ),
913 // c_method_attr, tb,
916 method_builder
= type_builder
->DefineMethod(
917 ustring_to_String( xMethod
->getMemberName() ),
918 c_method_attr
, get_type( xMethod
->getReturnType() ),
920 // then define parameter infos
922 for ( ; params_pos
< params_length
; ++params_pos
)
924 Reference
< reflection::XMethodParameter
> const & xParam
=
925 parameters
[ params_pos
];
926 long param_flags
= 0;
928 param_flags
|= (long)ParameterAttributes::In
;
930 param_flags
|= (long)ParameterAttributes::Out
;
931 OSL_ASSERT( 0 != param_flags
);
932 method_builder
->DefineParameter(
933 xParam
->getPosition() +1 /* starts with 1 */,
934 (ParameterAttributes
) param_flags
,
935 ustring_to_String( xParam
->getName() ) );
937 //Apply attribute TypeParametersAttribute to return value if it
938 //is a parameterized Type. Currently only structs can have parameters.
939 Reference
<reflection::XStructTypeDescription
> xReturnStruct(
940 xMethod
->getReturnType(), UNO_QUERY
);
942 if (xReturnStruct
.is())
944 Sequence
<Reference
<reflection::XTypeDescription
> > seq_type_args
=
945 xReturnStruct
->getTypeArguments();
946 if (seq_type_args
.getLength() != 0)
948 //get th ctor of the attribute
949 array
< ::System::Type
^>^ arCtor
= {::System::Type::GetType("System.Type[]")};
950 //Get the arguments for the attribute's ctor
951 Reference
<reflection::XTypeDescription
> const * arXTypeArgs
=
952 seq_type_args
.getConstArray();
953 int numTypes
= seq_type_args
.getLength();
954 array
< ::System::Type
^>^ arCtsTypes
= gcnew array
< ::System::Type
^>(numTypes
);
955 for (int i
= 0; i
< numTypes
; i
++)
956 arCtsTypes
[i
] = get_type(arXTypeArgs
[i
]);
957 array
< ::System::Object
^>^ arArgs
= {arCtsTypes
};
959 Emit::CustomAttributeBuilder
^ attrBuilder
=
960 gcnew
Emit::CustomAttributeBuilder(
961 ::uno::TypeArgumentsAttribute::typeid
962 ->GetConstructor( arCtor
),
965 method_builder
->SetCustomAttribute(attrBuilder
);
969 //define UNO exception attribute (exceptions)--------------------------------------
970 Emit::CustomAttributeBuilder
^ attrBuilder
=
971 get_iface_method_exception_attribute(xMethod
);
972 if (attrBuilder
!= nullptr)
973 method_builder
->SetCustomAttribute(attrBuilder
);
976 if (xMethod
->isOneway())
978 array
< ::System::Type
^>^ arCtorOneway
= gcnew array
< ::System::Type
^>(0);
979 array
< ::System::Object
^>^ arArgs
= gcnew array
< ::System::Object
^>(0);
980 Emit::CustomAttributeBuilder
^ attrBuilder
=
981 gcnew
Emit::CustomAttributeBuilder(
982 ::uno::OnewayAttribute::typeid->GetConstructor( arCtorOneway
),
984 method_builder
->SetCustomAttribute(attrBuilder
);
990 TypeClass_INTERFACE_ATTRIBUTE
== xMember
->getTypeClass() );
992 reflection::XInterfaceAttributeTypeDescription2
> xAttribute(
993 xMember
, UNO_QUERY_THROW
);
995 MethodAttributes c_property_method_attr
= (MethodAttributes
)
996 (c_method_attr
| MethodAttributes::SpecialName
);
998 ::System::Type
^ attribute_type
= get_type( xAttribute
->getType() );
999 array
< ::System::Type
^>^ parameters
=
1000 gcnew array
< ::System::Type
^> ( 0 );
1002 Emit::PropertyBuilder
^ property_builder
=
1003 type_builder
->DefineProperty(
1004 ustring_to_String( xAttribute
->getMemberName() ),
1005 PropertyAttributes::None
,
1006 attribute_type
, parameters
);
1008 //set BoundAttribute, if necessary
1009 if (xAttribute
->isBound())
1011 ConstructorInfo
^ ctorBoundAttr
=
1012 ::uno::BoundAttribute::typeid->GetConstructor(
1013 gcnew array
<System::Type
^>(0));
1014 Emit::CustomAttributeBuilder
^ attrBuilderBound
=
1015 gcnew
Emit::CustomAttributeBuilder(
1016 ctorBoundAttr
, gcnew array
< ::System::Object
^>(0));
1017 property_builder
->SetCustomAttribute(attrBuilderBound
);
1021 Emit::MethodBuilder
^ method_builder
=
1022 type_builder
->DefineMethod(
1023 ustring_to_String( "get_" +
1024 xAttribute
->getMemberName() ),
1025 c_property_method_attr
, attribute_type
, parameters
);
1027 //define UNO exception attribute (exceptions)--------------------------------------
1028 Emit::CustomAttributeBuilder
^ attrBuilder
=
1029 get_exception_attribute(xAttribute
->getGetExceptions());
1030 if (attrBuilder
!= nullptr)
1031 method_builder
->SetCustomAttribute(attrBuilder
);
1033 property_builder
->SetGetMethod( method_builder
);
1035 if (! xAttribute
->isReadOnly())
1038 parameters
= gcnew array
< ::System::Type
^> ( 1 );
1039 parameters
[ 0 ] = attribute_type
;
1041 type_builder
->DefineMethod(
1042 ustring_to_String( "set_" +
1043 xAttribute
->getMemberName() ),
1044 c_property_method_attr
, nullptr, parameters
);
1045 // define parameter info
1046 method_builder
->DefineParameter(
1047 1 /* starts with 1 */, ParameterAttributes::In
, "value" );
1048 //define UNO exception attribute (exceptions)--------------------------------------
1049 Emit::CustomAttributeBuilder
^ attrBuilder
=
1050 get_exception_attribute(xAttribute
->getSetExceptions());
1051 if (attrBuilder
!= nullptr)
1052 method_builder
->SetCustomAttribute(attrBuilder
);
1054 property_builder
->SetSetMethod( method_builder
);
1059 // remove from incomplete types map
1060 ::System::String
^ cts_name
= type_builder
->FullName
;
1061 m_incomplete_ifaces
->Remove( cts_name
);
1066 ::System::Console::WriteLine(
1067 "> emitting interface type {0}", cts_name
);
1069 return type_builder
->CreateType();
1072 ::System::Type
^ TypeEmitter::complete_struct_type( struct_entry
^ entry
)
1075 ::System::String
^ cts_name
= entry
->m_type_builder
->FullName
;
1077 //Polymorphic struct, define uno.TypeParametersAttribute
1078 //A polymorphic struct cannot have a basetype.
1079 //When we create the template of the struct then we have no exact types
1080 //and the name does not contain a parameter list
1081 Sequence
< OUString
> seq_type_parameters
;
1082 Reference
< reflection::XStructTypeDescription
> xStructTypeDesc(
1083 entry
->m_xType
, UNO_QUERY
);
1084 if (xStructTypeDesc
.is())
1086 seq_type_parameters
= xStructTypeDesc
->getTypeParameters();
1088 if ((numTypes
= seq_type_parameters
.getLength()) > 0)
1090 array
< ::System::Object
^>^ aArg
= gcnew array
< ::System::Object
^>(numTypes
);
1091 for (int i
= 0; i
< numTypes
; i
++)
1092 aArg
[i
] = ustring_to_String(seq_type_parameters
.getConstArray()[i
]);
1093 array
< ::System::Object
^>^ args
= {aArg
};
1095 array
< ::System::Type
^>^ arTypesCtor
=
1096 {::System::Type::GetType("System.String[]")};
1097 Emit::CustomAttributeBuilder
^ attrBuilder
=
1098 gcnew
Emit::CustomAttributeBuilder(
1099 ::uno::TypeParametersAttribute::typeid->GetConstructor(arTypesCtor
),
1101 entry
->m_type_builder
->SetCustomAttribute(attrBuilder
);
1105 // optional: lookup base type whether generated entry of this session
1106 struct_entry
^ base_type_entry
= nullptr;
1107 if (nullptr != entry
->m_base_type
)
1109 //ToDo maybe get from incomplete structs
1111 dynamic_cast< struct_entry
^ >(
1112 m_generated_structs
[
1113 entry
->m_base_type
->FullName
] );
1117 Sequence
< Reference
< reflection::XTypeDescription
> > seq_members(
1118 entry
->m_xType
->getMemberTypes() );
1119 Sequence
< OUString
> seq_member_names( entry
->m_xType
->getMemberNames() );
1120 sal_Int32 members_length
= seq_members
.getLength();
1121 OSL_ASSERT( seq_member_names
.getLength() == members_length
);
1122 //check if we have a XTypeDescription for every member. If not then the user may
1123 //have forgotten to specify additional rdbs with the --extra option.
1124 Reference
< reflection::XTypeDescription
> const * pseq_members
=
1125 seq_members
.getConstArray();
1126 OUString
const * pseq_member_names
=
1127 seq_member_names
.getConstArray();
1128 for (int i
= 0; i
< members_length
; i
++)
1130 const OUString
sType(entry
->m_xType
->getName());
1131 const OUString
sMemberName(pseq_member_names
[i
]);
1132 if ( ! pseq_members
[i
].is())
1133 throw RuntimeException("Missing type description . Check if you need to "
1134 "specify additional RDBs with the --extra option. Type missing for: " + sType
+
1135 "::" + sMemberName
,0);
1138 sal_Int32 all_members_length
= 0;
1139 sal_Int32 member_pos
;
1140 sal_Int32 type_param_pos
= 0;
1142 // collect base types; wrong order
1143 ::System::Collections::ArrayList
^ base_types_list
=
1144 gcnew ::System::Collections::ArrayList( 3 /* initial capacity */ );
1145 for (::System::Type
^ base_type_pos
= entry
->m_base_type
;
1146 ! base_type_pos
->Equals( ::System::Object::typeid );
1147 base_type_pos
= base_type_pos
->BaseType
)
1149 base_types_list
->Add( base_type_pos
);
1150 if (base_type_pos
->Equals( ::System::Exception::typeid ))
1152 // special Message member
1153 all_members_length
+= 1;
1154 break; // don't include System.Exception base classes
1158 //ensure the base type is complete. Otherwise GetFields won't work
1159 get_complete_struct(base_type_pos
->FullName
);
1160 all_members_length
+=
1161 base_type_pos
->GetFields(
1162 (BindingFlags
) (BindingFlags::Instance
|
1163 BindingFlags::Public
|
1164 BindingFlags::DeclaredOnly
) )
1169 // create all_members arrays; right order
1170 array
< ::System::String
^>^ all_member_names
=
1171 gcnew array
< ::System::String
^> (all_members_length
+ members_length
);
1172 array
< ::System::Type
^>^ all_param_types
=
1173 gcnew array
< ::System::Type
^> (all_members_length
+ members_length
);
1175 for ( sal_Int32 pos
= base_types_list
->Count
; pos
--; )
1177 ::System::Type
^ base_type
= safe_cast
< ::System::Type
^ >(
1178 base_types_list
[pos
] );
1179 if (base_type
->Equals( ::System::Exception::typeid ))
1181 all_member_names
[ member_pos
] = "Message";
1182 all_param_types
[ member_pos
] = ::System::String::typeid;
1187 ::System::String
^ base_type_name
= base_type
->FullName
;
1189 //ToDo m_generated_structs?
1190 struct_entry
^ entry
=
1191 dynamic_cast< struct_entry
^ >(
1192 m_generated_structs
[base_type_name
] );
1193 if (nullptr == entry
)
1196 array
<FieldInfo
^>^ fields
=
1197 base_type
->GetFields(
1198 (BindingFlags
) (BindingFlags::Instance
|
1199 BindingFlags::Public
|
1200 BindingFlags::DeclaredOnly
) );
1201 sal_Int32 len
= fields
->Length
;
1202 for ( sal_Int32 pos
= 0; pos
< len
; ++pos
)
1204 FieldInfo
^ field
= fields
[ pos
];
1205 all_member_names
[ member_pos
] = field
->Name
;
1206 all_param_types
[ member_pos
] = field
->FieldType
;
1210 else // generated during this session:
1211 // members may be incomplete ifaces
1213 sal_Int32 len
= entry
->m_member_names
->Length
;
1214 for ( sal_Int32 pos
= 0; pos
< len
; ++pos
)
1216 all_member_names
[ member_pos
] =
1217 entry
->m_member_names
[ pos
];
1218 all_param_types
[ member_pos
] =
1219 entry
->m_param_types
[ pos
];
1225 OSL_ASSERT( all_members_length
== member_pos
);
1228 // struct_entry * entry = new struct_entry();
1229 entry
->m_member_names
= gcnew array
< ::System::String
^> ( members_length
);
1230 entry
->m_param_types
= gcnew array
< ::System::Type
^> ( members_length
);
1233 array
<Emit::FieldBuilder
^>^ members
= gcnew array
<Emit::FieldBuilder
^> ( members_length
);
1234 //Reference< reflection::XTypeDescription > const * pseq_members =
1235 // seq_members.getConstArray();
1236 //OUString const * pseq_member_names =
1237 // seq_member_names.getConstArray();
1239 int curParamIndex
= 0; //count the fields which have parameterized types
1240 for ( member_pos
= 0; member_pos
< members_length
; ++member_pos
)
1242 ::System::String
^ field_name
=
1243 ustring_to_String( pseq_member_names
[ member_pos
] );
1244 ::System::Type
^ field_type
;
1245 //Special handling of struct parameter types
1246 bool bParameterizedType
= false;
1247 if (pseq_members
[ member_pos
]->getTypeClass() == TypeClass_UNKNOWN
)
1249 bParameterizedType
= true;
1250 if (type_param_pos
< seq_type_parameters
.getLength())
1252 field_type
= ::System::Object::typeid;
1257 throw RuntimeException(
1258 "unexpected member type in " + entry
->m_xType
->getName() );
1263 field_type
= get_type( pseq_members
[ member_pos
] );
1265 if (field_type
->IsArray
1266 && m_incomplete_structs
[cts_name
]
1267 && !field_type
->Namespace
->Equals("System"))
1269 //Find the value type. In case of sequence<sequence< ... > > find the actual value type
1270 ::System::Type
^ value
= field_type
;
1271 while ((value
= value
->GetElementType())->IsArray
);
1272 //If the value type is a struct then make sure it is fully created.
1273 get_complete_struct(value
->FullName
);
1274 field_type
= get_type(pseq_members
[member_pos
]);
1277 members
[ member_pos
] =
1278 entry
->m_type_builder
->DefineField(
1279 field_name
, field_type
, FieldAttributes::Public
);
1281 //parameterized type (polymorphic struct) ?
1282 if (bParameterizedType
&& xStructTypeDesc
.is())
1285 OSL_ASSERT(seq_type_parameters
.getLength() > curParamIndex
);
1286 ::System::String
^ sTypeName
= ustring_to_String(
1287 seq_type_parameters
.getConstArray()[curParamIndex
++]);
1288 array
< ::System::Object
^>^ args
= {sTypeName
};
1289 //set ParameterizedTypeAttribute
1290 array
< ::System::Type
^>^ arCtorTypes
= {::System::String::typeid};
1292 Emit::CustomAttributeBuilder
^ attrBuilder
=
1293 gcnew
Emit::CustomAttributeBuilder(
1294 ::uno::ParameterizedTypeAttribute::typeid
1295 ->GetConstructor(arCtorTypes
),
1298 members
[member_pos
]->SetCustomAttribute(attrBuilder
);
1300 // add to all_members
1301 all_member_names
[ all_members_length
+ member_pos
] = field_name
;
1302 all_param_types
[ all_members_length
+ member_pos
] = field_type
;
1304 entry
->m_member_names
[ member_pos
] = field_name
;
1305 entry
->m_param_types
[ member_pos
] = field_type
;
1307 all_members_length
+= members_length
;
1310 Emit::ConstructorBuilder
^ ctor_builder
=
1311 entry
->m_type_builder
->DefineConstructor(
1312 c_ctor_method_attr
, CallingConventions::Standard
,
1313 gcnew array
< ::System::Type
^> ( 0 ) );
1314 Emit::ILGenerator
^ code
= ctor_builder
->GetILGenerator();
1315 code
->Emit( Emit::OpCodes::Ldarg_0
);
1317 Emit::OpCodes::Call
,
1318 nullptr == base_type_entry
1319 ? entry
->m_base_type
->GetConstructor( gcnew array
< ::System::Type
^> ( 0 ) )
1320 : base_type_entry
->m_default_ctor
);
1321 // default initialize members
1322 for ( member_pos
= 0; member_pos
< members_length
; ++member_pos
)
1324 FieldInfo
^ field
= members
[ member_pos
];
1325 ::System::Type
^ field_type
= field
->FieldType
;
1326 // ::System::Type * new_field_type = m_module_builder->GetType(field_type->FullName, false);
1327 // default initialize:
1328 // string, type, enum, sequence, struct, exception, any
1329 if (field_type
->Equals( ::System::String::typeid ))
1331 code
->Emit( Emit::OpCodes::Ldarg_0
);
1332 code
->Emit( Emit::OpCodes::Ldstr
, "" );
1333 code
->Emit( Emit::OpCodes::Stfld
, field
);
1335 else if (field_type
->Equals( ::System::Type::typeid ))
1337 code
->Emit( Emit::OpCodes::Ldarg_0
);
1339 Emit::OpCodes::Ldtoken
, ::System::Void::typeid );
1341 Emit::OpCodes::Call
, m_method_info_Type_GetTypeFromHandle
);
1342 code
->Emit( Emit::OpCodes::Stfld
, field
);
1344 else if (field_type
->IsArray
)
1346 code
->Emit( Emit::OpCodes::Ldarg_0
);
1347 code
->Emit( Emit::OpCodes::Ldc_I4_0
);
1349 Emit::OpCodes::Newarr
, field_type
->GetElementType() );
1350 code
->Emit( Emit::OpCodes::Stfld
, field
);
1352 else if (field_type
->IsValueType
)
1354 if (field_type
->FullName
->Equals( "uno.Any" ))
1356 code
->Emit( Emit::OpCodes::Ldarg_0
);
1357 code
->Emit( Emit::OpCodes::Ldsfld
, ::uno::Any::typeid->GetField("VOID"));
1358 code
->Emit( Emit::OpCodes::Stfld
, field
);
1361 else if (field_type
->IsClass
)
1363 /* may be XInterface */
1364 if (! field_type
->Equals( ::System::Object::typeid ))
1366 // struct, exception
1367 //make sure the struct is already complete.
1368 get_complete_struct(field_type
->FullName
);
1369 code
->Emit( Emit::OpCodes::Ldarg_0
);
1371 Emit::OpCodes::Newobj
,
1372 //GetConstructor requies that the member types of the object which is to be constructed are already known.
1373 field_type
->GetConstructor(
1374 gcnew array
< ::System::Type
^> ( 0 ) ) );
1375 code
->Emit( Emit::OpCodes::Stfld
, field
);
1379 code
->Emit( Emit::OpCodes::Ret
);
1380 entry
->m_default_ctor
= ctor_builder
;
1382 // parameterized .ctor including all base members
1383 ctor_builder
= entry
->m_type_builder
->DefineConstructor(
1384 c_ctor_method_attr
, CallingConventions::Standard
, all_param_types
);
1385 for ( member_pos
= 0; member_pos
< all_members_length
; ++member_pos
)
1387 ctor_builder
->DefineParameter(
1388 member_pos
+1 /* starts with 1 */, ParameterAttributes::In
,
1389 all_member_names
[ member_pos
] );
1391 code
= ctor_builder
->GetILGenerator();
1393 code
->Emit( Emit::OpCodes::Ldarg_0
); // push this
1394 sal_Int32 base_members_length
= all_members_length
- members_length
;
1395 array
< ::System::Type
^>^ param_types
=
1396 gcnew array
< ::System::Type
^> ( base_members_length
);
1397 for ( member_pos
= 0; member_pos
< base_members_length
; ++member_pos
)
1399 emit_ldarg( code
, member_pos
+1 );
1400 param_types
[ member_pos
] = all_param_types
[ member_pos
];
1403 Emit::OpCodes::Call
,
1404 nullptr == base_type_entry
1405 ? entry
->m_base_type
->GetConstructor( param_types
)
1406 : base_type_entry
->m_ctor
);
1407 // initialize members
1408 for ( member_pos
= 0; member_pos
< members_length
; ++member_pos
)
1410 code
->Emit( Emit::OpCodes::Ldarg_0
); // push this
1411 emit_ldarg( code
, member_pos
+ base_members_length
+1 );
1412 code
->Emit( Emit::OpCodes::Stfld
, members
[ member_pos
] );
1414 code
->Emit( Emit::OpCodes::Ret
);
1415 entry
->m_ctor
= ctor_builder
;
1419 ::System::Console::WriteLine(
1420 "> emitting {0} type {1}",
1421 TypeClass_STRUCT
== entry
->m_xType
->getTypeClass()
1427 m_generated_structs
->Add(cts_name
, entry
);
1428 ::System::Type
^ ret_type
= entry
->m_type_builder
->CreateType();
1430 // remove from incomplete types map
1431 m_incomplete_structs
->Remove( cts_name
);
1432 entry
->m_xType
->release();
1436 ::System::Console::WriteLine(
1437 "> emitting struct type {0}", cts_name
);
1442 //Examples of generated code
1443 // public static XWeak constructor1(XComponentContext ctx)
1445 // XMultiComponentFactory factory = ctx.getServiceManager();
1446 // if (factory == null)
1447 // throw new com.sun.star.uno.DeploymentException("bla", null);
1448 // return (XWeak) factory.createInstanceWithContext("service_specifier", ctx);
1450 // public static XWeak constructor2(XComponentContext ctx, int a, int b, Any c)
1452 // XMultiComponentFactory factory = ctx.getServiceManager();
1453 // if (factory == null)
1454 // throw new com.sun.star.uno.DeploymentException("bla", null);
1455 // Any[] arAny = new Any[3];
1456 // arAny[0] = new Any(typeof(int), a);
1457 // arAny[1] = new Any(typeof(int), b);
1458 // arAny[2] = new Any(c.Type, c.Value);
1459 // return (XWeak) factory.createInstanceWithArgumentsAndContext("service_specifier", arAny, ctx);
1461 // Notice that a any parameter is NOT wrapped by another any. Instead the new any is created with the type and value
1462 // of the parameter.
1464 // public static XWeak constructor3(XComponentContext ctx, params Any[] c)
1466 // XMultiComponentFactory factory = ctx.getServiceManager();
1467 // if (factory == null)
1468 // throw new com.sun.star.uno.DeploymentException("bla", null);
1469 // return (XWeak) factory.createInstanceWithArgumentsAndContext("service_specifier", c, ctx);
1471 ::System::Type
^ TypeEmitter::complete_service_type(service_entry
^ entry
)
1473 Emit::TypeBuilder
^ type_builder
= entry
->m_type_builder
;
1474 reflection::XServiceTypeDescription2
* xServiceType
= entry
->m_xType
;
1476 //Create the private default constructor
1477 Emit::ConstructorBuilder
^ ctor_builder
=
1478 type_builder
->DefineConstructor(
1479 (MethodAttributes
) (MethodAttributes::Private
|
1480 MethodAttributes::HideBySig
|
1481 MethodAttributes::SpecialName
|
1482 MethodAttributes::RTSpecialName
),
1483 CallingConventions::Standard
, nullptr);
1485 Emit::ILGenerator
^ ilGen
= ctor_builder
->GetILGenerator();
1486 ilGen
->Emit( Emit::OpCodes::Ldarg_0
); // push this
1488 Emit::OpCodes::Call
,
1489 type_builder
->BaseType
->GetConstructor(gcnew array
< ::System::Type
^>(0)));
1490 ilGen
->Emit( Emit::OpCodes::Ret
);
1493 //Create the service constructors.
1494 //obtain the interface which makes up this service, it is the return
1495 //type of the constructor functions
1496 Reference
<reflection::XInterfaceTypeDescription2
> xIfaceType(
1497 xServiceType
->getInterface(), UNO_QUERY
);
1498 if (xIfaceType
.is () == sal_False
)
1499 xIfaceType
= resolveInterfaceTypedef(xServiceType
->getInterface());
1500 System::Type
^ retType
= get_type(xIfaceType
);
1502 //Create the ConstructorInfo for a DeploymentException
1503 ::System::Type
^ typeDeploymentExc
=
1504 get_type("unoidl.com.sun.star.uno.DeploymentException", true);
1506 array
< ::System::Type
^>^ arTypeCtor
= {::System::String::typeid,
1507 ::System::Object::typeid};
1508 ::System::Reflection::ConstructorInfo
^ ctorDeploymentException
=
1509 typeDeploymentExc
->GetConstructor(arTypeCtor
);
1511 Sequence
<Reference
<reflection::XServiceConstructorDescription
> > seqCtors
=
1512 xServiceType
->getConstructors();
1514 ::System::Type
^ type_uno_exception
= get_type("unoidl.com.sun.star.uno.Exception", true);
1516 for (int i
= seqCtors
.getLength() - 1; i
>= 0; i
--)
1518 bool bParameterArray
= false;
1519 ::System::Type
^ typeAny
= ::uno::Any::typeid;
1520 const Reference
<reflection::XServiceConstructorDescription
> & ctorDes
=
1522 //obtain the parameter types
1523 Sequence
<Reference
<reflection::XParameter
> > seqParams
=
1524 ctorDes
->getParameters();
1525 Reference
<reflection::XParameter
> const * arXParams
= seqParams
.getConstArray();
1526 sal_Int32 cParams
= seqParams
.getLength();
1527 array
< ::System::Type
^>^ arTypeParameters
= gcnew array
< ::System::Type
^> (cParams
+ 1);
1528 arTypeParameters
[0] = get_type("unoidl.com.sun.star.uno.XComponentContext", true);
1529 for (int iparam
= 0; iparam
!= cParams
; iparam
++)
1531 if (arXParams
[iparam
]->isRestParameter())
1532 arTypeParameters
[iparam
+ 1] = array
< ::uno::Any
>::typeid;
1534 arTypeParameters
[iparam
+ 1] = get_type(arXParams
[iparam
]->getType());
1536 //The array arTypeParameters can contain:
1537 //System.Type and uno.PolymorphicType.
1538 //Passing PolymorphicType to MethodBuilder.DefineMethod will cause a problem.
1539 //The exception will read something like no on information for parameter # d
1540 //Maybe we need no override another Type method in PolymorphicType ...
1541 //Until we have figured this out, we will create another array of System.Type which
1542 //we pass on to DefineMethod.
1543 array
< ::System::Type
^>^ arParamTypes
= gcnew array
< ::System::Type
^> (cParams
+ 1);
1544 // arParamTypes[0] = get_type("unoidl.com.sun.star.uno.XComponentContext", true);
1545 for (int i
= 0; i
< cParams
+ 1; i
++)
1547 ::uno::PolymorphicType
^ pT
= dynamic_cast< ::uno::PolymorphicType
^ >(arTypeParameters
[i
]);
1549 arParamTypes
[i
] = pT
->OriginalType
;
1551 arParamTypes
[i
] = arTypeParameters
[i
];
1554 System::String
^ ctorName
;
1555 if (ctorDes
->isDefaultConstructor())
1556 ctorName
= gcnew ::System::String("create");
1558 ctorName
= ustring_to_String(ctorDes
->getName());
1559 Emit::MethodBuilder
^ method_builder
= type_builder
->DefineMethod(
1561 static_cast<MethodAttributes
>(MethodAttributes::Public
| MethodAttributes::HideBySig
|
1562 MethodAttributes::Static
),
1564 // arTypeParameters);
1567 //define UNO exception attribute (exceptions)--------------------------------------
1568 Emit::CustomAttributeBuilder
^ attrBuilder
= get_service_exception_attribute(ctorDes
);
1569 if (attrBuilder
!= nullptr)
1570 method_builder
->SetCustomAttribute(attrBuilder
);
1573 //define parameter attributes (paramarray), names etc.
1574 //The first parameter is the XComponentContext, which cannot be obtained
1576 //The context is not part of the idl description
1577 method_builder
->DefineParameter(
1578 1, ParameterAttributes::In
, "the_context");
1580 array
<Emit::ParameterBuilder
^>^ arParameterBuilder
=
1581 gcnew array
<Emit::ParameterBuilder
^> (cParams
);
1582 for (int iparam
= 0; iparam
!= cParams
; iparam
++)
1584 Reference
<reflection::XParameter
> const & aParam
= arXParams
[iparam
];
1585 ::System::String
^ sParamName
= ustring_to_String(aParam
->getName());
1587 arParameterBuilder
[iparam
] = method_builder
->DefineParameter(
1588 iparam
+ 2, ParameterAttributes::In
, sParamName
);
1590 if (aParam
->isRestParameter())
1592 bParameterArray
= true;
1593 //set the ParameterArrayAttribute
1594 ::System::Reflection::ConstructorInfo
^ ctor_info
=
1595 System::ParamArrayAttribute::typeid->GetConstructor(
1596 gcnew array
< ::System::Type
^>(0));
1597 Emit::CustomAttributeBuilder
^ attr_builder
=
1598 gcnew
Emit::CustomAttributeBuilder(ctor_info
, gcnew array
< ::System::Object
^>(0));
1599 arParameterBuilder
[iparam
]->SetCustomAttribute(attr_builder
);
1604 Emit::ILGenerator
^ ilGen
= method_builder
->GetILGenerator();
1606 //Define locals ---------------------------------
1607 //XMultiComponentFactory
1608 Emit::LocalBuilder
^ local_factory
=
1609 ilGen
->DeclareLocal(
1610 get_type("unoidl.com.sun.star.lang.XMultiComponentFactory", true));
1613 Emit::LocalBuilder
^ local_return_val
=
1614 ilGen
->DeclareLocal(retType
);
1616 //Obtain the XMultiComponentFactory and throw an exception if we do not get one
1617 ilGen
->Emit(Emit::OpCodes::Ldarg_0
);
1619 ::System::Reflection::MethodInfo
^ methodGetServiceManager
= get_type(
1620 "unoidl.com.sun.star.uno.XComponentContext", true)
1621 ->GetMethod("getServiceManager");
1622 ilGen
->Emit(Emit::OpCodes::Callvirt
, methodGetServiceManager
);
1623 ilGen
->Emit(Emit::OpCodes::Stloc
, local_factory
);
1624 ilGen
->Emit(Emit::OpCodes::Ldloc
, local_factory
);
1625 Emit::Label label1
= ilGen
->DefineLabel();
1626 ilGen
->Emit(Emit::OpCodes::Brtrue
, label1
);
1627 //The string for the exception
1628 ::System::Text::StringBuilder
^ strbuilder
= gcnew ::System::Text::StringBuilder(256);
1629 strbuilder
->Append("The service ");
1630 strbuilder
->Append(to_cts_name(xServiceType
->getName()));
1631 strbuilder
->Append(" could not be created. The context failed to supply the service manager.");
1633 ilGen
->Emit(Emit::OpCodes::Ldstr
, strbuilder
->ToString());
1634 ilGen
->Emit(Emit::OpCodes::Ldarg_0
);
1635 ilGen
->Emit(Emit::OpCodes::Newobj
, ctorDeploymentException
);
1636 ilGen
->Emit(Emit::OpCodes::Throw
);
1637 ilGen
->MarkLabel(label1
);
1639 //We create a try/ catch around the createInstanceWithContext, etc. functions
1641 //1. function do not specify exceptions. Then RuntimeExceptions are retrhown and other
1642 // exceptions produce a DeploymentException.
1643 //2. function specify Exception. Then all exceptions fly through
1644 //3. function specifies exceptions but no Exception. Then these are rethrown
1645 // and other exceptions, except RuntimeException, produce a deployment exception.
1646 //In case there are no parameters we call
1647 //XMultiComponentFactory.createInstanceWithContext
1649 ::System::Collections::ArrayList
^ arExceptionTypes
=
1650 get_service_ctor_method_exceptions_reduced(ctorDes
->getExceptions());
1651 if (arExceptionTypes
->Contains(
1652 type_uno_exception
) == false)
1654 ilGen
->BeginExceptionBlock();
1658 ilGen
->Emit(Emit::OpCodes::Ldloc
, local_factory
);
1659 ilGen
->Emit(Emit::OpCodes::Ldstr
, ustring_to_String(xServiceType
->getName()));
1660 ilGen
->Emit(Emit::OpCodes::Ldarg_0
);
1662 ::System::Reflection::MethodInfo
^ methodCreate
=
1663 local_factory
->LocalType
->GetMethod("createInstanceWithContext");
1664 ilGen
->Emit(Emit::OpCodes::Callvirt
, methodCreate
);
1666 else if(bParameterArray
)
1668 //Service constructor with parameter array
1669 ilGen
->Emit(Emit::OpCodes::Ldloc
, local_factory
);
1670 ilGen
->Emit(Emit::OpCodes::Ldstr
, ustring_to_String(xServiceType
->getName()));
1671 ilGen
->Emit(Emit::OpCodes::Ldarg_1
);
1672 ilGen
->Emit(Emit::OpCodes::Ldarg_0
);
1673 ::System::Reflection::MethodInfo
^ methodCreate
=
1674 local_factory
->LocalType
->GetMethod("createInstanceWithArgumentsAndContext");
1675 ilGen
->Emit(Emit::OpCodes::Callvirt
, methodCreate
);
1679 // Any param1, Any param2, etc.
1680 // For each parameter,except the component context, and parameter array
1681 // and Any is created.
1682 array
<Emit::LocalBuilder
^>^ arLocalAny
= gcnew array
<Emit::LocalBuilder
^> (cParams
);
1684 for (int iParam
= 0; iParam
< cParams
; iParam
++)
1686 arLocalAny
[iParam
] = ilGen
->DeclareLocal(typeAny
);
1689 //Any[]. This array is filled with the created Anys which contain the parameters
1690 //and the values contained in the parameter array
1691 Emit::LocalBuilder
^ local_anyParams
=
1692 ilGen
->DeclareLocal(array
< ::uno::Any
>::typeid);
1694 //Create the Any for every argument, except for the parameter array
1695 //arLocalAny contains the LocalBuilder for all these parameters.
1696 //we call the ctor Any(Type, Object)
1697 //If the parameter is an Any then the Any is created with Any(param.Type, param.Value);
1698 array
< ::System::Type
^>^ arTypesCtorAny
= {::System::Type::typeid,
1699 ::System::Object::typeid};
1700 ::System::Reflection::ConstructorInfo
^ ctorAny
=
1701 typeAny
->GetConstructor( arTypesCtorAny
);
1702 ::System::Reflection::MethodInfo
^ methodAnyGetType
=
1703 typeAny
->GetProperty("Type")->GetGetMethod();
1704 ::System::Reflection::MethodInfo
^ methodAnyGetValue
=
1705 typeAny
->GetProperty("Value")->GetGetMethod();
1706 for (int i
= 0; i
< arLocalAny
->Length
; i
++)
1708 //check if the parameter is a polymorphic struct
1709 ::uno::PolymorphicType
^polyType
= dynamic_cast< ::uno::PolymorphicType
^ >(arTypeParameters
[i
+1]);
1710 //arTypeParameters[i+1] = polyType->OriginalType;
1713 //It is a polymorphic struct
1714 //Load the uninitialized local Any on which we will call the ctor
1715 ilGen
->Emit(Emit::OpCodes::Ldloca
, arLocalAny
[i
]);
1716 // Call PolymorphicType PolymorphicType::GetType(Type t, String polyName)
1717 // Prepare the first parameter
1718 ilGen
->Emit(Emit::OpCodes::Ldtoken
, polyType
->OriginalType
);
1719 array
< ::System::Type
^>^ arTypeParams
= {::System::RuntimeTypeHandle::typeid};
1720 ilGen
->Emit(Emit::OpCodes::Call
,
1721 ::System::Type::typeid->GetMethod(
1722 "GetTypeFromHandle", arTypeParams
));
1723 // Prepare the second parameter
1724 ilGen
->Emit(Emit::OpCodes::Ldstr
, polyType
->PolymorphicName
);
1725 // Make the actual call
1726 array
< ::System::Type
^>^ arTypeParam_GetType
= {
1727 ::System::Type::typeid, ::System::String::typeid };
1728 ilGen
->Emit(Emit::OpCodes::Call
,
1729 ::uno::PolymorphicType::typeid->GetMethod(gcnew
System::String("GetType"),
1730 arTypeParam_GetType
));
1732 //Stack is: localAny, PolymorphicType
1733 //Call Any::Any(Type, Object)
1734 //Prepare the second parameter for the any ctor
1735 ilGen
->Emit(Emit::OpCodes::Ldarg
, i
+ 1);
1736 // if the parameter is a value type then we need to box it, because
1737 // the Any ctor takes an Object
1738 if (arTypeParameters
[i
+1]->IsValueType
)
1739 ilGen
->Emit(Emit::OpCodes::Box
, arTypeParameters
[i
+1]);
1740 ilGen
->Emit(Emit::OpCodes::Call
, ctorAny
);
1742 else if (arTypeParameters
[i
+1] == typeAny
)
1744 //Create the call new Any(param.Type,param,Value)
1745 //Stack must be Any,Type,Value
1746 //First load the Any which is to be constructed
1747 ilGen
->Emit(Emit::OpCodes::Ldloca
, arLocalAny
[i
]);
1748 //Load the Type, which is obtained by calling param.Type
1749 ilGen
->Emit(Emit::OpCodes::Ldarga
, i
+ 1);
1750 ilGen
->Emit(Emit::OpCodes::Call
, methodAnyGetType
);
1751 //Load the Value, which is obtained by calling param.Value
1752 ilGen
->Emit(Emit::OpCodes::Ldarga
, i
+ 1);
1753 ilGen
->Emit(Emit::OpCodes::Call
, methodAnyGetValue
);
1754 //Call the Any ctor.
1755 ilGen
->Emit(Emit::OpCodes::Call
, ctorAny
);
1759 ilGen
->Emit(Emit::OpCodes::Ldloca
, arLocalAny
[i
]);
1760 ilGen
->Emit(Emit::OpCodes::Ldtoken
, arTypeParameters
[i
+1]);
1762 array
< ::System::Type
^>^ arTypeParams
= {::System::RuntimeTypeHandle::typeid};
1763 ilGen
->Emit(Emit::OpCodes::Call
,
1764 ::System::Type::typeid->GetMethod(
1765 "GetTypeFromHandle", arTypeParams
));
1766 ilGen
->Emit(Emit::OpCodes::Ldarg
, i
+ 1);
1767 // if the parameter is a value type then we need to box it, because
1768 // the Any ctor takes an Object
1769 if (arTypeParameters
[i
+1]->IsValueType
)
1770 ilGen
->Emit(Emit::OpCodes::Box
, arTypeParameters
[i
+1]);
1771 ilGen
->Emit(Emit::OpCodes::Call
, ctorAny
);
1775 //Create the Any[] that is passed to the
1776 //createInstanceWithContext[AndArguments] function
1777 ilGen
->Emit(Emit::OpCodes::Ldc_I4
, arLocalAny
->Length
);
1778 ilGen
->Emit(Emit::OpCodes::Newarr
, typeAny
);
1779 ilGen
->Emit(Emit::OpCodes::Stloc
, local_anyParams
);
1781 //Assign all anys created from the parameters
1782 //array to the Any[]
1783 for (int i
= 0; i
< arLocalAny
->Length
; i
++)
1785 ilGen
->Emit(Emit::OpCodes::Ldloc
, local_anyParams
);
1786 ilGen
->Emit(Emit::OpCodes::Ldc_I4
, i
);
1787 ilGen
->Emit(Emit::OpCodes::Ldelema
, typeAny
);
1788 ilGen
->Emit(Emit::OpCodes::Ldloc
, arLocalAny
[i
]);
1789 ilGen
->Emit(Emit::OpCodes::Stobj
, typeAny
);
1791 // call createInstanceWithContextAndArguments
1792 ilGen
->Emit(Emit::OpCodes::Ldloc
, local_factory
);
1793 ilGen
->Emit(Emit::OpCodes::Ldstr
, ustring_to_String(xServiceType
->getName()));
1794 ilGen
->Emit(Emit::OpCodes::Ldloc
, local_anyParams
);
1795 ilGen
->Emit(Emit::OpCodes::Ldarg_0
);
1796 ::System::Reflection::MethodInfo
^ methodCreate
=
1797 local_factory
->LocalType
->GetMethod("createInstanceWithArgumentsAndContext");
1798 ilGen
->Emit(Emit::OpCodes::Callvirt
, methodCreate
);
1800 //cast the object returned by the functions createInstanceWithContext or
1801 //createInstanceWithArgumentsAndContext to the interface type
1802 ilGen
->Emit(Emit::OpCodes::Castclass
, retType
);
1803 ilGen
->Emit(Emit::OpCodes::Stloc
, local_return_val
);
1805 //catch exceptions thrown by createInstanceWithArgumentsAndContext and createInstanceWithContext
1806 if (arExceptionTypes
->Contains(type_uno_exception
) == false)
1808 // catch (unoidl.com.sun.star.uno.RuntimeException) {throw;}
1809 ilGen
->BeginCatchBlock(get_type("unoidl.com.sun.star.uno.RuntimeException", true));
1810 ilGen
->Emit(Emit::OpCodes::Pop
);
1811 ilGen
->Emit(Emit::OpCodes::Rethrow
);
1813 //catch and rethrow all other defined Exceptions
1814 for (int i
= 0; i
< arExceptionTypes
->Count
; i
++)
1816 ::System::Type
^ excType
= safe_cast
< ::System::Type
^ >(
1817 arExceptionTypes
[i
]);
1818 if (excType
->IsInstanceOfType(
1819 get_type("unoidl.com.sun.star.uno.RuntimeException", true)))
1820 {// we have a catch for RuntimeException already defined
1824 //catch Exception and rethrow
1825 ilGen
->BeginCatchBlock(excType
);
1826 ilGen
->Emit(Emit::OpCodes::Pop
);
1827 ilGen
->Emit(Emit::OpCodes::Rethrow
);
1829 //catch (unoidl.com.sun.star.uno.Exception) {throw DeploymentException...}
1830 ilGen
->BeginCatchBlock(type_uno_exception
);
1832 //Define the local variabe that keeps the exception
1833 Emit::LocalBuilder
^ local_exception
= ilGen
->DeclareLocal(
1834 type_uno_exception
);
1836 //Store the exception
1837 ilGen
->Emit(Emit::OpCodes::Stloc
, local_exception
);
1839 //prepare the construction of the exception
1840 strbuilder
= gcnew ::System::Text::StringBuilder(256);
1841 strbuilder
->Append("The context (com.sun.star.uno.XComponentContext) failed to supply the service ");
1842 strbuilder
->Append(to_cts_name(xServiceType
->getName()));
1843 strbuilder
->Append(": ");
1845 ilGen
->Emit(Emit::OpCodes::Ldstr
, strbuilder
->ToString());
1847 //add to the string the Exception.Message
1848 ilGen
->Emit(Emit::OpCodes::Ldloc
, local_exception
);
1849 ilGen
->Emit(Emit::OpCodes::Callvirt
,
1850 type_uno_exception
->GetProperty("Message")->GetGetMethod());
1851 array
< ::System::Type
^>^ arConcatParams
= {System::String::typeid,
1852 System::String::typeid};
1853 ilGen
->Emit(Emit::OpCodes::Call
,
1854 System::String::typeid->GetMethod("Concat", arConcatParams
));
1855 //load contex argument
1856 ilGen
->Emit(Emit::OpCodes::Ldarg_0
);
1857 ilGen
->Emit(Emit::OpCodes::Newobj
, ctorDeploymentException
);
1858 ilGen
->Emit(Emit::OpCodes::Throw
);//Exception(typeDeploymentExc);
1860 ilGen
->EndExceptionBlock();
1864 //Check if the service instance was create and throw a exception if not.
1865 Emit::Label label_service_created
= ilGen
->DefineLabel();
1866 ilGen
->Emit(Emit::OpCodes::Ldloc
, local_return_val
);
1867 ilGen
->Emit(Emit::OpCodes::Brtrue_S
, label_service_created
);
1869 strbuilder
= gcnew ::System::Text::StringBuilder(256);
1870 strbuilder
->Append("The context (com.sun.star.uno.XComponentContext) failed to supply the service ");
1871 strbuilder
->Append(to_cts_name(xServiceType
->getName()));
1872 strbuilder
->Append(".");
1873 ilGen
->Emit(Emit::OpCodes::Ldstr
, strbuilder
->ToString());
1874 ilGen
->Emit(Emit::OpCodes::Ldarg_0
);
1875 ilGen
->Emit(Emit::OpCodes::Newobj
, ctorDeploymentException
);
1876 ilGen
->Emit(Emit::OpCodes::Throw
);//Exception(typeDeploymentExc);
1878 ilGen
->MarkLabel(label_service_created
);
1879 ilGen
->Emit(Emit::OpCodes::Ldloc
, local_return_val
);
1880 ilGen
->Emit(Emit::OpCodes::Ret
);
1883 // remove from incomplete types map
1884 ::System::String
^ cts_name
= type_builder
->FullName
;
1885 m_incomplete_services
->Remove( cts_name
);
1886 xServiceType
->release();
1889 ::System::Console::WriteLine(
1890 "> emitting service type {0}", cts_name
);
1892 return type_builder
->CreateType();
1896 Emit::CustomAttributeBuilder
^ TypeEmitter::get_service_exception_attribute(
1897 const Reference
<reflection::XServiceConstructorDescription
> & ctorDes
)
1899 return get_exception_attribute(ctorDes
->getExceptions());
1902 Emit::CustomAttributeBuilder
^ TypeEmitter::get_iface_method_exception_attribute(
1903 const Reference
< reflection::XInterfaceMethodTypeDescription
>& xMethod
)
1906 const Sequence
<Reference
<reflection::XTypeDescription
> > seqTD
= xMethod
->getExceptions();
1907 int len
= seqTD
.getLength();
1908 Sequence
<Reference
<reflection::XCompoundTypeDescription
> > seqCTD(len
);
1909 Reference
<reflection::XCompoundTypeDescription
> * arCTD
= seqCTD
.getArray();
1910 for (int i
= 0; i
< len
; i
++)
1911 arCTD
[i
] = Reference
<reflection::XCompoundTypeDescription
>(seqTD
[i
], UNO_QUERY_THROW
);
1912 return get_exception_attribute(seqCTD
);
1915 Emit::CustomAttributeBuilder
^ TypeEmitter::get_exception_attribute(
1917 const Sequence
<Reference
< reflection::XCompoundTypeDescription
> >& seq_exceptionsTd
)
1919 Emit::CustomAttributeBuilder
^ attr_builder
= nullptr;
1921 Reference
< reflection::XCompoundTypeDescription
> const * exceptions
=
1922 seq_exceptionsTd
.getConstArray();
1924 array
< ::System::Type
^>^ arTypesCtor
= {::System::Type::GetType("System.Type[]")};
1925 ConstructorInfo
^ ctor_ExceptionAttribute
=
1926 ::uno::ExceptionAttribute::typeid->GetConstructor(arTypesCtor
);
1928 sal_Int32 exc_length
= seq_exceptionsTd
.getLength();
1929 if (exc_length
!= 0) // opt
1931 array
< ::System::Type
^>^ exception_types
=
1932 gcnew array
< ::System::Type
^> ( exc_length
);
1933 for ( sal_Int32 exc_pos
= 0; exc_pos
< exc_length
; ++exc_pos
)
1935 Reference
< reflection::XCompoundTypeDescription
> const & xExc
=
1936 exceptions
[ exc_pos
];
1937 exception_types
[ exc_pos
] = get_type( xExc
);
1939 array
< ::System::Object
^>^ args
= {exception_types
};
1940 attr_builder
= gcnew
Emit::CustomAttributeBuilder(
1941 ctor_ExceptionAttribute
, args
);
1943 return attr_builder
;
1947 ::System::Type
^ TypeEmitter::complete_singleton_type(singleton_entry
^ entry
)
1949 Emit::TypeBuilder
^ type_builder
= entry
->m_type_builder
;
1950 reflection::XSingletonTypeDescription2
* xSingletonType
= entry
->m_xType
;
1951 ::System::String
^ sSingletonName
= to_cts_name(xSingletonType
->getName());
1953 //Create the private default constructor
1954 Emit::ConstructorBuilder
^ ctor_builder
=
1955 type_builder
->DefineConstructor(
1956 static_cast<MethodAttributes
>(MethodAttributes::Private
|
1957 MethodAttributes::HideBySig
|
1958 MethodAttributes::SpecialName
|
1959 MethodAttributes::RTSpecialName
),
1960 CallingConventions::Standard
, nullptr);
1962 Emit::ILGenerator
^ ilGen
= ctor_builder
->GetILGenerator();
1963 ilGen
->Emit( Emit::OpCodes::Ldarg_0
); // push this
1965 Emit::OpCodes::Call
,
1966 type_builder
->BaseType
->GetConstructor(gcnew array
< ::System::Type
^>(0)));
1967 ilGen
->Emit( Emit::OpCodes::Ret
);
1970 //obtain the interface which makes up this service, it is the return
1971 //type of the constructor functions
1972 Reference
<reflection::XInterfaceTypeDescription2
> xIfaceType(
1973 xSingletonType
->getInterface(), UNO_QUERY
);
1974 if (xIfaceType
.is () == sal_False
)
1975 xIfaceType
= resolveInterfaceTypedef(xSingletonType
->getInterface());
1976 System::Type
^ retType
= get_type(xIfaceType
);
1979 array
< ::System::Type
^>^ arTypeParameters
= {get_type("unoidl.com.sun.star.uno.XComponentContext", true)};
1980 Emit::MethodBuilder
^ method_builder
= type_builder
->DefineMethod(
1981 gcnew
System::String("get"),
1982 static_cast<MethodAttributes
>(MethodAttributes::Public
| MethodAttributes::HideBySig
|
1983 MethodAttributes::Static
),
1988 // method_builder->SetCustomAttribute(get_service_ctor_method_attribute(ctorDes));
1990 //The first parameter is the XComponentContext, which cannot be obtained
1992 //The context is not part of the idl description
1993 method_builder
->DefineParameter(1, ParameterAttributes::In
, "the_context");
1996 ilGen
= method_builder
->GetILGenerator();
1997 //Define locals ---------------------------------
1998 // Any, returned by XComponentContext.getValueByName
1999 Emit::LocalBuilder
^ local_any
=
2000 ilGen
->DeclareLocal(::uno::Any::typeid);
2002 //Call XContext::getValueByName
2003 ilGen
->Emit(Emit::OpCodes::Ldarg_0
);
2004 // build the singleton name : /singleton/unoidl.com.sun.star.XXX
2005 ::System::Text::StringBuilder
^ sBuilder
=
2006 gcnew ::System::Text::StringBuilder("/singletons/");
2007 sBuilder
->Append(sSingletonName
);
2008 ilGen
->Emit(Emit::OpCodes::Ldstr
, sBuilder
->ToString());
2010 ::System::Reflection::MethodInfo
^ methodGetValueByName
=
2011 get_type("unoidl.com.sun.star.uno.XComponentContext", true)->GetMethod("getValueByName");
2012 ilGen
->Emit(Emit::OpCodes::Callvirt
, methodGetValueByName
);
2013 ilGen
->Emit(Emit::OpCodes::Stloc_0
);
2015 //Contains the returned Any a value?
2016 ilGen
->Emit(Emit::OpCodes::Ldloca_S
, local_any
);
2017 ::System::Reflection::MethodInfo
^ methodHasValue
=
2018 ::uno::Any::typeid->GetMethod("hasValue");
2019 ilGen
->Emit(Emit::OpCodes::Call
, methodHasValue
);
2021 //If not, then throw an DeploymentException
2022 Emit::Label label_singleton_exists
= ilGen
->DefineLabel();
2023 ilGen
->Emit(Emit::OpCodes::Brtrue_S
, label_singleton_exists
);
2024 sBuilder
= gcnew ::System::Text::StringBuilder(
2025 "Component context fails to supply singleton ");
2026 sBuilder
->Append(sSingletonName
);
2027 sBuilder
->Append(" of type ");
2028 sBuilder
->Append(retType
->FullName
);
2029 sBuilder
->Append(".");
2030 ilGen
->Emit(Emit::OpCodes::Ldstr
, sBuilder
->ToString());
2031 ilGen
->Emit(Emit::OpCodes::Ldarg_0
);
2032 array
< ::System::Type
^>^ arTypesCtorDeploymentException
= {
2033 ::System::String::typeid, ::System::Object::typeid};
2034 ilGen
->Emit(Emit::OpCodes::Newobj
,
2035 get_type("unoidl.com.sun.star.uno.DeploymentException",true)
2036 ->GetConstructor(arTypesCtorDeploymentException
));
2037 ilGen
->Emit(Emit::OpCodes::Throw
);
2038 ilGen
->MarkLabel(label_singleton_exists
);
2040 //Cast the singleton contained in the Any to the expected interface and return it.
2041 ilGen
->Emit(Emit::OpCodes::Ldloca_S
, local_any
);
2042 ilGen
->Emit(Emit::OpCodes::Call
, ::uno::Any::typeid->GetProperty("Value")->GetGetMethod());
2043 ilGen
->Emit(Emit::OpCodes::Castclass
, retType
);
2044 ilGen
->Emit(Emit::OpCodes::Ret
);
2046 // remove from incomplete types map
2047 ::System::String
^ cts_name
= type_builder
->FullName
;
2048 m_incomplete_singletons
->Remove( cts_name
);
2049 xSingletonType
->release();
2052 ::System::Console::WriteLine(
2053 "> emitting singleton type {0}", cts_name
);
2055 return type_builder
->CreateType();
2060 ::System::Type
^ TypeEmitter::get_type(
2061 Reference
< reflection::XTypeDescription
> const & xType
)
2063 switch (xType
->getTypeClass())
2065 case TypeClass_VOID
:
2066 return ::System::Void::typeid;
2067 case TypeClass_CHAR
:
2068 return ::System::Char::typeid;
2069 case TypeClass_BOOLEAN
:
2070 return ::System::Boolean::typeid;
2071 case TypeClass_BYTE
:
2072 return ::System::Byte::typeid;
2073 case TypeClass_SHORT
:
2074 return ::System::Int16::typeid;
2075 case TypeClass_UNSIGNED_SHORT
:
2076 return ::System::UInt16::typeid;
2077 case TypeClass_LONG
:
2078 return ::System::Int32::typeid;
2079 case TypeClass_UNSIGNED_LONG
:
2080 return ::System::UInt32::typeid;
2081 case TypeClass_HYPER
:
2082 return ::System::Int64::typeid;
2083 case TypeClass_UNSIGNED_HYPER
:
2084 return ::System::UInt64::typeid;
2085 case TypeClass_FLOAT
:
2086 return ::System::Single::typeid;
2087 case TypeClass_DOUBLE
:
2088 return ::System::Double::typeid;
2089 case TypeClass_STRING
:
2090 return ::System::String::typeid;
2091 case TypeClass_TYPE
:
2092 return ::System::Type::typeid;
2094 return ::uno::Any::typeid;
2095 case TypeClass_ENUM
:
2096 return get_type( Reference
< reflection::XEnumTypeDescription
>(
2097 xType
, UNO_QUERY_THROW
) );
2098 case TypeClass_TYPEDEF
:
2101 Reference
< reflection::XIndirectTypeDescription
>(
2102 xType
, UNO_QUERY_THROW
)->getReferencedType() );
2103 case TypeClass_STRUCT
:
2104 case TypeClass_EXCEPTION
:
2106 Reference
< reflection::XCompoundTypeDescription
>(
2107 xType
, UNO_QUERY_THROW
) );
2108 case TypeClass_SEQUENCE
:
2110 ::System::Type
^ element_type
= get_type(
2111 Reference
< reflection::XIndirectTypeDescription
>(
2112 xType
, UNO_QUERY_THROW
)->getReferencedType() );
2113 ::System::Type
^ retType
= get_type(
2114 ::System::String::Concat(
2115 element_type
->FullName
, "[]" ), true );
2117 ::uno::PolymorphicType
^ pt
= dynamic_cast< ::uno::PolymorphicType
^ >(element_type
);
2120 ::System::String
^ sName
= ::System::String::Concat(pt
->PolymorphicName
, "[]");
2121 retType
= ::uno::PolymorphicType::GetType(retType
, sName
);
2125 case TypeClass_INTERFACE
:
2127 Reference
< reflection::XInterfaceTypeDescription2
>(
2128 xType
, UNO_QUERY_THROW
) );
2129 case TypeClass_CONSTANT
:
2131 Reference
< reflection::XConstantTypeDescription
>(
2132 xType
, UNO_QUERY_THROW
) );
2133 case TypeClass_CONSTANTS
:
2135 Reference
< reflection::XConstantsTypeDescription
>(
2136 xType
, UNO_QUERY_THROW
) );
2137 case TypeClass_SERVICE
:
2139 Reference
< reflection::XServiceTypeDescription2
>(
2140 xType
, UNO_QUERY_THROW
) );
2141 case TypeClass_SINGLETON
:
2143 Reference
< reflection::XSingletonTypeDescription2
>(
2144 xType
, UNO_QUERY_THROW
) );
2145 case TypeClass_MODULE
:
2149 throw RuntimeException(
2150 "unexpected type " + xType
->getName() );
2155 ::System::Type
^ TypeEmitter::get_complete_struct( ::System::String
^ sName
)
2157 struct_entry
^ pStruct
= safe_cast
< struct_entry
^>(
2158 m_incomplete_structs
[sName
]);
2161 complete_struct_type(pStruct
);
2163 //get_type will asked the module builder for the type or otherwise all known assemblies.
2164 return get_type(sName
, true);
2166 TypeEmitter::~TypeEmitter()
2170 ::System::Collections::IDictionaryEnumerator
^ enumerator
=
2171 m_incomplete_ifaces
->GetEnumerator();
2172 if (! enumerator
->MoveNext())
2174 complete_iface_type(
2175 safe_cast
< iface_entry
^ >( enumerator
->Value
) );
2180 ::System::Collections::IDictionaryEnumerator
^ enumerator
=
2181 m_incomplete_structs
->GetEnumerator();
2182 if (! enumerator
->MoveNext())
2184 complete_struct_type(
2185 safe_cast
< struct_entry
^ >( enumerator
->Value
) );
2191 ::System::Collections::IDictionaryEnumerator
^ enumerator
=
2192 m_incomplete_services
->GetEnumerator();
2193 if (! enumerator
->MoveNext())
2195 complete_service_type(
2196 safe_cast
< service_entry
^ >( enumerator
->Value
) );
2201 ::System::Collections::IDictionaryEnumerator
^ enumerator
=
2202 m_incomplete_singletons
->GetEnumerator();
2203 if (! enumerator
->MoveNext())
2205 complete_singleton_type(
2206 safe_cast
< singleton_entry
^ >( enumerator
->Value
) );
2210 TypeEmitter::TypeEmitter(
2211 ::System::Reflection::Emit::ModuleBuilder
^ module_builder
,
2212 array
< ::System::Reflection::Assembly
^>^ extra_assemblies
)
2213 : m_module_builder( module_builder
),
2214 m_extra_assemblies( extra_assemblies
),
2215 m_method_info_Type_GetTypeFromHandle( nullptr ),
2216 m_type_Exception( nullptr ),
2217 m_type_RuntimeException( nullptr ),
2218 m_incomplete_ifaces( gcnew ::System::Collections::Hashtable() ),
2219 m_incomplete_structs( gcnew ::System::Collections::Hashtable() ),
2220 m_incomplete_services(gcnew ::System::Collections::Hashtable() ),
2221 m_incomplete_singletons(gcnew ::System::Collections::Hashtable() ),
2222 m_generated_structs( gcnew ::System::Collections::Hashtable() )
2224 array
< ::System::Type
^>^ param_types
= gcnew array
< ::System::Type
^> ( 1 );
2225 param_types
[ 0 ] = ::System::RuntimeTypeHandle::typeid;
2226 m_method_info_Type_GetTypeFromHandle
=
2227 ::System::Type::typeid
2228 ->GetMethod( "GetTypeFromHandle", param_types
);
2231 ::System::Collections::ArrayList
^ TypeEmitter::get_service_ctor_method_exceptions_reduced(
2232 const Sequence
<Reference
<reflection::XCompoundTypeDescription
> > & seqExceptionsTd
)
2234 if (seqExceptionsTd
.getLength() == 0)
2235 return gcnew ::System::Collections::ArrayList();
2237 ::System::Collections::ArrayList
^ arTypes
= gcnew ::System::Collections::ArrayList();
2238 for (int i
= 0; i
< seqExceptionsTd
.getLength(); i
++)
2239 arTypes
->Add(get_type(to_cts_name(seqExceptionsTd
[i
]->getName()), true));
2244 bool bRemove
= false;
2245 for (int i
= start
; i
< arTypes
->Count
; i
++)
2247 ::System::Type
^ t
= safe_cast
< ::System::Type
^ >(arTypes
[i
]);
2248 for (int j
= 0; j
< arTypes
->Count
; j
++)
2250 if (t
->IsSubclassOf(safe_cast
< ::System::Type
^ >(arTypes
[j
])))
2252 arTypes
->RemoveAt(i
);
2262 if (bRemove
== false)
2269 css::uno::Reference
< css::reflection::XInterfaceTypeDescription2
>
2270 resolveInterfaceTypedef(
2271 const css::uno::Reference
<css::reflection::XTypeDescription
>& type
)
2273 Reference
<reflection::XInterfaceTypeDescription2
>
2274 xIfaceTd(type
, UNO_QUERY
);
2279 Reference
<reflection::XIndirectTypeDescription
> xIndTd(
2281 if (xIndTd
.is() == sal_False
)
2282 throw css::uno::Exception(
2283 "resolveInterfaceTypedef was called with an invalid argument", 0);
2285 return resolveInterfaceTypedef(xIndTd
->getReferencedType());
2291 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */