Type get_type(XCompoundTypeDescription xType) { string uno_name = xType.getName(); if (xType.getTypeClass() == TypeClass.EXCEPTION) { switch (uno_name) { case "com.sun.star.uno.Exception": return get_type_Exception(); case "com.sun.star.uno.RuntimeException": return get_type_RuntimeException(); default: break; } } string cts_name = to_cts_name(uno_name); // if the struct is an instantiated polymorphic struct then we create // the simple struct name // // For example: // void func ([in] PolyStruct<boolean> arg9, // PolyStruct<boolean> will be converted to PolyStruct polymorphicStructNameToStructName(ref cts_name); Type ret_type = get_type(cts_name, false /* no exc */); if (ret_type == null) { XCompoundTypeDescription xBaseType = xType.getBaseType() as XCompoundTypeDescription; Type base_type = (xBaseType != null ? get_type(xBaseType) : typeof(Object)); TypeBuilder type_builder = m_module_builder.DefineType( cts_name, (TypeAttributes.Public | TypeAttributes.BeforeFieldInit | TypeAttributes.AnsiClass), base_type); // Polymorphic struct, define uno.TypeParametersAttribute string[] type_parameters = null; XStructTypeDescription xStructTypeDesc = xType as XStructTypeDescription; if (xStructTypeDesc != null) { type_parameters = xStructTypeDesc.getTypeParameters(); if (type_parameters.Length != 0) { Type[] typesCtor = new Type[] { Type.GetType("System.String[]") }; CustomAttributeBuilder attrBuilder = new CustomAttributeBuilder( typeof(uno.TypeParametersAttribute) .GetConstructor(typesCtor), type_parameters); type_builder.SetCustomAttribute(attrBuilder); } } // FIXME huh? what does this mean: // optional: lookup base type whether generated entry of this session struct_entry base_type_entry = null; if (base_type != null) { base_type_entry = m_generated_structs[base_type.FullName] as struct_entry; } // members XTypeDescription[] seq_members = xType.getMemberTypes(); string[] member_names = xType.getMemberNames(); Trace.Assert(seq_members.Length == member_names.Length); int all_members_length = 0; int member_pos; int type_param_pos = 0; // collect base type; wrong order ArrayList base_types_list = new ArrayList(3 /* initial capacity */); for (Type base_type_pos = base_type_pos = base_type; ! base_type_pos.Equals(typeof(System.Object)); base_type_pos = base_type_pos.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.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly).Length; } } // create all_members_arrays; right order string[] all_member_names = new string[all_members_length + seq_members.Length]; Type[] all_param_types = new Type[all_members_length + seq_members.Length]; member_pos =0; for (int pos = base_types_list.Count; pos-- != 0; ) { Type ancestor = (Type) base_types_list[pos]; if (ancestor.Equals(typeof(System.Exception))) { all_member_names[member_pos] = "Message"; all_param_types[member_pos] = typeof (System.String); ++member_pos; } else { struct_entry existing_entry = m_generated_structs[ancestor.FullName] as struct_entry; if (existing_entry == null) { // complete type FieldInfo[] fields = ancestor.GetFields( BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly); foreach (FieldInfo field in fields) { all_member_names[member_pos] = field.Name; all_param_types[member_pos] = field.FieldType; ++member_pos; } } else // generated during this session: // members may be incomplete ifaces { for (int i = 0; i < existing_entry.m_member_names.Length; ++i) { all_member_names[member_pos] = existing_entry.m_member_names[i]; all_param_types[member_pos] = existing_entry.m_param_types[i]; ++member_pos; } } } } Trace.Assert(all_members_length == member_pos); // build up entry struct_entry entry = new struct_entry(); entry.m_member_names = new string[seq_members.Length]; entry.m_param_types = new Type[seq_members.Length]; // add members FieldBuilder[] members = new FieldBuilder[seq_members.Length]; int curParamIndex = 0; // count the fields which have // parameterized types for (member_pos = 0; member_pos < seq_members.Length; ++member_pos) { string field_name = member_names[member_pos]; Type field_type; // Special handling of struct parameter types bool bParameterizedType = false; if (seq_members[member_pos].getTypeClass() == TypeClass.UNKNOWN) { bParameterizedType = true; if (type_param_pos < type_parameters.Length) { field_type = typeof(System.Object); type_param_pos++; } else { throw new System.Exception("unexpected member type in " + xType.getName()); } } else { field_type = get_type(seq_members[member_pos]); } members[member_pos] = type_builder.DefineField( field_name, field_type, FieldAttributes.Public); // parameterized type (polymorphic struct) ? if (bParameterizedType && xStructTypeDesc != null) { // get the name Trace.Assert(type_parameters.Length > curParamIndex); string sTypeName = type_parameters[curParamIndex++]; object[] args = new object[] { sTypeName }; // set ParameterizedTypeAttribute Type[] ctorTypes = new Type[] { typeof(System.String) }; CustomAttributeBuilder attrBuilder = new CustomAttributeBuilder( typeof(uno.ParameterizedTypeAttribute) .GetConstructor(ctorTypes), 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 ConstructorBuilder ctor_builder = type_builder.DefineConstructor( c_ctor_method_attr, CallingConventions.Standard, new Type[0]); ILGenerator code = ctor_builder.GetILGenerator(); code.Emit(OpCodes.Ldarg_0); code.Emit(OpCodes.Call, base_type_entry == null ? base_type.GetConstructor(new Type[0]) : base_type_entry.m_default_ctor); // default initialize members for (member_pos = 0; member_pos < seq_members.Length; ++member_pos) { FieldInfo field = members[member_pos]; Type field_type = field.FieldType; // default initialize: // string, type, enum, sequence, struct, exception, any if (field_type.Equals(typeof(System.String))) { code.Emit(OpCodes.Ldarg_0); code.Emit(OpCodes.Ldstr, ""); code.Emit(OpCodes.Stfld, field); } else if (field_type.Equals(typeof(System.Type))) { code.Emit(OpCodes.Ldarg_0); code.Emit(OpCodes.Ldtoken, typeof(void)); code.Emit(OpCodes.Call, m_method_info_Type_GetTypeFromHandle); code.Emit(OpCodes.Stfld, field); } else if (field_type.IsArray) { code.Emit(OpCodes.Ldarg_0); code.Emit(OpCodes.Ldc_I4_0); code.Emit(OpCodes.Newarr, field_type.GetElementType()); code.Emit(OpCodes.Stfld, field); } else if (field_type.IsValueType) { if (field_type.FullName.Equals("uno.Any")) { code.Emit(OpCodes.Ldarg_0); code.Emit(OpCodes.Ldsfld, typeof(uno.Any).GetField("VOID")); code.Emit(OpCodes.Stfld, field); } } else if (field_type.IsClass) { /* may be XInterface */ if (! field_type.Equals(typeof(System.Object))) { // struct, exception code.Emit(OpCodes.Ldarg_0); code.Emit(OpCodes.Newobj, field_type.GetConstructor(new Type[0])); code.Emit(OpCodes.Stfld, field); } } } code.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(OpCodes.Ldarg_0); // push this int base_members_length = all_members_length - seq_members.Length; Type[] param_types = new 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(OpCodes.Call, base_type_entry == null ? base_type.GetConstructor(param_types) : base_type_entry.m_ctor); // initialize members for (member_pos = 0; member_pos < seq_members.Length; ++member_pos) { code.Emit(OpCodes.Ldarg_0); // push this emit_ldarg(code, member_pos + base_members_length + 1); code.Emit(OpCodes.Stfld, members[member_pos]); } code.Emit(OpCodes.Ret); entry.m_ctor = ctor_builder; if (Climaker.g_verbose) { Console.WriteLine("> emitting {0} type {1}", xType.getTypeClass() == TypeClass.STRUCT ? "struct" : "exception", cts_name); } // new entry m_generated_structs.Add(cts_name, entry); ret_type = type_builder.CreateType(); } return ret_type; }