Mono.CSharp.MetadataImporter.CreateProperty C# (CSharp) Method

CreateProperty() public method

public CreateProperty ( PropertyInfo pi, System.TypeSpec declaringType, MethodSpec get, MethodSpec set ) : PropertySpec
pi PropertyInfo
declaringType System.TypeSpec
get MethodSpec
set MethodSpec
return PropertySpec
        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 != TypeManager.void_type)
                    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.IsNotRealProperty = true;
                return spec;
            }

            if (set != null)
                spec.Set = set;
            if (get != null)
                spec.Get = get;

            return spec;
        }