diff options
Diffstat (limited to 'cli_ure/source/climaker/climaker_emit.cxx')
-rw-r--r-- | cli_ure/source/climaker/climaker_emit.cxx | 2326 |
1 files changed, 0 insertions, 2326 deletions
diff --git a/cli_ure/source/climaker/climaker_emit.cxx b/cli_ure/source/climaker/climaker_emit.cxx deleted file mode 100644 index ffc63a06e..000000000 --- a/cli_ure/source/climaker/climaker_emit.cxx +++ /dev/null @@ -1,2326 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_cli_ure.hxx" - -#include "climaker_share.h" - -#include "rtl/string.hxx" -#include "rtl/ustrbuf.hxx" -#include "com/sun/star/reflection/XIndirectTypeDescription.hpp" -#include "com/sun/star/reflection/XStructTypeDescription.hpp" -#include "com/sun/star/reflection/XInterfaceTypeDescription2.hpp" -#include "com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp" -#include "com/sun/star/reflection/XInterfaceAttributeTypeDescription.hpp" -#include "com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp" -#include <vector> - -using namespace ::System::Reflection; - -using namespace ::rtl; -using namespace ::com::sun::star; -using namespace ::com::sun::star::uno; - -namespace climaker -{ -System::String* mapUnoPolymorphicName(System::String* unoName); -//------------------------------------------------------------------------------ -static inline ::System::String * to_cts_name( - OUString const & uno_name ) -{ - OUStringBuffer buf( 7 + uno_name.getLength() ); - buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("unoidl.") ); - buf.append( uno_name ); - return ustring_to_String( buf.makeStringAndClear() ); -} - -//------------------------------------------------------------------------------ -static inline ::System::Object * to_cli_constant( Any const & value ) -{ - switch (value.getValueTypeClass()) - { - case TypeClass_CHAR: - return __box - ((::System::Char) *reinterpret_cast< sal_Unicode const * >( - value.getValue() )); - case TypeClass_BOOLEAN: - return __box - ((::System::Boolean) - sal_False != *reinterpret_cast< sal_Bool const * >( - value.getValue() )); - case TypeClass_BYTE: - return __box - ((::System::Byte) *reinterpret_cast< sal_Int8 const * >( - value.getValue() )); - case TypeClass_SHORT: - return __box - ((::System::Int16) *reinterpret_cast< sal_Int16 const * >( - value.getValue() )); - case TypeClass_UNSIGNED_SHORT: - return __box - ((::System::UInt16) *reinterpret_cast< sal_uInt16 const * >( - value.getValue() )); - case TypeClass_LONG: - return __box - ((::System::Int32) *reinterpret_cast< sal_Int32 const * >( - value.getValue() )); - case TypeClass_UNSIGNED_LONG: - return __box - ((::System::UInt32) *reinterpret_cast< sal_uInt32 const * >( - value.getValue() )); - case TypeClass_HYPER: - return __box - ((::System::Int64) *reinterpret_cast< sal_Int64 const * >( - value.getValue() )); - case TypeClass_UNSIGNED_HYPER: - return __box - ((::System::UInt64) *reinterpret_cast< sal_uInt64 const * >( - value.getValue() )); - case TypeClass_FLOAT: - return __box - ((::System::Single) *reinterpret_cast< float const * >( - value.getValue() )); - case TypeClass_DOUBLE: - return __box - ((::System::Double) *reinterpret_cast< double const * >( - value.getValue() )); - default: - throw RuntimeException( - OUSTR("unexpected constant type ") + - value.getValueType().getTypeName(), - Reference< XInterface >() ); - } -} - -//------------------------------------------------------------------------------ -static inline void emit_ldarg( Emit::ILGenerator * code, ::System::Int32 index ) -{ - switch (index) - { - case 0: - code->Emit( Emit::OpCodes::Ldarg_0 ); - break; - case 1: - code->Emit( Emit::OpCodes::Ldarg_1 ); - break; - case 2: - code->Emit( Emit::OpCodes::Ldarg_2 ); - break; - case 3: - code->Emit( Emit::OpCodes::Ldarg_3 ); - break; - default: - if (index < 0x100) - code->Emit( Emit::OpCodes::Ldarg_S, (::System::Byte) index ); - else if (index < 0x8000) - code->Emit( Emit::OpCodes::Ldarg_S, (::System::Int16) index ); - else - code->Emit( Emit::OpCodes::Ldarg, index ); - break; - } -} - -void polymorphicStructNameToStructName(::System::String ** sPolyName) -{ - if ((*sPolyName)->EndsWith(S">") == false) - return; - - int index = (*sPolyName)->IndexOf('<'); - OSL_ASSERT(index != -1); - *sPolyName = (*sPolyName)->Substring(0, index); -} - - -System::String* mapUnoTypeName(System::String * typeName) -{ - ::System::Text::StringBuilder* buf= new System::Text::StringBuilder(); - ::System::String * sUnoName = ::System::String::Copy(typeName); - //determine if the type is a sequence and its dimensions - int dims= 0; - if (typeName->StartsWith(S"["))//if (usUnoName[0] == '[') - { - int index= 1; - while (true) - { - if (typeName->get_Chars(index++) == ']')//if (usUnoName[index++] == ']') - dims++; - if (typeName->get_Chars(index++) != '[')//usUnoName[index++] != '[') - break; - } - sUnoName = sUnoName->Substring(index - 1);//usUnoName = usUnoName.copy(index - 1); - } - if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoBool))) - buf->Append(const_cast<System::String*>(Constants::sBoolean)); - else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoChar))) - buf->Append(const_cast<System::String*>(Constants::sChar)); - else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoByte))) - buf->Append(const_cast<System::String*>(Constants::sByte)); - else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoShort))) - buf->Append(const_cast<System::String*>(Constants::sInt16)); - else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoUShort))) - buf->Append(const_cast<System::String*>(Constants::sUInt16)); - else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoLong))) - buf->Append(const_cast<System::String*>(Constants::sInt32)); - else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoULong))) - buf->Append(const_cast<System::String*>(Constants::sUInt32)); - else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoHyper))) - buf->Append(const_cast<System::String*>(Constants::sInt64)); - else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoUHyper))) - buf->Append(const_cast<System::String*>(Constants::sUInt64)); - else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoFloat))) - buf->Append(const_cast<System::String*>(Constants::sSingle)); - else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoDouble))) - buf->Append(const_cast<System::String*>(Constants::sDouble)); - else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoString))) - buf->Append(const_cast<System::String*>(Constants::sString)); - else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoVoid))) - buf->Append(const_cast<System::String*>(Constants::sVoid)); - else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoType))) - buf->Append(const_cast<System::String*>(Constants::sType)); - else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoXInterface))) - buf->Append(const_cast<System::String*>(Constants::sObject)); - else if (sUnoName->Equals(const_cast<System::String*>(Constants::sUnoAny))) - { - buf->Append(const_cast<System::String*>(Constants::sAny)); - } - else - { - //put "unoidl." at the beginning - buf->Append(const_cast<System::String*>(Constants::sUnoidl)); - buf->Append(mapUnoPolymorphicName(sUnoName)); - } - // apend [] - for (;dims--;) - buf->Append(const_cast<System::String*>(Constants::sBrackets)); - - return buf->ToString(); -} - - -/** For example, there is a uno type - com.sun.star.Foo<char, long>. - The values in the type list - are uno types and are replaced by cli types, such as System.Char, - System.Int32, etc. - - Strings can be as complicated as this - test.MyStruct<char,test.MyStruct<long, []string>> - */ -System::String* mapUnoPolymorphicName(System::String* unoName) -{ - int index = unoName->IndexOf('<'); - if (index == -1) - return unoName; - - System::Text::StringBuilder * builder = - new System::Text::StringBuilder(unoName->Substring(0, index +1 )); - - //Find the first occurrence of ',' - //If the parameter is a polymorphic struct then we neede to ignore everything - //between the brackets because it can also contain commas - //get the type list within < and > - int endIndex = unoName->Length - 1; - index++; - int cur = index; - int countParams = 0; - while (cur <= endIndex) - { - System::Char c = unoName->Chars[cur]; - if (c == ',' || c == '>') - { - //insert a comma if needed - if (countParams != 0) - builder->Append(S","); - countParams++; - System::String * sParam = unoName->Substring(index, cur - index); - //skip the comma - cur++; - //the the index to the beginning of the next param - index = cur; - builder->Append(mapUnoTypeName(sParam)); - } - else if (c == '<') - { - cur++; - //continue until the matching '>' - int numNested = 0; - for (;;cur++) - { - System::Char curChar = unoName->Chars[cur]; - if (curChar == '<') - { - numNested ++; - } - else if (curChar == '>') - { - if (numNested > 0) - numNested--; - else - break; - } - } - } - cur++; - } - - builder->Append((System::Char) '>'); - return builder->ToString(); -} - - - -//______________________________________________________________________________ -Assembly * TypeEmitter::type_resolve( - ::System::Object *, ::System::ResolveEventArgs * args ) -{ - ::System::String * cts_name = args->get_Name(); - ::System::Type * ret_type = m_module_builder->GetType( - cts_name, false /* no exc */ ); - if (0 == ret_type) - { - iface_entry * entry = dynamic_cast< iface_entry * >( - m_incomplete_ifaces->get_Item( cts_name ) ); - if (0 != entry) - ret_type = entry->m_type_builder; - } - if (0 == ret_type) - { - sal_Int32 len = m_extra_assemblies->get_Length(); - for ( sal_Int32 pos = 0; pos < len; ++pos ) - { - ret_type = m_extra_assemblies[ pos ]->GetType( - cts_name, false /* no exc */ ); - if (0 != ret_type) - { - if (g_verbose) - { - ::System::Console::WriteLine( - "> resolving type {0} from {1}.", - cts_name, ret_type->get_Assembly()->get_FullName() ); - } - break; - } - } - } - if (0 != ret_type) - return ret_type->get_Assembly(); - return 0; -} - -//______________________________________________________________________________ -::System::Type * TypeEmitter::get_type( - ::System::String * cts_name, bool throw_exc ) -{ - ::System::Type * ret_type = m_module_builder->GetType( cts_name, false ); - //We get the type from the ModuleBuilder even if the type is not complete - //but have been defined. - //if (ret_type == 0) - //{ - // iface_entry * entry = dynamic_cast< iface_entry * >( - // m_incomplete_ifaces->get_Item( cts_name ) ); - // if (0 != entry) - // ret_type = entry->m_type_builder; - //} - //try the cli_basetypes assembly - if (ret_type == 0) - { - ::System::Text::StringBuilder * builder = new ::System::Text::StringBuilder(cts_name); - builder->Append(S",cli_basetypes"); - ret_type = ::System::Type::GetType(builder->ToString()); - } - - if (ret_type == 0) - { - try - { - // may call on type_resolve() - return ::System::Type::GetType( cts_name, throw_exc ); - } - catch (::System::Exception* exc) - { - //If the type is not found one may have forgotten to specify assemblies with - //additional types - ::System::Text::StringBuilder * sb = new ::System::Text::StringBuilder(); - sb->Append(new ::System::String(S"\nThe type ")); - sb->Append(cts_name); - sb->Append(new ::System::String(S" \n could not be found. Did you forget to " \ - S"specify an additional assembly with the --reference option?\n")); - if (throw_exc) - throw new ::System::Exception(sb->ToString(), exc); - } - } - else - { - return ret_type; - } -} - -//______________________________________________________________________________ -::System::Type * TypeEmitter::get_type_Exception() -{ - if (0 == m_type_Exception) - { - m_type_Exception = get_type( - S"unoidl.com.sun.star.uno.Exception", false /* no exc */ ); - if (0 == m_type_Exception) - { - // define hardcoded type unoidl.com.sun.star.uno.Exception - Emit::TypeBuilder * type_builder = - m_module_builder->DefineType( - S"unoidl.com.sun.star.uno.Exception", - (TypeAttributes) (TypeAttributes::Public | - TypeAttributes::BeforeFieldInit | - TypeAttributes::AnsiClass), - __typeof (::System::Exception) ); - Emit::FieldBuilder * field_Context = type_builder->DefineField( - S"Context", __typeof (::System::Object), - FieldAttributes::Public ); - // default .ctor - type_builder->DefineDefaultConstructor( c_ctor_method_attr ); - // .ctor - ::System::Type * param_types[] = - new ::System::Type *[ 2 ]; - param_types[ 0 ] = __typeof (::System::String); - param_types[ 1 ] = __typeof (::System::Object); - Emit::ConstructorBuilder * ctor_builder = - type_builder->DefineConstructor( - c_ctor_method_attr, CallingConventions::Standard, - param_types ); - ctor_builder->DefineParameter( - 1, ParameterAttributes::In, S"Message" ); - ctor_builder->DefineParameter( - 2, ParameterAttributes::In, S"Context" ); - Emit::ILGenerator * code = ctor_builder->GetILGenerator(); - code->Emit( Emit::OpCodes::Ldarg_0 ); - code->Emit( Emit::OpCodes::Ldarg_1 ); - param_types = new ::System::Type * [ 1 ]; - param_types[ 0 ] = __typeof (::System::String); - code->Emit( - Emit::OpCodes::Call, - __typeof (::System::Exception) - ->GetConstructor( param_types ) ); - code->Emit( Emit::OpCodes::Ldarg_0 ); - code->Emit( Emit::OpCodes::Ldarg_2 ); - code->Emit( Emit::OpCodes::Stfld, field_Context ); - code->Emit( Emit::OpCodes::Ret ); - - if (g_verbose) - { - ::System::Console::WriteLine( - "> emitting exception type " - "unoidl.com.sun.star.uno.Exception" ); - } - m_type_Exception = type_builder->CreateType(); - } - } - return m_type_Exception; -} - -//______________________________________________________________________________ -::System::Type * TypeEmitter::get_type_RuntimeException() -{ - if (0 == m_type_RuntimeException) - { - m_type_RuntimeException = get_type( - S"unoidl.com.sun.star.uno.RuntimeException", false /* no exc */ ); - if (0 == m_type_RuntimeException) - { - // define hardcoded type unoidl.com.sun.star.uno.RuntimeException - ::System::Type * type_Exception = get_type_Exception(); - Emit::TypeBuilder * type_builder = - m_module_builder->DefineType( - S"unoidl.com.sun.star.uno.RuntimeException", - (TypeAttributes) (TypeAttributes::Public | - TypeAttributes::BeforeFieldInit | - TypeAttributes::AnsiClass), - type_Exception ); - // default .ctor - type_builder->DefineDefaultConstructor( c_ctor_method_attr ); - // .ctor - ::System::Type * param_types [] = - new ::System::Type * [ 2 ]; - param_types[ 0 ] = __typeof (::System::String); - param_types[ 1 ] = __typeof (::System::Object); - Emit::ConstructorBuilder * ctor_builder = - type_builder->DefineConstructor( - c_ctor_method_attr, CallingConventions::Standard, - param_types ); - ctor_builder->DefineParameter( - 1, ParameterAttributes::In, S"Message" ); - ctor_builder->DefineParameter( - 2, ParameterAttributes::In, S"Context" ); - Emit::ILGenerator * code = ctor_builder->GetILGenerator(); - code->Emit( Emit::OpCodes::Ldarg_0 ); - code->Emit( Emit::OpCodes::Ldarg_1 ); - code->Emit( Emit::OpCodes::Ldarg_2 ); - code->Emit( - Emit::OpCodes::Call, - type_Exception->GetConstructor( param_types ) ); - code->Emit( Emit::OpCodes::Ret ); - - if (g_verbose) - { - ::System::Console::WriteLine( - "> emitting exception type " - "unoidl.com.sun.star.uno.RuntimeException" ); - } - m_type_RuntimeException = type_builder->CreateType(); - } - } - return m_type_RuntimeException; -} - -//______________________________________________________________________________ -::System::Type * TypeEmitter::get_type( - Reference< reflection::XConstantTypeDescription > const & xType ) -{ - ::System::String * cts_name = to_cts_name( xType->getName() ); - ::System::Type * ret_type = get_type( cts_name, false /* no exc */ ); - if (0 == ret_type) - { - Reference< reflection::XConstantTypeDescription > xConstant( - xType, UNO_QUERY_THROW ); - ::System::Object * constant = - to_cli_constant( xConstant->getConstantValue() ); - Emit::TypeBuilder * type_builder = - m_module_builder->DefineType( - cts_name, - (TypeAttributes) (TypeAttributes::Public | - TypeAttributes::Sealed | - TypeAttributes::BeforeFieldInit | - TypeAttributes::AnsiClass) ); - - Emit::FieldBuilder * field_builder = type_builder->DefineField( - cts_name->Substring( cts_name->LastIndexOf( '.' ) +1 ), - constant->GetType(), - (FieldAttributes) (FieldAttributes::Public | - FieldAttributes::Static | - FieldAttributes::Literal) ); - field_builder->SetConstant( constant ); - - if (g_verbose) - { - ::System::Console::WriteLine( - "> emitting constant type {0}", cts_name ); - } - ret_type = type_builder->CreateType(); - } - return ret_type; -} - -//______________________________________________________________________________ -::System::Type * TypeEmitter::get_type( - Reference< reflection::XConstantsTypeDescription > const & xType ) -{ - ::System::String * cts_name = to_cts_name( xType->getName() ); - ::System::Type * ret_type = get_type( cts_name, false /* no exc */ ); - if (0 == ret_type) - { - Emit::TypeBuilder * type_builder = - m_module_builder->DefineType( - cts_name, - (TypeAttributes) (TypeAttributes::Public | - TypeAttributes::Sealed | - TypeAttributes::BeforeFieldInit | - TypeAttributes::AnsiClass) ); - - Sequence< Reference< - reflection::XConstantTypeDescription > > seq_constants( - xType->getConstants() ); - Reference< reflection::XConstantTypeDescription > const * constants = - seq_constants.getConstArray(); - sal_Int32 constants_length = seq_constants.getLength(); - for ( sal_Int32 constants_pos = 0; - constants_pos < constants_length; ++constants_pos ) - { - Reference< - reflection::XConstantTypeDescription > const & xConstant = - constants[ constants_pos ]; - ::System::Object * constant = - to_cli_constant( xConstant->getConstantValue() ); - ::System::String * uno_name = - ustring_to_String( xConstant->getName() ); - Emit::FieldBuilder * field_builder = type_builder->DefineField( - uno_name->Substring( uno_name->LastIndexOf( '.' ) +1 ), - constant->GetType(), - (FieldAttributes) (FieldAttributes::Public | - FieldAttributes::Static | - FieldAttributes::Literal) ); - field_builder->SetConstant( constant ); - } - - if (g_verbose) - { - ::System::Console::WriteLine( - "> emitting constants group type {0}", cts_name ); - } - ret_type = type_builder->CreateType(); - } - return ret_type; -} - -//______________________________________________________________________________ -::System::Type * TypeEmitter::get_type( - Reference< reflection::XEnumTypeDescription > const & xType ) -{ - ::System::String * cts_name = to_cts_name( xType->getName() ); - ::System::Type * ret_type = get_type( cts_name, false /* no exc */ ); - if (0 == ret_type) - { -// Emit::EnumBuilder * enum_builder = -// m_module_builder->DefineEnum( -// cts_name, -// (TypeAttributes) (TypeAttributes::Public | -// // TypeAttributes::Sealed | -// TypeAttributes::AnsiClass), -// __typeof (::System::Int32) ); - // workaround enum builder bug - Emit::TypeBuilder * enum_builder = - m_module_builder->DefineType( - cts_name, - (TypeAttributes) (TypeAttributes::Public | - TypeAttributes::Sealed), - __typeof (::System::Enum) ); - enum_builder->DefineField( - S"value__", __typeof (::System::Int32), - (FieldAttributes) (FieldAttributes::Private | - FieldAttributes::SpecialName | - FieldAttributes::RTSpecialName) ); - Sequence< OUString > seq_enum_names( xType->getEnumNames() ); - Sequence< sal_Int32 > seq_enum_values( xType->getEnumValues() ); - sal_Int32 enum_length = seq_enum_names.getLength(); - OSL_ASSERT( enum_length == seq_enum_values.getLength() ); - OUString const * enum_names = seq_enum_names.getConstArray(); - sal_Int32 const * enum_values = seq_enum_values.getConstArray(); - for ( sal_Int32 enum_pos = 0; enum_pos < enum_length; ++enum_pos ) - { -// enum_builder->DefineLiteral( -// ustring_to_String( enum_names[ enum_pos ] ), -// __box ((::System::Int32) enum_values[ enum_pos ]) ); - Emit::FieldBuilder * field_builder = - enum_builder->DefineField( - ustring_to_String( enum_names[ enum_pos ] ), - enum_builder, - (FieldAttributes) (FieldAttributes::Public | - FieldAttributes::Static | - FieldAttributes::Literal) ); - field_builder->SetConstant( - __box ((::System::Int32) enum_values[ enum_pos ]) ); - } - - if (g_verbose) - { - ::System::Console::WriteLine( - "> emitting enum type {0}", cts_name ); - } - ret_type = enum_builder->CreateType(); - } - return ret_type; -} - -//______________________________________________________________________________ -::System::Type * TypeEmitter::get_type( - Reference< reflection::XCompoundTypeDescription > const & xType ) -{ - OUString uno_name( xType->getName() ); - if (TypeClass_EXCEPTION == xType->getTypeClass()) - { - if (uno_name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( - "com.sun.star.uno.Exception") )) - { - return get_type_Exception(); - } - if (uno_name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( - "com.sun.star.uno.RuntimeException") )) - { - return get_type_RuntimeException(); - } - } - ::System::String * cts_name = to_cts_name( uno_name ); - // if the struct is an instantiated polymorpic struct then we create the simple struct name - // For example: - // void func ([in] PolyStruct<boolean> arg); - //PolyStruct<boolean> will be converted to PolyStruct - polymorphicStructNameToStructName( & cts_name); - - ::System::Type * ret_type = get_type( cts_name, false /* no exc */ ); - if (0 == ret_type) - { - Reference< reflection::XCompoundTypeDescription > xBaseType( - xType->getBaseType(), UNO_QUERY ); - ::System::Type * base_type = (xBaseType.is() - ? get_type( xBaseType ) - : __typeof (::System::Object)); - Emit::TypeBuilder * type_builder = - m_module_builder->DefineType( - cts_name, - (TypeAttributes) (TypeAttributes::Public | - TypeAttributes::BeforeFieldInit | - TypeAttributes::AnsiClass), - base_type ); - - - // insert to be completed - struct_entry * entry = new struct_entry(); - xType->acquire(); - entry->m_xType = xType.get(); - entry->m_type_builder = type_builder; - entry->m_base_type = base_type; - m_incomplete_structs->Add( cts_name, entry ); - - // type is incomplete - ret_type = type_builder; - } - - //In case of an instantiated polymorphic struct we want to return a - //uno.PolymorphicType (inherits Type) rather then Type. This is neaded for constructing - //the service code. We can only do that if the struct is completed. - if (m_generated_structs->get_Item(cts_name)) - { - Reference< reflection::XStructTypeDescription> xStructTypeDesc( - xType, UNO_QUERY); - - if (xStructTypeDesc.is()) - { - Sequence< Reference< reflection::XTypeDescription > > seqTypeArgs = xStructTypeDesc->getTypeArguments(); - sal_Int32 numTypes = seqTypeArgs.getLength(); - if (numTypes > 0) - { - //it is an instantiated polymorphic struct - ::System::String * sCliName = mapUnoTypeName(ustring_to_String(xType->getName())); - ret_type = ::uno::PolymorphicType::GetType(ret_type, sCliName); - } - } - } - return ret_type; -} - -//______________________________________________________________________________ -::System::Type * TypeEmitter::get_type( - Reference< reflection::XInterfaceTypeDescription2 > const & xType ) -{ - OUString uno_name( xType->getName() ); - if (uno_name.equalsAsciiL( - RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") )) - { - return __typeof (::System::Object); - } - - ::System::String * cts_name = to_cts_name( xType->getName() ); - ::System::Type * ret_type = get_type( cts_name, false /* no exc */ ); - if (0 == ret_type) - { - Emit::TypeBuilder * type_builder; - - TypeAttributes attr = (TypeAttributes) (TypeAttributes::Public | - TypeAttributes::Interface | - TypeAttributes::Abstract | - TypeAttributes::AnsiClass); - - std::vector<Reference<reflection::XInterfaceTypeDescription2> > vecBaseTypes; - Sequence<Reference< reflection::XTypeDescription > > seqBaseTypes = - xType->getBaseTypes(); - if (seqBaseTypes.getLength() > 0) - { - for (int i = 0; i < seqBaseTypes.getLength(); i++) - { - Reference<reflection::XInterfaceTypeDescription2> xIfaceTd = - resolveInterfaceTypedef(seqBaseTypes[i]); - - if (xIfaceTd->getName().equalsAsciiL( - RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") ) == sal_False) - { - vecBaseTypes.push_back(xIfaceTd); - } - } - - ::System::Type * base_interfaces [] = - new ::System::Type * [ vecBaseTypes.size() ]; - - typedef std::vector<Reference<reflection::XInterfaceTypeDescription2> >::const_iterator it; - int index = 0; - for (it i = vecBaseTypes.begin(); i != vecBaseTypes.end(); ++i, ++index) - base_interfaces[ index ] = get_type( *i ); - type_builder = m_module_builder->DefineType( - cts_name, attr, 0, base_interfaces ); - } - else - { - ::System::Console::WriteLine( - "warning: IDL interface {0} is not derived from " - "com.sun.star.uno.XInterface!", - ustring_to_String( uno_name ) ); - - type_builder = m_module_builder->DefineType( cts_name, attr ); - } - - // insert to be completed - iface_entry * entry = new iface_entry(); - xType->acquire(); - entry->m_xType = xType.get(); - entry->m_type_builder = type_builder; - m_incomplete_ifaces->Add( cts_name, entry ); - - // type is incomplete - ret_type = type_builder; - } - return ret_type; -} - - -//______________________________________________________________________________ -::System::Type * TypeEmitter::get_type( - Reference< reflection::XServiceTypeDescription2 > const & xType ) -{ - if (xType->isSingleInterfaceBased() == sal_False) - return NULL; - - System::String * cts_name = to_cts_name( xType->getName() ); - System::Type * ret_type = get_type( cts_name, false /* no exc */ ); - if (ret_type != NULL) - return ret_type; - - TypeAttributes attr = (TypeAttributes) (TypeAttributes::Public | - TypeAttributes::Sealed | - TypeAttributes::BeforeFieldInit | - TypeAttributes::AnsiClass); - - Emit::TypeBuilder * type_builder = m_module_builder->DefineType( - cts_name, attr); - - // insert to be completed - service_entry * entry = new service_entry(); - xType->acquire(); - entry->m_xType = xType.get(); - entry->m_type_builder = type_builder; - m_incomplete_services->Add(cts_name,entry ); - - return type_builder; -} - -::System::Type * TypeEmitter::get_type( - Reference<reflection::XSingletonTypeDescription2 > const & xType ) -{ - if (xType->isInterfaceBased() == sal_False) - return NULL; - - ::System::String* cts_name = to_cts_name( xType->getName() ); - ::System::Type * ret_type = get_type( cts_name, false /* no exc */ ); - if (ret_type != NULL) - return ret_type; - - TypeAttributes attr = static_cast<TypeAttributes>( - TypeAttributes::Public | - TypeAttributes::Sealed | - TypeAttributes::BeforeFieldInit | - TypeAttributes::AnsiClass); - - Emit::TypeBuilder * type_builder = m_module_builder->DefineType( - cts_name, attr); - - // insert to be completed - singleton_entry * entry = new singleton_entry(); - xType->acquire(); - entry->m_xType = xType.get(); - entry->m_type_builder = type_builder; - m_incomplete_singletons->Add(cts_name,entry ); - - return type_builder; - -} - -//______________________________________________________________________________ -::System::Type * TypeEmitter::complete_iface_type( iface_entry * entry ) -{ - Emit::TypeBuilder * type_builder = entry->m_type_builder; - reflection::XInterfaceTypeDescription2 * xType = entry->m_xType; - - Sequence<Reference< reflection::XTypeDescription > > seqBaseTypes( xType->getBaseTypes() ); - if (seqBaseTypes.getLength() > 0) - { - for (int i = 0; i < seqBaseTypes.getLength(); i++) - { - //make sure we get the interface rather then a typedef - Reference<reflection::XInterfaceTypeDescription2> aBaseType = - resolveInterfaceTypedef( seqBaseTypes[i]); - - if (aBaseType->getName().equalsAsciiL( - RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") ) == sal_False) - { - ::System::String * basetype_name = to_cts_name( aBaseType->getName() ); - iface_entry * base_entry = dynamic_cast< iface_entry * >( - m_incomplete_ifaces->get_Item( basetype_name ) ); - if (0 != base_entry) - { - // complete uncompleted base type first - complete_iface_type( base_entry ); - } - } - } - } - - Sequence< - Reference< reflection::XInterfaceMemberTypeDescription > > seq_members( - xType->getMembers() ); - Reference< reflection::XInterfaceMemberTypeDescription > const * members = - seq_members.getConstArray(); - sal_Int32 members_length = seq_members.getLength(); - for ( sal_Int32 members_pos = 0; - members_pos < members_length; ++members_pos ) - { - Reference< - reflection::XInterfaceMemberTypeDescription > const & xMember = - members[ members_pos ]; - Sequence< Reference< reflection::XTypeDescription > > seq_exceptions; - Emit::MethodBuilder * method_builder; - - const MethodAttributes c_method_attr = (MethodAttributes) - (MethodAttributes::Public | - MethodAttributes::Abstract | - MethodAttributes::Virtual | - MethodAttributes::NewSlot | - MethodAttributes::HideBySig); -//#if defined(_MSC_VER) && (_MSC_VER < 1400) -// MethodAttributes::Instance); -//#else -// Instance); -//#endif - - if (TypeClass_INTERFACE_METHOD == xMember->getTypeClass()) - { - Reference< reflection::XInterfaceMethodTypeDescription > xMethod( - xMember, UNO_QUERY_THROW ); - - Sequence< - Reference< reflection::XMethodParameter > > seq_parameters( - xMethod->getParameters() ); - sal_Int32 params_length = seq_parameters.getLength(); - ::System::Type * param_types [] = - new ::System::Type * [ params_length ]; - Reference< reflection::XMethodParameter > const * parameters = - seq_parameters.getConstArray(); - // first determine all types - //Make the first param type as return type - sal_Int32 params_pos = 0; - for ( ; params_pos < params_length; ++params_pos ) - { - Reference< reflection::XMethodParameter > const & xParam = - parameters[ params_pos ]; - ::System::Type * param_type = get_type( xParam->getType() ); - ::System::String * param_type_name = param_type->get_FullName(); - if (xParam->isOut()) - { - param_type = get_type( - ::System::String::Concat( - param_type_name, S"&" ), true ); - } - param_types[ xParam->getPosition() ] = param_type; - } - - - // create method -// if (tb) -// method_builder = type_builder->DefineMethod( -// ustring_to_String( xMethod->getMemberName() ), -// c_method_attr, tb, -// param_types ); -// else - method_builder = type_builder->DefineMethod( - ustring_to_String( xMethod->getMemberName() ), - c_method_attr, get_type( xMethod->getReturnType() ), - param_types ); - // then define parameter infos - params_pos = 0; - for ( ; params_pos < params_length; ++params_pos ) - { - Reference< reflection::XMethodParameter > const & xParam = - parameters[ params_pos ]; - long param_flags = 0; - if (xParam->isIn()) - param_flags |= ParameterAttributes::In; - if (xParam->isOut()) - param_flags |= ParameterAttributes::Out; - OSL_ASSERT( 0 != param_flags ); - method_builder->DefineParameter( - xParam->getPosition() +1 /* starts with 1 */, - (ParameterAttributes) param_flags, - ustring_to_String( xParam->getName() ) ); - } - //Apply attribute TypeParametersAttribute to return value if it - //is a parameterized Type. Currently only structs can have parameters. - Reference<reflection::XStructTypeDescription> xReturnStruct( - xMethod->getReturnType(), UNO_QUERY); - - if (xReturnStruct.is()) - { - Sequence<Reference<reflection::XTypeDescription> > seq_type_args = - xReturnStruct->getTypeArguments(); - if (seq_type_args.getLength() != 0) - { - //get th ctor of the attribute - ::System::Type * arCtor[] = {::System::Type::GetType(S"System.Type[]")}; - //Get the arguments for the attribute's ctor - Reference<reflection::XTypeDescription> const * arXTypeArgs = - seq_type_args.getConstArray(); - int numTypes = seq_type_args.getLength(); - ::System::Type * arCtsTypes[] = new ::System::Type*[numTypes]; - for (int i = 0; i < numTypes; i++) - arCtsTypes[i] = get_type(arXTypeArgs[i]); - ::System::Object * arArgs[] = {arCtsTypes}; - - Emit::CustomAttributeBuilder * attrBuilder = - new Emit::CustomAttributeBuilder( - __typeof(::uno::TypeArgumentsAttribute) - ->GetConstructor( arCtor), - arArgs); - - method_builder->SetCustomAttribute(attrBuilder); - } - } - - //define UNO exception attribute (exceptions)-------------------------------------- - Emit::CustomAttributeBuilder* attrBuilder = - get_iface_method_exception_attribute(xMethod); - if (attrBuilder != NULL) - method_builder->SetCustomAttribute(attrBuilder); - - // oneway attribute - if (xMethod->isOneway()) - { - ::System::Type * arCtorOneway[] = new ::System::Type*[0]; - ::System::Object * arArgs[] = new ::System::Object*[0]; - Emit::CustomAttributeBuilder * attrBuilder = - new Emit::CustomAttributeBuilder( - __typeof(::uno::OnewayAttribute)->GetConstructor( arCtorOneway), - arArgs); - method_builder->SetCustomAttribute(attrBuilder); - } - } - else // attribute - { - OSL_ASSERT( - TypeClass_INTERFACE_ATTRIBUTE == xMember->getTypeClass() ); - Reference< - reflection::XInterfaceAttributeTypeDescription2 > xAttribute( - xMember, UNO_QUERY_THROW ); - - const MethodAttributes c_property_method_attr = (MethodAttributes) - (c_method_attr | MethodAttributes::SpecialName); - - ::System::Type * attribute_type = get_type( xAttribute->getType() ); - ::System::Type * parameters [] = - new ::System::Type * [ 0 ]; - - Emit::PropertyBuilder * property_builder = - type_builder->DefineProperty( - ustring_to_String( xAttribute->getMemberName() ), - PropertyAttributes::None, - attribute_type, parameters ); - - //set BoundAttribute, if necessary - if (xAttribute->isBound()) - { - ConstructorInfo * ctorBoundAttr = - __typeof(::uno::BoundAttribute)->GetConstructor( - new System::Type*[0]); - Emit::CustomAttributeBuilder * attrBuilderBound = - new Emit::CustomAttributeBuilder( - ctorBoundAttr, new ::System::Object*[0]); - property_builder->SetCustomAttribute(attrBuilderBound); - } - - // getter - Emit::MethodBuilder * method_builder = - type_builder->DefineMethod( - ustring_to_String( OUSTR("get_") + - xAttribute->getMemberName() ), - c_property_method_attr, attribute_type, parameters ); - - //define UNO exception attribute (exceptions)-------------------------------------- - Emit::CustomAttributeBuilder* attrBuilder = - get_exception_attribute(xAttribute->getGetExceptions()); - if (attrBuilder != NULL) - method_builder->SetCustomAttribute(attrBuilder); - - property_builder->SetGetMethod( method_builder ); - - if (! xAttribute->isReadOnly()) - { - // setter - parameters = new ::System::Type * [ 1 ]; - parameters[ 0 ] = attribute_type; - method_builder = - type_builder->DefineMethod( - ustring_to_String( OUSTR("set_") + - xAttribute->getMemberName() ), - c_property_method_attr, 0, parameters ); - // define parameter info - method_builder->DefineParameter( - 1 /* starts with 1 */, ParameterAttributes::In, S"value" ); - //define UNO exception attribute (exceptions)-------------------------------------- - Emit::CustomAttributeBuilder* attrBuilder = - get_exception_attribute(xAttribute->getSetExceptions()); - if (attrBuilder != NULL) - method_builder->SetCustomAttribute(attrBuilder); - - property_builder->SetSetMethod( method_builder ); - } - } - } - - // remove from incomplete types map - ::System::String * cts_name = type_builder->get_FullName(); - m_incomplete_ifaces->Remove( cts_name ); - xType->release(); - - if (g_verbose) - { - ::System::Console::WriteLine( - "> emitting interface type {0}", cts_name ); - } - return type_builder->CreateType(); -} - -::System::Type * TypeEmitter::complete_struct_type( struct_entry * entry ) -{ - OSL_ASSERT(entry); - ::System::String * cts_name = entry->m_type_builder->get_FullName(); - - //Polymorphic struct, define uno.TypeParametersAttribute - //A polymorphic struct cannot have a basetype. - //When we create the template of the struct then we have no exact types - //and the name does not contain a parameter list - Sequence< OUString > seq_type_parameters; - Reference< reflection::XStructTypeDescription> xStructTypeDesc( - entry->m_xType, UNO_QUERY); - if (xStructTypeDesc.is()) - { - seq_type_parameters = xStructTypeDesc->getTypeParameters(); - int numTypes = 0; - if ((numTypes = seq_type_parameters.getLength()) > 0) - { - ::System::Object * aArg[] = new ::System::Object*[numTypes]; - for (int i = 0; i < numTypes; i++) - aArg[i] = ustring_to_String(seq_type_parameters.getConstArray()[i]); - ::System::Object * args[] = {aArg}; - - ::System::Type * arTypesCtor[] = - {::System::Type::GetType(S"System.String[]")}; - Emit::CustomAttributeBuilder * attrBuilder = - new Emit::CustomAttributeBuilder( - __typeof(::uno::TypeParametersAttribute)->GetConstructor(arTypesCtor), - args); - entry->m_type_builder->SetCustomAttribute(attrBuilder); - } - } - - // optional: lookup base type whether generated entry of this session - struct_entry * base_type_entry = 0; - if (0 != entry->m_base_type) - { - //ToDo maybe get from incomplete structs - base_type_entry = - dynamic_cast< struct_entry * >( - m_generated_structs->get_Item( - entry->m_base_type->get_FullName() ) ); - } - - // members - Sequence< Reference< reflection::XTypeDescription > > seq_members( - entry->m_xType->getMemberTypes() ); - Sequence< OUString > seq_member_names( entry->m_xType->getMemberNames() ); - sal_Int32 members_length = seq_members.getLength(); - OSL_ASSERT( seq_member_names.getLength() == members_length ); - //check if we have a XTypeDescription for every member. If not then the user may - //have forgotten to specify additional rdbs with the --extra option. - Reference< reflection::XTypeDescription > const * pseq_members = - seq_members.getConstArray(); - OUString const * pseq_member_names = - seq_member_names.getConstArray(); - for (int i = 0; i < members_length; i++) - { - const OUString sType(entry->m_xType->getName()); - const OUString sMemberName(pseq_member_names[i]); - if ( ! pseq_members[i].is()) - throw RuntimeException(OUSTR("Missing type description . Check if you need to " \ - "specify additional RDBs with the --extra option. Type missing for: ") + sType + - OUSTR("::") + sMemberName,0); - } - - sal_Int32 all_members_length = 0; - sal_Int32 member_pos; - sal_Int32 type_param_pos = 0; - - // collect base types; wrong order - ::System::Collections::ArrayList * base_types_list = - new ::System::Collections::ArrayList( 3 /* initial capacity */ ); - for (::System::Type * base_type_pos = entry->m_base_type; - ! base_type_pos->Equals( __typeof (::System::Object) ); - base_type_pos = base_type_pos->get_BaseType() ) - { - base_types_list->Add( base_type_pos ); - if (base_type_pos->Equals( __typeof (::System::Exception) )) - { - // special Message member - all_members_length += 1; - break; // don't include System.Exception base classes - } - else - { - //ensure the base type is complete. Otherwise GetFields won't work - get_complete_struct(base_type_pos->get_FullName()); - all_members_length += - base_type_pos->GetFields( - (BindingFlags) (BindingFlags::Instance | - BindingFlags::Public | - BindingFlags::DeclaredOnly) ) - ->get_Length(); - } - } - - // create all_members arrays; right order - ::System::String * all_member_names[] = - new ::System::String * [all_members_length + members_length ]; - ::System::Type * all_param_types[] = - new ::System::Type * [all_members_length + members_length ]; - member_pos = 0; - for ( sal_Int32 pos = base_types_list->get_Count(); pos--; ) - { - ::System::Type * base_type = __try_cast< ::System::Type * >( - base_types_list->get_Item( pos ) ); - if (base_type->Equals( __typeof (::System::Exception) )) - { - all_member_names[ member_pos ] = S"Message"; - all_param_types[ member_pos ] = __typeof (::System::String); - ++member_pos; - } - else - { - ::System::String * base_type_name = base_type->get_FullName(); - - //ToDo m_generated_structs? - struct_entry * entry = - dynamic_cast< struct_entry * >( - m_generated_structs->get_Item( base_type_name ) ); - if (0 == entry) - { - // complete type - FieldInfo * fields [] = - base_type->GetFields( - (BindingFlags) (BindingFlags::Instance | - BindingFlags::Public | - BindingFlags::DeclaredOnly) ); - sal_Int32 len = fields->get_Length(); - for ( sal_Int32 pos = 0; pos < len; ++pos ) - { - FieldInfo * field = fields[ pos ]; - all_member_names[ member_pos ] = field->get_Name(); - all_param_types[ member_pos ] = field->get_FieldType(); - ++member_pos; - } - } - else // generated during this session: - // members may be incomplete ifaces - { - sal_Int32 len = entry->m_member_names->get_Length(); - for ( sal_Int32 pos = 0; pos < len; ++pos ) - { - all_member_names[ member_pos ] = - entry->m_member_names[ pos ]; - all_param_types[ member_pos ] = - entry->m_param_types[ pos ]; - ++member_pos; - } - } - } - } - OSL_ASSERT( all_members_length == member_pos ); - - // build up entry -// struct_entry * entry = new struct_entry(); - entry->m_member_names = new ::System::String * [ members_length ]; - entry->m_param_types = new ::System::Type * [ members_length ]; - - // add members - Emit::FieldBuilder * members[] = new Emit::FieldBuilder * [ members_length ]; - //Reference< reflection::XTypeDescription > const * pseq_members = - // seq_members.getConstArray(); - //OUString const * pseq_member_names = - // seq_member_names.getConstArray(); - - int curParamIndex = 0; //count the fields which have parameterized types - for ( member_pos = 0; member_pos < members_length; ++member_pos ) - { - ::System::String * field_name = - ustring_to_String( pseq_member_names[ member_pos ] ); - ::System::Type * field_type; - //Special handling of struct parameter types - bool bParameterizedType = false; - if (pseq_members[ member_pos ]->getTypeClass() == TypeClass_UNKNOWN) - { - bParameterizedType = true; - if (type_param_pos < seq_type_parameters.getLength()) - { - field_type = __typeof(::System::Object); - type_param_pos++; - } - else - { - throw RuntimeException( - OUSTR("unexpected member type in ") + entry->m_xType->getName(), - Reference< XInterface >() ); - } - } - else - { - field_type = - get_type( pseq_members[ member_pos ] ); - } - members[ member_pos ] = - entry->m_type_builder->DefineField( - field_name, field_type, FieldAttributes::Public ); - - //parameterized type (polymorphic struct) ? - if (bParameterizedType && xStructTypeDesc.is()) - { - //get the name - OSL_ASSERT(seq_type_parameters.getLength() > curParamIndex); - ::System::String* sTypeName = ustring_to_String( - seq_type_parameters.getConstArray()[curParamIndex++]); - ::System::Object * args[] = {sTypeName}; - //set ParameterizedTypeAttribute - ::System::Type * arCtorTypes[] = {__typeof(::System::String)}; - - Emit::CustomAttributeBuilder * attrBuilder = - new Emit::CustomAttributeBuilder( - __typeof(::uno::ParameterizedTypeAttribute) - ->GetConstructor(arCtorTypes), - args); - - members[member_pos]->SetCustomAttribute(attrBuilder); - } - // add to all_members - all_member_names[ all_members_length + member_pos ] = field_name; - all_param_types[ all_members_length + member_pos ] = field_type; - // add to entry - entry->m_member_names[ member_pos ] = field_name; - entry->m_param_types[ member_pos ] = field_type; - } - all_members_length += members_length; - - // default .ctor - Emit::ConstructorBuilder * ctor_builder = - entry->m_type_builder->DefineConstructor( - c_ctor_method_attr, CallingConventions::Standard, - new ::System::Type * [ 0 ] ); - Emit::ILGenerator * code = ctor_builder->GetILGenerator(); - code->Emit( Emit::OpCodes::Ldarg_0 ); - code->Emit( - Emit::OpCodes::Call, - 0 == base_type_entry - ? entry->m_base_type->GetConstructor( new ::System::Type * [ 0 ] ) - : base_type_entry->m_default_ctor ); - // default initialize members - for ( member_pos = 0; member_pos < members_length; ++member_pos ) - { - FieldInfo * field = members[ member_pos ]; - ::System::Type * field_type = field->get_FieldType(); - // ::System::Type * new_field_type = m_module_builder->GetType(field_type->FullName, false); - // default initialize: - // string, type, enum, sequence, struct, exception, any - if (field_type->Equals( __typeof (::System::String) )) - { - code->Emit( Emit::OpCodes::Ldarg_0 ); - code->Emit( Emit::OpCodes::Ldstr, S"" ); - code->Emit( Emit::OpCodes::Stfld, field ); - } - else if (field_type->Equals( __typeof (::System::Type) )) - { - code->Emit( Emit::OpCodes::Ldarg_0 ); - code->Emit( - Emit::OpCodes::Ldtoken, __typeof (::System::Void) ); - code->Emit( - Emit::OpCodes::Call, m_method_info_Type_GetTypeFromHandle ); - code->Emit( Emit::OpCodes::Stfld, field ); - } - else if (field_type->get_IsArray()) - { - //Find the value type. In case of sequence<sequence< ... > > find the actual value type - ::System::Type * value = field_type; - while ((value = value->GetElementType())->get_IsArray()); - //If the value type is a struct then make sure it is fully created. - get_complete_struct(value->get_FullName()); - - code->Emit( Emit::OpCodes::Ldarg_0 ); - code->Emit( Emit::OpCodes::Ldc_I4_0 ); - code->Emit( - Emit::OpCodes::Newarr, field_type->GetElementType() ); - code->Emit( Emit::OpCodes::Stfld, field ); - } - else if (field_type->get_IsValueType()) - { - if (field_type->get_FullName()->Equals( S"uno.Any" )) - { - code->Emit( Emit::OpCodes::Ldarg_0 ); - code->Emit( Emit::OpCodes::Ldsfld, __typeof(::uno::Any)->GetField(S"VOID")); - code->Emit( Emit::OpCodes::Stfld, field ); - } - } - else if (field_type->get_IsClass()) - { - /* may be XInterface */ - if (! field_type->Equals( __typeof (::System::Object) )) - { - // struct, exception - //make sure the struct is already complete. - get_complete_struct(field_type->get_FullName()); - code->Emit( Emit::OpCodes::Ldarg_0 ); - code->Emit( - Emit::OpCodes::Newobj, - //GetConstructor requies that the member types of the object which is to be constructed are already known. - field_type->GetConstructor( - new ::System::Type * [ 0 ] ) ); - code->Emit( Emit::OpCodes::Stfld, field ); - } - } - } - code->Emit( Emit::OpCodes::Ret ); - entry->m_default_ctor = ctor_builder; - - // parameterized .ctor including all base members - ctor_builder = entry->m_type_builder->DefineConstructor( - c_ctor_method_attr, CallingConventions::Standard, all_param_types ); - for ( member_pos = 0; member_pos < all_members_length; ++member_pos ) - { - ctor_builder->DefineParameter( - member_pos +1 /* starts with 1 */, ParameterAttributes::In, - all_member_names[ member_pos ] ); - } - code = ctor_builder->GetILGenerator(); - // call base .ctor - code->Emit( Emit::OpCodes::Ldarg_0 ); // push this - sal_Int32 base_members_length = all_members_length - members_length; - ::System::Type * param_types [] = - new ::System::Type * [ base_members_length ]; - for ( member_pos = 0; member_pos < base_members_length; ++member_pos ) - { - emit_ldarg( code, member_pos +1 ); - param_types[ member_pos ] = all_param_types[ member_pos ]; - } - code->Emit( - Emit::OpCodes::Call, - 0 == base_type_entry - ? entry->m_base_type->GetConstructor( param_types ) - : base_type_entry->m_ctor ); - // initialize members - for ( member_pos = 0; member_pos < members_length; ++member_pos ) - { - code->Emit( Emit::OpCodes::Ldarg_0 ); // push this - emit_ldarg( code, member_pos + base_members_length +1 ); - code->Emit( Emit::OpCodes::Stfld, members[ member_pos ] ); - } - code->Emit( Emit::OpCodes::Ret ); - entry->m_ctor = ctor_builder; - - if (g_verbose) - { - ::System::Console::WriteLine( - "> emitting {0} type {1}", - TypeClass_STRUCT == entry->m_xType->getTypeClass() - ? S"struct" - : S"exception", - cts_name); - } - // new entry - m_generated_structs->Add(cts_name, entry ); - ::System::Type * ret_type = entry->m_type_builder->CreateType(); - - // remove from incomplete types map - m_incomplete_structs->Remove( cts_name ); - entry->m_xType->release(); - - if (g_verbose) - { - ::System::Console::WriteLine( - "> emitting struct type {0}", cts_name); - } - return ret_type; -} - -//Examples of generated code -// public static XWeak constructor1(XComponentContext ctx) -// { -// XMultiComponentFactory factory = ctx.getServiceManager(); -// if (factory == null) -// throw new com.sun.star.uno.DeploymentException("bla", null); -// return (XWeak) factory.createInstanceWithContext("service_specifier", ctx); -// } -// public static XWeak constructor2(XComponentContext ctx, int a, int b, Any c) -// { -// XMultiComponentFactory factory = ctx.getServiceManager(); -// if (factory == null) -// throw new com.sun.star.uno.DeploymentException("bla", null); -// Any[] arAny = new Any[3]; -// arAny[0] = new Any(typeof(int), a); -// arAny[1] = new Any(typeof(int), b); -// arAny[2] = new Any(c.Type, c.Value); -// return (XWeak) factory.createInstanceWithArgumentsAndContext("service_specifier", arAny, ctx); -// } -// Notice that a any parameter is NOT wrapped by another any. Instead the new any is created with the type and value -// of the parameter. - -// public static XWeak constructor3(XComponentContext ctx, params Any[] c) -// { -// XMultiComponentFactory factory = ctx.getServiceManager(); -// if (factory == null) -// throw new com.sun.star.uno.DeploymentException("bla", null); -// return (XWeak) factory.createInstanceWithArgumentsAndContext("service_specifier", c, ctx); -// } -::System::Type * TypeEmitter::complete_service_type(service_entry * entry) -{ - Emit::TypeBuilder * type_builder = entry->m_type_builder; - reflection::XServiceTypeDescription2 * xServiceType = entry->m_xType; - - //Create the private default constructor - Emit::ConstructorBuilder* ctor_builder = - type_builder->DefineConstructor( - (MethodAttributes) (MethodAttributes::Private | - MethodAttributes::HideBySig | - MethodAttributes::SpecialName | - MethodAttributes::RTSpecialName), - CallingConventions::Standard, NULL); - - Emit::ILGenerator* ilGen = ctor_builder->GetILGenerator(); - ilGen->Emit( Emit::OpCodes::Ldarg_0 ); // push this - ilGen->Emit( - Emit::OpCodes::Call, - type_builder->BaseType->GetConstructor(new ::System::Type*[0])); - ilGen->Emit( Emit::OpCodes::Ret ); - - - //Create the service constructors. - //obtain the interface which makes up this service, it is the return - //type of the constructor functions - Reference<reflection::XInterfaceTypeDescription2> xIfaceType( - xServiceType->getInterface(), UNO_QUERY); - if (xIfaceType.is () == sal_False) - xIfaceType = resolveInterfaceTypedef(xServiceType->getInterface()); - System::Type * retType = get_type(xIfaceType); - - //Create the ConstructorInfo for a DeploymentException - ::System::Type * typeDeploymentExc = - get_type(S"unoidl.com.sun.star.uno.DeploymentException", true); - - ::System::Type * arTypeCtor[] = {__typeof(::System::String), - __typeof(::System::Object)}; - ::System::Reflection::ConstructorInfo * ctorDeploymentException = - typeDeploymentExc->GetConstructor(arTypeCtor); - - Sequence<Reference<reflection::XServiceConstructorDescription> > seqCtors = - xServiceType->getConstructors(); - - ::System::Type * type_uno_exception = get_type(S"unoidl.com.sun.star.uno.Exception", true); - - for (int i = seqCtors.getLength() - 1; i >= 0; i--) - { - bool bParameterArray = false; - ::System::Type * typeAny = __typeof(::uno::Any); - const Reference<reflection::XServiceConstructorDescription> & ctorDes = - seqCtors[i]; - //obtain the parameter types - Sequence<Reference<reflection::XParameter> > seqParams = - ctorDes->getParameters(); - Reference<reflection::XParameter> const * arXParams = seqParams.getConstArray(); - sal_Int32 cParams = seqParams.getLength(); - ::System::Type * arTypeParameters[] = new ::System::Type* [cParams + 1]; - arTypeParameters[0] = get_type(S"unoidl.com.sun.star.uno.XComponentContext", true); - for (int iparam = 0; iparam != cParams; iparam++) - { - if (arXParams[iparam]->isRestParameter()) - arTypeParameters[iparam + 1] = __typeof(::uno::Any[]); - else - arTypeParameters[iparam + 1] = get_type(arXParams[iparam]->getType()); - } - //The array arTypeParameters can contain: - //System.Type and uno.PolymorphicType. - //Passing PolymorphicType to MethodBuilder.DefineMethod will cause a problem. - //The exception will read something like no on information for parameter # d - //Maybe we need no override another Type method in PolymorphicType ... - //Until we have figured this out, we will create another array of System.Type which - //we pass on to DefineMethod. - ::System::Type * arParamTypes[] = new ::System::Type * [cParams + 1]; -// arParamTypes[0] = get_type(S"unoidl.com.sun.star.uno.XComponentContext", true); - for (int i = 0; i < cParams + 1; i++) - { - ::uno::PolymorphicType * pT = dynamic_cast< ::uno::PolymorphicType * >(arTypeParameters[i]); - if (pT) - arParamTypes[i] = pT->OriginalType; - else - arParamTypes[i] = arTypeParameters[i]; - } - //define method - System::String * ctorName; - if (ctorDes->isDefaultConstructor()) - ctorName = new ::System::String(S"create"); - else - ctorName = ustring_to_String(ctorDes->getName()); - Emit::MethodBuilder* method_builder = type_builder->DefineMethod( - ctorName, - static_cast<MethodAttributes>(MethodAttributes::Public | MethodAttributes::HideBySig | - MethodAttributes::Static), - retType, -// arTypeParameters); - arParamTypes); - - //define UNO exception attribute (exceptions)-------------------------------------- - Emit::CustomAttributeBuilder* attrBuilder = get_service_exception_attribute(ctorDes); - if (attrBuilder != NULL) - method_builder->SetCustomAttribute(attrBuilder); - - //------------------------------------------------------------- - //define parameter attributes (paramarray), names etc. - //The first parameter is the XComponentContext, which cannot be obtained - //from reflection. - //The context is not part of the idl description - method_builder->DefineParameter( - 1, ParameterAttributes::In, S"the_context"); - - Emit::ParameterBuilder * arParameterBuilder[] = - new Emit::ParameterBuilder * [cParams]; - for (int iparam = 0; iparam != cParams; iparam++) - { - Reference<reflection::XParameter> const & aParam = arXParams[iparam]; - ::System::String * sParamName = ustring_to_String(aParam->getName()); - - arParameterBuilder[iparam] = method_builder->DefineParameter( - iparam + 2, ParameterAttributes::In, sParamName); - - if (aParam->isRestParameter()) - { - bParameterArray = true; - //set the ParameterArrayAttribute - ::System::Reflection::ConstructorInfo* ctor_info = - __typeof(System::ParamArrayAttribute)->GetConstructor( - new ::System::Type*[0]); - Emit::CustomAttributeBuilder * attr_builder = - new Emit::CustomAttributeBuilder(ctor_info, new ::System::Object*[0]); - arParameterBuilder[iparam]->SetCustomAttribute(attr_builder); - break; - } - } - - Emit::ILGenerator * ilGen = method_builder->GetILGenerator(); - - //Define locals --------------------------------- - //XMultiComponentFactory - Emit::LocalBuilder* local_factory = - ilGen->DeclareLocal( - get_type(S"unoidl.com.sun.star.lang.XMultiComponentFactory", true)); - - //The return type - Emit::LocalBuilder* local_return_val = - ilGen->DeclareLocal(retType); - - //Obtain the XMultiComponentFactory and throw an exception if we do not get one - ilGen->Emit(Emit::OpCodes::Ldarg_0); - - ::System::Reflection::MethodInfo * methodGetServiceManager = get_type( - S"unoidl.com.sun.star.uno.XComponentContext", true) - ->GetMethod(S"getServiceManager"); - ilGen->Emit(Emit::OpCodes::Callvirt, methodGetServiceManager); - ilGen->Emit(Emit::OpCodes::Stloc, local_factory); - ilGen->Emit(Emit::OpCodes::Ldloc, local_factory); - Emit::Label label1 = ilGen->DefineLabel(); - ilGen->Emit(Emit::OpCodes::Brtrue, label1); - //The string for the exception - ::System::Text::StringBuilder * strbuilder = new ::System::Text::StringBuilder(256); - strbuilder->Append(S"The service "); - strbuilder->Append(to_cts_name(xServiceType->getName())); - strbuilder->Append(S" could not be created. The context failed to supply the service manager."); - - ilGen->Emit(Emit::OpCodes::Ldstr, strbuilder->ToString()); - ilGen->Emit(Emit::OpCodes::Ldarg_0); - ilGen->Emit(Emit::OpCodes::Newobj, ctorDeploymentException); - ilGen->Emit(Emit::OpCodes::Throw); - ilGen->MarkLabel(label1); - - //We create a try/ catch around the createInstanceWithContext, etc. functions - //There are 3 cases - //1. function do not specify exceptions. Then RuntimeExceptions are retrhown and other - // exceptions produce a DeploymentException. - //2. function specify Exception. Then all exceptions fly through - //3. function specifies exceptions but no Exception. Then these are rethrown - // and other exceptions, except RuntimeException, produce a deployment exception. - //In case there are no parameters we call - //XMultiComponentFactory.createInstanceWithContext - - ::System::Collections::ArrayList * arExceptionTypes = - get_service_ctor_method_exceptions_reduced(ctorDes->getExceptions()); - if (arExceptionTypes->Contains( - type_uno_exception) == false) - { - ilGen->BeginExceptionBlock(); - } - if (cParams == 0) - { - ilGen->Emit(Emit::OpCodes::Ldloc, local_factory); - ilGen->Emit(Emit::OpCodes::Ldstr, ustring_to_String(xServiceType->getName())); - ilGen->Emit(Emit::OpCodes::Ldarg_0); - - ::System::Reflection::MethodInfo * methodCreate = - local_factory->get_LocalType()->GetMethod(S"createInstanceWithContext"); - ilGen->Emit(Emit::OpCodes::Callvirt, methodCreate); - } - else if(bParameterArray) - { - //Service constructor with parameter array - ilGen->Emit(Emit::OpCodes::Ldloc, local_factory); - ilGen->Emit(Emit::OpCodes::Ldstr, ustring_to_String(xServiceType->getName())); - ilGen->Emit(Emit::OpCodes::Ldarg_1); - ilGen->Emit(Emit::OpCodes::Ldarg_0); - ::System::Reflection::MethodInfo * methodCreate = - local_factory->get_LocalType()->GetMethod(S"createInstanceWithArgumentsAndContext"); - ilGen->Emit(Emit::OpCodes::Callvirt, methodCreate); - } - else - { - // Any param1, Any param2, etc. - // For each parameter,except the component context, and parameter array - // and Any is created. - Emit::LocalBuilder * arLocalAny[] = new Emit::LocalBuilder* [cParams]; - - for (int iParam = 0; iParam < cParams; iParam ++) - { - arLocalAny[iParam] = ilGen->DeclareLocal(typeAny); - } - - //Any[]. This array is filled with the created Anys which contain the parameters - //and the values contained in the parameter array - Emit::LocalBuilder * local_anyParams = - ilGen->DeclareLocal(__typeof(::uno::Any[])); - - //Create the Any for every argument, except for the parameter array - //arLocalAny contains the LocalBuilder for all these parameters. - //we call the ctor Any(Type, Object) - //If the parameter is an Any then the Any is created with Any(param.Type, param.Value); - ::System::Type * arTypesCtorAny[] = {__typeof(::System::Type), - __typeof(::System::Object)}; - ::System::Reflection::ConstructorInfo * ctorAny = - typeAny->GetConstructor( arTypesCtorAny); - ::System::Reflection::MethodInfo * methodAnyGetType = - typeAny->GetProperty(S"Type")->GetGetMethod(); - ::System::Reflection::MethodInfo * methodAnyGetValue = - typeAny->GetProperty(S"Value")->GetGetMethod(); - for (int i = 0; i < arLocalAny->Length; i ++) - { - //check if the parameter is a polymorphic struct - ::uno::PolymorphicType *polyType = dynamic_cast< ::uno::PolymorphicType* >(arTypeParameters[i+1]); - //arTypeParameters[i+1] = polyType->OriginalType; - if (polyType) - { - //It is a polymorphic struct - //Load the uninitialized local Any on which we will call the ctor - ilGen->Emit(Emit::OpCodes::Ldloca, arLocalAny[i]); - // Call PolymorphicType PolymorphicType::GetType(Type t, String polyName) - // Prepare the first parameter - ilGen->Emit(Emit::OpCodes::Ldtoken, polyType->get_OriginalType()); - ::System::Type * arTypeParams[] = {__typeof(::System::RuntimeTypeHandle)}; - ilGen->Emit(Emit::OpCodes::Call, - __typeof(::System::Type)->GetMethod( - S"GetTypeFromHandle", arTypeParams)); - // Prepare the second parameter - ilGen->Emit(Emit::OpCodes::Ldstr, polyType->get_PolymorphicName()); - // Make the actual call - ::System::Type * arTypeParam_GetType[] = { - __typeof(::System::Type), __typeof(::System::String) }; - ilGen->Emit(Emit::OpCodes::Call, - __typeof(::uno::PolymorphicType)->GetMethod(new System::String(S"GetType"), - arTypeParam_GetType)); - - //Stack is: localAny, PolymorphicType - //Call Any::Any(Type, Object) - //Prepare the second parameter for the any ctor - ilGen->Emit(Emit::OpCodes::Ldarg, i + 1); - // if the parameter is a value type then we need to box it, because - // the Any ctor takes an Object - if (arTypeParameters[i+1]->IsValueType) - ilGen->Emit(Emit::OpCodes::Box, arTypeParameters[i+1]); - ilGen->Emit(Emit::OpCodes::Call, ctorAny); - } - else if (arTypeParameters[i+1] == typeAny) - { - //Create the call new Any(param.Type,param,Value) - //Stack must be Any,Type,Value - //First load the Any which is to be constructed - ilGen->Emit(Emit::OpCodes::Ldloca, arLocalAny[i]); - //Load the Type, which is obtained by calling param.Type - ilGen->Emit(Emit::OpCodes::Ldarga, i + 1); - ilGen->Emit(Emit::OpCodes::Call, methodAnyGetType); - //Load the Value, which is obtained by calling param.Value - ilGen->Emit(Emit::OpCodes::Ldarga, i + 1); - ilGen->Emit(Emit::OpCodes::Call, methodAnyGetValue); - //Call the Any ctor. - ilGen->Emit(Emit::OpCodes::Call, ctorAny); - } - else - { - ilGen->Emit(Emit::OpCodes::Ldloca, arLocalAny[i]); - ilGen->Emit(Emit::OpCodes::Ldtoken, arTypeParameters[i+1]); - - ::System::Type * arTypeParams[] = {__typeof(::System::RuntimeTypeHandle)}; - ilGen->Emit(Emit::OpCodes::Call, - __typeof(::System::Type)->GetMethod( - S"GetTypeFromHandle", arTypeParams)); - ilGen->Emit(Emit::OpCodes::Ldarg, i + 1); - // if the parameter is a value type then we need to box it, because - // the Any ctor takes an Object - if (arTypeParameters[i+1]->IsValueType) - ilGen->Emit(Emit::OpCodes::Box, arTypeParameters[i+1]); - ilGen->Emit(Emit::OpCodes::Call, ctorAny); - } - } - - //Create the Any[] that is passed to the - //createInstanceWithContext[AndArguments] function - ilGen->Emit(Emit::OpCodes::Ldc_I4, arLocalAny->Length); - ilGen->Emit(Emit::OpCodes::Newarr, typeAny); - ilGen->Emit(Emit::OpCodes::Stloc, local_anyParams); - - //Assign all anys created from the parameters - //array to the Any[] - for (int i = 0; i < arLocalAny->Length; i++) - { - ilGen->Emit(Emit::OpCodes::Ldloc, local_anyParams); - ilGen->Emit(Emit::OpCodes::Ldc_I4, i); - ilGen->Emit(Emit::OpCodes::Ldelema, typeAny); - ilGen->Emit(Emit::OpCodes::Ldloc, arLocalAny[i]); - ilGen->Emit(Emit::OpCodes::Stobj, typeAny); - } - // call createInstanceWithContextAndArguments - ilGen->Emit(Emit::OpCodes::Ldloc, local_factory); - ilGen->Emit(Emit::OpCodes::Ldstr, ustring_to_String(xServiceType->getName())); - ilGen->Emit(Emit::OpCodes::Ldloc, local_anyParams); - ilGen->Emit(Emit::OpCodes::Ldarg_0); - ::System::Reflection::MethodInfo * methodCreate = - local_factory->get_LocalType()->GetMethod(S"createInstanceWithArgumentsAndContext"); - ilGen->Emit(Emit::OpCodes::Callvirt, methodCreate); - } - //cast the object returned by the functions createInstanceWithContext or - //createInstanceWithArgumentsAndContext to the interface type - ilGen->Emit(Emit::OpCodes::Castclass, retType); - ilGen->Emit(Emit::OpCodes::Stloc, local_return_val); - - //catch exceptions thrown by createInstanceWithArgumentsAndContext and createInstanceWithContext - if (arExceptionTypes->Contains(type_uno_exception) == false) - { - // catch (unoidl.com.sun.star.uno.RuntimeException) {throw;} - ilGen->BeginCatchBlock(get_type(S"unoidl.com.sun.star.uno.RuntimeException", true)); - ilGen->Emit(Emit::OpCodes::Pop); - ilGen->Emit(Emit::OpCodes::Rethrow); - - //catch and rethrow all other defined Exceptions - for (int i = 0; i < arExceptionTypes->Count; i++) - { - ::System::Type * excType = __try_cast< ::System::Type* >( - arExceptionTypes->get_Item(i)); - if (excType->IsInstanceOfType( - get_type(S"unoidl.com.sun.star.uno.RuntimeException", true))) - {// we have a catch for RuntimeException already defined - continue; - } - - //catch Exception and rethrow - ilGen->BeginCatchBlock(excType); - ilGen->Emit(Emit::OpCodes::Pop); - ilGen->Emit(Emit::OpCodes::Rethrow); - } - //catch (unoidl.com.sun.star.uno.Exception) {throw DeploymentException...} - ilGen->BeginCatchBlock(type_uno_exception); - - //Define the local variabe that keeps the exception - Emit::LocalBuilder * local_exception = ilGen->DeclareLocal( - type_uno_exception); - - //Store the exception - ilGen->Emit(Emit::OpCodes::Stloc, local_exception); - - //prepare the construction of the exception - strbuilder = new ::System::Text::StringBuilder(256); - strbuilder->Append(S"The context (com.sun.star.uno.XComponentContext) failed to supply the service "); - strbuilder->Append(to_cts_name(xServiceType->getName())); - strbuilder->Append(S": "); - - ilGen->Emit(Emit::OpCodes::Ldstr, strbuilder->ToString()); - - //add to the string the Exception.Message - ilGen->Emit(Emit::OpCodes::Ldloc, local_exception); - ilGen->Emit(Emit::OpCodes::Callvirt, - type_uno_exception->GetProperty(S"Message")->GetGetMethod()); - ::System::Type * arConcatParams [] = {__typeof(System::String), - __typeof(System::String)}; - ilGen->Emit(Emit::OpCodes::Call, - __typeof(System::String)->GetMethod(S"Concat", arConcatParams)); - //load contex argument - ilGen->Emit(Emit::OpCodes::Ldarg_0); - ilGen->Emit(Emit::OpCodes::Newobj, ctorDeploymentException); - ilGen->Emit(Emit::OpCodes::Throw);//Exception(typeDeploymentExc); - - ilGen->EndExceptionBlock(); - } - - - //Check if the service instance was create and throw a exception if not. - Emit::Label label_service_created = ilGen->DefineLabel(); - ilGen->Emit(Emit::OpCodes::Ldloc, local_return_val); - ilGen->Emit(Emit::OpCodes::Brtrue_S, label_service_created); - - strbuilder = new ::System::Text::StringBuilder(256); - strbuilder->Append(S"The context (com.sun.star.uno.XComponentContext) failed to supply the service "); - strbuilder->Append(to_cts_name(xServiceType->getName())); - strbuilder->Append(S"."); - ilGen->Emit(Emit::OpCodes::Ldstr, strbuilder->ToString()); - ilGen->Emit(Emit::OpCodes::Ldarg_0); - ilGen->Emit(Emit::OpCodes::Newobj, ctorDeploymentException); - ilGen->Emit(Emit::OpCodes::Throw);//Exception(typeDeploymentExc); - - ilGen->MarkLabel(label_service_created); - ilGen->Emit(Emit::OpCodes::Ldloc, local_return_val); - ilGen->Emit(Emit::OpCodes::Ret); - - } - // remove from incomplete types map - ::System::String * cts_name = type_builder->get_FullName(); - m_incomplete_services->Remove( cts_name ); - xServiceType->release(); - if (g_verbose) - { - ::System::Console::WriteLine( - "> emitting service type {0}", cts_name ); - } - return type_builder->CreateType(); -} - - -Emit::CustomAttributeBuilder* TypeEmitter::get_service_exception_attribute( - const Reference<reflection::XServiceConstructorDescription> & ctorDes ) -{ - return get_exception_attribute(ctorDes->getExceptions()); -} - -Emit::CustomAttributeBuilder* TypeEmitter::get_iface_method_exception_attribute( - const Reference< reflection::XInterfaceMethodTypeDescription >& xMethod ) -{ - - const Sequence<Reference<reflection::XTypeDescription> > seqTD = xMethod->getExceptions(); - int len = seqTD.getLength(); - Sequence<Reference<reflection::XCompoundTypeDescription> > seqCTD(len); - Reference<reflection::XCompoundTypeDescription> * arCTD = seqCTD.getArray(); - for (int i = 0; i < len; i++) - arCTD[i] = Reference<reflection::XCompoundTypeDescription>(seqTD[i], UNO_QUERY_THROW); - return get_exception_attribute(seqCTD); -} - -Emit::CustomAttributeBuilder* TypeEmitter::get_exception_attribute( - - const Sequence<Reference< reflection::XCompoundTypeDescription > >& seq_exceptionsTd ) -{ - Emit::CustomAttributeBuilder * attr_builder = NULL; - - Reference< reflection::XCompoundTypeDescription > const * exceptions = - seq_exceptionsTd.getConstArray(); - - ::System::Type * arTypesCtor[] = {::System::Type::GetType(S"System.Type[]")}; - ConstructorInfo * ctor_ExceptionAttribute = - __typeof(::uno::ExceptionAttribute)->GetConstructor(arTypesCtor); - - sal_Int32 exc_length = seq_exceptionsTd.getLength(); - if (exc_length != 0) // opt - { - ::System::Type * exception_types [] = - new ::System::Type * [ exc_length ]; - for ( sal_Int32 exc_pos = 0; exc_pos < exc_length; ++exc_pos ) - { - Reference< reflection::XCompoundTypeDescription > const & xExc = - exceptions[ exc_pos ]; - exception_types[ exc_pos ] = get_type( xExc ); - } - ::System::Object * args [] = {exception_types}; - attr_builder = new Emit::CustomAttributeBuilder( - ctor_ExceptionAttribute, args ); - } - return attr_builder; -} - - -::System::Type * TypeEmitter::complete_singleton_type(singleton_entry * entry) -{ - Emit::TypeBuilder * type_builder = entry->m_type_builder; - reflection::XSingletonTypeDescription2 * xSingletonType = entry->m_xType; - ::System::String* sSingletonName = to_cts_name(xSingletonType->getName()); - - //Create the private default constructor - Emit::ConstructorBuilder* ctor_builder = - type_builder->DefineConstructor( - static_cast<MethodAttributes>(MethodAttributes::Private | - MethodAttributes::HideBySig | - MethodAttributes::SpecialName | - MethodAttributes::RTSpecialName), - CallingConventions::Standard, NULL); - - Emit::ILGenerator* ilGen = ctor_builder->GetILGenerator(); - ilGen->Emit( Emit::OpCodes::Ldarg_0 ); // push this - ilGen->Emit( - Emit::OpCodes::Call, - type_builder->BaseType->GetConstructor(new ::System::Type*[0])); - ilGen->Emit( Emit::OpCodes::Ret ); - - - //obtain the interface which makes up this service, it is the return - //type of the constructor functions - Reference<reflection::XInterfaceTypeDescription2> xIfaceType( - xSingletonType->getInterface(), UNO_QUERY); - if (xIfaceType.is () == sal_False) - xIfaceType = resolveInterfaceTypedef(xSingletonType->getInterface()); - System::Type * retType = get_type(xIfaceType); - - //define method - ::System::Type * arTypeParameters[] = {get_type(S"unoidl.com.sun.star.uno.XComponentContext", true)}; - Emit::MethodBuilder* method_builder = type_builder->DefineMethod( - new System::String(S"get"), - static_cast<MethodAttributes>(MethodAttributes::Public | MethodAttributes::HideBySig | - MethodAttributes::Static), - retType, - arTypeParameters); - - -// method_builder->SetCustomAttribute(get_service_ctor_method_attribute(ctorDes)); - - //The first parameter is the XComponentContext, which cannot be obtained - //from reflection. - //The context is not part of the idl description - method_builder->DefineParameter(1, ParameterAttributes::In, S"the_context"); - - - ilGen = method_builder->GetILGenerator(); - //Define locals --------------------------------- - // Any, returned by XComponentContext.getValueByName - Emit::LocalBuilder* local_any = - ilGen->DeclareLocal(__typeof(::uno::Any)); - - //Call XContext::getValueByName - ilGen->Emit(Emit::OpCodes::Ldarg_0); - // build the singleton name : /singleton/unoidl.com.sun.star.XXX - ::System::Text::StringBuilder* sBuilder = - new ::System::Text::StringBuilder(S"/singletons/"); - sBuilder->Append(sSingletonName); - ilGen->Emit(Emit::OpCodes::Ldstr, sBuilder->ToString()); - - ::System::Reflection::MethodInfo * methodGetValueByName = - get_type(S"unoidl.com.sun.star.uno.XComponentContext", true)->GetMethod(S"getValueByName"); - ilGen->Emit(Emit::OpCodes::Callvirt, methodGetValueByName); - ilGen->Emit(Emit::OpCodes::Stloc_0); - - //Contains the returned Any a value? - ilGen->Emit(Emit::OpCodes::Ldloca_S, local_any); - ::System::Reflection::MethodInfo * methodHasValue = - __typeof(::uno::Any)->GetMethod(S"hasValue"); - ilGen->Emit(Emit::OpCodes::Call, methodHasValue); - - //If not, then throw an DeploymentException - Emit::Label label_singleton_exists = ilGen->DefineLabel(); - ilGen->Emit(Emit::OpCodes::Brtrue_S, label_singleton_exists); - sBuilder = new ::System::Text::StringBuilder( - S"Component context fails to supply singleton "); - sBuilder->Append(sSingletonName); - sBuilder->Append(S" of type "); - sBuilder->Append(retType->FullName); - sBuilder->Append(S"."); - ilGen->Emit(Emit::OpCodes::Ldstr, sBuilder->ToString()); - ilGen->Emit(Emit::OpCodes::Ldarg_0); - ::System::Type * arTypesCtorDeploymentException[] = { - __typeof(::System::String), __typeof(::System::Object)}; - ilGen->Emit(Emit::OpCodes::Newobj, - get_type(S"unoidl.com.sun.star.uno.DeploymentException",true) - ->GetConstructor(arTypesCtorDeploymentException)); - ilGen->Emit(Emit::OpCodes::Throw); - ilGen->MarkLabel(label_singleton_exists); - - //Cast the singleton contained in the Any to the expected interface and return it. - ilGen->Emit(Emit::OpCodes::Ldloca_S, local_any); - ilGen->Emit(Emit::OpCodes::Call, __typeof(::uno::Any)->GetProperty(S"Value")->GetGetMethod()); - ilGen->Emit(Emit::OpCodes::Castclass, retType); - ilGen->Emit(Emit::OpCodes::Ret); - - // remove from incomplete types map - ::System::String * cts_name = type_builder->get_FullName(); - m_incomplete_singletons->Remove( cts_name ); - xSingletonType->release(); - if (g_verbose) - { - ::System::Console::WriteLine( - "> emitting singleton type {0}", cts_name ); - } - return type_builder->CreateType(); -} - - -//______________________________________________________________________________ -::System::Type * TypeEmitter::get_type( - Reference< reflection::XTypeDescription > const & xType ) -{ - switch (xType->getTypeClass()) - { - case TypeClass_VOID: - return __typeof (::System::Void); - case TypeClass_CHAR: - return __typeof (::System::Char); - case TypeClass_BOOLEAN: - return __typeof (::System::Boolean); - case TypeClass_BYTE: - return __typeof (::System::Byte); - case TypeClass_SHORT: - return __typeof (::System::Int16); - case TypeClass_UNSIGNED_SHORT: - return __typeof (::System::UInt16); - case TypeClass_LONG: - return __typeof (::System::Int32); - case TypeClass_UNSIGNED_LONG: - return __typeof (::System::UInt32); - case TypeClass_HYPER: - return __typeof (::System::Int64); - case TypeClass_UNSIGNED_HYPER: - return __typeof (::System::UInt64); - case TypeClass_FLOAT: - return __typeof (::System::Single); - case TypeClass_DOUBLE: - return __typeof (::System::Double); - case TypeClass_STRING: - return __typeof (::System::String); - case TypeClass_TYPE: - return __typeof (::System::Type); - case TypeClass_ANY: - return __typeof(::uno::Any); - case TypeClass_ENUM: - return get_type( Reference< reflection::XEnumTypeDescription >( - xType, UNO_QUERY_THROW ) ); - case TypeClass_TYPEDEF: - // unwind typedefs - return get_type( - Reference< reflection::XIndirectTypeDescription >( - xType, UNO_QUERY_THROW )->getReferencedType() ); - case TypeClass_STRUCT: - case TypeClass_EXCEPTION: - return get_type( - Reference< reflection::XCompoundTypeDescription >( - xType, UNO_QUERY_THROW ) ); - case TypeClass_SEQUENCE: - { - ::System::Type * element_type = get_type( - Reference< reflection::XIndirectTypeDescription >( - xType, UNO_QUERY_THROW )->getReferencedType() ); - ::System::Type * retType = get_type( - ::System::String::Concat( - element_type->get_FullName(), S"[]" ), true ); - - ::uno::PolymorphicType * pt = dynamic_cast< ::uno::PolymorphicType * >(element_type); - if (pt) - { - ::System::String * sName = ::System::String::Concat(pt->PolymorphicName, S"[]"); - retType = ::uno::PolymorphicType::GetType(retType, sName); - } - return retType; - } - case TypeClass_INTERFACE: - return get_type( - Reference< reflection::XInterfaceTypeDescription2 >( - xType, UNO_QUERY_THROW ) ); - case TypeClass_CONSTANT: - return get_type( - Reference< reflection::XConstantTypeDescription >( - xType, UNO_QUERY_THROW ) ); - case TypeClass_CONSTANTS: - return get_type( - Reference< reflection::XConstantsTypeDescription >( - xType, UNO_QUERY_THROW ) ); - case TypeClass_SERVICE: - return get_type( - Reference< reflection::XServiceTypeDescription2 >( - xType, UNO_QUERY_THROW) ); - case TypeClass_SINGLETON: - return get_type( - Reference< reflection::XSingletonTypeDescription2 >( - xType, UNO_QUERY_THROW) ); - case TypeClass_MODULE: - // ignore these - return 0; - default: - throw RuntimeException( - OUSTR("unexpected type ") + xType->getName(), - Reference< XInterface >() ); - } -} - -//______________________________________________________________________________ -::System::Type * TypeEmitter::get_complete_struct( ::System::String * sName) -{ - struct_entry * pStruct = __try_cast< struct_entry *>( - m_incomplete_structs->get_Item(sName)); - if (pStruct) - { - complete_struct_type(pStruct); - } - //get_type will asked the module builder for the type or otherwise all known assemblies. - return get_type(sName, true); -} -void TypeEmitter::Dispose() -{ - while (true) - { - ::System::Collections::IDictionaryEnumerator * enumerator = - m_incomplete_ifaces->GetEnumerator(); - if (! enumerator->MoveNext()) - break; - complete_iface_type( - __try_cast< iface_entry * >( enumerator->get_Value() ) ); - } - - while (true) - { - ::System::Collections::IDictionaryEnumerator * enumerator = - m_incomplete_structs->GetEnumerator(); - if (! enumerator->MoveNext()) - break; - complete_struct_type( - __try_cast< struct_entry * >( enumerator->get_Value() ) ); - } - - - while (true) - { - ::System::Collections::IDictionaryEnumerator * enumerator = - m_incomplete_services->GetEnumerator(); - if (! enumerator->MoveNext()) - break; - complete_service_type( - __try_cast< service_entry * >( enumerator->get_Value() ) ); - } - - while (true) - { - ::System::Collections::IDictionaryEnumerator * enumerator = - m_incomplete_singletons->GetEnumerator(); - if (! enumerator->MoveNext()) - break; - complete_singleton_type( - __try_cast< singleton_entry * >( enumerator->get_Value() ) ); - } -} -//______________________________________________________________________________ -TypeEmitter::TypeEmitter( - ::System::Reflection::Emit::ModuleBuilder * module_builder, - ::System::Reflection::Assembly * extra_assemblies [] ) - : m_module_builder( module_builder ), - m_extra_assemblies( extra_assemblies ), - m_method_info_Type_GetTypeFromHandle( 0 ), - m_type_Exception( 0 ), - m_type_RuntimeException( 0 ), - m_incomplete_ifaces( new ::System::Collections::Hashtable() ), - m_incomplete_structs( new ::System::Collections::Hashtable() ), - m_incomplete_services(new ::System::Collections::Hashtable() ), - m_incomplete_singletons(new ::System::Collections::Hashtable() ), - m_generated_structs( new ::System::Collections::Hashtable() ) -{ - ::System::Type * param_types[] = new ::System::Type * [ 1 ]; - param_types[ 0 ] = __typeof (::System::RuntimeTypeHandle); - m_method_info_Type_GetTypeFromHandle = - __typeof (::System::Type) - ->GetMethod( "GetTypeFromHandle", param_types ); -} - -::System::Collections::ArrayList * TypeEmitter::get_service_ctor_method_exceptions_reduced( - const Sequence<Reference<reflection::XCompoundTypeDescription> > & seqExceptionsTd) -{ - if (seqExceptionsTd.getLength() == 0) - return new ::System::Collections::ArrayList(); - - ::System::Collections::ArrayList * arTypes = new ::System::Collections::ArrayList(); - for (int i = 0; i < seqExceptionsTd.getLength(); i++) - arTypes->Add(get_type(to_cts_name(seqExceptionsTd[i]->getName()), true)); - - int start = 0; - while (true) - { - bool bRemove = false; - for (int i = start; i < arTypes->Count; i++) - { - ::System::Type * t = __try_cast< ::System::Type* >(arTypes->get_Item(i)); - for (int j = 0; j < arTypes->Count; j++) - { - if (t->IsSubclassOf(__try_cast< ::System::Type* >(arTypes->get_Item(j)))) - { - arTypes->RemoveAt(i); - bRemove = true; - break; - } - } - if (bRemove) - break; - start++; - } - - if (bRemove == false) - break; - } - return arTypes; -} - - -css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > -resolveInterfaceTypedef( - const css::uno::Reference<css::reflection::XTypeDescription>& type) -{ - Reference<reflection::XInterfaceTypeDescription2> - xIfaceTd(type, UNO_QUERY); - - if (xIfaceTd.is()) - return xIfaceTd; - - Reference<reflection::XIndirectTypeDescription> xIndTd( - type, UNO_QUERY); - if (xIndTd.is() == sal_False) - throw css::uno::Exception( - OUSTR("resolveInterfaceTypedef was called with an invalid argument"), 0); - - return resolveInterfaceTypedef(xIndTd->getReferencedType()); -} - - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |