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 ::rtl
;
35 using namespace ::com::sun::star
;
36 using namespace ::com::sun::star::uno
;
40 System::String
^ mapUnoPolymorphicName(System::String
^ unoName
);
41 //------------------------------------------------------------------------------
42 static inline ::System::String
^ to_cts_name(
43 OUString
const & uno_name
)
45 OUStringBuffer
buf( 7 + uno_name
.getLength() );
46 buf
.append( "unoidl." );
47 buf
.append( uno_name
);
48 return ustring_to_String( buf
.makeStringAndClear() );
51 //------------------------------------------------------------------------------
52 static inline ::System::Object
^ to_cli_constant( Any
const & value
)
54 switch (value
.getValueTypeClass())
57 return ((::System::Char
) *reinterpret_cast< sal_Unicode
const * >(
59 case TypeClass_BOOLEAN
:
60 return ((::System::Boolean
)
61 sal_False
!= *reinterpret_cast< sal_Bool
const * >(
64 return ((::System::Byte
) *reinterpret_cast< sal_Int8
const * >(
67 return ((::System::Int16
) *reinterpret_cast< sal_Int16
const * >(
69 case TypeClass_UNSIGNED_SHORT
:
70 return ((::System::UInt16
) *reinterpret_cast< sal_uInt16
const * >(
73 return ((::System::Int32
) *reinterpret_cast< sal_Int32
const * >(
75 case TypeClass_UNSIGNED_LONG
:
76 return ((::System::UInt32
) *reinterpret_cast< sal_uInt32
const * >(
79 return ((::System::Int64
) *reinterpret_cast< sal_Int64
const * >(
81 case TypeClass_UNSIGNED_HYPER
:
82 return ((::System::UInt64
) *reinterpret_cast< sal_uInt64
const * >(
85 return ((::System::Single
) *reinterpret_cast< float const * >(
87 case TypeClass_DOUBLE
:
88 return ((::System::Double
) *reinterpret_cast< double const * >(
91 throw RuntimeException(
92 "unexpected constant type " +
93 value
.getValueType().getTypeName(),
94 Reference
< XInterface
>() );
98 //------------------------------------------------------------------------------
99 static inline void emit_ldarg( Emit::ILGenerator
^ code
, ::System::Int32 index
)
104 #pragma warning (push)
105 #pragma warning (disable: 4538)
106 code
->Emit( Emit::OpCodes::Ldarg_0
);
107 #pragma warning (pop)
110 code
->Emit( Emit::OpCodes::Ldarg_1
);
113 code
->Emit( Emit::OpCodes::Ldarg_2
);
116 code
->Emit( Emit::OpCodes::Ldarg_3
);
120 code
->Emit( Emit::OpCodes::Ldarg_S
, (::System::Byte
) index
);
121 else if (index
< 0x8000)
122 code
->Emit( Emit::OpCodes::Ldarg_S
, (::System::Int16
) index
);
124 code
->Emit( Emit::OpCodes::Ldarg
, index
);
129 void polymorphicStructNameToStructName(::System::String
^* sPolyName
)
131 if ((*sPolyName
)->EndsWith(">") == false)
134 int index
= (*sPolyName
)->IndexOf('<');
135 OSL_ASSERT(index
!= -1);
136 *sPolyName
= (*sPolyName
)->Substring(0, index
);
140 System::String
^ mapUnoTypeName(System::String
^ typeName
)
142 ::System::Text::StringBuilder
^ buf
= gcnew
System::Text::StringBuilder();
143 ::System::String
^ sUnoName
= ::System::String::Copy(typeName
);
144 //determine if the type is a sequence and its dimensions
146 if (typeName
->StartsWith("["))//if (usUnoName[0] == '[')
151 if (typeName
[index
++] == ']')//if (usUnoName[index++] == ']')
153 if (typeName
[index
++] != '[')//usUnoName[index++] != '[')
156 sUnoName
= sUnoName
->Substring(index
- 1);//usUnoName = usUnoName.copy(index - 1);
158 if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoBool
)))
159 buf
->Append(const_cast<System::String
^>(Constants::sBoolean
));
160 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoChar
)))
161 buf
->Append(const_cast<System::String
^>(Constants::sChar
));
162 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoByte
)))
163 buf
->Append(const_cast<System::String
^>(Constants::sByte
));
164 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoShort
)))
165 buf
->Append(const_cast<System::String
^>(Constants::sInt16
));
166 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoUShort
)))
167 buf
->Append(const_cast<System::String
^>(Constants::sUInt16
));
168 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoLong
)))
169 buf
->Append(const_cast<System::String
^>(Constants::sInt32
));
170 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoULong
)))
171 buf
->Append(const_cast<System::String
^>(Constants::sUInt32
));
172 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoHyper
)))
173 buf
->Append(const_cast<System::String
^>(Constants::sInt64
));
174 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoUHyper
)))
175 buf
->Append(const_cast<System::String
^>(Constants::sUInt64
));
176 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoFloat
)))
177 buf
->Append(const_cast<System::String
^>(Constants::sSingle
));
178 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoDouble
)))
179 buf
->Append(const_cast<System::String
^>(Constants::sDouble
));
180 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoString
)))
181 buf
->Append(const_cast<System::String
^>(Constants::sString
));
182 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoVoid
)))
183 buf
->Append(const_cast<System::String
^>(Constants::sVoid
));
184 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoType
)))
185 buf
->Append(const_cast<System::String
^>(Constants::sType
));
186 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoXInterface
)))
187 buf
->Append(const_cast<System::String
^>(Constants::sObject
));
188 else if (sUnoName
->Equals(const_cast<System::String
^>(Constants::sUnoAny
)))
190 buf
->Append(const_cast<System::String
^>(Constants::sAny
));
194 //put "unoidl." at the beginning
195 buf
->Append(const_cast<System::String
^>(Constants::sUnoidl
));
196 buf
->Append(mapUnoPolymorphicName(sUnoName
));
200 buf
->Append(const_cast<System::String
^>(Constants::sBrackets
));
202 return buf
->ToString();
206 /** For example, there is a uno type
207 com.sun.star.Foo<char, long>.
208 The values in the type list
209 are uno types and are replaced by cli types, such as System.Char,
212 Strings can be as complicated as this
213 test.MyStruct<char,test.MyStruct<long, []string>>
215 System::String
^ mapUnoPolymorphicName(System::String
^ unoName
)
217 int index
= unoName
->IndexOf('<');
221 System::Text::StringBuilder
^ builder
=
222 gcnew
System::Text::StringBuilder(unoName
->Substring(0, index
+1 ));
224 //Find the first occurrence of ','
225 //If the parameter is a polymorphic struct then we neede to ignore everything
226 //between the brackets because it can also contain commas
227 //get the type list within < and >
228 int endIndex
= unoName
->Length
- 1;
232 while (cur
<= endIndex
)
234 System::Char c
= unoName
[cur
];
235 if (c
== ',' || c
== '>')
237 //insert a comma if needed
238 if (countParams
!= 0)
239 builder
->Append(",");
241 System::String
^ sParam
= unoName
->Substring(index
, cur
- index
);
244 //the the index to the beginning of the next param
246 builder
->Append(mapUnoTypeName(sParam
));
251 //continue until the matching '>'
255 System::Char curChar
= unoName
[cur
];
260 else if (curChar
== '>')
272 builder
->Append((System::Char
) '>');
273 return builder
->ToString();
278 //______________________________________________________________________________
279 Assembly
^ TypeEmitter::type_resolve(
280 ::System::Object
^, ::System::ResolveEventArgs
^ args
)
282 ::System::String
^ cts_name
= args
->Name
;
283 ::System::Type
^ ret_type
;
285 iface_entry
^ entry
= dynamic_cast< iface_entry
^ >(m_incomplete_ifaces
[cts_name
] );
286 if (nullptr != entry
)
287 ret_type
= entry
->m_type_builder
;
289 if (nullptr == ret_type
)
291 sal_Int32 len
= m_extra_assemblies
->Length
;
292 for ( sal_Int32 pos
= 0; pos
< len
; ++pos
)
294 ret_type
= m_extra_assemblies
[ pos
]->GetType(
295 cts_name
, false /* no exc */ );
296 if (nullptr != ret_type
)
300 ::System::Console::WriteLine(
301 "> resolving type {0} from {1}.",
302 cts_name
, ret_type
->Assembly
->FullName
);
308 if (nullptr != ret_type
)
309 return ret_type
->Assembly
;
313 //______________________________________________________________________________
314 ::System::Type
^ TypeEmitter::get_type(
315 ::System::String
^ cts_name
, bool throw_exc
)
317 ::System::Type
^ ret_type
= m_module_builder
->GetType( cts_name
, false );
318 //We get the type from the ModuleBuilder even if the type is not complete
319 //but have been defined.
322 // iface_entry * entry = dynamic_cast< iface_entry * >(
323 // m_incomplete_ifaces->get_Item( cts_name ) );
325 // ret_type = entry->m_type_builder;
327 //try the cli_basetypes assembly
328 if (ret_type
== nullptr)
330 ::System::Text::StringBuilder
^ builder
= gcnew ::System::Text::StringBuilder(cts_name
);
331 builder
->Append(",cli_basetypes");
332 ret_type
= ::System::Type::GetType(builder
->ToString());
335 if (ret_type
== nullptr)
339 // may call on type_resolve()
340 return ::System::Type::GetType( cts_name
, throw_exc
);
342 catch (::System::Exception
^ exc
)
344 //If the type is not found one may have forgotten to specify assemblies with
346 ::System::Text::StringBuilder
^ sb
= gcnew ::System::Text::StringBuilder();
347 sb
->Append(gcnew ::System::String("\nThe type "));
348 sb
->Append(cts_name
);
349 sb
->Append(gcnew ::System::String(" \n could not be found. Did you forget to " \
350 "specify an additional assembly with the --reference option?\n"));
352 throw gcnew ::System::Exception(sb
->ToString(), exc
);
361 //______________________________________________________________________________
362 ::System::Type
^ TypeEmitter::get_type_Exception()
364 if (nullptr == m_type_Exception
)
366 m_type_Exception
= get_type(
367 "unoidl.com.sun.star.uno.Exception", false /* no exc */ );
368 if (nullptr == m_type_Exception
)
370 // define hardcoded type unoidl.com.sun.star.uno.Exception
371 Emit::TypeBuilder
^ type_builder
=
372 m_module_builder
->DefineType(
373 "unoidl.com.sun.star.uno.Exception",
374 (TypeAttributes
) (TypeAttributes::Public
|
375 TypeAttributes::BeforeFieldInit
|
376 TypeAttributes::AnsiClass
),
377 (::System::Exception::typeid) );
378 Emit::FieldBuilder
^ field_Context
= type_builder
->DefineField(
379 "Context", (::System::Object::typeid),
380 FieldAttributes::Public
);
382 type_builder
->DefineDefaultConstructor( c_ctor_method_attr
);
384 array
< ::System::Type
^>^ param_types
=
385 gcnew array
< ::System::Type
^>(2);
386 param_types
[ 0 ] = ::System::String::typeid;
387 param_types
[ 1 ] = ::System::Object::typeid;
388 Emit::ConstructorBuilder
^ ctor_builder
=
389 type_builder
->DefineConstructor(
390 c_ctor_method_attr
, CallingConventions::Standard
,
392 ctor_builder
->DefineParameter(
393 1, ParameterAttributes::In
, "Message" );
394 ctor_builder
->DefineParameter(
395 2, ParameterAttributes::In
, "Context" );
396 Emit::ILGenerator
^ code
= ctor_builder
->GetILGenerator();
397 code
->Emit( Emit::OpCodes::Ldarg_0
);
398 code
->Emit( Emit::OpCodes::Ldarg_1
);
399 param_types
= gcnew array
< ::System::Type
^>(1);
400 param_types
[ 0 ] = ::System::String::typeid;
403 (::System::Exception::typeid)
404 ->GetConstructor( param_types
) );
405 code
->Emit( Emit::OpCodes::Ldarg_0
);
406 code
->Emit( Emit::OpCodes::Ldarg_2
);
407 code
->Emit( Emit::OpCodes::Stfld
, field_Context
);
408 code
->Emit( Emit::OpCodes::Ret
);
412 ::System::Console::WriteLine(
413 "> emitting exception type "
414 "unoidl.com.sun.star.uno.Exception" );
416 m_type_Exception
= type_builder
->CreateType();
419 return m_type_Exception
;
422 //______________________________________________________________________________
423 ::System::Type
^ TypeEmitter::get_type_RuntimeException()
425 if (nullptr == m_type_RuntimeException
)
427 m_type_RuntimeException
= get_type(
428 "unoidl.com.sun.star.uno.RuntimeException", false /* no exc */ );
429 if (nullptr == m_type_RuntimeException
)
431 // define hardcoded type unoidl.com.sun.star.uno.RuntimeException
432 ::System::Type
^ type_Exception
= get_type_Exception();
433 Emit::TypeBuilder
^ type_builder
=
434 m_module_builder
->DefineType(
435 "unoidl.com.sun.star.uno.RuntimeException",
436 (TypeAttributes
) (TypeAttributes::Public
|
437 TypeAttributes::BeforeFieldInit
|
438 TypeAttributes::AnsiClass
),
441 type_builder
->DefineDefaultConstructor( c_ctor_method_attr
);
443 array
< ::System::Type
^>^ param_types
=
444 gcnew array
< ::System::Type
^>(2);
445 param_types
[ 0 ] = ::System::String::typeid;
446 param_types
[ 1 ] = ::System::Object::typeid;
447 Emit::ConstructorBuilder
^ ctor_builder
=
448 type_builder
->DefineConstructor(
449 c_ctor_method_attr
, CallingConventions::Standard
,
451 ctor_builder
->DefineParameter(
452 1, ParameterAttributes::In
, "Message" );
453 ctor_builder
->DefineParameter(
454 2, ParameterAttributes::In
, "Context" );
455 Emit::ILGenerator
^ code
= ctor_builder
->GetILGenerator();
456 code
->Emit( Emit::OpCodes::Ldarg_0
);
457 code
->Emit( Emit::OpCodes::Ldarg_1
);
458 code
->Emit( Emit::OpCodes::Ldarg_2
);
461 type_Exception
->GetConstructor( param_types
) );
462 code
->Emit( Emit::OpCodes::Ret
);
466 ::System::Console::WriteLine(
467 "> emitting exception type "
468 "unoidl.com.sun.star.uno.RuntimeException" );
470 m_type_RuntimeException
= type_builder
->CreateType();
473 return m_type_RuntimeException
;
476 //______________________________________________________________________________
477 ::System::Type
^ TypeEmitter::get_type(
478 Reference
< reflection::XConstantTypeDescription
> const & xType
)
480 ::System::String
^ cts_name
= to_cts_name( xType
->getName() );
481 ::System::Type
^ ret_type
= get_type( cts_name
, false /* no exc */ );
482 if (nullptr == ret_type
)
484 Reference
< reflection::XConstantTypeDescription
> xConstant(
485 xType
, UNO_QUERY_THROW
);
486 ::System::Object
^ constant
=
487 to_cli_constant( xConstant
->getConstantValue() );
488 Emit::TypeBuilder
^ type_builder
=
489 m_module_builder
->DefineType(
491 (TypeAttributes
) (TypeAttributes::Public
|
492 TypeAttributes::Sealed
|
493 TypeAttributes::BeforeFieldInit
|
494 TypeAttributes::AnsiClass
) );
496 Emit::FieldBuilder
^ field_builder
= type_builder
->DefineField(
497 cts_name
->Substring( cts_name
->LastIndexOf( '.' ) +1 ),
499 (FieldAttributes
) (FieldAttributes::Public
|
500 FieldAttributes::Static
|
501 FieldAttributes::Literal
) );
502 field_builder
->SetConstant( constant
);
506 ::System::Console::WriteLine(
507 "> emitting constant type {0}", cts_name
);
509 ret_type
= type_builder
->CreateType();
514 //______________________________________________________________________________
515 ::System::Type
^ TypeEmitter::get_type(
516 Reference
< reflection::XConstantsTypeDescription
> const & xType
)
518 ::System::String
^ cts_name
= to_cts_name( xType
->getName() );
519 ::System::Type
^ ret_type
= get_type( cts_name
, false /* no exc */ );
520 if (nullptr == ret_type
)
522 Emit::TypeBuilder
^ type_builder
=
523 m_module_builder
->DefineType(
525 (TypeAttributes
) (TypeAttributes::Public
|
526 TypeAttributes::Sealed
|
527 TypeAttributes::BeforeFieldInit
|
528 TypeAttributes::AnsiClass
) );
531 reflection::XConstantTypeDescription
> > seq_constants(
532 xType
->getConstants() );
533 Reference
< reflection::XConstantTypeDescription
> const * constants
=
534 seq_constants
.getConstArray();
535 sal_Int32 constants_length
= seq_constants
.getLength();
536 for ( sal_Int32 constants_pos
= 0;
537 constants_pos
< constants_length
; ++constants_pos
)
540 reflection::XConstantTypeDescription
> const & xConstant
=
541 constants
[ constants_pos
];
542 ::System::Object
^ constant
=
543 to_cli_constant( xConstant
->getConstantValue() );
544 ::System::String
^ uno_name
=
545 ustring_to_String( xConstant
->getName() );
546 Emit::FieldBuilder
^ field_builder
= type_builder
->DefineField(
547 uno_name
->Substring( uno_name
->LastIndexOf( '.' ) +1 ),
549 (FieldAttributes
) (FieldAttributes::Public
|
550 FieldAttributes::Static
|
551 FieldAttributes::Literal
) );
552 field_builder
->SetConstant( constant
);
557 ::System::Console::WriteLine(
558 "> emitting constants group type {0}", cts_name
);
560 ret_type
= type_builder
->CreateType();
565 //______________________________________________________________________________
566 ::System::Type
^ TypeEmitter::get_type(
567 Reference
< reflection::XEnumTypeDescription
> const & xType
)
569 ::System::String
^ cts_name
= to_cts_name( xType
->getName() );
570 ::System::Type
^ ret_type
= get_type( cts_name
, false /* no exc */ );
571 if (nullptr == ret_type
)
573 // Emit::EnumBuilder * enum_builder =
574 // m_module_builder->DefineEnum(
576 // (TypeAttributes) (TypeAttributes::Public |
577 // // TypeAttributes::Sealed |
578 // TypeAttributes::AnsiClass),
579 // __typeof (::System::Int32) );
580 // workaround enum builder bug
581 Emit::TypeBuilder
^ enum_builder
=
582 m_module_builder
->DefineType(
584 (TypeAttributes
) (TypeAttributes::Public
|
585 TypeAttributes::Sealed
),
586 ::System::Enum::typeid );
587 enum_builder
->DefineField(
588 "value__", ::System::Int32::typeid,
589 (FieldAttributes
) (FieldAttributes::Private
|
590 FieldAttributes::SpecialName
|
591 FieldAttributes::RTSpecialName
) );
592 Sequence
< OUString
> seq_enum_names( xType
->getEnumNames() );
593 Sequence
< sal_Int32
> seq_enum_values( xType
->getEnumValues() );
594 sal_Int32 enum_length
= seq_enum_names
.getLength();
595 OSL_ASSERT( enum_length
== seq_enum_values
.getLength() );
596 OUString
const * enum_names
= seq_enum_names
.getConstArray();
597 sal_Int32
const * enum_values
= seq_enum_values
.getConstArray();
598 for ( sal_Int32 enum_pos
= 0; enum_pos
< enum_length
; ++enum_pos
)
600 // enum_builder->DefineLiteral(
601 // ustring_to_String( enum_names[ enum_pos ] ),
602 // __box ((::System::Int32) enum_values[ enum_pos ]) );
603 Emit::FieldBuilder
^ field_builder
=
604 enum_builder
->DefineField(
605 ustring_to_String( enum_names
[ enum_pos
] ),
607 (FieldAttributes
) (FieldAttributes::Public
|
608 FieldAttributes::Static
|
609 FieldAttributes::Literal
) );
610 field_builder
->SetConstant(
611 ((::System::Int32
) enum_values
[ enum_pos
]) );
616 ::System::Console::WriteLine(
617 "> emitting enum type {0}", cts_name
);
619 ret_type
= enum_builder
->CreateType();
624 //______________________________________________________________________________
625 ::System::Type
^ TypeEmitter::get_type(
626 Reference
< reflection::XCompoundTypeDescription
> const & xType
)
628 OUString
uno_name( xType
->getName() );
629 if (TypeClass_EXCEPTION
== xType
->getTypeClass())
631 if ( uno_name
== "com.sun.star.uno.Exception" )
633 return get_type_Exception();
635 if ( uno_name
== "com.sun.star.uno.RuntimeException" )
637 return get_type_RuntimeException();
640 ::System::String
^ cts_name
= to_cts_name( uno_name
);
641 // if the struct is an instantiated polymorpic struct then we create the simple struct name
643 // void func ([in] PolyStruct<boolean> arg);
644 //PolyStruct<boolean> will be converted to PolyStruct
645 polymorphicStructNameToStructName( & cts_name
);
647 ::System::Type
^ ret_type
= get_type( cts_name
, false /* no exc */ );
648 if (nullptr == ret_type
)
650 Reference
< reflection::XCompoundTypeDescription
> xBaseType(
651 xType
->getBaseType(), UNO_QUERY
);
652 ::System::Type
^ base_type
= (xBaseType
.is()
653 ? get_type( xBaseType
)
654 : ::System::Object::typeid);
655 Emit::TypeBuilder
^ type_builder
=
656 m_module_builder
->DefineType(
658 (TypeAttributes
) (TypeAttributes::Public
|
659 TypeAttributes::BeforeFieldInit
|
660 TypeAttributes::AnsiClass
),
664 // insert to be completed
665 struct_entry
^ entry
= gcnew
struct_entry();
667 entry
->m_xType
= xType
.get();
668 entry
->m_type_builder
= type_builder
;
669 entry
->m_base_type
= base_type
;
670 m_incomplete_structs
->Add( cts_name
, entry
);
672 // type is incomplete
673 ret_type
= type_builder
;
676 //In case of an instantiated polymorphic struct we want to return a
677 //uno.PolymorphicType (inherits Type) rather then Type. This is neaded for constructing
678 //the service code. We can only do that if the struct is completed.
679 if (m_generated_structs
[cts_name
])
681 Reference
< reflection::XStructTypeDescription
> xStructTypeDesc(
684 if (xStructTypeDesc
.is())
686 Sequence
< Reference
< reflection::XTypeDescription
> > seqTypeArgs
= xStructTypeDesc
->getTypeArguments();
687 sal_Int32 numTypes
= seqTypeArgs
.getLength();
690 //it is an instantiated polymorphic struct
691 ::System::String
^ sCliName
= mapUnoTypeName(ustring_to_String(xType
->getName()));
692 ret_type
= ::uno::PolymorphicType::GetType(ret_type
, sCliName
);
699 //______________________________________________________________________________
700 ::System::Type
^ TypeEmitter::get_type(
701 Reference
< reflection::XInterfaceTypeDescription2
> const & xType
)
703 OUString
uno_name( xType
->getName() );
704 if ( uno_name
== "com.sun.star.uno.XInterface" )
706 return ::System::Object::typeid;
709 ::System::String
^ cts_name
= to_cts_name( xType
->getName() );
710 ::System::Type
^ ret_type
= get_type( cts_name
, false /* no exc */ );
711 if (nullptr == ret_type
)
713 Emit::TypeBuilder
^ type_builder
;
715 TypeAttributes attr
= (TypeAttributes
) (TypeAttributes::Public
|
716 TypeAttributes::Interface
|
717 TypeAttributes::Abstract
|
718 TypeAttributes::AnsiClass
);
720 std::vector
<Reference
<reflection::XInterfaceTypeDescription2
> > vecBaseTypes
;
721 Sequence
<Reference
< reflection::XTypeDescription
> > seqBaseTypes
=
722 xType
->getBaseTypes();
723 if (seqBaseTypes
.getLength() > 0)
725 for (int i
= 0; i
< seqBaseTypes
.getLength(); i
++)
727 Reference
<reflection::XInterfaceTypeDescription2
> xIfaceTd
=
728 resolveInterfaceTypedef(seqBaseTypes
[i
]);
730 if ( xIfaceTd
->getName() != "com.sun.star.uno.XInterface" )
732 vecBaseTypes
.push_back(xIfaceTd
);
736 array
< ::System::Type
^>^ base_interfaces
=
737 gcnew array
< ::System::Type
^>( vecBaseTypes
.size() );
739 typedef std::vector
<Reference
<reflection::XInterfaceTypeDescription2
> >::const_iterator it
;
741 for (it i
= vecBaseTypes
.begin(); i
!= vecBaseTypes
.end(); ++i
, ++index
)
742 base_interfaces
[ index
] = get_type( *i
);
743 type_builder
= m_module_builder
->DefineType(
744 cts_name
, attr
, nullptr, base_interfaces
);
748 ::System::Console::WriteLine(
749 "warning: IDL interface {0} is not derived from "
750 "com.sun.star.uno.XInterface!",
751 ustring_to_String( uno_name
) );
753 type_builder
= m_module_builder
->DefineType( cts_name
, attr
);
756 // insert to be completed
757 iface_entry
^ entry
= gcnew
iface_entry();
759 entry
->m_xType
= xType
.get();
760 entry
->m_type_builder
= type_builder
;
761 m_incomplete_ifaces
->Add( cts_name
, entry
);
763 // type is incomplete
764 ret_type
= type_builder
;
770 //______________________________________________________________________________
771 ::System::Type
^ TypeEmitter::get_type(
772 Reference
< reflection::XServiceTypeDescription2
> const & xType
)
774 if (xType
->isSingleInterfaceBased() == sal_False
)
777 System::String
^ cts_name
= to_cts_name( xType
->getName() );
778 System::Type
^ ret_type
= get_type( cts_name
, false /* no exc */ );
779 if (ret_type
!= nullptr)
782 TypeAttributes attr
= (TypeAttributes
) (TypeAttributes::Public
|
783 TypeAttributes::Sealed
|
784 TypeAttributes::BeforeFieldInit
|
785 TypeAttributes::AnsiClass
);
787 Emit::TypeBuilder
^ type_builder
= m_module_builder
->DefineType(
790 // insert to be completed
791 service_entry
^ entry
= gcnew
service_entry();
793 entry
->m_xType
= xType
.get();
794 entry
->m_type_builder
= type_builder
;
795 m_incomplete_services
->Add(cts_name
,entry
);
800 ::System::Type
^ TypeEmitter::get_type(
801 Reference
<reflection::XSingletonTypeDescription2
> const & xType
)
803 if (xType
->isInterfaceBased() == 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
!= nullptr)
811 TypeAttributes attr
= static_cast<TypeAttributes
>(
812 TypeAttributes::Public
|
813 TypeAttributes::Sealed
|
814 TypeAttributes::BeforeFieldInit
|
815 TypeAttributes::AnsiClass
);
817 Emit::TypeBuilder
^ type_builder
= m_module_builder
->DefineType(
820 // insert to be completed
821 singleton_entry
^ entry
= gcnew
singleton_entry();
823 entry
->m_xType
= xType
.get();
824 entry
->m_type_builder
= type_builder
;
825 m_incomplete_singletons
->Add(cts_name
,entry
);
831 //______________________________________________________________________________
832 ::System::Type
^ TypeEmitter::complete_iface_type( iface_entry
^ entry
)
834 Emit::TypeBuilder
^ type_builder
= entry
->m_type_builder
;
835 reflection::XInterfaceTypeDescription2
* xType
= entry
->m_xType
;
837 Sequence
<Reference
< reflection::XTypeDescription
> > seqBaseTypes( xType
->getBaseTypes() );
838 if (seqBaseTypes
.getLength() > 0)
840 for (int i
= 0; i
< seqBaseTypes
.getLength(); i
++)
842 //make sure we get the interface rather then a typedef
843 Reference
<reflection::XInterfaceTypeDescription2
> aBaseType
=
844 resolveInterfaceTypedef( seqBaseTypes
[i
]);
846 if ( aBaseType
->getName() != "com.sun.star.uno.XInterface" )
848 ::System::String
^ basetype_name
= to_cts_name( aBaseType
->getName() );
849 iface_entry
^ base_entry
= dynamic_cast< iface_entry
^ >(
850 m_incomplete_ifaces
[basetype_name
] );
851 if (nullptr != base_entry
)
853 // complete uncompleted base type first
854 complete_iface_type( base_entry
);
861 Reference
< reflection::XInterfaceMemberTypeDescription
> > seq_members(
862 xType
->getMembers() );
863 Reference
< reflection::XInterfaceMemberTypeDescription
> const * members
=
864 seq_members
.getConstArray();
865 sal_Int32 members_length
= seq_members
.getLength();
866 for ( sal_Int32 members_pos
= 0;
867 members_pos
< members_length
; ++members_pos
)
870 reflection::XInterfaceMemberTypeDescription
> const & xMember
=
871 members
[ members_pos
];
872 Sequence
< Reference
< reflection::XTypeDescription
> > seq_exceptions
;
873 Emit::MethodBuilder
^ method_builder
;
875 MethodAttributes c_method_attr
= (MethodAttributes
)
876 (MethodAttributes::Public
|
877 MethodAttributes::Abstract
|
878 MethodAttributes::Virtual
|
879 MethodAttributes::NewSlot
|
880 MethodAttributes::HideBySig
);
881 //#if defined(_MSC_VER) && (_MSC_VER < 1400)
882 // MethodAttributes::Instance);
887 if (TypeClass_INTERFACE_METHOD
== xMember
->getTypeClass())
889 Reference
< reflection::XInterfaceMethodTypeDescription
> xMethod(
890 xMember
, UNO_QUERY_THROW
);
893 Reference
< reflection::XMethodParameter
> > seq_parameters(
894 xMethod
->getParameters() );
895 sal_Int32 params_length
= seq_parameters
.getLength();
896 array
< ::System::Type
^>^ param_types
=
897 gcnew array
< ::System::Type
^>( params_length
);
898 Reference
< reflection::XMethodParameter
> const * parameters
=
899 seq_parameters
.getConstArray();
900 // first determine all types
901 //Make the first param type as return type
902 sal_Int32 params_pos
= 0;
903 for ( ; params_pos
< params_length
; ++params_pos
)
905 Reference
< reflection::XMethodParameter
> const & xParam
=
906 parameters
[ params_pos
];
907 ::System::Type
^ param_type
= get_type( xParam
->getType() );
908 ::System::String
^ param_type_name
= param_type
->FullName
;
911 param_type
= get_type(
912 ::System::String::Concat(
913 param_type_name
, "&" ), true );
915 param_types
[ xParam
->getPosition() ] = param_type
;
921 // method_builder = type_builder->DefineMethod(
922 // ustring_to_String( xMethod->getMemberName() ),
923 // c_method_attr, tb,
926 method_builder
= type_builder
->DefineMethod(
927 ustring_to_String( xMethod
->getMemberName() ),
928 c_method_attr
, get_type( xMethod
->getReturnType() ),
930 // then define parameter infos
932 for ( ; params_pos
< params_length
; ++params_pos
)
934 Reference
< reflection::XMethodParameter
> const & xParam
=
935 parameters
[ params_pos
];
936 long param_flags
= 0;
938 param_flags
|= (long)ParameterAttributes::In
;
940 param_flags
|= (long)ParameterAttributes::Out
;
941 OSL_ASSERT( 0 != param_flags
);
942 method_builder
->DefineParameter(
943 xParam
->getPosition() +1 /* starts with 1 */,
944 (ParameterAttributes
) param_flags
,
945 ustring_to_String( xParam
->getName() ) );
947 //Apply attribute TypeParametersAttribute to return value if it
948 //is a parameterized Type. Currently only structs can have parameters.
949 Reference
<reflection::XStructTypeDescription
> xReturnStruct(
950 xMethod
->getReturnType(), UNO_QUERY
);
952 if (xReturnStruct
.is())
954 Sequence
<Reference
<reflection::XTypeDescription
> > seq_type_args
=
955 xReturnStruct
->getTypeArguments();
956 if (seq_type_args
.getLength() != 0)
958 //get th ctor of the attribute
959 array
< ::System::Type
^>^ arCtor
= {::System::Type::GetType("System.Type[]")};
960 //Get the arguments for the attribute's ctor
961 Reference
<reflection::XTypeDescription
> const * arXTypeArgs
=
962 seq_type_args
.getConstArray();
963 int numTypes
= seq_type_args
.getLength();
964 array
< ::System::Type
^>^ arCtsTypes
= gcnew array
< ::System::Type
^>(numTypes
);
965 for (int i
= 0; i
< numTypes
; i
++)
966 arCtsTypes
[i
] = get_type(arXTypeArgs
[i
]);
967 array
< ::System::Object
^>^ arArgs
= {arCtsTypes
};
969 Emit::CustomAttributeBuilder
^ attrBuilder
=
970 gcnew
Emit::CustomAttributeBuilder(
971 ::uno::TypeArgumentsAttribute::typeid
972 ->GetConstructor( arCtor
),
975 method_builder
->SetCustomAttribute(attrBuilder
);
979 //define UNO exception attribute (exceptions)--------------------------------------
980 Emit::CustomAttributeBuilder
^ attrBuilder
=
981 get_iface_method_exception_attribute(xMethod
);
982 if (attrBuilder
!= nullptr)
983 method_builder
->SetCustomAttribute(attrBuilder
);
986 if (xMethod
->isOneway())
988 array
< ::System::Type
^>^ arCtorOneway
= gcnew array
< ::System::Type
^>(0);
989 array
< ::System::Object
^>^ arArgs
= gcnew array
< ::System::Object
^>(0);
990 Emit::CustomAttributeBuilder
^ attrBuilder
=
991 gcnew
Emit::CustomAttributeBuilder(
992 ::uno::OnewayAttribute::typeid->GetConstructor( arCtorOneway
),
994 method_builder
->SetCustomAttribute(attrBuilder
);
1000 TypeClass_INTERFACE_ATTRIBUTE
== xMember
->getTypeClass() );
1002 reflection::XInterfaceAttributeTypeDescription2
> xAttribute(
1003 xMember
, UNO_QUERY_THROW
);
1005 MethodAttributes c_property_method_attr
= (MethodAttributes
)
1006 (c_method_attr
| MethodAttributes::SpecialName
);
1008 ::System::Type
^ attribute_type
= get_type( xAttribute
->getType() );
1009 array
< ::System::Type
^>^ parameters
=
1010 gcnew array
< ::System::Type
^> ( 0 );
1012 Emit::PropertyBuilder
^ property_builder
=
1013 type_builder
->DefineProperty(
1014 ustring_to_String( xAttribute
->getMemberName() ),
1015 PropertyAttributes::None
,
1016 attribute_type
, parameters
);
1018 //set BoundAttribute, if necessary
1019 if (xAttribute
->isBound())
1021 ConstructorInfo
^ ctorBoundAttr
=
1022 ::uno::BoundAttribute::typeid->GetConstructor(
1023 gcnew array
<System::Type
^>(0));
1024 Emit::CustomAttributeBuilder
^ attrBuilderBound
=
1025 gcnew
Emit::CustomAttributeBuilder(
1026 ctorBoundAttr
, gcnew array
< ::System::Object
^>(0));
1027 property_builder
->SetCustomAttribute(attrBuilderBound
);
1031 Emit::MethodBuilder
^ method_builder
=
1032 type_builder
->DefineMethod(
1033 ustring_to_String( "get_" +
1034 xAttribute
->getMemberName() ),
1035 c_property_method_attr
, attribute_type
, parameters
);
1037 //define UNO exception attribute (exceptions)--------------------------------------
1038 Emit::CustomAttributeBuilder
^ attrBuilder
=
1039 get_exception_attribute(xAttribute
->getGetExceptions());
1040 if (attrBuilder
!= nullptr)
1041 method_builder
->SetCustomAttribute(attrBuilder
);
1043 property_builder
->SetGetMethod( method_builder
);
1045 if (! xAttribute
->isReadOnly())
1048 parameters
= gcnew array
< ::System::Type
^> ( 1 );
1049 parameters
[ 0 ] = attribute_type
;
1051 type_builder
->DefineMethod(
1052 ustring_to_String( "set_" +
1053 xAttribute
->getMemberName() ),
1054 c_property_method_attr
, nullptr, parameters
);
1055 // define parameter info
1056 method_builder
->DefineParameter(
1057 1 /* starts with 1 */, ParameterAttributes::In
, "value" );
1058 //define UNO exception attribute (exceptions)--------------------------------------
1059 Emit::CustomAttributeBuilder
^ attrBuilder
=
1060 get_exception_attribute(xAttribute
->getSetExceptions());
1061 if (attrBuilder
!= nullptr)
1062 method_builder
->SetCustomAttribute(attrBuilder
);
1064 property_builder
->SetSetMethod( method_builder
);
1069 // remove from incomplete types map
1070 ::System::String
^ cts_name
= type_builder
->FullName
;
1071 m_incomplete_ifaces
->Remove( cts_name
);
1076 ::System::Console::WriteLine(
1077 "> emitting interface type {0}", cts_name
);
1079 return type_builder
->CreateType();
1082 ::System::Type
^ TypeEmitter::complete_struct_type( struct_entry
^ entry
)
1085 ::System::String
^ cts_name
= entry
->m_type_builder
->FullName
;
1087 //Polymorphic struct, define uno.TypeParametersAttribute
1088 //A polymorphic struct cannot have a basetype.
1089 //When we create the template of the struct then we have no exact types
1090 //and the name does not contain a parameter list
1091 Sequence
< OUString
> seq_type_parameters
;
1092 Reference
< reflection::XStructTypeDescription
> xStructTypeDesc(
1093 entry
->m_xType
, UNO_QUERY
);
1094 if (xStructTypeDesc
.is())
1096 seq_type_parameters
= xStructTypeDesc
->getTypeParameters();
1098 if ((numTypes
= seq_type_parameters
.getLength()) > 0)
1100 array
< ::System::Object
^>^ aArg
= gcnew array
< ::System::Object
^>(numTypes
);
1101 for (int i
= 0; i
< numTypes
; i
++)
1102 aArg
[i
] = ustring_to_String(seq_type_parameters
.getConstArray()[i
]);
1103 array
< ::System::Object
^>^ args
= {aArg
};
1105 array
< ::System::Type
^>^ arTypesCtor
=
1106 {::System::Type::GetType("System.String[]")};
1107 Emit::CustomAttributeBuilder
^ attrBuilder
=
1108 gcnew
Emit::CustomAttributeBuilder(
1109 ::uno::TypeParametersAttribute::typeid->GetConstructor(arTypesCtor
),
1111 entry
->m_type_builder
->SetCustomAttribute(attrBuilder
);
1115 // optional: lookup base type whether generated entry of this session
1116 struct_entry
^ base_type_entry
= nullptr;
1117 if (nullptr != entry
->m_base_type
)
1119 //ToDo maybe get from incomplete structs
1121 dynamic_cast< struct_entry
^ >(
1122 m_generated_structs
[
1123 entry
->m_base_type
->FullName
] );
1127 Sequence
< Reference
< reflection::XTypeDescription
> > seq_members(
1128 entry
->m_xType
->getMemberTypes() );
1129 Sequence
< OUString
> seq_member_names( entry
->m_xType
->getMemberNames() );
1130 sal_Int32 members_length
= seq_members
.getLength();
1131 OSL_ASSERT( seq_member_names
.getLength() == members_length
);
1132 //check if we have a XTypeDescription for every member. If not then the user may
1133 //have forgotten to specify additional rdbs with the --extra option.
1134 Reference
< reflection::XTypeDescription
> const * pseq_members
=
1135 seq_members
.getConstArray();
1136 OUString
const * pseq_member_names
=
1137 seq_member_names
.getConstArray();
1138 for (int i
= 0; i
< members_length
; i
++)
1140 const OUString
sType(entry
->m_xType
->getName());
1141 const OUString
sMemberName(pseq_member_names
[i
]);
1142 if ( ! pseq_members
[i
].is())
1143 throw RuntimeException("Missing type description . Check if you need to "
1144 "specify additional RDBs with the --extra option. Type missing for: " + sType
+
1145 "::" + sMemberName
,0);
1148 sal_Int32 all_members_length
= 0;
1149 sal_Int32 member_pos
;
1150 sal_Int32 type_param_pos
= 0;
1152 // collect base types; wrong order
1153 ::System::Collections::ArrayList
^ base_types_list
=
1154 gcnew ::System::Collections::ArrayList( 3 /* initial capacity */ );
1155 for (::System::Type
^ base_type_pos
= entry
->m_base_type
;
1156 ! base_type_pos
->Equals( ::System::Object::typeid );
1157 base_type_pos
= base_type_pos
->BaseType
)
1159 base_types_list
->Add( base_type_pos
);
1160 if (base_type_pos
->Equals( ::System::Exception::typeid ))
1162 // special Message member
1163 all_members_length
+= 1;
1164 break; // don't include System.Exception base classes
1168 //ensure the base type is complete. Otherwise GetFields won't work
1169 get_complete_struct(base_type_pos
->FullName
);
1170 all_members_length
+=
1171 base_type_pos
->GetFields(
1172 (BindingFlags
) (BindingFlags::Instance
|
1173 BindingFlags::Public
|
1174 BindingFlags::DeclaredOnly
) )
1179 // create all_members arrays; right order
1180 array
< ::System::String
^>^ all_member_names
=
1181 gcnew array
< ::System::String
^> (all_members_length
+ members_length
);
1182 array
< ::System::Type
^>^ all_param_types
=
1183 gcnew array
< ::System::Type
^> (all_members_length
+ members_length
);
1185 for ( sal_Int32 pos
= base_types_list
->Count
; pos
--; )
1187 ::System::Type
^ base_type
= safe_cast
< ::System::Type
^ >(
1188 base_types_list
[pos
] );
1189 if (base_type
->Equals( ::System::Exception::typeid ))
1191 all_member_names
[ member_pos
] = "Message";
1192 all_param_types
[ member_pos
] = ::System::String::typeid;
1197 ::System::String
^ base_type_name
= base_type
->FullName
;
1199 //ToDo m_generated_structs?
1200 struct_entry
^ entry
=
1201 dynamic_cast< struct_entry
^ >(
1202 m_generated_structs
[base_type_name
] );
1203 if (nullptr == entry
)
1206 array
<FieldInfo
^>^ fields
=
1207 base_type
->GetFields(
1208 (BindingFlags
) (BindingFlags::Instance
|
1209 BindingFlags::Public
|
1210 BindingFlags::DeclaredOnly
) );
1211 sal_Int32 len
= fields
->Length
;
1212 for ( sal_Int32 pos
= 0; pos
< len
; ++pos
)
1214 FieldInfo
^ field
= fields
[ pos
];
1215 all_member_names
[ member_pos
] = field
->Name
;
1216 all_param_types
[ member_pos
] = field
->FieldType
;
1220 else // generated during this session:
1221 // members may be incomplete ifaces
1223 sal_Int32 len
= entry
->m_member_names
->Length
;
1224 for ( sal_Int32 pos
= 0; pos
< len
; ++pos
)
1226 all_member_names
[ member_pos
] =
1227 entry
->m_member_names
[ pos
];
1228 all_param_types
[ member_pos
] =
1229 entry
->m_param_types
[ pos
];
1235 OSL_ASSERT( all_members_length
== member_pos
);
1238 // struct_entry * entry = new struct_entry();
1239 entry
->m_member_names
= gcnew array
< ::System::String
^> ( members_length
);
1240 entry
->m_param_types
= gcnew array
< ::System::Type
^> ( members_length
);
1243 array
<Emit::FieldBuilder
^>^ members
= gcnew array
<Emit::FieldBuilder
^> ( members_length
);
1244 //Reference< reflection::XTypeDescription > const * pseq_members =
1245 // seq_members.getConstArray();
1246 //OUString const * pseq_member_names =
1247 // seq_member_names.getConstArray();
1249 int curParamIndex
= 0; //count the fields which have parameterized types
1250 for ( member_pos
= 0; member_pos
< members_length
; ++member_pos
)
1252 ::System::String
^ field_name
=
1253 ustring_to_String( pseq_member_names
[ member_pos
] );
1254 ::System::Type
^ field_type
;
1255 //Special handling of struct parameter types
1256 bool bParameterizedType
= false;
1257 if (pseq_members
[ member_pos
]->getTypeClass() == TypeClass_UNKNOWN
)
1259 bParameterizedType
= true;
1260 if (type_param_pos
< seq_type_parameters
.getLength())
1262 field_type
= ::System::Object::typeid;
1267 throw RuntimeException(
1268 "unexpected member type in " + entry
->m_xType
->getName(),
1269 Reference
< XInterface
>() );
1275 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 //Find the value type. In case of sequence<sequence< ... > > find the actual value type
1347 ::System::Type
^ value
= field_type
;
1348 while ((value
= value
->GetElementType())->IsArray
);
1349 //If the value type is a struct then make sure it is fully created.
1350 get_complete_struct(value
->FullName
);
1352 code
->Emit( Emit::OpCodes::Ldarg_0
);
1353 code
->Emit( Emit::OpCodes::Ldc_I4_0
);
1355 Emit::OpCodes::Newarr
, field_type
->GetElementType() );
1356 code
->Emit( Emit::OpCodes::Stfld
, field
);
1358 else if (field_type
->IsValueType
)
1360 if (field_type
->FullName
->Equals( "uno.Any" ))
1362 code
->Emit( Emit::OpCodes::Ldarg_0
);
1363 code
->Emit( Emit::OpCodes::Ldsfld
, ::uno::Any::typeid->GetField("VOID"));
1364 code
->Emit( Emit::OpCodes::Stfld
, field
);
1367 else if (field_type
->IsClass
)
1369 /* may be XInterface */
1370 if (! field_type
->Equals( ::System::Object::typeid ))
1372 // struct, exception
1373 //make sure the struct is already complete.
1374 get_complete_struct(field_type
->FullName
);
1375 code
->Emit( Emit::OpCodes::Ldarg_0
);
1377 Emit::OpCodes::Newobj
,
1378 //GetConstructor requies that the member types of the object which is to be constructed are already known.
1379 field_type
->GetConstructor(
1380 gcnew array
< ::System::Type
^> ( 0 ) ) );
1381 code
->Emit( Emit::OpCodes::Stfld
, field
);
1385 code
->Emit( Emit::OpCodes::Ret
);
1386 entry
->m_default_ctor
= ctor_builder
;
1388 // parameterized .ctor including all base members
1389 ctor_builder
= entry
->m_type_builder
->DefineConstructor(
1390 c_ctor_method_attr
, CallingConventions::Standard
, all_param_types
);
1391 for ( member_pos
= 0; member_pos
< all_members_length
; ++member_pos
)
1393 ctor_builder
->DefineParameter(
1394 member_pos
+1 /* starts with 1 */, ParameterAttributes::In
,
1395 all_member_names
[ member_pos
] );
1397 code
= ctor_builder
->GetILGenerator();
1399 code
->Emit( Emit::OpCodes::Ldarg_0
); // push this
1400 sal_Int32 base_members_length
= all_members_length
- members_length
;
1401 array
< ::System::Type
^>^ param_types
=
1402 gcnew array
< ::System::Type
^> ( base_members_length
);
1403 for ( member_pos
= 0; member_pos
< base_members_length
; ++member_pos
)
1405 emit_ldarg( code
, member_pos
+1 );
1406 param_types
[ member_pos
] = all_param_types
[ member_pos
];
1409 Emit::OpCodes::Call
,
1410 nullptr == base_type_entry
1411 ? entry
->m_base_type
->GetConstructor( param_types
)
1412 : base_type_entry
->m_ctor
);
1413 // initialize members
1414 for ( member_pos
= 0; member_pos
< members_length
; ++member_pos
)
1416 code
->Emit( Emit::OpCodes::Ldarg_0
); // push this
1417 emit_ldarg( code
, member_pos
+ base_members_length
+1 );
1418 code
->Emit( Emit::OpCodes::Stfld
, members
[ member_pos
] );
1420 code
->Emit( Emit::OpCodes::Ret
);
1421 entry
->m_ctor
= ctor_builder
;
1425 ::System::Console::WriteLine(
1426 "> emitting {0} type {1}",
1427 TypeClass_STRUCT
== entry
->m_xType
->getTypeClass()
1433 m_generated_structs
->Add(cts_name
, entry
);
1434 ::System::Type
^ ret_type
= entry
->m_type_builder
->CreateType();
1436 // remove from incomplete types map
1437 m_incomplete_structs
->Remove( cts_name
);
1438 entry
->m_xType
->release();
1442 ::System::Console::WriteLine(
1443 "> emitting struct type {0}", cts_name
);
1448 //Examples of generated code
1449 // public static XWeak constructor1(XComponentContext ctx)
1451 // XMultiComponentFactory factory = ctx.getServiceManager();
1452 // if (factory == null)
1453 // throw new com.sun.star.uno.DeploymentException("bla", null);
1454 // return (XWeak) factory.createInstanceWithContext("service_specifier", ctx);
1456 // public static XWeak constructor2(XComponentContext ctx, int a, int b, Any c)
1458 // XMultiComponentFactory factory = ctx.getServiceManager();
1459 // if (factory == null)
1460 // throw new com.sun.star.uno.DeploymentException("bla", null);
1461 // Any[] arAny = new Any[3];
1462 // arAny[0] = new Any(typeof(int), a);
1463 // arAny[1] = new Any(typeof(int), b);
1464 // arAny[2] = new Any(c.Type, c.Value);
1465 // return (XWeak) factory.createInstanceWithArgumentsAndContext("service_specifier", arAny, ctx);
1467 // Notice that a any parameter is NOT wrapped by another any. Instead the new any is created with the type and value
1468 // of the parameter.
1470 // public static XWeak constructor3(XComponentContext ctx, params Any[] c)
1472 // XMultiComponentFactory factory = ctx.getServiceManager();
1473 // if (factory == null)
1474 // throw new com.sun.star.uno.DeploymentException("bla", null);
1475 // return (XWeak) factory.createInstanceWithArgumentsAndContext("service_specifier", c, ctx);
1477 ::System::Type
^ TypeEmitter::complete_service_type(service_entry
^ entry
)
1479 Emit::TypeBuilder
^ type_builder
= entry
->m_type_builder
;
1480 reflection::XServiceTypeDescription2
* xServiceType
= entry
->m_xType
;
1482 //Create the private default constructor
1483 Emit::ConstructorBuilder
^ ctor_builder
=
1484 type_builder
->DefineConstructor(
1485 (MethodAttributes
) (MethodAttributes::Private
|
1486 MethodAttributes::HideBySig
|
1487 MethodAttributes::SpecialName
|
1488 MethodAttributes::RTSpecialName
),
1489 CallingConventions::Standard
, nullptr);
1491 Emit::ILGenerator
^ ilGen
= ctor_builder
->GetILGenerator();
1492 ilGen
->Emit( Emit::OpCodes::Ldarg_0
); // push this
1494 Emit::OpCodes::Call
,
1495 type_builder
->BaseType
->GetConstructor(gcnew array
< ::System::Type
^>(0)));
1496 ilGen
->Emit( Emit::OpCodes::Ret
);
1499 //Create the service constructors.
1500 //obtain the interface which makes up this service, it is the return
1501 //type of the constructor functions
1502 Reference
<reflection::XInterfaceTypeDescription2
> xIfaceType(
1503 xServiceType
->getInterface(), UNO_QUERY
);
1504 if (xIfaceType
.is () == sal_False
)
1505 xIfaceType
= resolveInterfaceTypedef(xServiceType
->getInterface());
1506 System::Type
^ retType
= get_type(xIfaceType
);
1508 //Create the ConstructorInfo for a DeploymentException
1509 ::System::Type
^ typeDeploymentExc
=
1510 get_type("unoidl.com.sun.star.uno.DeploymentException", true);
1512 array
< ::System::Type
^>^ arTypeCtor
= {::System::String::typeid,
1513 ::System::Object::typeid};
1514 ::System::Reflection::ConstructorInfo
^ ctorDeploymentException
=
1515 typeDeploymentExc
->GetConstructor(arTypeCtor
);
1517 Sequence
<Reference
<reflection::XServiceConstructorDescription
> > seqCtors
=
1518 xServiceType
->getConstructors();
1520 ::System::Type
^ type_uno_exception
= get_type("unoidl.com.sun.star.uno.Exception", true);
1522 for (int i
= seqCtors
.getLength() - 1; i
>= 0; i
--)
1524 bool bParameterArray
= false;
1525 ::System::Type
^ typeAny
= ::uno::Any::typeid;
1526 const Reference
<reflection::XServiceConstructorDescription
> & ctorDes
=
1528 //obtain the parameter types
1529 Sequence
<Reference
<reflection::XParameter
> > seqParams
=
1530 ctorDes
->getParameters();
1531 Reference
<reflection::XParameter
> const * arXParams
= seqParams
.getConstArray();
1532 sal_Int32 cParams
= seqParams
.getLength();
1533 array
< ::System::Type
^>^ arTypeParameters
= gcnew array
< ::System::Type
^> (cParams
+ 1);
1534 arTypeParameters
[0] = get_type("unoidl.com.sun.star.uno.XComponentContext", true);
1535 for (int iparam
= 0; iparam
!= cParams
; iparam
++)
1537 if (arXParams
[iparam
]->isRestParameter())
1538 arTypeParameters
[iparam
+ 1] = array
< ::uno::Any
>::typeid;
1540 arTypeParameters
[iparam
+ 1] = get_type(arXParams
[iparam
]->getType());
1542 //The array arTypeParameters can contain:
1543 //System.Type and uno.PolymorphicType.
1544 //Passing PolymorphicType to MethodBuilder.DefineMethod will cause a problem.
1545 //The exception will read something like no on information for parameter # d
1546 //Maybe we need no override another Type method in PolymorphicType ...
1547 //Until we have figured this out, we will create another array of System.Type which
1548 //we pass on to DefineMethod.
1549 array
< ::System::Type
^>^ arParamTypes
= gcnew array
< ::System::Type
^> (cParams
+ 1);
1550 // arParamTypes[0] = get_type("unoidl.com.sun.star.uno.XComponentContext", true);
1551 for (int i
= 0; i
< cParams
+ 1; i
++)
1553 ::uno::PolymorphicType
^ pT
= dynamic_cast< ::uno::PolymorphicType
^ >(arTypeParameters
[i
]);
1555 arParamTypes
[i
] = pT
->OriginalType
;
1557 arParamTypes
[i
] = arTypeParameters
[i
];
1560 System::String
^ ctorName
;
1561 if (ctorDes
->isDefaultConstructor())
1562 ctorName
= gcnew ::System::String("create");
1564 ctorName
= ustring_to_String(ctorDes
->getName());
1565 Emit::MethodBuilder
^ method_builder
= type_builder
->DefineMethod(
1567 static_cast<MethodAttributes
>(MethodAttributes::Public
| MethodAttributes::HideBySig
|
1568 MethodAttributes::Static
),
1570 // arTypeParameters);
1573 //define UNO exception attribute (exceptions)--------------------------------------
1574 Emit::CustomAttributeBuilder
^ attrBuilder
= get_service_exception_attribute(ctorDes
);
1575 if (attrBuilder
!= nullptr)
1576 method_builder
->SetCustomAttribute(attrBuilder
);
1578 //-------------------------------------------------------------
1579 //define parameter attributes (paramarray), names etc.
1580 //The first parameter is the XComponentContext, which cannot be obtained
1582 //The context is not part of the idl description
1583 method_builder
->DefineParameter(
1584 1, ParameterAttributes::In
, "the_context");
1586 array
<Emit::ParameterBuilder
^>^ arParameterBuilder
=
1587 gcnew array
<Emit::ParameterBuilder
^> (cParams
);
1588 for (int iparam
= 0; iparam
!= cParams
; iparam
++)
1590 Reference
<reflection::XParameter
> const & aParam
= arXParams
[iparam
];
1591 ::System::String
^ sParamName
= ustring_to_String(aParam
->getName());
1593 arParameterBuilder
[iparam
] = method_builder
->DefineParameter(
1594 iparam
+ 2, ParameterAttributes::In
, sParamName
);
1596 if (aParam
->isRestParameter())
1598 bParameterArray
= true;
1599 //set the ParameterArrayAttribute
1600 ::System::Reflection::ConstructorInfo
^ ctor_info
=
1601 System::ParamArrayAttribute::typeid->GetConstructor(
1602 gcnew array
< ::System::Type
^>(0));
1603 Emit::CustomAttributeBuilder
^ attr_builder
=
1604 gcnew
Emit::CustomAttributeBuilder(ctor_info
, gcnew array
< ::System::Object
^>(0));
1605 arParameterBuilder
[iparam
]->SetCustomAttribute(attr_builder
);
1610 Emit::ILGenerator
^ ilGen
= method_builder
->GetILGenerator();
1612 //Define locals ---------------------------------
1613 //XMultiComponentFactory
1614 Emit::LocalBuilder
^ local_factory
=
1615 ilGen
->DeclareLocal(
1616 get_type("unoidl.com.sun.star.lang.XMultiComponentFactory", true));
1619 Emit::LocalBuilder
^ local_return_val
=
1620 ilGen
->DeclareLocal(retType
);
1622 //Obtain the XMultiComponentFactory and throw an exception if we do not get one
1623 ilGen
->Emit(Emit::OpCodes::Ldarg_0
);
1625 ::System::Reflection::MethodInfo
^ methodGetServiceManager
= get_type(
1626 "unoidl.com.sun.star.uno.XComponentContext", true)
1627 ->GetMethod("getServiceManager");
1628 ilGen
->Emit(Emit::OpCodes::Callvirt
, methodGetServiceManager
);
1629 ilGen
->Emit(Emit::OpCodes::Stloc
, local_factory
);
1630 ilGen
->Emit(Emit::OpCodes::Ldloc
, local_factory
);
1631 Emit::Label label1
= ilGen
->DefineLabel();
1632 ilGen
->Emit(Emit::OpCodes::Brtrue
, label1
);
1633 //The string for the exception
1634 ::System::Text::StringBuilder
^ strbuilder
= gcnew ::System::Text::StringBuilder(256);
1635 strbuilder
->Append("The service ");
1636 strbuilder
->Append(to_cts_name(xServiceType
->getName()));
1637 strbuilder
->Append(" could not be created. The context failed to supply the service manager.");
1639 ilGen
->Emit(Emit::OpCodes::Ldstr
, strbuilder
->ToString());
1640 ilGen
->Emit(Emit::OpCodes::Ldarg_0
);
1641 ilGen
->Emit(Emit::OpCodes::Newobj
, ctorDeploymentException
);
1642 ilGen
->Emit(Emit::OpCodes::Throw
);
1643 ilGen
->MarkLabel(label1
);
1645 //We create a try/ catch around the createInstanceWithContext, etc. functions
1647 //1. function do not specify exceptions. Then RuntimeExceptions are retrhown and other
1648 // exceptions produce a DeploymentException.
1649 //2. function specify Exception. Then all exceptions fly through
1650 //3. function specifies exceptions but no Exception. Then these are rethrown
1651 // and other exceptions, except RuntimeException, produce a deployment exception.
1652 //In case there are no parameters we call
1653 //XMultiComponentFactory.createInstanceWithContext
1655 ::System::Collections::ArrayList
^ arExceptionTypes
=
1656 get_service_ctor_method_exceptions_reduced(ctorDes
->getExceptions());
1657 if (arExceptionTypes
->Contains(
1658 type_uno_exception
) == false)
1660 ilGen
->BeginExceptionBlock();
1664 ilGen
->Emit(Emit::OpCodes::Ldloc
, local_factory
);
1665 ilGen
->Emit(Emit::OpCodes::Ldstr
, ustring_to_String(xServiceType
->getName()));
1666 ilGen
->Emit(Emit::OpCodes::Ldarg_0
);
1668 ::System::Reflection::MethodInfo
^ methodCreate
=
1669 local_factory
->LocalType
->GetMethod("createInstanceWithContext");
1670 ilGen
->Emit(Emit::OpCodes::Callvirt
, methodCreate
);
1672 else if(bParameterArray
)
1674 //Service constructor with parameter array
1675 ilGen
->Emit(Emit::OpCodes::Ldloc
, local_factory
);
1676 ilGen
->Emit(Emit::OpCodes::Ldstr
, ustring_to_String(xServiceType
->getName()));
1677 ilGen
->Emit(Emit::OpCodes::Ldarg_1
);
1678 ilGen
->Emit(Emit::OpCodes::Ldarg_0
);
1679 ::System::Reflection::MethodInfo
^ methodCreate
=
1680 local_factory
->LocalType
->GetMethod("createInstanceWithArgumentsAndContext");
1681 ilGen
->Emit(Emit::OpCodes::Callvirt
, methodCreate
);
1685 // Any param1, Any param2, etc.
1686 // For each parameter,except the component context, and parameter array
1687 // and Any is created.
1688 array
<Emit::LocalBuilder
^>^ arLocalAny
= gcnew array
<Emit::LocalBuilder
^> (cParams
);
1690 for (int iParam
= 0; iParam
< cParams
; iParam
++)
1692 arLocalAny
[iParam
] = ilGen
->DeclareLocal(typeAny
);
1695 //Any[]. This array is filled with the created Anys which contain the parameters
1696 //and the values contained in the parameter array
1697 Emit::LocalBuilder
^ local_anyParams
=
1698 ilGen
->DeclareLocal(array
< ::uno::Any
>::typeid);
1700 //Create the Any for every argument, except for the parameter array
1701 //arLocalAny contains the LocalBuilder for all these parameters.
1702 //we call the ctor Any(Type, Object)
1703 //If the parameter is an Any then the Any is created with Any(param.Type, param.Value);
1704 array
< ::System::Type
^>^ arTypesCtorAny
= {::System::Type::typeid,
1705 ::System::Object::typeid};
1706 ::System::Reflection::ConstructorInfo
^ ctorAny
=
1707 typeAny
->GetConstructor( arTypesCtorAny
);
1708 ::System::Reflection::MethodInfo
^ methodAnyGetType
=
1709 typeAny
->GetProperty("Type")->GetGetMethod();
1710 ::System::Reflection::MethodInfo
^ methodAnyGetValue
=
1711 typeAny
->GetProperty("Value")->GetGetMethod();
1712 for (int i
= 0; i
< arLocalAny
->Length
; i
++)
1714 //check if the parameter is a polymorphic struct
1715 ::uno::PolymorphicType
^polyType
= dynamic_cast< ::uno::PolymorphicType
^ >(arTypeParameters
[i
+1]);
1716 //arTypeParameters[i+1] = polyType->OriginalType;
1719 //It is a polymorphic struct
1720 //Load the uninitialized local Any on which we will call the ctor
1721 ilGen
->Emit(Emit::OpCodes::Ldloca
, arLocalAny
[i
]);
1722 // Call PolymorphicType PolymorphicType::GetType(Type t, String polyName)
1723 // Prepare the first parameter
1724 ilGen
->Emit(Emit::OpCodes::Ldtoken
, polyType
->OriginalType
);
1725 array
< ::System::Type
^>^ arTypeParams
= {::System::RuntimeTypeHandle::typeid};
1726 ilGen
->Emit(Emit::OpCodes::Call
,
1727 ::System::Type::typeid->GetMethod(
1728 "GetTypeFromHandle", arTypeParams
));
1729 // Prepare the second parameter
1730 ilGen
->Emit(Emit::OpCodes::Ldstr
, polyType
->PolymorphicName
);
1731 // Make the actual call
1732 array
< ::System::Type
^>^ arTypeParam_GetType
= {
1733 ::System::Type::typeid, ::System::String::typeid };
1734 ilGen
->Emit(Emit::OpCodes::Call
,
1735 ::uno::PolymorphicType::typeid->GetMethod(gcnew
System::String("GetType"),
1736 arTypeParam_GetType
));
1738 //Stack is: localAny, PolymorphicType
1739 //Call Any::Any(Type, Object)
1740 //Prepare the second parameter for the any ctor
1741 ilGen
->Emit(Emit::OpCodes::Ldarg
, i
+ 1);
1742 // if the parameter is a value type then we need to box it, because
1743 // the Any ctor takes an Object
1744 if (arTypeParameters
[i
+1]->IsValueType
)
1745 ilGen
->Emit(Emit::OpCodes::Box
, arTypeParameters
[i
+1]);
1746 ilGen
->Emit(Emit::OpCodes::Call
, ctorAny
);
1748 else if (arTypeParameters
[i
+1] == typeAny
)
1750 //Create the call new Any(param.Type,param,Value)
1751 //Stack must be Any,Type,Value
1752 //First load the Any which is to be constructed
1753 ilGen
->Emit(Emit::OpCodes::Ldloca
, arLocalAny
[i
]);
1754 //Load the Type, which is obtained by calling param.Type
1755 ilGen
->Emit(Emit::OpCodes::Ldarga
, i
+ 1);
1756 ilGen
->Emit(Emit::OpCodes::Call
, methodAnyGetType
);
1757 //Load the Value, which is obtained by calling param.Value
1758 ilGen
->Emit(Emit::OpCodes::Ldarga
, i
+ 1);
1759 ilGen
->Emit(Emit::OpCodes::Call
, methodAnyGetValue
);
1760 //Call the Any ctor.
1761 ilGen
->Emit(Emit::OpCodes::Call
, ctorAny
);
1765 ilGen
->Emit(Emit::OpCodes::Ldloca
, arLocalAny
[i
]);
1766 ilGen
->Emit(Emit::OpCodes::Ldtoken
, arTypeParameters
[i
+1]);
1768 array
< ::System::Type
^>^ arTypeParams
= {::System::RuntimeTypeHandle::typeid};
1769 ilGen
->Emit(Emit::OpCodes::Call
,
1770 ::System::Type::typeid->GetMethod(
1771 "GetTypeFromHandle", arTypeParams
));
1772 ilGen
->Emit(Emit::OpCodes::Ldarg
, i
+ 1);
1773 // if the parameter is a value type then we need to box it, because
1774 // the Any ctor takes an Object
1775 if (arTypeParameters
[i
+1]->IsValueType
)
1776 ilGen
->Emit(Emit::OpCodes::Box
, arTypeParameters
[i
+1]);
1777 ilGen
->Emit(Emit::OpCodes::Call
, ctorAny
);
1781 //Create the Any[] that is passed to the
1782 //createInstanceWithContext[AndArguments] function
1783 ilGen
->Emit(Emit::OpCodes::Ldc_I4
, arLocalAny
->Length
);
1784 ilGen
->Emit(Emit::OpCodes::Newarr
, typeAny
);
1785 ilGen
->Emit(Emit::OpCodes::Stloc
, local_anyParams
);
1787 //Assign all anys created from the parameters
1788 //array to the Any[]
1789 for (int i
= 0; i
< arLocalAny
->Length
; i
++)
1791 ilGen
->Emit(Emit::OpCodes::Ldloc
, local_anyParams
);
1792 ilGen
->Emit(Emit::OpCodes::Ldc_I4
, i
);
1793 ilGen
->Emit(Emit::OpCodes::Ldelema
, typeAny
);
1794 ilGen
->Emit(Emit::OpCodes::Ldloc
, arLocalAny
[i
]);
1795 ilGen
->Emit(Emit::OpCodes::Stobj
, typeAny
);
1797 // call createInstanceWithContextAndArguments
1798 ilGen
->Emit(Emit::OpCodes::Ldloc
, local_factory
);
1799 ilGen
->Emit(Emit::OpCodes::Ldstr
, ustring_to_String(xServiceType
->getName()));
1800 ilGen
->Emit(Emit::OpCodes::Ldloc
, local_anyParams
);
1801 ilGen
->Emit(Emit::OpCodes::Ldarg_0
);
1802 ::System::Reflection::MethodInfo
^ methodCreate
=
1803 local_factory
->LocalType
->GetMethod("createInstanceWithArgumentsAndContext");
1804 ilGen
->Emit(Emit::OpCodes::Callvirt
, methodCreate
);
1806 //cast the object returned by the functions createInstanceWithContext or
1807 //createInstanceWithArgumentsAndContext to the interface type
1808 ilGen
->Emit(Emit::OpCodes::Castclass
, retType
);
1809 ilGen
->Emit(Emit::OpCodes::Stloc
, local_return_val
);
1811 //catch exceptions thrown by createInstanceWithArgumentsAndContext and createInstanceWithContext
1812 if (arExceptionTypes
->Contains(type_uno_exception
) == false)
1814 // catch (unoidl.com.sun.star.uno.RuntimeException) {throw;}
1815 ilGen
->BeginCatchBlock(get_type("unoidl.com.sun.star.uno.RuntimeException", true));
1816 ilGen
->Emit(Emit::OpCodes::Pop
);
1817 ilGen
->Emit(Emit::OpCodes::Rethrow
);
1819 //catch and rethrow all other defined Exceptions
1820 for (int i
= 0; i
< arExceptionTypes
->Count
; i
++)
1822 ::System::Type
^ excType
= safe_cast
< ::System::Type
^ >(
1823 arExceptionTypes
[i
]);
1824 if (excType
->IsInstanceOfType(
1825 get_type("unoidl.com.sun.star.uno.RuntimeException", true)))
1826 {// we have a catch for RuntimeException already defined
1830 //catch Exception and rethrow
1831 ilGen
->BeginCatchBlock(excType
);
1832 ilGen
->Emit(Emit::OpCodes::Pop
);
1833 ilGen
->Emit(Emit::OpCodes::Rethrow
);
1835 //catch (unoidl.com.sun.star.uno.Exception) {throw DeploymentException...}
1836 ilGen
->BeginCatchBlock(type_uno_exception
);
1838 //Define the local variabe that keeps the exception
1839 Emit::LocalBuilder
^ local_exception
= ilGen
->DeclareLocal(
1840 type_uno_exception
);
1842 //Store the exception
1843 ilGen
->Emit(Emit::OpCodes::Stloc
, local_exception
);
1845 //prepare the construction of the exception
1846 strbuilder
= gcnew ::System::Text::StringBuilder(256);
1847 strbuilder
->Append("The context (com.sun.star.uno.XComponentContext) failed to supply the service ");
1848 strbuilder
->Append(to_cts_name(xServiceType
->getName()));
1849 strbuilder
->Append(": ");
1851 ilGen
->Emit(Emit::OpCodes::Ldstr
, strbuilder
->ToString());
1853 //add to the string the Exception.Message
1854 ilGen
->Emit(Emit::OpCodes::Ldloc
, local_exception
);
1855 ilGen
->Emit(Emit::OpCodes::Callvirt
,
1856 type_uno_exception
->GetProperty("Message")->GetGetMethod());
1857 array
< ::System::Type
^>^ arConcatParams
= {System::String::typeid,
1858 System::String::typeid};
1859 ilGen
->Emit(Emit::OpCodes::Call
,
1860 System::String::typeid->GetMethod("Concat", arConcatParams
));
1861 //load contex argument
1862 ilGen
->Emit(Emit::OpCodes::Ldarg_0
);
1863 ilGen
->Emit(Emit::OpCodes::Newobj
, ctorDeploymentException
);
1864 ilGen
->Emit(Emit::OpCodes::Throw
);//Exception(typeDeploymentExc);
1866 ilGen
->EndExceptionBlock();
1870 //Check if the service instance was create and throw a exception if not.
1871 Emit::Label label_service_created
= ilGen
->DefineLabel();
1872 ilGen
->Emit(Emit::OpCodes::Ldloc
, local_return_val
);
1873 ilGen
->Emit(Emit::OpCodes::Brtrue_S
, label_service_created
);
1875 strbuilder
= gcnew ::System::Text::StringBuilder(256);
1876 strbuilder
->Append("The context (com.sun.star.uno.XComponentContext) failed to supply the service ");
1877 strbuilder
->Append(to_cts_name(xServiceType
->getName()));
1878 strbuilder
->Append(".");
1879 ilGen
->Emit(Emit::OpCodes::Ldstr
, strbuilder
->ToString());
1880 ilGen
->Emit(Emit::OpCodes::Ldarg_0
);
1881 ilGen
->Emit(Emit::OpCodes::Newobj
, ctorDeploymentException
);
1882 ilGen
->Emit(Emit::OpCodes::Throw
);//Exception(typeDeploymentExc);
1884 ilGen
->MarkLabel(label_service_created
);
1885 ilGen
->Emit(Emit::OpCodes::Ldloc
, local_return_val
);
1886 ilGen
->Emit(Emit::OpCodes::Ret
);
1889 // remove from incomplete types map
1890 ::System::String
^ cts_name
= type_builder
->FullName
;
1891 m_incomplete_services
->Remove( cts_name
);
1892 xServiceType
->release();
1895 ::System::Console::WriteLine(
1896 "> emitting service type {0}", cts_name
);
1898 return type_builder
->CreateType();
1902 Emit::CustomAttributeBuilder
^ TypeEmitter::get_service_exception_attribute(
1903 const Reference
<reflection::XServiceConstructorDescription
> & ctorDes
)
1905 return get_exception_attribute(ctorDes
->getExceptions());
1908 Emit::CustomAttributeBuilder
^ TypeEmitter::get_iface_method_exception_attribute(
1909 const Reference
< reflection::XInterfaceMethodTypeDescription
>& xMethod
)
1912 const Sequence
<Reference
<reflection::XTypeDescription
> > seqTD
= xMethod
->getExceptions();
1913 int len
= seqTD
.getLength();
1914 Sequence
<Reference
<reflection::XCompoundTypeDescription
> > seqCTD(len
);
1915 Reference
<reflection::XCompoundTypeDescription
> * arCTD
= seqCTD
.getArray();
1916 for (int i
= 0; i
< len
; i
++)
1917 arCTD
[i
] = Reference
<reflection::XCompoundTypeDescription
>(seqTD
[i
], UNO_QUERY_THROW
);
1918 return get_exception_attribute(seqCTD
);
1921 Emit::CustomAttributeBuilder
^ TypeEmitter::get_exception_attribute(
1923 const Sequence
<Reference
< reflection::XCompoundTypeDescription
> >& seq_exceptionsTd
)
1925 Emit::CustomAttributeBuilder
^ attr_builder
= nullptr;
1927 Reference
< reflection::XCompoundTypeDescription
> const * exceptions
=
1928 seq_exceptionsTd
.getConstArray();
1930 array
< ::System::Type
^>^ arTypesCtor
= {::System::Type::GetType("System.Type[]")};
1931 ConstructorInfo
^ ctor_ExceptionAttribute
=
1932 ::uno::ExceptionAttribute::typeid->GetConstructor(arTypesCtor
);
1934 sal_Int32 exc_length
= seq_exceptionsTd
.getLength();
1935 if (exc_length
!= 0) // opt
1937 array
< ::System::Type
^>^ exception_types
=
1938 gcnew array
< ::System::Type
^> ( exc_length
);
1939 for ( sal_Int32 exc_pos
= 0; exc_pos
< exc_length
; ++exc_pos
)
1941 Reference
< reflection::XCompoundTypeDescription
> const & xExc
=
1942 exceptions
[ exc_pos
];
1943 exception_types
[ exc_pos
] = get_type( xExc
);
1945 array
< ::System::Object
^>^ args
= {exception_types
};
1946 attr_builder
= gcnew
Emit::CustomAttributeBuilder(
1947 ctor_ExceptionAttribute
, args
);
1949 return attr_builder
;
1953 ::System::Type
^ TypeEmitter::complete_singleton_type(singleton_entry
^ entry
)
1955 Emit::TypeBuilder
^ type_builder
= entry
->m_type_builder
;
1956 reflection::XSingletonTypeDescription2
* xSingletonType
= entry
->m_xType
;
1957 ::System::String
^ sSingletonName
= to_cts_name(xSingletonType
->getName());
1959 //Create the private default constructor
1960 Emit::ConstructorBuilder
^ ctor_builder
=
1961 type_builder
->DefineConstructor(
1962 static_cast<MethodAttributes
>(MethodAttributes::Private
|
1963 MethodAttributes::HideBySig
|
1964 MethodAttributes::SpecialName
|
1965 MethodAttributes::RTSpecialName
),
1966 CallingConventions::Standard
, nullptr);
1968 Emit::ILGenerator
^ ilGen
= ctor_builder
->GetILGenerator();
1969 ilGen
->Emit( Emit::OpCodes::Ldarg_0
); // push this
1971 Emit::OpCodes::Call
,
1972 type_builder
->BaseType
->GetConstructor(gcnew array
< ::System::Type
^>(0)));
1973 ilGen
->Emit( Emit::OpCodes::Ret
);
1976 //obtain the interface which makes up this service, it is the return
1977 //type of the constructor functions
1978 Reference
<reflection::XInterfaceTypeDescription2
> xIfaceType(
1979 xSingletonType
->getInterface(), UNO_QUERY
);
1980 if (xIfaceType
.is () == sal_False
)
1981 xIfaceType
= resolveInterfaceTypedef(xSingletonType
->getInterface());
1982 System::Type
^ retType
= get_type(xIfaceType
);
1985 array
< ::System::Type
^>^ arTypeParameters
= {get_type("unoidl.com.sun.star.uno.XComponentContext", true)};
1986 Emit::MethodBuilder
^ method_builder
= type_builder
->DefineMethod(
1987 gcnew
System::String("get"),
1988 static_cast<MethodAttributes
>(MethodAttributes::Public
| MethodAttributes::HideBySig
|
1989 MethodAttributes::Static
),
1994 // method_builder->SetCustomAttribute(get_service_ctor_method_attribute(ctorDes));
1996 //The first parameter is the XComponentContext, which cannot be obtained
1998 //The context is not part of the idl description
1999 method_builder
->DefineParameter(1, ParameterAttributes::In
, "the_context");
2002 ilGen
= method_builder
->GetILGenerator();
2003 //Define locals ---------------------------------
2004 // Any, returned by XComponentContext.getValueByName
2005 Emit::LocalBuilder
^ local_any
=
2006 ilGen
->DeclareLocal(::uno::Any::typeid);
2008 //Call XContext::getValueByName
2009 ilGen
->Emit(Emit::OpCodes::Ldarg_0
);
2010 // build the singleton name : /singleton/unoidl.com.sun.star.XXX
2011 ::System::Text::StringBuilder
^ sBuilder
=
2012 gcnew ::System::Text::StringBuilder("/singletons/");
2013 sBuilder
->Append(sSingletonName
);
2014 ilGen
->Emit(Emit::OpCodes::Ldstr
, sBuilder
->ToString());
2016 ::System::Reflection::MethodInfo
^ methodGetValueByName
=
2017 get_type("unoidl.com.sun.star.uno.XComponentContext", true)->GetMethod("getValueByName");
2018 ilGen
->Emit(Emit::OpCodes::Callvirt
, methodGetValueByName
);
2019 ilGen
->Emit(Emit::OpCodes::Stloc_0
);
2021 //Contains the returned Any a value?
2022 ilGen
->Emit(Emit::OpCodes::Ldloca_S
, local_any
);
2023 ::System::Reflection::MethodInfo
^ methodHasValue
=
2024 ::uno::Any::typeid->GetMethod("hasValue");
2025 ilGen
->Emit(Emit::OpCodes::Call
, methodHasValue
);
2027 //If not, then throw an DeploymentException
2028 Emit::Label label_singleton_exists
= ilGen
->DefineLabel();
2029 ilGen
->Emit(Emit::OpCodes::Brtrue_S
, label_singleton_exists
);
2030 sBuilder
= gcnew ::System::Text::StringBuilder(
2031 "Component context fails to supply singleton ");
2032 sBuilder
->Append(sSingletonName
);
2033 sBuilder
->Append(" of type ");
2034 sBuilder
->Append(retType
->FullName
);
2035 sBuilder
->Append(".");
2036 ilGen
->Emit(Emit::OpCodes::Ldstr
, sBuilder
->ToString());
2037 ilGen
->Emit(Emit::OpCodes::Ldarg_0
);
2038 array
< ::System::Type
^>^ arTypesCtorDeploymentException
= {
2039 ::System::String::typeid, ::System::Object::typeid};
2040 ilGen
->Emit(Emit::OpCodes::Newobj
,
2041 get_type("unoidl.com.sun.star.uno.DeploymentException",true)
2042 ->GetConstructor(arTypesCtorDeploymentException
));
2043 ilGen
->Emit(Emit::OpCodes::Throw
);
2044 ilGen
->MarkLabel(label_singleton_exists
);
2046 //Cast the singleton contained in the Any to the expected interface and return it.
2047 ilGen
->Emit(Emit::OpCodes::Ldloca_S
, local_any
);
2048 ilGen
->Emit(Emit::OpCodes::Call
, ::uno::Any::typeid->GetProperty("Value")->GetGetMethod());
2049 ilGen
->Emit(Emit::OpCodes::Castclass
, retType
);
2050 ilGen
->Emit(Emit::OpCodes::Ret
);
2052 // remove from incomplete types map
2053 ::System::String
^ cts_name
= type_builder
->FullName
;
2054 m_incomplete_singletons
->Remove( cts_name
);
2055 xSingletonType
->release();
2058 ::System::Console::WriteLine(
2059 "> emitting singleton type {0}", cts_name
);
2061 return type_builder
->CreateType();
2065 //______________________________________________________________________________
2066 ::System::Type
^ TypeEmitter::get_type(
2067 Reference
< reflection::XTypeDescription
> const & xType
)
2069 switch (xType
->getTypeClass())
2071 case TypeClass_VOID
:
2072 return ::System::Void::typeid;
2073 case TypeClass_CHAR
:
2074 return ::System::Char::typeid;
2075 case TypeClass_BOOLEAN
:
2076 return ::System::Boolean::typeid;
2077 case TypeClass_BYTE
:
2078 return ::System::Byte::typeid;
2079 case TypeClass_SHORT
:
2080 return ::System::Int16::typeid;
2081 case TypeClass_UNSIGNED_SHORT
:
2082 return ::System::UInt16::typeid;
2083 case TypeClass_LONG
:
2084 return ::System::Int32::typeid;
2085 case TypeClass_UNSIGNED_LONG
:
2086 return ::System::UInt32::typeid;
2087 case TypeClass_HYPER
:
2088 return ::System::Int64::typeid;
2089 case TypeClass_UNSIGNED_HYPER
:
2090 return ::System::UInt64::typeid;
2091 case TypeClass_FLOAT
:
2092 return ::System::Single::typeid;
2093 case TypeClass_DOUBLE
:
2094 return ::System::Double::typeid;
2095 case TypeClass_STRING
:
2096 return ::System::String::typeid;
2097 case TypeClass_TYPE
:
2098 return ::System::Type::typeid;
2100 return ::uno::Any::typeid;
2101 case TypeClass_ENUM
:
2102 return get_type( Reference
< reflection::XEnumTypeDescription
>(
2103 xType
, UNO_QUERY_THROW
) );
2104 case TypeClass_TYPEDEF
:
2107 Reference
< reflection::XIndirectTypeDescription
>(
2108 xType
, UNO_QUERY_THROW
)->getReferencedType() );
2109 case TypeClass_STRUCT
:
2110 case TypeClass_EXCEPTION
:
2112 Reference
< reflection::XCompoundTypeDescription
>(
2113 xType
, UNO_QUERY_THROW
) );
2114 case TypeClass_SEQUENCE
:
2116 ::System::Type
^ element_type
= get_type(
2117 Reference
< reflection::XIndirectTypeDescription
>(
2118 xType
, UNO_QUERY_THROW
)->getReferencedType() );
2119 ::System::Type
^ retType
= get_type(
2120 ::System::String::Concat(
2121 element_type
->FullName
, "[]" ), true );
2123 ::uno::PolymorphicType
^ pt
= dynamic_cast< ::uno::PolymorphicType
^ >(element_type
);
2126 ::System::String
^ sName
= ::System::String::Concat(pt
->PolymorphicName
, "[]");
2127 retType
= ::uno::PolymorphicType::GetType(retType
, sName
);
2131 case TypeClass_INTERFACE
:
2133 Reference
< reflection::XInterfaceTypeDescription2
>(
2134 xType
, UNO_QUERY_THROW
) );
2135 case TypeClass_CONSTANT
:
2137 Reference
< reflection::XConstantTypeDescription
>(
2138 xType
, UNO_QUERY_THROW
) );
2139 case TypeClass_CONSTANTS
:
2141 Reference
< reflection::XConstantsTypeDescription
>(
2142 xType
, UNO_QUERY_THROW
) );
2143 case TypeClass_SERVICE
:
2145 Reference
< reflection::XServiceTypeDescription2
>(
2146 xType
, UNO_QUERY_THROW
) );
2147 case TypeClass_SINGLETON
:
2149 Reference
< reflection::XSingletonTypeDescription2
>(
2150 xType
, UNO_QUERY_THROW
) );
2151 case TypeClass_MODULE
:
2155 throw RuntimeException(
2156 "unexpected type " + xType
->getName(),
2157 Reference
< XInterface
>() );
2161 //______________________________________________________________________________
2162 ::System::Type
^ TypeEmitter::get_complete_struct( ::System::String
^ sName
)
2164 struct_entry
^ pStruct
= safe_cast
< struct_entry
^>(
2165 m_incomplete_structs
[sName
]);
2168 complete_struct_type(pStruct
);
2170 //get_type will asked the module builder for the type or otherwise all known assemblies.
2171 return get_type(sName
, true);
2173 TypeEmitter::~TypeEmitter()
2177 ::System::Collections::IDictionaryEnumerator
^ enumerator
=
2178 m_incomplete_ifaces
->GetEnumerator();
2179 if (! enumerator
->MoveNext())
2181 complete_iface_type(
2182 safe_cast
< iface_entry
^ >( enumerator
->Value
) );
2187 ::System::Collections::IDictionaryEnumerator
^ enumerator
=
2188 m_incomplete_structs
->GetEnumerator();
2189 if (! enumerator
->MoveNext())
2191 complete_struct_type(
2192 safe_cast
< struct_entry
^ >( enumerator
->Value
) );
2198 ::System::Collections::IDictionaryEnumerator
^ enumerator
=
2199 m_incomplete_services
->GetEnumerator();
2200 if (! enumerator
->MoveNext())
2202 complete_service_type(
2203 safe_cast
< service_entry
^ >( enumerator
->Value
) );
2208 ::System::Collections::IDictionaryEnumerator
^ enumerator
=
2209 m_incomplete_singletons
->GetEnumerator();
2210 if (! enumerator
->MoveNext())
2212 complete_singleton_type(
2213 safe_cast
< singleton_entry
^ >( enumerator
->Value
) );
2216 //______________________________________________________________________________
2217 TypeEmitter::TypeEmitter(
2218 ::System::Reflection::Emit::ModuleBuilder
^ module_builder
,
2219 array
< ::System::Reflection::Assembly
^>^ extra_assemblies
)
2220 : m_module_builder( module_builder
),
2221 m_extra_assemblies( extra_assemblies
),
2222 m_method_info_Type_GetTypeFromHandle( nullptr ),
2223 m_type_Exception( nullptr ),
2224 m_type_RuntimeException( nullptr ),
2225 m_incomplete_ifaces( gcnew ::System::Collections::Hashtable() ),
2226 m_incomplete_structs( gcnew ::System::Collections::Hashtable() ),
2227 m_incomplete_services(gcnew ::System::Collections::Hashtable() ),
2228 m_incomplete_singletons(gcnew ::System::Collections::Hashtable() ),
2229 m_generated_structs( gcnew ::System::Collections::Hashtable() )
2231 array
< ::System::Type
^>^ param_types
= gcnew array
< ::System::Type
^> ( 1 );
2232 param_types
[ 0 ] = ::System::RuntimeTypeHandle::typeid;
2233 m_method_info_Type_GetTypeFromHandle
=
2234 ::System::Type::typeid
2235 ->GetMethod( "GetTypeFromHandle", param_types
);
2238 ::System::Collections::ArrayList
^ TypeEmitter::get_service_ctor_method_exceptions_reduced(
2239 const Sequence
<Reference
<reflection::XCompoundTypeDescription
> > & seqExceptionsTd
)
2241 if (seqExceptionsTd
.getLength() == 0)
2242 return gcnew ::System::Collections::ArrayList();
2244 ::System::Collections::ArrayList
^ arTypes
= gcnew ::System::Collections::ArrayList();
2245 for (int i
= 0; i
< seqExceptionsTd
.getLength(); i
++)
2246 arTypes
->Add(get_type(to_cts_name(seqExceptionsTd
[i
]->getName()), true));
2251 bool bRemove
= false;
2252 for (int i
= start
; i
< arTypes
->Count
; i
++)
2254 ::System::Type
^ t
= safe_cast
< ::System::Type
^ >(arTypes
[i
]);
2255 for (int j
= 0; j
< arTypes
->Count
; j
++)
2257 if (t
->IsSubclassOf(safe_cast
< ::System::Type
^ >(arTypes
[j
])))
2259 arTypes
->RemoveAt(i
);
2269 if (bRemove
== false)
2276 css::uno::Reference
< css::reflection::XInterfaceTypeDescription2
>
2277 resolveInterfaceTypedef(
2278 const css::uno::Reference
<css::reflection::XTypeDescription
>& type
)
2280 Reference
<reflection::XInterfaceTypeDescription2
>
2281 xIfaceTd(type
, UNO_QUERY
);
2286 Reference
<reflection::XIndirectTypeDescription
> xIndTd(
2288 if (xIndTd
.is() == sal_False
)
2289 throw css::uno::Exception(
2290 "resolveInterfaceTypedef was called with an invalid argument", 0);
2292 return resolveInterfaceTypedef(xIndTd
->getReferencedType());
2298 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */