Browse Source

Using BindingFlags from System.Reflection

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5101 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 16 years ago
parent
commit
f800c21074
  1. 46
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/ChildNodesOfObject.cs
  2. 6
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs
  3. 8
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/GridVisualizer/ValueProviders/GridValuesProvider.cs
  4. 17
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Utils/DebuggerHelpers.cs
  5. 1
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj
  6. 15
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/ExpressionEvaluator.cs
  7. 41
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/BindingFlags.cs
  8. 320
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType-Helpers.cs
  9. 161
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType.cs
  10. 14
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/PropertyInfo.cs

46
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/ChildNodesOfObject.cs

@ -4,14 +4,15 @@ @@ -4,14 +4,15 @@
// <version>$Revision$</version>
// </file>
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 @@ -19,42 +20,41 @@ namespace Debugger.AddIn.TreeModel
{
public static IEnumerable<TreeNode> 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<TreeNode> childs = Utils.LazyGetMembersOfObject(targetObject, shownType, publicStaticFlags);
if (shownType.HasMembers(nonPublicStaticFlags)) {
if (publicStatic.Length > 0 || nonPublicStatic.Length > 0) {
IEnumerable<TreeNode> 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 @@ -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<TreeNode> LazyGetMembersOfObject(Expression expression, DebugType type, BindingFlags bindingFlags)
public static IEnumerable<TreeNode> LazyGetMembersOfObject(Expression expression, MemberInfo[] members)
{
List<TreeNode> members = new List<TreeNode>();
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<TreeNode> nodes = new List<TreeNode>();
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;
}

6
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs

@ -60,10 +60,10 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -60,10 +60,10 @@ namespace Debugger.AddIn.Visualizers.Graph
/// Binding flags for getting member expressions.
/// </summary>
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;
/// <summary>
/// Creates ObjectGraphBuilder.
@ -225,7 +225,7 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -225,7 +225,7 @@ namespace Debugger.AddIn.Visualizers.Graph
{
List<ObjectGraphProperty> propertyList = new List<ObjectGraphProperty>();
foreach (MemberInfo memberProp in shownType.GetFieldsAndProperties(flags))
foreach (MemberInfo memberProp in shownType.GetFieldsAndNonIndexedProperties(flags))
{
// skip backing fields
if (memberProp.Name.Contains("<"))

8
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/GridVisualizer/ValueProviders/GridValuesProvider.cs

@ -6,9 +6,10 @@ @@ -6,9 +6,10 @@
// </file>
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 @@ -18,9 +19,6 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer
/// </summary>
public class GridValuesProvider
{
protected readonly BindingFlags memberBindingFlags =
BindingFlags.Public | BindingFlags.Instance | BindingFlags.Field | BindingFlags.GetProperty;
/// <summary> Used to quickly find MemberInfo by member name - DebugType.GetMember(name) uses a loop to search members </summary>
protected Dictionary<string, MemberInfo> memberFromNameMap;
@ -42,7 +40,7 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer @@ -42,7 +40,7 @@ namespace Debugger.AddIn.Visualizers.GridVisualizer
/// </summary>
public IList<MemberInfo> GetItemTypeMembers()
{
return itemType.GetMembers(this.memberBindingFlags);
return itemType.GetFieldsAndNonIndexedProperties(BindingFlags.Public | BindingFlags.Instance);
}
}
}

17
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Utils/DebuggerHelpers.cs

@ -5,12 +5,13 @@ @@ -5,12 +5,13 @@
// <version>$Revision$</version>
// </file>
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 @@ -66,16 +67,6 @@ namespace Debugger.AddIn.Visualizers.Utils
return expr.Evaluate(WindowsDebugger.CurrentProcess).GetObjectAddress();
}
public static IEnumerable<MemberInfo> 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;
}
}
/// <summary>
/// System.Runtime.CompilerServices.GetHashCode method, for obtaining non-overriden hash codes from debuggee.
/// </summary>
@ -91,7 +82,7 @@ namespace Debugger.AddIn.Visualizers.Utils @@ -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");

1
src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj

@ -219,7 +219,6 @@ @@ -219,7 +219,6 @@
<Compile Include="Src\Interop\Enums\CorTokenType.cs" />
<Compile Include="Src\Interop\MetaData\COR_FIELD_OFFSET.cs" />
<Compile Include="Src\Interop\MetaData\IMetaDataImport.cs" />
<Compile Include="Src\Metadata\BindingFlags.cs" />
<Compile Include="Src\Metadata\DebugParameterInfo.cs" />
<Compile Include="Src\Metadata\DebugType-Helpers.cs" />
<Compile Include="Src\Metadata\DebugType.cs" />

15
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/ExpressionEvaluator.cs

@ -4,21 +4,26 @@ @@ -4,21 +4,26 @@
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision$</version>
// </file>
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 @@ -333,9 +338,9 @@ namespace Debugger
}
}
MethodInfo method;
IList<MemberInfo> methods = targetType.GetMembers(methodName, BindingFlags.Method);
IList<MemberInfo> 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 @@ -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);

41
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/BindingFlags.cs

@ -1,41 +0,0 @@ @@ -1,41 +0,0 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using Debugger.Wrappers.CorDebug;
using Debugger.Wrappers.MetaData;
namespace Debugger.MetaData
{
/// <summary>
/// Binding flags specify which members should be returned.
/// <para> Use 'or' operation to combine flags. </para>
/// </summary>
[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
};
}

320
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType-Helpers.cs

@ -9,330 +9,12 @@ using System; @@ -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<uint> 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<Query, object> queries = new Dictionary<Query, object>();
List<T> QueryMembers<T>(BindingFlags bindingFlags) where T:MemberInfo
{
return QueryMembers<T>(bindingFlags, null, null);
}
List<T> QueryMembers<T>(string name) where T:MemberInfo
{
return QueryMembers<T>(BindingFlags.All, name, null);
}
T QueryMember<T>(string name) where T:MemberInfo
{
List<T> result = QueryMembers<T>(BindingFlags.All, name, null);
if (result.Count > 0) {
return result[0];
} else {
return null;
}
}
T QueryMember<T>(string name, BindingFlags bindingFlags) where T:MemberInfo
{
List<T> result = QueryMembers<T>(bindingFlags, name, null);
if (result.Count > 0) {
return result[0];
} else {
return null;
}
}
T QueryMember<T>(uint token) where T:MemberInfo
{
List<T> result = QueryMembers<T>(BindingFlags.All, null, token);
if (result.Count > 0) {
return result[0];
} else {
return null;
}
}
List<T> QueryMembers<T>(BindingFlags bindingFlags, string name, Nullable<uint> token) where T:MemberInfo
{
Query query = new Query(typeof(T), bindingFlags, name, token);
if (queries.ContainsKey(query)) {
return (List<T>)queries[query];
}
List<T> results = new List<T>();
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<T> superResults = this.BaseType.QueryMembers<T>(bindingFlags, name, token);
results.AddRange(superResults);
}
queries[query] = results;
return results;
}
#region Queries
/// <summary> Return all public members.</summary>
public IList<MemberInfo> GetMembers()
{
return QueryMembers<MemberInfo>(BindingFlags.Public);
}
/// <summary> Return all members with the given name.</summary>
public IList<MemberInfo> GetMembers(string name)
{
return QueryMembers<MemberInfo>(name);
}
/// <summary> Return all members satisfing binding flags.</summary>
public IList<MemberInfo> GetMembers(string name, BindingFlags bindingFlags)
{
return QueryMembers<MemberInfo>(bindingFlags, name, null);
}
/// <summary> Return all members satisfing binding flags.</summary>
public IList<MemberInfo> GetMembers(BindingFlags bindingFlags)
{
return QueryMembers<MemberInfo>(bindingFlags);
}
/// <summary> Return first member with the given name</summary>
public MemberInfo GetMember(string name)
{
return QueryMember<MemberInfo>(name);
}
/// <summary> Return first member with the given name</summary>
public MemberInfo GetMember(string name, BindingFlags bindingFlags)
{
return QueryMember<MemberInfo>(name, bindingFlags);
}
/// <summary> Return first member with the given token</summary>
public MemberInfo GetMember(uint token)
{
return QueryMember<MemberInfo>(token);
}
/// <summary> Return all public fields.</summary>
public IList<DebugFieldInfo> GetFields()
{
return QueryMembers<DebugFieldInfo>(BindingFlags.Public);
}
/// <summary> Return all fields satisfing binding flags.</summary>
public IList<DebugFieldInfo> GetFields(BindingFlags bindingFlags)
{
return QueryMembers<DebugFieldInfo>(bindingFlags);
}
/// <summary> Return first field with the given name</summary>
public DebugFieldInfo GetField(string name)
{
return QueryMember<DebugFieldInfo>(name);
}
/// <summary> Return fields with the given name</summary>
public IList<DebugFieldInfo> GetFields(string name)
{
return QueryMembers<DebugFieldInfo>(name);
}
/// <summary> Return first field with the given token</summary>
public DebugFieldInfo GetField(uint token)
{
return QueryMember<DebugFieldInfo>(token);
}
/// <summary> Return all public methods.</summary>
public IList<MethodInfo> GetMethods()
{
return QueryMembers<MethodInfo>(BindingFlags.Public);
}
/// <summary> Return all methods satisfing binding flags.</summary>
public IList<MethodInfo> GetMethods(BindingFlags bindingFlags)
{
return QueryMembers<MethodInfo>(bindingFlags);
}
/// <summary> Return first method with the given name</summary>
public MethodInfo GetMethod(string name)
{
return QueryMember<MethodInfo>(name);
}
/// <summary> Return methods with the given name</summary>
public IList<MethodInfo> GetMethods(string name)
{
return QueryMembers<MethodInfo>(name);
}
/// <summary> Return method overload with given type parameters </summary>
/// <returns> Null if not found </returns>
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;
}
/// <summary> Return method overload with given parameter names </summary>
/// <returns> Null if not found </returns>
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;
}
/// <summary> Return first method with the given token</summary>
public MethodInfo GetMethod(uint token)
{
return QueryMember<MethodInfo>(token);
}
/// <summary> Return all public properties.</summary>
public IList<PropertyInfo> GetProperties()
{
return QueryMembers<PropertyInfo>(BindingFlags.Public);
}
/// <summary> Return all properties satisfing binding flags.</summary>
public IList<PropertyInfo> GetProperties(BindingFlags bindingFlags)
{
return QueryMembers<PropertyInfo>(bindingFlags);
}
/// <summary> Return first property with the given name</summary>
public PropertyInfo GetProperty(string name)
{
return QueryMember<PropertyInfo>(name);
}
/// <summary> Return propertyies with the given name</summary>
public IList<PropertyInfo> GetProperties(string name)
{
return QueryMembers<PropertyInfo>(name);
}
/// <summary> Return first property with the given token</summary>
public PropertyInfo GetProperty(uint token)
{
return QueryMember<PropertyInfo>(token);
}
#endregion
private bool primitiveTypeCached;
private System.Type primitiveType;

161
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType.cs

@ -211,6 +211,93 @@ namespace Debugger.MetaData @@ -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<T>(string name, BindingFlags bindingFlags, Predicate<T> filter) where T:MemberInfo
{
T[] res = GetMembersImpl<T>(name, bindingFlags, filter);
if (res.Length > 0) {
return res[0];
} else {
return null;
}
}
public T[] GetMembers<T>(string name, BindingFlags bindingFlags, Predicate<T> 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<T> results = new List<T>();
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<T> superResults = this.BaseType.QueryMembers<T>(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 @@ -225,12 +312,12 @@ namespace Debugger.MetaData
public override FieldInfo GetField(string name, BindingFlags bindingAttr)
{
throw new NotSupportedException();
return GetMember<FieldInfo>(name, bindingAttr, null);
}
public override FieldInfo[] GetFields(BindingFlags bindingAttr)
{
throw new NotSupportedException();
return GetMembers<FieldInfo>(null, bindingAttr, null);
}
// public virtual Type[] GetGenericArguments();
@ -249,22 +336,62 @@ namespace Debugger.MetaData @@ -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<MemberInfo>(name, bindingAttr, delegate(MemberInfo info) { return (info.MemberType & type) != 0; });
}
public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
{
throw new NotSupportedException();
return GetMembers<MemberInfo>(null, bindingAttr, null);
}
protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
/// <summary> Return first method with the given token</summary>
public MethodInfo GetMethod(uint token)
{
throw new NotSupportedException();
return QueryMember<MethodInfo>(token);
}
/// <summary> Return method overload with given parameter names </summary>
/// <returns> Null if not found </returns>
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<MethodInfo>(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<MethodInfo>(null, bindingAttr, null);
}
public override Type GetNestedType(string name, BindingFlags bindingAttr)
@ -277,14 +404,28 @@ namespace Debugger.MetaData @@ -277,14 +404,28 @@ namespace Debugger.MetaData
throw new NotSupportedException();
}
public MemberInfo[] GetFieldsAndNonIndexedProperties(BindingFlags bindingAttr)
{
return GetMembers<MemberInfo>(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<PropertyInfo>(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<PropertyInfo>(name, bindingAttr, null);
}
// internal virtual Type GetRootElementType();

14
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/PropertyInfo.cs

@ -134,5 +134,19 @@ namespace Debugger.MetaData @@ -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;
}
}
}
}

Loading…
Cancel
Save