// // Returns null when the property is not valid C# property // public PropertySpec CreateProperty (PropertyInfo pi, TypeSpec declaringType, MethodSpec get, MethodSpec set) { Modifiers mod = 0; AParametersCollection param = null; TypeSpec type = null; if (get != null) { mod = get.Modifiers; param = get.Parameters; type = get.ReturnType; } bool is_valid_property = true; if (set != null) { if (set.ReturnType.Kind != MemberKind.Void) is_valid_property = false; var set_param_count = set.Parameters.Count - 1; if (set_param_count < 0) { set_param_count = 0; is_valid_property = false; } var set_type = set.Parameters.Types[set_param_count]; if (mod == 0) { AParametersCollection set_based_param; if (set_param_count == 0) { set_based_param = ParametersCompiled.EmptyReadOnlyParameters; } else { // // Create indexer parameters based on setter method parameters (the last parameter has to be removed) // var data = new IParameterData[set_param_count]; var types = new TypeSpec[set_param_count]; Array.Copy (set.Parameters.FixedParameters, data, set_param_count); Array.Copy (set.Parameters.Types, types, set_param_count); set_based_param = new ParametersImported (data, types, set.Parameters.HasParams); } mod = set.Modifiers; param = set_based_param; type = set_type; } else { if (set_param_count != get.Parameters.Count) is_valid_property = false; if (get.ReturnType != set_type) is_valid_property = false; // Possible custom accessor modifiers if ((mod & Modifiers.AccessibilityMask) != (set.Modifiers & Modifiers.AccessibilityMask)) { var get_acc = mod & Modifiers.AccessibilityMask; if (get_acc != Modifiers.PUBLIC) { var set_acc = set.Modifiers & Modifiers.AccessibilityMask; // If the accessor modifiers are not same, do extra restriction checks if (get_acc != set_acc) { var get_restr = ModifiersExtensions.IsRestrictedModifier (get_acc, set_acc); var set_restr = ModifiersExtensions.IsRestrictedModifier (set_acc, get_acc); if (get_restr && set_restr) { is_valid_property = false; // Neither is more restrictive } if (get_restr) { mod &= ~Modifiers.AccessibilityMask; mod |= set_acc; } } } } } } PropertySpec spec = null; if (!param.IsEmpty) { var index_name = declaringType.MemberDefinition.GetAttributeDefaultMember (); if (index_name == null) { is_valid_property = false; } else { if (get != null) { if (get.IsStatic) is_valid_property = false; if (get.Name.IndexOf (index_name, StringComparison.Ordinal) != 4) is_valid_property = false; } if (set != null) { if (set.IsStatic) is_valid_property = false; if (set.Name.IndexOf (index_name, StringComparison.Ordinal) != 4) is_valid_property = false; } } if (is_valid_property) spec = new IndexerSpec (declaringType, new ImportedParameterMemberDefinition (pi, type, param, this), type, param, pi, mod); } if (spec == null) spec = new PropertySpec (MemberKind.Property, declaringType, new ImportedMemberDefinition (pi, type, this), type, pi, mod); if (!is_valid_property) { spec.IsNotCSharpCompatible = true; return spec; } if (set != null) spec.Set = set; if (get != null) spec.Get = get; return spec; }
protected void DefineBuilders (MemberKind kind, ParametersCompiled parameters) { PropertyBuilder = Parent.TypeBuilder.DefineProperty ( GetFullName (MemberName), PropertyAttributes.None, #if !BOOTSTRAP_BASIC // Requires trunk version mscorlib IsStatic ? 0 : CallingConventions.HasThis, #endif MemberType.GetMetaInfo (), null, null, parameters.GetMetaInfo (), null, null); PropertySpec spec; if (kind == MemberKind.Indexer) spec = new IndexerSpec (Parent.Definition, this, MemberType, parameters, PropertyBuilder, ModFlags); else spec = new PropertySpec (kind, Parent.Definition, this, MemberType, PropertyBuilder, ModFlags); if (Get != null) { spec.Get = Get.Spec; var method = Get.Spec.GetMetaInfo () as MethodBuilder; if (method != null) { PropertyBuilder.SetGetMethod (method); Parent.MemberCache.AddMember (this, method.Name, Get.Spec); } } else { CheckMissingAccessor (kind, parameters, true); } if (Set != null) { spec.Set = Set.Spec; var method = Set.Spec.GetMetaInfo () as MethodBuilder; if (method != null) { PropertyBuilder.SetSetMethod (method); Parent.MemberCache.AddMember (this, method.Name, Set.Spec); } } else { CheckMissingAccessor (kind, parameters, false); } Parent.MemberCache.AddMember (this, PropertyBuilder.Name, spec); }
protected void DefineBuilders(MemberKind kind, ParametersCompiled parameters) { // FIXME - PropertyAttributes.HasDefault ? PropertyBuilder = Parent.TypeBuilder.DefineProperty ( GetFullName (MemberName), PropertyAttributes.None, MemberType.GetMetaInfo (), parameters.GetMetaInfo ()); PropertySpec spec; if (kind == MemberKind.Indexer) spec = new IndexerSpec (Parent.Definition, this, MemberType, parameters, PropertyBuilder, ModFlags); else spec = new PropertySpec (kind, Parent.Definition, this, MemberType, PropertyBuilder, ModFlags); spec.Get = Get.Spec; spec.Set = Set.Spec; if (!Get.IsDummy) { PropertyBuilder.SetGetMethod (GetBuilder); } if (!Set.IsDummy) { PropertyBuilder.SetSetMethod (SetBuilder); } Parent.MemberCache.AddMember (this, Get.IsDummy ? Get.Name : GetBuilder.Name, Get.Spec); Parent.MemberCache.AddMember (this, Set.IsDummy ? Set.Name : SetBuilder.Name, Set.Spec); Parent.MemberCache.AddMember (this, PropertyBuilder.Name, spec); }