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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 //------------------------------------------------------------------------------ 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 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 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 // append [] 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 an 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 */ 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 need 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 //______________________________________________________________________________ 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 //______________________________________________________________________________ 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 //______________________________________________________________________________ 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 //______________________________________________________________________________ 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 //______________________________________________________________________________ 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 //______________________________________________________________________________ 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 //______________________________________________________________________________ 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 //______________________________________________________________________________ 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 needed 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 //______________________________________________________________________________ 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 //______________________________________________________________________________ 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 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 //______________________________________________________________________________ 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 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 requires 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 // } 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 variable 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 created 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 1925 Emit::CustomAttributeBuilder* TypeEmitter::get_service_exception_attribute( 1926 const Reference<reflection::XServiceConstructorDescription> & ctorDes ) 1927 { 1928 return get_exception_attribute(ctorDes->getExceptions()); 1929 } 1930 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 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 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 //______________________________________________________________________________ 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 //______________________________________________________________________________ 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 ask the module builder for the type or otherwise all known assemblies. 2194 return get_type(sName, true); 2195 } 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 //______________________________________________________________________________ 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 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 > 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