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;
}