X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fmembercache.cs;h=a01100c25f69ffe8098f03027742bdbcc7c19fe9;hb=76ce601441e821a12585ae269d29fa34c2143864;hp=9a8e61c52ad1271501cf94d03ce0e922b403a253;hpb=89505e0582de3fc98826a2415839d9172e101602;p=mono.git diff --git a/mcs/mcs/membercache.cs b/mcs/mcs/membercache.cs index 9a8e61c52ad..a01100c25f6 100644 --- a/mcs/mcs/membercache.cs +++ b/mcs/mcs/membercache.cs @@ -12,12 +12,7 @@ // using System; -using System.Text; using System.Collections.Generic; -using System.Globalization; -using System.Reflection.Emit; -using System.Reflection; -using System.Linq; namespace Mono.CSharp { @@ -43,11 +38,12 @@ namespace Mono.CSharp { ArrayType = 1 << 19, PointerType = 1 << 20, InternalCompilerType = 1 << 21, + MissingType = 1 << 22, + Void = 1 << 23, NestedMask = Class | Struct | Delegate | Enum | Interface, GenericMask = Method | Class | Struct | Delegate | Interface, - MaskType = Constructor | Event | Field | Method | Property | Indexer | Operator | Destructor | NestedMask, - All = MaskType + MaskType = Constructor | Event | Field | Method | Property | Indexer | Operator | Destructor | NestedMask } [Flags] @@ -55,23 +51,16 @@ namespace Mono.CSharp { { None = 0, - // Member has to be accessible - AccessibleOnly = 1, - // Inspect only queried type members DeclaredOnly = 1 << 1, // Exclude static InstanceOnly = 1 << 2, - // Ignore member overrides - NoOverrides = 1 << 3, - - NoAccessors = 1 << 4, - - StopOnFirstMatch = 1 << 5, + NoAccessors = 1 << 3, - DefaultMemberLookup = NoOverrides | StopOnFirstMatch + // Member has to be override + OverrideOnly = 1 << 4 } public struct MemberFilter : IEquatable @@ -80,9 +69,7 @@ namespace Mono.CSharp { public readonly MemberKind Kind; public readonly AParametersCollection Parameters; public readonly TypeSpec MemberType; - - int arity; // -1 to ignore the check - TypeSpec invocation_type; + public readonly int Arity; // -1 to ignore the check private MemberFilter (string name, MemberKind kind) { @@ -90,8 +77,7 @@ namespace Mono.CSharp { Kind = kind; Parameters = null; MemberType = null; - arity = -1; - invocation_type = null; + Arity = -1; } public MemberFilter (MethodSpec m) @@ -100,8 +86,7 @@ namespace Mono.CSharp { Kind = MemberKind.Method; Parameters = m.Parameters; MemberType = m.ReturnType; - arity = m.Arity; - invocation_type = null; + Arity = m.Arity; } public MemberFilter (string name, int arity, MemberKind kind, AParametersCollection param, TypeSpec type) @@ -110,22 +95,12 @@ namespace Mono.CSharp { Kind = kind; Parameters = param; MemberType = type; - this.arity = arity; - invocation_type = null; - } - - public TypeSpec InvocationType { - get { - return invocation_type; - } - set { - invocation_type = value; - } + this.Arity = arity; } public static MemberFilter Constructor (AParametersCollection param) { - return new MemberFilter (System.Reflection.ConstructorInfo.ConstructorName, 0, MemberKind.Constructor, param, null); + return new MemberFilter (Mono.CSharp.Constructor.ConstructorName, 0, MemberKind.Constructor, param, null); } public static MemberFilter Property (string name, TypeSpec type) @@ -153,7 +128,7 @@ namespace Mono.CSharp { return false; // Check arity when not disabled - if (arity >= 0 && arity != other.Arity) + if (Arity >= 0 && Arity != other.Arity) return false; if (Parameters != null) { @@ -176,18 +151,9 @@ namespace Mono.CSharp { } } - if (invocation_type != null && !IsAccessible (other)) - return false; - return true; } - bool IsAccessible (MemberSpec other) - { - bool extra; - return Expression.IsMemberAccessible (invocation_type, other, out extra); - } - #endregion } @@ -202,6 +168,7 @@ namespace Mono.CSharp { // public class MemberCache { + [Flags] enum StateFlags { HasConversionOperator = 1 << 1, @@ -211,7 +178,7 @@ namespace Mono.CSharp { readonly Dictionary> member_hash; Dictionary locase_members; IList missing_abstract; - StateFlags state; + StateFlags state; // TODO: Move to TypeSpec or ITypeDefinition public static readonly string IndexerNameAlias = ""; @@ -241,6 +208,40 @@ namespace Mono.CSharp { { } + // + // For cases where we need to union cache members + // + public void AddBaseType (TypeSpec baseType) + { + var cache = baseType.MemberCache; + + IList list; + foreach (var entry in cache.member_hash) { + if (!member_hash.TryGetValue (entry.Key, out list)) { + if (entry.Value.Count == 1) { + list = entry.Value; + } else { + list = new List (entry.Value); + } + + member_hash.Add (entry.Key, list); + continue; + } + + foreach (var ce in entry.Value) { + if (list.Contains (ce)) + continue; + + if (list is MemberSpec[]) { + list = new List () { list [0] }; + member_hash[entry.Key] = list; + } + + list.Add (ce); + } + } + } + // // Member-cache does not contain base members but it does // contain all base interface members, so the Lookup code @@ -264,9 +265,6 @@ namespace Mono.CSharp { } foreach (var ce in entry.Value) { - if (ce.DeclaringType != iface) - break; - if (list.Contains (ce)) continue; @@ -274,6 +272,12 @@ namespace Mono.CSharp { member_hash[entry.Key] = list; } } + + // Add also all base interfaces + if (iface.Interfaces != null) { + foreach (var base_iface in iface.Interfaces) + AddInterface (base_iface); + } } public void AddMember (InterfaceMemberBase imb, string exlicitName, MemberSpec ms) @@ -281,7 +285,7 @@ namespace Mono.CSharp { // Explicit names cannot be looked-up but can be used for // collision checking (no name mangling needed) if (imb.IsExplicitImpl) - AddMember (exlicitName, ms); + AddMember (exlicitName, ms, false); else AddMember (ms); } @@ -291,23 +295,31 @@ namespace Mono.CSharp { // public void AddMember (MemberSpec ms) { - AddMember (GetLookupName (ms), ms); + AddMember (GetLookupName (ms), ms, false); } - void AddMember (string name, MemberSpec member) + void AddMember (string name, MemberSpec member, bool removeHiddenMembers) { if (member.Kind == MemberKind.Operator) { var dt = member.DeclaringType; - if (dt == TypeManager.string_type || dt == TypeManager.delegate_type || dt == TypeManager.multicast_delegate_type) { + switch (dt.BuiltinType) { + case BuiltinTypeSpec.Type.String: + case BuiltinTypeSpec.Type.Delegate: + case BuiltinTypeSpec.Type.MulticastDelegate: // Some core types have user operators but they cannot be used as normal // user operators as they are predefined and therefore having different // rules (e.g. binary operators) by not setting the flag we hide them for // user conversions // TODO: Should I do this for all core types ? - } else if (name == Operator.GetMetadataName (Operator.OpType.Implicit) || name == Operator.GetMetadataName (Operator.OpType.Explicit)) { - state |= StateFlags.HasConversionOperator; - } else { - state |= StateFlags.HasUserOperator; + break; + default: + if (name == Operator.GetMetadataName (Operator.OpType.Implicit) || name == Operator.GetMetadataName (Operator.OpType.Explicit)) { + state |= StateFlags.HasConversionOperator; + } else { + state |= StateFlags.HasUserOperator; + } + + break; } } @@ -317,11 +329,11 @@ namespace Mono.CSharp { return; } - if (member.DeclaringType.IsInterface) { + if (removeHiddenMembers && member.DeclaringType.IsInterface) { if (AddInterfaceMember (member, ref list)) member_hash[name] = list; } else { - if (list is MemberSpec[]) { + if (list.Count == 1) { list = new List () { list[0] }; member_hash[name] = list; } @@ -330,6 +342,11 @@ namespace Mono.CSharp { } } + public void AddMemberImported (MemberSpec ms) + { + AddMember (GetLookupName (ms), ms, true); + } + // // Ignores any base interface member which can be hidden // by this interface @@ -356,8 +373,8 @@ namespace Mono.CSharp { continue; } - if (member.DeclaringType.ImplementsInterface (entry.DeclaringType)) { - if (existing is MemberSpec[]) { + if (member.DeclaringType.ImplementsInterface (entry.DeclaringType, false)) { + if (existing.Count == 1) { existing = new MemberSpec[] { member }; return true; } @@ -367,11 +384,11 @@ namespace Mono.CSharp { } if ((entry.DeclaringType == member.DeclaringType && entry.IsAccessor == member.IsAccessor) || - entry.DeclaringType.ImplementsInterface (member.DeclaringType)) + entry.DeclaringType.ImplementsInterface (member.DeclaringType, false)) return false; } - if (existing is MemberSpec[]) { + if (existing.Count == 1) { existing = new List () { existing[0], member }; return true; } @@ -380,13 +397,6 @@ namespace Mono.CSharp { return false; } - public static IEnumerable FindIndexers (TypeSpec container, BindingRestriction restrictions) - { - var filter = new MemberFilter (IndexerNameAlias, 0, MemberKind.Indexer, null, null); - var found = FindMembers (container, filter, restrictions); - return found == null ? null : found.Cast (); - } - public static MemberSpec FindMember (TypeSpec container, MemberFilter filter, BindingRestriction restrictions) { do { @@ -402,6 +412,9 @@ namespace Mono.CSharp { if ((restrictions & BindingRestriction.NoAccessors) != 0 && entry.IsAccessor) continue; + if ((restrictions & BindingRestriction.OverrideOnly) != 0 && (entry.Modifiers & Modifiers.OVERRIDE) == 0) + continue; + if (!filter.Equals (entry)) continue; @@ -409,10 +422,6 @@ namespace Mono.CSharp { continue; return entry; - - // TODO MemberCache: - //if ((restrictions & BindingRestriction.AccessibleOnly) != 0) - // throw new NotImplementedException ("net"); } } @@ -426,91 +435,21 @@ namespace Mono.CSharp { } // - // Returns the first set of members starting from - // container, the returned list must not be modified + // A special method to work with member lookup only. It returns a list of all members named @name + // starting from @container. It's very performance sensitive // - public static IList FindMembers (TypeSpec container, MemberFilter filter, BindingRestriction restrictions) + public static IList FindMembers (TypeSpec container, string name, bool declaredOnly) { IList applicable; - List found = null; - int match_counter = 0; do { - int i; - if (container.MemberCache.member_hash.TryGetValue (filter.Name, out applicable)) { - for (i = 0; i < applicable.Count; ++i) { - var entry = applicable [i]; - - // Is the member of the correct type - if ((entry.Kind & filter.Kind & MemberKind.MaskType) == 0) - continue; - - // - // When using overloadable overrides filter ignore members which - // are not base members. Including properties because overrides can - // implement get or set only and we are looking for complete base member - // - const MemberKind overloadable = MemberKind.Indexer | MemberKind.Method | MemberKind.Property; - if ((restrictions & BindingRestriction.NoOverrides) != 0 && (entry.Kind & overloadable) != 0) { - if ((entry.Modifiers & Modifiers.OVERRIDE) != 0) - continue; - } - - if ((restrictions & BindingRestriction.InstanceOnly) != 0 && entry.IsStatic) - continue; - - // Apply the filter to it. - if (!filter.Equals (entry)) - continue; - - // Try not to allocate a new list until it's necessary - if (found == null) { - if (i == match_counter) { - ++match_counter; - continue; - } - - found = new List (System.Math.Max (4, match_counter + 1)); - for (int ii = 0; ii < match_counter; ++ii) - found.Add (applicable [ii]); - } - - found.Add (entry); - } - - // Deal with allocation-less optimization - if ((restrictions & (BindingRestriction.DeclaredOnly | BindingRestriction.StopOnFirstMatch)) != 0) { - if (found != null) - return found; - - if (i == match_counter) - return applicable; - - if (match_counter > 0) { - found = new List (match_counter); - for (int ii = 0; ii < match_counter; ++ii) - found.Add (applicable[ii]); - - return found; - } - - if ((restrictions & BindingRestriction.DeclaredOnly) != 0) - return null; - } else if (found == null) { - if (i == match_counter) { - found = new List (applicable); - } else if (match_counter > 0) { - found = new List (System.Math.Max (4, match_counter)); - for (int ii = 0; ii < match_counter; ++ii) - found.Add (applicable[ii]); - } - } - } + if (container.MemberCache.member_hash.TryGetValue (name, out applicable) || declaredOnly) + return applicable; container = container.BaseType; } while (container != null); - return found; + return null; } // @@ -559,7 +498,7 @@ namespace Mono.CSharp { // // Looks for extension methods with defined name and extension type // - public List FindExtensionMethods (TypeSpec invocationType, TypeSpec extensionType, string name, int arity) + public List FindExtensionMethods (IMemberContext invocationContext, TypeSpec extensionType, string name, int arity) { IList entries; if (!member_hash.TryGetValue (name, out entries)) @@ -567,20 +506,20 @@ namespace Mono.CSharp { List candidates = null; foreach (var entry in entries) { - if (entry.Kind != MemberKind.Method || (arity >= 0 && entry.Arity != arity)) + if (entry.Kind != MemberKind.Method || (arity > 0 && entry.Arity != arity)) continue; var ms = (MethodSpec) entry; if (!ms.IsExtensionMethod) continue; - bool extra; - if (!Expression.IsMemberAccessible (invocationType, ms, out extra)) + if (!ms.IsAccessible (invocationContext)) continue; - // TODO: CodeGen.Assembly.Builder - if ((ms.DeclaringType.Modifiers & Modifiers.INTERNAL) != 0 && - !TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, ms.Assembly)) + // + // Extension methods cannot be nested hence checking parent is enough + // + if ((ms.DeclaringType.Modifiers & Modifiers.INTERNAL) != 0 && !ms.DeclaringType.MemberDefinition.IsInternalAsPublic (invocationContext.Module.DeclaringAssembly)) continue; if (candidates == null) @@ -595,20 +534,27 @@ namespace Mono.CSharp { // Returns base members of @member member if no exact match is found @bestCandidate returns // the best match // - public static MemberSpec FindBaseMember (MemberCore member, out MemberSpec bestCandidate) + public static MemberSpec FindBaseMember (MemberCore member, out MemberSpec bestCandidate, ref bool overrides) { bestCandidate = null; var container = member.Parent.PartialContainer.Definition; - if (!container.IsInterface) + if (!container.IsInterface) { container = container.BaseType; + // It can happen for a user definition of System.Object + if (container == null) + return null; + } + string name = GetLookupName (member); - IList applicable; var member_param = member is IParametersMember ? ((IParametersMember) member).Parameters : null; var mkind = GetMemberCoreKind (member); bool member_with_accessors = mkind == MemberKind.Indexer || mkind == MemberKind.Property; + IList applicable; + MemberSpec ambig_candidate = null; + do { if (container.MemberCache.member_hash.TryGetValue (name, out applicable)) { for (int i = 0; i < applicable.Count; ++i) { @@ -617,60 +563,76 @@ namespace Mono.CSharp { if ((entry.Modifiers & Modifiers.PRIVATE) != 0) continue; + if ((entry.Modifiers & Modifiers.AccessibilityMask) == Modifiers.INTERNAL && + !entry.DeclaringType.MemberDefinition.IsInternalAsPublic (member.Module.DeclaringAssembly)) + continue; + // - // Skip override members with accessors they may not fully implement the base member + // Isn't the member of same kind ? // - if (member_with_accessors && (entry.Modifiers & (Modifiers.OVERRIDE | Modifiers.SEALED)) == Modifiers.OVERRIDE) - continue; + if ((entry.Kind & ~MemberKind.Destructor & mkind & MemberKind.MaskType) == 0) { + // Destructors are ignored as they cannot be overridden by user + if ((entry.Kind & MemberKind.Destructor) != 0) + continue; - if ((entry.Modifiers & Modifiers.AccessibilityMask) == Modifiers.INTERNAL) { - if (!TypeManager.IsThisOrFriendAssembly (member.Assembly, entry.Assembly)) + // A method with different arity does not hide base member + if (mkind != MemberKind.Method && member.MemberName.Arity != entry.Arity) continue; + + bestCandidate = entry; + return null; } // - // Is the member of the correct type ? - // Destructors are ignored as they cannot be overridden by user - if ((entry.Kind & ~MemberKind.Destructor & mkind & MemberKind.MaskType) == 0) { - if ((entry.Kind & MemberKind.Destructor) == 0 && (member_param == null || !(entry is IParametersMember))) { - bestCandidate = entry; - return null; - } - + // Same kind of different arity is valid + // + if (member.MemberName.Arity != entry.Arity) { continue; } - if (member_param == null) - return entry; - - // Check arity match - int arity = member.MemberName.Arity; - if (arity != entry.Arity) - continue; - - if (entry is IParametersMember) { + if ((entry.Kind & mkind & (MemberKind.Method | MemberKind.Indexer)) != 0) { if (entry.IsAccessor != member is AbstractPropertyEventMethod) continue; - var entry_param = ((IParametersMember) entry).Parameters; - if (TypeSpecComparer.Override.IsEqual (entry_param, member_param)) - return entry; + var pm = entry as IParametersMember; + if (!TypeSpecComparer.Override.IsEqual (pm.Parameters, member_param)) + continue; + } + // + // Skip override for member with accessors. It may not fully implement the base member + // but keep flag we found an implementation in case the base member is abstract + // + if (member_with_accessors && ((entry.Modifiers & (Modifiers.OVERRIDE | Modifiers.SEALED)) == Modifiers.OVERRIDE)) { + // + // Set candidate to override implementation to flag we found an implementation + // + overrides = true; continue; } - if (bestCandidate == null) - bestCandidate = entry; + // + // For members with parameters we can encounter an ambiguous candidates (they match exactly) + // because generic type parameters could be inflated into same types + // + if (ambig_candidate == null && (entry.Kind & mkind & (MemberKind.Method | MemberKind.Indexer)) != 0) { + bestCandidate = null; + ambig_candidate = entry; + continue; + } + + bestCandidate = ambig_candidate; + return entry; } } - if (container.IsInterface) + if (container.IsInterface || ambig_candidate != null) break; container = container.BaseType; } while (container != null); - return null; + return ambig_candidate; } // @@ -714,11 +676,15 @@ namespace Mono.CSharp { return MemberKind.Interface; if (member is EventProperty) return MemberKind.Event; + if (member is Delegate) + return MemberKind.Delegate; + if (member is Enum) + return MemberKind.Enum; throw new NotImplementedException (member.GetType ().ToString ()); } - public static IList GetCompletitionMembers (TypeSpec container, string name) + public static IList GetCompletitionMembers (IMemberContext ctx, TypeSpec container, string name) { var matches = new List (); foreach (var entry in container.MemberCache.member_hash) { @@ -729,8 +695,7 @@ namespace Mono.CSharp { if ((name_entry.Kind & (MemberKind.Constructor | MemberKind.Destructor | MemberKind.Operator)) != 0) continue; - bool extra; - if (!Expression.IsMemberAccessible (InternalType.FakeInternalType, name_entry, out extra)) + if (!name_entry.IsAccessible (ctx)) continue; if (name == null || name_entry.Name.StartsWith (name)) { @@ -745,7 +710,7 @@ namespace Mono.CSharp { // // Returns members of @iface only, base members are ignored // - public static IList GetInterfaceMethods (TypeSpec iface) + public static List GetInterfaceMethods (TypeSpec iface) { // // MemberCache flatten interfaces, therefore in cases like this one @@ -871,9 +836,9 @@ namespace Mono.CSharp { if (ms.Kind == MemberKind.Constructor) { if (ms.IsStatic) - return ConstructorInfo.TypeConstructorName; + return Constructor.TypeConstructorName; - return ConstructorInfo.ConstructorName; + return Constructor.ConstructorName; } return ms.Name; @@ -885,7 +850,7 @@ namespace Mono.CSharp { return IndexerNameAlias; if (mc is Constructor) - return ConstructorInfo.ConstructorName; + return Constructor.ConstructorName; return mc.MemberName.Name; } @@ -905,29 +870,37 @@ namespace Mono.CSharp { (mc.state & StateFlags.HasUserOperator) != 0) { if (mc.member_hash.TryGetValue (Operator.GetMetadataName (op), out applicable)) { - int match_count = 0; - for (int i = 0; i < applicable.Count; ++i) { - if (applicable[i].Kind == MemberKind.Operator) { - ++match_count; - continue; + int i; + for (i = 0; i < applicable.Count; ++i) { + if (applicable[i].Kind != MemberKind.Operator) { + break; } + } - // Handles very rare case where a method exists with same name as operator (op_xxxx) - if (found == null) { - found = new List (); - found.Add (applicable [i]); - } else { - var prev = found as List; - if (prev == null) { - prev = new List (found.Count + 1); - prev.AddRange (found); + // + // Handles very rare case where a method with same name as operator (op_xxxx) exists + // and we have to resize the applicable list + // + if (i != applicable.Count) { + for (i = 0; i < applicable.Count; ++i) { + if (applicable[i].Kind != MemberKind.Operator) { + continue; } - prev.Add (applicable[i]); - } - } + if (found == null) { + found = new List (); + found.Add (applicable[i]); + } else { + var prev = found as List; + if (prev == null) { + prev = new List (found.Count + 1); + prev.AddRange (found); + } - if (match_count > 0 && match_count == applicable.Count) { + prev.Add (applicable[i]); + } + } + } else { if (found == null) { found = applicable; } else { @@ -987,9 +960,12 @@ namespace Mono.CSharp { public void InflateMembers (MemberCache cacheToInflate, TypeSpec inflatedType, TypeParameterInflator inflator) { var inflated_member_hash = cacheToInflate.member_hash; - Dictionary accessor_relation = null; + Dictionary accessor_relation = null; List accessor_members = null; + // Copy member specific flags when all members were added + cacheToInflate.state = state; + foreach (var item in member_hash) { var members = item.Value; IList inflated_members = null; @@ -1020,10 +996,10 @@ namespace Mono.CSharp { if (member.DeclaringType != inflatedType) { // - // Don't inflate non generic interface members + // Don't inflate top-level non-generic interface members // merged into generic interface // - if (!member.DeclaringType.IsGeneric) { + if (!member.DeclaringType.IsGeneric && !member.DeclaringType.IsNested) { inflated_members [i] = member; continue; } @@ -1060,8 +1036,8 @@ namespace Mono.CSharp { if (member.IsAccessor) { if (accessor_relation == null) - accessor_relation = new Dictionary (); - accessor_relation.Add ((MethodSpec) member, (MethodSpec) inflated); + accessor_relation = new Dictionary (); + accessor_relation.Add (member, (MethodSpec) inflated); } } } @@ -1085,6 +1061,53 @@ namespace Mono.CSharp { } } + // + // Removes hidden base members of an interface. For compiled interfaces we cannot + // do name filtering during Add (as we do for import) because we need all base + // names to be valid during type definition. + // Add replaces hidden base member with current one which means any name collision + // (CS0108) of non-first name would be unnoticed because the name was replaced + // with the one from compiled type + // + public void RemoveHiddenMembers (TypeSpec container) + { + foreach (var entry in member_hash) { + var values = entry.Value; + + int container_members_start_at = 0; + while (values[container_members_start_at].DeclaringType != container && ++container_members_start_at < entry.Value.Count); + + if (container_members_start_at == 0 || container_members_start_at == values.Count) + continue; + + for (int i = 0; i < container_members_start_at; ++i) { + var member = values[i]; + + if (!container.ImplementsInterface (member.DeclaringType, false)) + continue; + + var member_param = member is IParametersMember ? ((IParametersMember) member).Parameters : ParametersCompiled.EmptyReadOnlyParameters; + + for (int ii = container_members_start_at; ii < values.Count; ++ii) { + var container_entry = values[ii]; + + if (container_entry.Arity != member.Arity) + continue; + + if (container_entry is IParametersMember) { + if (!TypeSpecComparer.Override.IsEqual (((IParametersMember) container_entry).Parameters, member_param)) + continue; + } + + values.RemoveAt (i); + --container_members_start_at; + --ii; + --i; + } + } + } + } + // // Checks all appropriate container members for CLS compliance // @@ -1113,7 +1136,7 @@ namespace Mono.CSharp { if ((name_entry.Kind & MemberKind.MaskType) == 0) continue; - if (name_entry.MemberDefinition.IsNotCLSCompliant ()) + if (name_entry.MemberDefinition.CLSAttributeValue == false) continue; IParametersMember p_a = name_entry as IParametersMember;