summaryrefslogtreecommitdiff
path: root/cli_ure
diff options
context:
space:
mode:
authorJens-Heiner Rechtien <hr@openoffice.org>2007-07-03 08:36:22 +0000
committerJens-Heiner Rechtien <hr@openoffice.org>2007-07-03 08:36:22 +0000
commitd95d72ac2849d9534a1ae7b1386f8a3c2cd49f7e (patch)
tree0764c32b77103c0adc9b402c32825249a7e86a7e /cli_ure
parent37caac0a4bd84ae378847be3c6810985cde79263 (diff)
#i79029#: fix for issue i79029
Diffstat (limited to 'cli_ure')
-rw-r--r--cli_ure/source/climaker/climaker_emit.cxx784
-rw-r--r--cli_ure/source/climaker/climaker_share.h24
2 files changed, 450 insertions, 358 deletions
diff --git a/cli_ure/source/climaker/climaker_emit.cxx b/cli_ure/source/climaker/climaker_emit.cxx
index 1832243cbd49..a3630d17aa65 100644
--- a/cli_ure/source/climaker/climaker_emit.cxx
+++ b/cli_ure/source/climaker/climaker_emit.cxx
@@ -4,9 +4,9 @@
*
* $RCSfile: climaker_emit.cxx,v $
*
- * $Revision: 1.16 $
+ * $Revision: 1.17 $
*
- * last change: $Author: vg $ $Date: 2006-09-25 13:04:37 $
+ * last change: $Author: hr $ $Date: 2007-07-03 09:36:22 $
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
@@ -345,13 +345,15 @@ Assembly * TypeEmitter::type_resolve(
::System::String * cts_name, bool throw_exc )
{
::System::Type * ret_type = m_module_builder->GetType( cts_name, false );
- 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;
- }
+ //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)
{
@@ -690,357 +692,39 @@ Assembly * TypeEmitter::type_resolve(
TypeAttributes::AnsiClass),
base_type );
- //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(
- 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);
- type_builder->SetCustomAttribute(attrBuilder);
- }
- }
-
- // optional: lookup base type whether generated entry of this session
- struct_entry * base_type_entry = 0;
- if (0 != base_type)
- {
- base_type_entry =
- dynamic_cast< struct_entry * >(
- m_generated_structs->get_Item(
- base_type->get_FullName() ) );
- }
-
- // members
- Sequence< Reference< reflection::XTypeDescription > > seq_members(
- xType->getMemberTypes() );
- Sequence< OUString > seq_member_names( 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++)
- {
- OUString sType = xType->getName();
- 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 = 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
- {
- 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();
- 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
+ // insert to be completed
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 ") + xType->getName(),
- Reference< XInterface >() );
- }
- }
- else
- {
- field_type =
- get_type( pseq_members[ member_pos ] );
- }
- members[ member_pos ] =
- 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 =
- 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
- ? 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();
- // 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())
- {
- 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
- code->Emit( Emit::OpCodes::Ldarg_0 );
- code->Emit(
- Emit::OpCodes::Newobj,
- 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 = 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
- ? 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;
+ 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 );
- if (g_verbose)
- {
- ::System::Console::WriteLine(
- "> emitting {0} type {1}",
- TypeClass_STRUCT == xType->getTypeClass()
- ? S"struct"
- : S"exception",
- cts_name );
- }
- // new entry
- m_generated_structs->Add( cts_name, entry );
- ret_type = type_builder->CreateType();
+ // 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.
- Reference< reflection::XStructTypeDescription> xStructTypeDesc(
- xType, UNO_QUERY);
- if (xStructTypeDesc.is())
+ //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))
{
- Sequence< Reference< reflection::XTypeDescription > > seqTypeArgs = xStructTypeDesc->getTypeArguments();
- sal_Int32 numTypes = seqTypeArgs.getLength();
- if (numTypes > 0)
+ Reference< reflection::XStructTypeDescription> xStructTypeDesc(
+ xType, UNO_QUERY);
+
+ if (xStructTypeDesc.is())
{
- //it is an instantiated polymorphic struct
- ::System::String * sCliName = mapUnoTypeName(ustring_to_String(xType->getName()));
- ret_type = ::uno::PolymorphicType::GetType(ret_type, sCliName);
+ 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;
}
@@ -1228,12 +912,12 @@ Assembly * TypeEmitter::type_resolve(
MethodAttributes::Abstract |
MethodAttributes::Virtual |
MethodAttributes::NewSlot |
- MethodAttributes::HideBySig |
-#if defined(_MSC_VER) && (_MSC_VER < 1400)
- MethodAttributes::Instance);
-#else
- Instance);
-#endif
+ MethodAttributes::HideBySig);
+//#if defined(_MSC_VER) && (_MSC_VER < 1400)
+// MethodAttributes::Instance);
+//#else
+// Instance);
+//#endif
if (TypeClass_INTERFACE_METHOD == xMember->getTypeClass())
{
@@ -1430,6 +1114,371 @@ Assembly * TypeEmitter::type_resolve(
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)
@@ -2145,6 +2194,17 @@ Emit::CustomAttributeBuilder* TypeEmitter::get_exception_attribute(
}
//______________________________________________________________________________
+::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)
@@ -2160,6 +2220,17 @@ void TypeEmitter::Dispose()
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;
@@ -2187,6 +2258,7 @@ TypeEmitter::TypeEmitter(
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() )
diff --git a/cli_ure/source/climaker/climaker_share.h b/cli_ure/source/climaker/climaker_share.h
index 69c2be7b681a..a41c0dd14ec4 100644
--- a/cli_ure/source/climaker/climaker_share.h
+++ b/cli_ure/source/climaker/climaker_share.h
@@ -4,9 +4,9 @@
*
* $RCSfile: climaker_share.h,v $
*
- * $Revision: 1.8 $
+ * $Revision: 1.9 $
*
- * last change: $Author: rt $ $Date: 2006-03-09 10:52:23 $
+ * last change: $Author: hr $ $Date: 2007-07-03 09:36:15 $
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
@@ -180,11 +180,27 @@ __gc class TypeEmitter : public ::System::IDisposable
__gc class struct_entry
{
public:
+ css::reflection::XCompoundTypeDescription * m_xType;
+ ::System::Reflection::Emit::TypeBuilder * m_type_builder;
+ ::System::Type * m_base_type;
+
::System::String * m_member_names __gc [];
::System::Type * m_param_types __gc [];
::System::Reflection::ConstructorInfo * m_default_ctor;
::System::Reflection::ConstructorInfo * m_ctor;
};
+ ::System::Collections::Hashtable * m_incomplete_structs;
+ ::System::Type * complete_struct_type( struct_entry * entry );
+
+ /* returns the type for the name. If it is a struct then it may
+ complete the struct if not already done. This also refers to its
+ base types.
+
+ @param sName
+ the full name of the type.
+ @return the type object for sName. Not necessarily a struct.
+ */
+ ::System::Type * get_complete_struct( ::System::String * sName);
__gc class service_entry
{
@@ -220,6 +236,10 @@ __gc class TypeEmitter : public ::System::IDisposable
::System::Type * get_type(
css::uno::Reference<
css::reflection::XEnumTypeDescription > const & xType );
+ /* returns the type for a struct or exception. In case of a polymorphic struct it may
+ return a ::uno::PolymorphicType (cli_basetypes.dll) only if the struct is already
+ complete.
+ */
::System::Type * get_type(
css::uno::Reference<
css::reflection::XCompoundTypeDescription > const & xType );