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; }
CustomAttributeBuilder get_iface_method_exception_attribute( XInterfaceMethodTypeDescription xMethod) { XTypeDescription[] TDs = xMethod.getExceptions(); XCompoundTypeDescription[] CTDs = new XCompoundTypeDescription[TDs.Length]; for (int i = 0; i < TDs.Length; ++i) CTDs[i] = (XCompoundTypeDescription) TDs[i]; return get_exception_attribute(CTDs); }
/* Creates .System.Type object for UNO exceptions. The UNO exceptions are obtained by com.sun.star.reflection.XServiceConstructorDescription.getExceptions In a first step the respective CLI types are created. Then it is examined if a Type represents a super class of another class. If so the Type of the derived class is discarded. For example there are a uno RuntimeException and a DeploymentException which inherits RuntimeException. Then only the cli Type of the RuntimeException is returned. The purpose of this function is to provide exceptions for which catch blocks are generated in the service constructor code. The result is always an instance of ArrayList, even if the sequence argument does not contain any elements. */ ArrayList get_service_ctor_method_exceptions_reduced( XCompoundTypeDescription[] exceptionsTd) { if (exceptionsTd.Length == 0) return new ArrayList(); ArrayList types = new ArrayList(); foreach (XCompoundTypeDescription xCompTd in exceptionsTd) { types.Add(get_type(to_cts_name(xCompTd.getName()), true)); } int start = 0; while (true) { bool bRemove = false; for (int i = start; i < types.Count; ++i) { Type t = (Type) types[i]; for (int j = 0; j < types.Count; ++j) { if (t.IsSubclassOf((Type) types[j])) { // FIXME Wow, we're using an ArrayList and calling // RemoveAt all the time? types.RemoveAt(i); bRemove = true; break; } } if (bRemove) break; start++; } if (bRemove == false) break; } return types; }
CustomAttributeBuilder get_exception_attribute( XCompoundTypeDescription[] exceptionsTd) { CustomAttributeBuilder attr_builder = null; Type[] typesCtor = new Type[] { Type.GetType("System.Type[]") }; ConstructorInfo ctor_ExceptionAttribute = typeof(uno.ExceptionAttribute).GetConstructor(typesCtor); if (exceptionsTd.Length != 0) // opt { Type[] exception_types = new Type[exceptionsTd.Length]; for (int exc_pos = 0; exc_pos < exceptionsTd.Length; ++exc_pos) { XCompoundTypeDescription xExc = exceptionsTd[exc_pos]; exception_types[exc_pos] = get_type(xExc); } object[] args = new object[] { exception_types }; attr_builder = new CustomAttributeBuilder( ctor_ExceptionAttribute, args); } return attr_builder; }