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