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