From f800c21074b8732952a1f0bdcdcd502bf15f4e9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Srbeck=C3=BD?= Date: Sat, 24 Oct 2009 12:53:54 +0000 Subject: [PATCH] Using BindingFlags from System.Reflection git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5101 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Src/TreeModel/ChildNodesOfObject.cs | 46 ++- .../Graph/ObjectGraph/ObjectGraphBuilder.cs | 6 +- .../ValueProviders/GridValuesProvider.cs | 8 +- .../Src/Visualizers/Utils/DebuggerHelpers.cs | 17 +- .../Project/Debugger.Core.csproj | 1 - .../Src/Expressions/ExpressionEvaluator.cs | 15 +- .../Project/Src/Metadata/BindingFlags.cs | 41 --- .../Project/Src/Metadata/DebugType-Helpers.cs | 320 +----------------- .../Project/Src/Metadata/DebugType.cs | 161 ++++++++- .../Project/Src/Metadata/PropertyInfo.cs | 14 + 10 files changed, 207 insertions(+), 422 deletions(-) delete mode 100644 src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/BindingFlags.cs diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/ChildNodesOfObject.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/ChildNodesOfObject.cs index bc261ec708..10811ae0cc 100644 --- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/ChildNodesOfObject.cs +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/ChildNodesOfObject.cs @@ -4,14 +4,15 @@ // $Revision$ // -using ICSharpCode.SharpDevelop.Services; using System.Collections; using System.Collections.Generic; +using Debugger.AddIn.Visualizers.Utils; using Debugger.MetaData; using ICSharpCode.Core; using ICSharpCode.NRefactory.Ast; using ICSharpCode.SharpDevelop; -using Debugger.AddIn.Visualizers.Utils; +using ICSharpCode.SharpDevelop.Services; +using System.Reflection; namespace Debugger.AddIn.TreeModel { @@ -19,42 +20,41 @@ namespace Debugger.AddIn.TreeModel { public static IEnumerable LazyGetChildNodesOfObject(Expression targetObject, DebugType shownType) { - BindingFlags publicStaticFlags = BindingFlags.Public | BindingFlags.Static | BindingFlags.Field | BindingFlags.GetProperty; - BindingFlags publicInstanceFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Field | BindingFlags.GetProperty; - BindingFlags nonPublicStaticFlags = BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Field | BindingFlags.GetProperty; - BindingFlags nonPublicInstanceFlags = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Field | BindingFlags.GetProperty; + MemberInfo[] publicStatic = shownType.GetFieldsAndNonIndexedProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly); + MemberInfo[] publicInstance = shownType.GetFieldsAndNonIndexedProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); + MemberInfo[] nonPublicStatic = shownType.GetFieldsAndNonIndexedProperties(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.DeclaredOnly); + MemberInfo[] nonPublicInstance = shownType.GetFieldsAndNonIndexedProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); DebugType baseType = shownType.BaseType; if (baseType != null) { yield return new TreeNode( DebuggerResourceService.GetImage("Icons.16x16.Class"), StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.BaseClass}"), - //string.Empty, baseType.Name, baseType.FullName, baseType.FullName == "System.Object" ? null : Utils.LazyGetChildNodesOfObject(targetObject, baseType) ); } - if (shownType.HasMembers(nonPublicInstanceFlags)) { + if (nonPublicInstance.Length > 0) { yield return new TreeNode( null, StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.NonPublicMembers}"), string.Empty, string.Empty, - Utils.LazyGetMembersOfObject(targetObject, shownType, nonPublicInstanceFlags) + Utils.LazyGetMembersOfObject(targetObject, shownType, nonPublicInstance) ); } - if (shownType.HasMembers(publicStaticFlags) || shownType.HasMembers(nonPublicStaticFlags)) { - IEnumerable childs = Utils.LazyGetMembersOfObject(targetObject, shownType, publicStaticFlags); - if (shownType.HasMembers(nonPublicStaticFlags)) { + if (publicStatic.Length > 0 || nonPublicStatic.Length > 0) { + IEnumerable childs = Utils.LazyGetMembersOfObject(targetObject, shownType, publicStatic); + if (nonPublicStatic.Length > 0) { TreeNode nonPublicStaticNode = new TreeNode( null, StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.NonPublicStaticMembers}"), string.Empty, string.Empty, - Utils.LazyGetMembersOfObject(targetObject, shownType, nonPublicStaticFlags) + Utils.LazyGetMembersOfObject(targetObject, shownType, nonPublicStatic) ); childs = Utils.PrependNode(nonPublicStaticNode, childs); } @@ -78,24 +78,20 @@ namespace Debugger.AddIn.TreeModel } } - foreach(TreeNode node in LazyGetMembersOfObject(targetObject, shownType, publicInstanceFlags)) { + foreach(TreeNode node in LazyGetMembersOfObject(targetObject, shownType, publicInstance)) { yield return node; } } - public static IEnumerable LazyGetMembersOfObject(Expression expression, DebugType type, BindingFlags bindingFlags) + public static IEnumerable LazyGetMembersOfObject(Expression expression, MemberInfo[] members) { - List members = new List(); - - foreach(FieldInfo field in type.GetFields(bindingFlags)) { - members.Add(new ExpressionNode(ExpressionNode.GetImageForMember(field), field.Name, expression.AppendMemberReference(field))); - } - foreach(PropertyInfo property in type.GetProperties(bindingFlags)) { - members.Add(new ExpressionNode(ExpressionNode.GetImageForMember(property), property.Name, expression.AppendMemberReference(property))); + List nodes = new List(); + foreach(MemberInfo memberInfo in members) { + members.Add(new ExpressionNode(ExpressionNode.GetImageForMember(memberInfo), memberInfo.Name, expression.AppendMemberReference(memberInfo))); + } - - members.Sort(); - return members; + nodes.Sort(); + return nodes; } diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs index a03856906e..aaac80c588 100644 --- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs @@ -60,10 +60,10 @@ namespace Debugger.AddIn.Visualizers.Graph /// Binding flags for getting member expressions. /// private readonly Debugger.MetaData.BindingFlags memberBindingFlags = - BindingFlags.Public | BindingFlags.Instance | BindingFlags.Field | BindingFlags.GetProperty; + BindingFlags.Public | BindingFlags.Instance; private readonly Debugger.MetaData.BindingFlags nonPublicInstanceMemberFlags = - BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Field | BindingFlags.GetProperty; + BindingFlags.NonPublic | BindingFlags.Instance; /// /// Creates ObjectGraphBuilder. @@ -225,7 +225,7 @@ namespace Debugger.AddIn.Visualizers.Graph { List propertyList = new List(); - foreach (MemberInfo memberProp in shownType.GetFieldsAndProperties(flags)) + foreach (MemberInfo memberProp in shownType.GetFieldsAndNonIndexedProperties(flags)) { // skip backing fields if (memberProp.Name.Contains("<")) diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/GridVisualizer/ValueProviders/GridValuesProvider.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/GridVisualizer/ValueProviders/GridValuesProvider.cs index ce14913e88..85b7dc5a3c 100644 --- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/GridVisualizer/ValueProviders/GridValuesProvider.cs +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/GridVisualizer/ValueProviders/GridValuesProvider.cs @@ -6,9 +6,10 @@ // using System; using System.Collections.Generic; +using Debugger.AddIn.Visualizers.Utils; using Debugger.MetaData; using ICSharpCode.NRefactory.Ast; -using Debugger.AddIn.Visualizers.Utils; +using System.Reflection; namespace Debugger.AddIn.Visualizers.GridVisualizer { @@ -18,9 +19,6 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer /// public class GridValuesProvider { - protected readonly BindingFlags memberBindingFlags = - BindingFlags.Public | BindingFlags.Instance | BindingFlags.Field | BindingFlags.GetProperty; - /// Used to quickly find MemberInfo by member name - DebugType.GetMember(name) uses a loop to search members protected Dictionary memberFromNameMap; @@ -42,7 +40,7 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer /// public IList GetItemTypeMembers() { - return itemType.GetMembers(this.memberBindingFlags); + return itemType.GetFieldsAndNonIndexedProperties(BindingFlags.Public | BindingFlags.Instance); } } } diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Utils/DebuggerHelpers.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Utils/DebuggerHelpers.cs index 4d2df45f0c..029f84164c 100644 --- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Utils/DebuggerHelpers.cs +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Utils/DebuggerHelpers.cs @@ -5,12 +5,13 @@ // $Revision$ // using System; +using System.Collections.Generic; using Debugger; using Debugger.MetaData; using Debugger.Wrappers.CorDebug; -using ICSharpCode.SharpDevelop.Services; -using System.Collections.Generic; using ICSharpCode.NRefactory.Ast; +using ICSharpCode.SharpDevelop.Services; +using System.Reflection; namespace Debugger.AddIn.Visualizers.Utils { @@ -66,16 +67,6 @@ namespace Debugger.AddIn.Visualizers.Utils return expr.Evaluate(WindowsDebugger.CurrentProcess).GetObjectAddress(); } - public static IEnumerable GetFieldsAndProperties(this DebugType type, BindingFlags bindingFlags) - { - foreach(FieldInfo field in type.GetFields(bindingFlags)) { - yield return field; - } - foreach(PropertyInfo property in type.GetProperties(bindingFlags)) { - yield return property; - } - } - /// /// System.Runtime.CompilerServices.GetHashCode method, for obtaining non-overriden hash codes from debuggee. /// @@ -91,7 +82,7 @@ namespace Debugger.AddIn.Visualizers.Utils if (DebuggerHelpers.hashCodeMethod == null || DebuggerHelpers.hashCodeMethod.Process.HasExited) { DebugType typeRuntimeHelpers = DebugType.CreateFromType(value.AppDomain, typeof(System.Runtime.CompilerServices.RuntimeHelpers)); - DebuggerHelpers.hashCodeMethod = typeRuntimeHelpers.GetMember("GetHashCode", BindingFlags.Public | BindingFlags.Static | BindingFlags.Method | BindingFlags.IncludeSuperType) as MethodInfo; + DebuggerHelpers.hashCodeMethod = typeRuntimeHelpers.GetMethod("GetHashCode", BindingFlags.Public | BindingFlags.Static); if (DebuggerHelpers.hashCodeMethod == null) { throw new DebuggerException("Cannot obtain method System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode"); diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj index e101386ccd..b7146cd1c5 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj @@ -219,7 +219,6 @@ - diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/ExpressionEvaluator.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/ExpressionEvaluator.cs index e7991e4d44..af06800eb6 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/ExpressionEvaluator.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/ExpressionEvaluator.cs @@ -4,21 +4,26 @@ // // $Revision$ // -using ICSharpCode.NRefactory.PrettyPrinter; using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; +using System.Reflection; using System.Text; + using Debugger.MetaData; using ICSharpCode.NRefactory; using ICSharpCode.NRefactory.Ast; +using ICSharpCode.NRefactory.PrettyPrinter; using ICSharpCode.NRefactory.Visitors; namespace Debugger { public class ExpressionEvaluator: NotImplementedAstVisitor { + const BindingFlags BindingFlagsAll = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; + const BindingFlags BindingFlagsAllDeclared = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; + public static INode Parse(string code, SupportedLanguage language) { SnippetParser parser = new SnippetParser(language); @@ -333,9 +338,9 @@ namespace Debugger } } MethodInfo method; - IList methods = targetType.GetMembers(methodName, BindingFlags.Method); + IList methods = targetType.GetMember(methodName, MemberTypes.Method, BindingFlagsAllDeclared); if (methods.Count == 0) - methods = targetType.GetMembers(methodName, BindingFlags.Method | BindingFlags.IncludeSuperType); + methods = targetType.GetMember(methodName, MemberTypes.Method, BindingFlagsAll); if (methods.Count == 0) { throw new GetValueException("Method " + methodName + " not found"); } else if (methods.Count == 1) { @@ -378,9 +383,9 @@ namespace Debugger { Value target = Evaluate(memberReferenceExpression.TargetObject); DebugType targetType = GetDebugType(memberReferenceExpression.TargetObject) ?? target.Type; - MemberInfo memberInfo = targetType.GetMember(memberReferenceExpression.MemberName, BindingFlags.AllInThisType); + MemberInfo memberInfo = targetType.GetMember(memberReferenceExpression.MemberName, BindingFlagsAllDeclared); if (memberInfo == null) - memberInfo = targetType.GetMember(memberReferenceExpression.MemberName, BindingFlags.All); + memberInfo = targetType.GetMember(memberReferenceExpression.MemberName, BindingFlagsAll); if (memberInfo == null) throw new GetValueException("Member \"" + memberReferenceExpression.MemberName + "\" not found"); Value member = target.GetMemberValue(memberInfo); diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/BindingFlags.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/BindingFlags.cs deleted file mode 100644 index bff8ae884c..0000000000 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/BindingFlags.cs +++ /dev/null @@ -1,41 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; -using System.Collections.Generic; -using Debugger.Wrappers.CorDebug; -using Debugger.Wrappers.MetaData; - -namespace Debugger.MetaData -{ - /// - /// Binding flags specify which members should be returned. - /// Use 'or' operation to combine flags. - /// - [Flags] - public enum BindingFlags: uint { - /// Return all members - All = 0xFFFFFFFF, - AllInThisType = 0xFFFF, - - AccessMask = 0x0F, - Public = 0x01, - NonPublic = 0x02, - - InstanceStaticMask = 0xF0, - Instance = 0x10, - Static = 0x20, - - TypeMask = 0x0F00, - Field = 0x0100, - Property = 0x0200, - Method = 0x0400, - GetProperty = 0x0800, - - IncludeSuperType = 0x10000 - }; -} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType-Helpers.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType-Helpers.cs index 0581f8da4a..567b3e1801 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType-Helpers.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType-Helpers.cs @@ -9,330 +9,12 @@ using System; using System.Collections.Generic; using Debugger.Wrappers.CorDebug; using Debugger.Wrappers.MetaData; +using System.Reflection; namespace Debugger.MetaData { public partial class DebugType { - class Query { - public Type MemberType; - public BindingFlags BindingFlags; - public string Name; - public uint? Token; - - public Query(Type memberType, BindingFlags bindingFlags, string name, Nullable token) - { - this.MemberType = memberType; - this.BindingFlags = bindingFlags; - this.Name = name; - this.Token = token; - } - - public override int GetHashCode() - { - int hashCode = 0; - unchecked { - if (MemberType != null) hashCode += 1000000007 * MemberType.GetHashCode(); - hashCode += 1000000009 * BindingFlags.GetHashCode(); - if (Name != null) hashCode += 1000000021 * Name.GetHashCode(); - hashCode += 1000000033 * Token.GetHashCode(); - } - return hashCode; - } - - public override bool Equals(object obj) - { - Query other = obj as Query; - if (other == null) return false; - return object.Equals(this.MemberType, other.MemberType) && this.BindingFlags == other.BindingFlags && this.Name == other.Name && this.Token == other.Token; - } - } - - Dictionary queries = new Dictionary(); - - List QueryMembers(BindingFlags bindingFlags) where T:MemberInfo - { - return QueryMembers(bindingFlags, null, null); - } - - List QueryMembers(string name) where T:MemberInfo - { - return QueryMembers(BindingFlags.All, name, null); - } - - T QueryMember(string name) where T:MemberInfo - { - List result = QueryMembers(BindingFlags.All, name, null); - if (result.Count > 0) { - return result[0]; - } else { - return null; - } - } - - T QueryMember(string name, BindingFlags bindingFlags) where T:MemberInfo - { - List result = QueryMembers(bindingFlags, name, null); - if (result.Count > 0) { - return result[0]; - } else { - return null; - } - } - - T QueryMember(uint token) where T:MemberInfo - { - List result = QueryMembers(BindingFlags.All, null, token); - if (result.Count > 0) { - return result[0]; - } else { - return null; - } - } - - List QueryMembers(BindingFlags bindingFlags, string name, Nullable token) where T:MemberInfo - { - Query query = new Query(typeof(T), bindingFlags, name, token); - - if (queries.ContainsKey(query)) { - return (List)queries[query]; - } - - List results = new List(); - foreach(MemberInfo memberInfo in members) { - // Filter by type - if (!(memberInfo is T)) continue; // Reject item - - // Filter by access - if ((bindingFlags & BindingFlags.AccessMask) != 0) { - bool accept = false; - if ((bindingFlags & BindingFlags.Public) != 0 && memberInfo.IsPublic) accept = true; - if ((bindingFlags & BindingFlags.NonPublic) != 0 && !memberInfo.IsPublic) accept = true; - if (!accept) continue; // Reject item - } - - // Filter by static / instance - if ((bindingFlags & BindingFlags.InstanceStaticMask) != 0) { - bool accept = false; - if ((bindingFlags & BindingFlags.Static) != 0 && memberInfo.IsStatic) accept = true; - if ((bindingFlags & BindingFlags.Instance) != 0 && !memberInfo.IsStatic) accept = true; - if (!accept) continue; // Reject item - } - - // Filter by type - if ((bindingFlags & BindingFlags.TypeMask) != 0) { - bool accept = false; - if ((bindingFlags & BindingFlags.Field) != 0 && memberInfo is DebugFieldInfo) accept = true; - if ((bindingFlags & BindingFlags.Property) != 0 && memberInfo is PropertyInfo) accept = true; - if ((bindingFlags & BindingFlags.Method) != 0 && memberInfo is MethodInfo) accept = true; - if ((bindingFlags & BindingFlags.GetProperty) != 0 && - memberInfo is PropertyInfo && - ((PropertyInfo)memberInfo).GetMethod != null && - ((PropertyInfo)memberInfo).GetMethod.ParameterCount == 0) - { - accept = true; - } - if (!accept) continue; // Reject item - } - - // Filter by name - if (name != null) { - if (memberInfo.Name != name) continue; // Reject item - } - - // Filter by token - if (token.HasValue) { - if (memberInfo.MetadataToken != token.Value) continue; // Reject item - } - - results.Add((T)memberInfo); - } - - // Query supertype - if ((bindingFlags & BindingFlags.IncludeSuperType) != 0 && this.BaseType != null) { - List superResults = this.BaseType.QueryMembers(bindingFlags, name, token); - results.AddRange(superResults); - } - - queries[query] = results; - return results; - } - - #region Queries - - /// Return all public members. - public IList GetMembers() - { - return QueryMembers(BindingFlags.Public); - } - - /// Return all members with the given name. - public IList GetMembers(string name) - { - return QueryMembers(name); - } - - /// Return all members satisfing binding flags. - public IList GetMembers(string name, BindingFlags bindingFlags) - { - return QueryMembers(bindingFlags, name, null); - } - - /// Return all members satisfing binding flags. - public IList GetMembers(BindingFlags bindingFlags) - { - return QueryMembers(bindingFlags); - } - - /// Return first member with the given name - public MemberInfo GetMember(string name) - { - return QueryMember(name); - } - - /// Return first member with the given name - public MemberInfo GetMember(string name, BindingFlags bindingFlags) - { - return QueryMember(name, bindingFlags); - } - - /// Return first member with the given token - public MemberInfo GetMember(uint token) - { - return QueryMember(token); - } - - - /// Return all public fields. - public IList GetFields() - { - return QueryMembers(BindingFlags.Public); - } - - /// Return all fields satisfing binding flags. - public IList GetFields(BindingFlags bindingFlags) - { - return QueryMembers(bindingFlags); - } - - /// Return first field with the given name - public DebugFieldInfo GetField(string name) - { - return QueryMember(name); - } - - /// Return fields with the given name - public IList GetFields(string name) - { - return QueryMembers(name); - } - - /// Return first field with the given token - public DebugFieldInfo GetField(uint token) - { - return QueryMember(token); - } - - - /// Return all public methods. - public IList GetMethods() - { - return QueryMembers(BindingFlags.Public); - } - - /// Return all methods satisfing binding flags. - public IList GetMethods(BindingFlags bindingFlags) - { - return QueryMembers(bindingFlags); - } - - /// Return first method with the given name - public MethodInfo GetMethod(string name) - { - return QueryMember(name); - } - - /// Return methods with the given name - public IList GetMethods(string name) - { - return QueryMembers(name); - } - - /// Return method overload with given type parameters - /// Null if not found - public MethodInfo GetMethod(string name, params DebugType[] paramTypes) - { - foreach(MethodInfo candidate in GetMethods(name)) { - if (candidate.ParameterCount == paramTypes.Length) { - bool match = true; - for(int i = 0; i < paramTypes.Length; i++) { - if (paramTypes[i] != candidate.ParameterTypes[i]) - match = false; - } - if (match) - return candidate; - } - } - return null; - } - - /// Return method overload with given parameter names - /// Null if not found - public MethodInfo GetMethod(string name, params string[] paramNames) - { - foreach(MethodInfo candidate in GetMethods(name)) { - if (candidate.ParameterCount == paramNames.Length) { - bool match = true; - for(int i = 0; i < paramNames.Length; i++) { - if (paramNames[i] != candidate.ParameterNames[i]) - match = false; - } - if (match) - return candidate; - } - } - return null; - } - - /// Return first method with the given token - public MethodInfo GetMethod(uint token) - { - return QueryMember(token); - } - - - /// Return all public properties. - public IList GetProperties() - { - return QueryMembers(BindingFlags.Public); - } - - /// Return all properties satisfing binding flags. - public IList GetProperties(BindingFlags bindingFlags) - { - return QueryMembers(bindingFlags); - } - - /// Return first property with the given name - public PropertyInfo GetProperty(string name) - { - return QueryMember(name); - } - - /// Return propertyies with the given name - public IList GetProperties(string name) - { - return QueryMembers(name); - } - - /// Return first property with the given token - public PropertyInfo GetProperty(uint token) - { - return QueryMember(token); - } - - #endregion - private bool primitiveTypeCached; private System.Type primitiveType; diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType.cs index 10b565ccd2..d39faac56d 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType.cs @@ -211,6 +211,93 @@ namespace Debugger.MetaData return this.GenericArguments[0]; } + const BindingFlags supportedFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.FlattenHierarchy; + + public T GetMember(string name, BindingFlags bindingFlags, Predicate filter) where T:MemberInfo + { + T[] res = GetMembersImpl(name, bindingFlags, filter); + if (res.Length > 0) { + return res[0]; + } else { + return null; + } + } + + public T[] GetMembers(string name, BindingFlags bindingFlags, Predicate filter) where T:MemberInfo + { + BindingFlags unsupported = bindingFlags & ~supportedFlags; + if (unsupported != 0) + throw new NotSupportedException("BindingFlags: " + unsupported); + + if ((bindingFlags & (BindingFlags.Public | BindingFlags.NonPublic)) == 0) + throw new ArgumentException("Public or NonPublic flag must be included", "bindingFlags"); + + if ((bindingFlags & (BindingFlags.Instance | BindingFlags.Static)) == 0) + throw new ArgumentException("Instance or Static flag must be included", "bindingFlags"); + + List results = new List(); + foreach(MemberInfo memberInfo in members) { + // Filter by type + if (!(memberInfo is T)) continue; // Reject item + + // Filter by name + if (name != null) { + if (memberInfo.Name != name) continue; // Reject item + } + + // Filter by access + bool memberIsPublic; + if (memberInfo is FieldInfo) { + memberIsPublic = ((FieldInfo)memberInfo).IsPublic; + } else if (memberInfo is DebugPropertyInfo) { + memberIsPublic = ((DebugPropertyInfo)memberInfo).IsPublic; + } else if (memberInfo is MethodInfo) { + memberIsPublic = ((MethodInfo)memberInfo).IsPublic; + } else { + throw new DebuggerException("Unexpected type: " + memberInfo.GetType()); + } + if (memberIsPublic) { + if ((bindingFlags & BindingFlags.Public) == 0) continue; // Reject item + } else { + if ((bindingFlags & BindingFlags.NonPublic) == 0) continue; // Reject item + } + + // Filter by static / instance + bool memberIsStatic; + if (memberInfo is FieldInfo) { + memberIsStatic = ((FieldInfo)memberInfo).IsStatic; + } else if (memberInfo is DebugPropertyInfo) { + memberIsStatic = ((DebugPropertyInfo)memberInfo).IsStatic; + } else if (memberInfo is MethodInfo) { + memberIsStatic = ((MethodInfo)memberInfo).IsStatic; + } else { + throw new DebuggerException("Unexpected type: " + memberInfo.GetType()); + } + if (memberIsStatic) { + if ((bindingFlags & BindingFlags.Static) == 0) continue; // Reject item + } else { + if ((bindingFlags & BindingFlags.Instance) == 0) continue; // Reject item + } + + // Filter using predicate + if (filter != null && !filter((T)memberInfo)) continue; // Reject item + + results.Add((T)memberInfo); + } + + // Query supertype + if ((bindingFlags & BindingFlags.DeclaredOnly) == 0 && this.BaseType != null) { + if ((bindingFlags & BindingFlags.FlattenHierarchy) == 0) { + // Do not include static types + bindingFlags = bindingFlags & ~BindingFlags.Static; + } + List superResults = this.BaseType.QueryMembers(bindingFlags, name, token); + results.AddRange(superResults); + } + + return results.ToArray(); + } + public override EventInfo GetEvent(string name, BindingFlags bindingAttr) { throw new NotSupportedException(); @@ -225,12 +312,12 @@ namespace Debugger.MetaData public override FieldInfo GetField(string name, BindingFlags bindingAttr) { - throw new NotSupportedException(); + return GetMember(name, bindingAttr, null); } public override FieldInfo[] GetFields(BindingFlags bindingAttr) { - throw new NotSupportedException(); + return GetMembers(null, bindingAttr, null); } // public virtual Type[] GetGenericArguments(); @@ -249,22 +336,62 @@ namespace Debugger.MetaData return this.interfaces.ToArray(); } - // public virtual MemberInfo[] GetMember(string name, BindingFlags bindingAttr); - // public virtual MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr); + public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) + { + return GetMembers(name, bindingAttr, delegate(MemberInfo info) { return (info.MemberType & type) != 0; }); + } public override MemberInfo[] GetMembers(BindingFlags bindingAttr) { - throw new NotSupportedException(); + return GetMembers(null, bindingAttr, null); } - protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) + /// Return first method with the given token + public MethodInfo GetMethod(uint token) { - throw new NotSupportedException(); + return QueryMember(token); + } + + /// Return method overload with given parameter names + /// Null if not found + public MethodInfo GetMethod(string name, string[] paramNames) + { + foreach(MethodInfo candidate in GetMethod(name)) { + if (candidate.ParameterCount == paramNames.Length) { + bool match = true; + for(int i = 0; i < paramNames.Length; i++) { + if (paramNames[i] != candidate.ParameterNames[i]) + match = false; + } + if (match) + return candidate; + } + } + return null; + } + + protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] paramTypes, ParameterModifier[] modifiers) + { + // TODO: Finish + foreach(MethodInfo candidate in GetMembers(name, bindingAttr, null))) { + if (paramTypes == null) + return candidate; + if (candidate.ParameterCount == paramTypes.Length) { + bool match = true; + for(int i = 0; i < paramTypes.Length; i++) { + if (paramTypes[i] != candidate.ParameterTypes[i]) + match = false; + } + if (match) + return candidate; + } + } + return null; } public override MethodInfo[] GetMethods(BindingFlags bindingAttr) { - throw new NotSupportedException(); + return GetMembers(null, bindingAttr, null); } public override Type GetNestedType(string name, BindingFlags bindingAttr) @@ -277,14 +404,28 @@ namespace Debugger.MetaData throw new NotSupportedException(); } + public MemberInfo[] GetFieldsAndNonIndexedProperties(BindingFlags bindingAttr) + { + return GetMembers(null, bindingAttr, delegate (MemberInfo info) { + if (info is FieldInfo) + return true; + if (info is PropertyInfo) { + return ((PropertyInfo)info).GetGetMethod(true) != null && + ((PropertyInfo)info).GetGetMethod(true).GetParameters().Length == 0; + } + return false; + }); + } + public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) { - throw new NotSupportedException(); + return GetMembers(null, bindingAttr, null); } protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) { - throw new NotSupportedException(); + // TODO: Finsih + return GetMember(name, bindingAttr, null); } // internal virtual Type GetRootElementType(); diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/PropertyInfo.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/PropertyInfo.cs index 599745765d..feb7d6e070 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/PropertyInfo.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/PropertyInfo.cs @@ -134,5 +134,19 @@ namespace Debugger.MetaData { throw new NotSupportedException(); } + + public bool IsPublic { + get { + if (getMethod != null && getMethod.IsPublic) return true; + if (setMethod != null && setMethod.IsPublic) return true; + return false; + } + } + + public bool IsStatic { + get { + return (getMethod ?? setMethod).IsStatic; + } + } } }