public ObjectValue GetValue(ObjectPath path, EvaluationOptions options) { if (path.Length != 2) { throw new NotSupportedException(); } int[] idx = StringToIndices(path [1]); object elem = array.GetElement(idx); EvaluationContext cctx = ctx.WithOptions(options); ObjectValue val = cctx.Adapter.CreateObjectValue(cctx, this, path, elem, ObjectValueFlags.ArrayElement); if (elem != null && !cctx.Adapter.IsNull(cctx, elem)) { TypeDisplayData tdata = cctx.Adapter.GetTypeDisplayData(cctx, cctx.Adapter.GetValueType(cctx, elem)); if (!string.IsNullOrEmpty(tdata.NameDisplayString)) { try { val.Name = cctx.Adapter.EvaluateDisplayString(cctx, elem, tdata.NameDisplayString); } catch (MissingMemberException) { // missing property or otherwise malformed DebuggerDisplay string } } } return(val); }
public ObjectValue[] GetChildren(ObjectPath path, int index, int count, EvaluationOptions options) { EvaluationContext cctx = ctx.WithOptions(options); object tdataType = null; TypeDisplayData tdata = null; List <ObjectValue> list = new List <ObjectValue> (); foreach (ValueReference val in cctx.Adapter.GetMembersSorted(cctx, objectSource, type, obj, bindingFlags)) { object decType = val.DeclaringType; if (decType != null && decType != tdataType) { tdataType = decType; tdata = cctx.Adapter.GetTypeDisplayData(cctx, decType); } DebuggerBrowsableState state = tdata.GetMemberBrowsableState(val.Name); if (state == DebuggerBrowsableState.Never) { continue; } ObjectValue oval = val.CreateObjectValue(options); list.Add(oval); } if ((bindingFlags & BindingFlags.NonPublic) == 0) { BindingFlags newFlags = bindingFlags | BindingFlags.NonPublic; newFlags &= ~BindingFlags.Public; list.Add(CreateNonPublicsNode(cctx, objectSource, type, obj, newFlags)); } return(list.ToArray()); }
public object GetProxyObject(EvaluationContext ctx, object obj) { TypeDisplayData data = GetTypeDisplayData(ctx, GetValueType(ctx, obj)); if (string.IsNullOrEmpty(data.ProxyType) || !ctx.Options.AllowDebuggerProxy) { return(obj); } object[] typeArgs = null; int i = data.ProxyType.IndexOf('`'); if (i != -1) { // The proxy type is an uninstantiated generic type. // The number of type args of the proxy must match the args of the target object int j = i + 1; for (; j < data.ProxyType.Length && char.IsDigit(data.ProxyType[j]); j++) { ; } int np = int.Parse(data.ProxyType.Substring(i + 1, j - i - 1)); typeArgs = GetTypeArgs(ctx, GetValueType(ctx, obj)); if (typeArgs.Length != np) { return(obj); } } object ttype = GetType(ctx, data.ProxyType, typeArgs); if (ttype == null) { i = data.ProxyType.IndexOf(','); if (i != -1) { ttype = GetType(ctx, data.ProxyType.Substring(0, i).Trim(), typeArgs); } } if (ttype == null) { throw new EvaluatorException("Unknown type '{0}'", data.ProxyType); } try { object val = CreateValue(ctx, ttype, obj); return(val ?? obj); } catch (Exception ex) { ctx.WriteDebuggerError(ex); return(obj); } }
protected virtual ObjectValue CreateObjectValueImpl(EvaluationContext ctx, Mono.Debugging.Backend.IObjectValueSource source, ObjectPath path, object obj, ObjectValueFlags flags) { string typeName = obj != null?GetValueTypeName(ctx, obj) : ""; if (obj == null || IsNull(ctx, obj)) { return(ObjectValue.CreateNullObject(source, path, GetDisplayTypeName(typeName), flags)); } else if (IsPrimitive(ctx, obj) || IsEnum(ctx, obj)) { return(ObjectValue.CreatePrimitive(source, path, GetDisplayTypeName(typeName), ctx.Evaluator.TargetObjectToExpression(ctx, obj), flags)); } else if (IsArray(ctx, obj)) { return(ObjectValue.CreateObject(source, path, GetDisplayTypeName(typeName), ctx.Evaluator.TargetObjectToExpression(ctx, obj), flags, null)); } else { TypeDisplayData tdata = GetTypeDisplayData(ctx, GetValueType(ctx, obj)); EvaluationResult tvalue; if (!string.IsNullOrEmpty(tdata.ValueDisplayString) && ctx.Options.AllowDisplayStringEvaluation) { tvalue = new EvaluationResult(EvaluateDisplayString(ctx, obj, tdata.ValueDisplayString)); } else { tvalue = ctx.Evaluator.TargetObjectToExpression(ctx, obj); } string tname; if (!string.IsNullOrEmpty(tdata.TypeDisplayString) && ctx.Options.AllowDisplayStringEvaluation) { tname = EvaluateDisplayString(ctx, obj, tdata.TypeDisplayString); } else { tname = GetDisplayTypeName(typeName); } ObjectValue oval = ObjectValue.CreateObject(source, path, tname, tvalue, flags, null); if (!string.IsNullOrEmpty(tdata.NameDisplayString) && ctx.Options.AllowDisplayStringEvaluation) { oval.Name = EvaluateDisplayString(ctx, obj, tdata.NameDisplayString); } return(oval); } }
public virtual object TargetObjectToObject(EvaluationContext ctx, object obj) { if (IsNull(ctx, obj)) { return(null); } else if (IsArray(ctx, obj)) { ICollectionAdaptor adaptor = CreateArrayAdaptor(ctx, obj); string ename = GetDisplayTypeName(GetTypeName(ctx, adaptor.ElementType)); int[] dims = adaptor.GetDimensions(); StringBuilder tn = new StringBuilder("["); for (int n = 0; n < dims.Length; n++) { if (n > 0) { tn.Append(','); } tn.Append(dims[n]); } tn.Append("]"); int i = ename.LastIndexOf('>'); if (i == -1) { i = 0; } i = ename.IndexOf('[', i); if (i != -1) { return(new EvaluationResult("{" + ename.Substring(0, i) + tn + ename.Substring(i) + "}")); } else { return(new EvaluationResult("{" + ename + tn + "}")); } } else if (IsEnum(ctx, obj)) { object type = GetValueType(ctx, obj); object longType = GetType(ctx, "System.Int64"); object c = Cast(ctx, obj, longType); long val = (long)TargetObjectToObject(ctx, c); long rest = val; string typeName = GetTypeName(ctx, type); string composed = string.Empty; string composedDisplay = string.Empty; foreach (EnumMember em in GetEnumMembers(ctx, type)) { if (em.Value == val) { return(new EvaluationResult(typeName + "." + em.Name, em.Name)); } else { if (em.Value != 0 && (rest & em.Value) == em.Value) { rest &= ~em.Value; if (composed.Length > 0) { composed += "|"; composedDisplay += "|"; } composed += typeName + "." + em.Name; composedDisplay += em.Name; } } } if (IsFlagsEnumType(ctx, type) && rest == 0 && composed.Length > 0) { return(new EvaluationResult(composed, composedDisplay)); } else { return(new EvaluationResult(val.ToString())); } } else if (GetValueTypeName(ctx, obj) == "System.Decimal") { string res = CallToString(ctx, obj); // This returns the decimal formatted using the current culture. It has to be converted to invariant culture. decimal dec = decimal.Parse(res); res = dec.ToString(System.Globalization.CultureInfo.InvariantCulture); return(new EvaluationResult(res)); } else if (IsClassInstance(ctx, obj)) { TypeDisplayData tdata = GetTypeDisplayData(ctx, GetValueType(ctx, obj)); if (!string.IsNullOrEmpty(tdata.ValueDisplayString) && ctx.Options.AllowDisplayStringEvaluation) { return(new EvaluationResult(EvaluateDisplayString(ctx, obj, tdata.ValueDisplayString))); } // Return the type name if (ctx.Options.AllowToStringCalls) { return(new EvaluationResult("{" + CallToString(ctx, obj) + "}")); } if (!string.IsNullOrEmpty(tdata.TypeDisplayString) && ctx.Options.AllowDisplayStringEvaluation) { return(new EvaluationResult("{" + EvaluateDisplayString(ctx, obj, tdata.TypeDisplayString) + "}")); } return(new EvaluationResult("{" + GetDisplayTypeName(GetValueTypeName(ctx, obj)) + "}")); } return(new EvaluationResult("{" + CallToString(ctx, obj) + "}")); }
public virtual ObjectValue[] GetObjectValueChildren(EvaluationContext ctx, IObjectSource objectSource, object type, object obj, int firstItemIndex, int count, bool dereferenceProxy) { if (IsArray(ctx, obj)) { ArrayElementGroup agroup = new ArrayElementGroup(ctx, CreateArrayAdaptor(ctx, obj)); return(agroup.GetChildren(ctx.Options)); } if (IsPrimitive(ctx, obj)) { return(new ObjectValue[0]); } bool showRawView = false; // If there is a proxy, it has to show the members of the proxy object proxy = obj; if (dereferenceProxy) { proxy = GetProxyObject(ctx, obj); if (proxy != obj) { type = GetValueType(ctx, proxy); showRawView = true; } } TypeDisplayData tdata = GetTypeDisplayData(ctx, type); bool groupPrivateMembers = ctx.Options.GroupPrivateMembers && (ctx.Options.GroupUserPrivateMembers || IsExternalType(ctx, type)); List <ObjectValue> values = new List <ObjectValue> (); BindingFlags flattenFlag = ctx.Options.FlattenHierarchy ? (BindingFlags)0 : BindingFlags.DeclaredOnly; BindingFlags nonNonPublicFlag = groupPrivateMembers || showRawView ? (BindingFlags)0 : BindingFlags.NonPublic; BindingFlags staticFlag = ctx.Options.GroupStaticMembers ? (BindingFlags)0 : BindingFlags.Static; BindingFlags access = BindingFlags.Public | BindingFlags.Instance | flattenFlag | nonNonPublicFlag | staticFlag; // Load all members to a list before creating the object values, // to avoid problems with objects being invalidated due to evaluations in the target, List <ValueReference> list = new List <ValueReference> (); list.AddRange(GetMembersSorted(ctx, objectSource, type, proxy, access)); object tdataType = type; foreach (ValueReference val in list) { try { object decType = val.DeclaringType; if (decType != null && decType != tdataType) { tdataType = decType; tdata = GetTypeDisplayData(ctx, decType); } DebuggerBrowsableState state = tdata.GetMemberBrowsableState(val.Name); if (state == DebuggerBrowsableState.Never) { continue; } if (state == DebuggerBrowsableState.RootHidden && dereferenceProxy) { object ob = val.Value; if (ob != null) { values.Clear(); values.AddRange(GetObjectValueChildren(ctx, val, ob, -1, -1)); showRawView = true; break; } } else { ObjectValue oval = val.CreateObjectValue(true); values.Add(oval); } } catch (Exception ex) { ctx.WriteDebuggerError(ex); values.Add(ObjectValue.CreateError(null, new ObjectPath(val.Name), GetDisplayTypeName(GetTypeName(ctx, val.Type)), ex.Message, val.Flags)); } } if (showRawView) { values.Add(RawViewSource.CreateRawView(ctx, objectSource, obj)); } else { if (IsArray(ctx, proxy)) { ICollectionAdaptor col = CreateArrayAdaptor(ctx, proxy); ArrayElementGroup agroup = new ArrayElementGroup(ctx, col); ObjectValue val = ObjectValue.CreateObject(null, new ObjectPath("Raw View"), "", "", ObjectValueFlags.ReadOnly, values.ToArray()); values = new List <ObjectValue> (); values.Add(val); values.AddRange(agroup.GetChildren(ctx.Options)); } else { if (ctx.Options.GroupStaticMembers && HasMembers(ctx, type, proxy, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | flattenFlag)) { access = BindingFlags.Static | BindingFlags.Public | flattenFlag | nonNonPublicFlag; values.Add(FilteredMembersSource.CreateStaticsNode(ctx, objectSource, type, proxy, access)); } if (groupPrivateMembers && HasMembers(ctx, type, proxy, BindingFlags.Instance | BindingFlags.NonPublic | flattenFlag | staticFlag)) { values.Add(FilteredMembersSource.CreateNonPublicsNode(ctx, objectSource, type, proxy, BindingFlags.Instance | BindingFlags.NonPublic | flattenFlag | staticFlag)); } if (!ctx.Options.FlattenHierarchy) { object baseType = GetBaseType(ctx, type, false); if (baseType != null) { values.Insert(0, BaseTypeViewSource.CreateBaseTypeView(ctx, objectSource, baseType, proxy)); } } } } return(values.ToArray()); }
public ObjectValue[] GetChildren(ObjectPath path, int firstItemIndex, int count, EvaluationOptions options) { EvaluationContext cctx = ctx.WithOptions(options); if (path.Length > 1) { // Looking for children of an array element int[] idx = StringToIndices(path [1]); object obj = array.GetElement(idx); return(cctx.Adapter.GetObjectValueChildren(cctx, new ArrayObjectSource(array, path[1]), obj, firstItemIndex, count)); } int lowerBound; int upperBound; bool isLastDimension; if (dimensions.Length > 1) { int rank = baseIndices.Length; lowerBound = array.GetLowerBounds() [rank]; upperBound = lowerBound + dimensions [rank] - 1; isLastDimension = rank == dimensions.Length - 1; } else { lowerBound = array.GetLowerBounds() [0]; upperBound = lowerBound + dimensions [0] - 1; isLastDimension = true; } int len; int initalIndex; if (!IsRange) { initalIndex = lowerBound; len = upperBound + 1 - lowerBound; } else { initalIndex = firstIndex; len = lastIndex - firstIndex + 1; } if (firstItemIndex == -1) { firstItemIndex = 0; count = len; } // Make sure the group doesn't have too many elements. If so, divide int div = 1; while (len / div > MaxChildCount) { div *= 10; } if (div == 1 && isLastDimension) { // Return array elements ObjectValue[] values = new ObjectValue [count]; ObjectPath newPath = new ObjectPath("this"); int[] curIndex = new int [baseIndices.Length + 1]; Array.Copy(baseIndices, curIndex, baseIndices.Length); string curIndexStr = IndicesToString(baseIndices); if (baseIndices.Length > 0) { curIndexStr += ","; } curIndex [curIndex.Length - 1] = initalIndex + firstItemIndex; var elems = array.GetElements(curIndex, System.Math.Min(values.Length, upperBound - lowerBound + 1)); for (int n = 0; n < values.Length; n++) { int index = n + initalIndex + firstItemIndex; string sidx = curIndexStr + index; ObjectValue val; string ename = "[" + sidx.Replace(",", ", ") + "]"; if (index > upperBound) { val = ObjectValue.CreateUnknown(sidx); } else { curIndex [curIndex.Length - 1] = index; val = cctx.Adapter.CreateObjectValue(cctx, this, newPath.Append(sidx), elems.GetValue(n), ObjectValueFlags.ArrayElement); if (elems.GetValue(n) != null && !cctx.Adapter.IsNull(cctx, elems.GetValue(n))) { TypeDisplayData tdata = cctx.Adapter.GetTypeDisplayData(cctx, cctx.Adapter.GetValueType(cctx, elems.GetValue(n))); if (!string.IsNullOrEmpty(tdata.NameDisplayString)) { try { ename = cctx.Adapter.EvaluateDisplayString(cctx, elems.GetValue(n), tdata.NameDisplayString); } catch (MissingMemberException) { // missing property or otherwise malformed DebuggerDisplay string } } } } val.Name = ename; values [n] = val; } return(values); } if (!isLastDimension && div == 1) { // Return an array element group for each index var list = new List <ObjectValue> (); for (int i = 0; i < count; i++) { int index = i + initalIndex + firstItemIndex; ObjectValue val; // This array must be created at every call to avoid sharing // changes with all array groups int[] curIndex = new int [baseIndices.Length + 1]; Array.Copy(baseIndices, curIndex, baseIndices.Length); curIndex [curIndex.Length - 1] = index; if (index > upperBound) { val = ObjectValue.CreateUnknown(""); } else { ArrayElementGroup grp = new ArrayElementGroup(cctx, array, curIndex); val = grp.CreateObjectValue(); } list.Add(val); } return(list.ToArray()); } else { // Too many elements. Split the array. // Don't make divisions of 10 elements, min is 100 if (div == 10) { div = 100; } // Create the child groups int i = initalIndex + firstItemIndex; len += i; var list = new List <ObjectValue> (); while (i < len) { int end = i + div - 1; if (end >= len) { end = len - 1; } ArrayElementGroup grp = new ArrayElementGroup(cctx, array, baseIndices, i, end); list.Add(grp.CreateObjectValue()); i += div; } return(list.ToArray()); } }
public override ObjectValue[] GetChildren(ObjectPath path, int index, int count, EvaluationOptions options) { EvaluationContext ctx = GetContext(options); try { List <ObjectValue> list = new List <ObjectValue> (); BindingFlags flattenFlag = options.FlattenHierarchy ? (BindingFlags)0 : BindingFlags.DeclaredOnly; BindingFlags flags = BindingFlags.Static | BindingFlags.Public | flattenFlag; bool groupPrivateMembers = options.GroupPrivateMembers && (options.GroupUserPrivateMembers || ctx.Adapter.IsExternalType(ctx, type)); if (!groupPrivateMembers) { flags |= BindingFlags.NonPublic; } TypeDisplayData tdata = ctx.Adapter.GetTypeDisplayData(ctx, type); object tdataType = type; foreach (ValueReference val in ctx.Adapter.GetMembersSorted(ctx, this, type, null, flags)) { object decType = val.DeclaringType; if (decType != null && decType != tdataType) { tdataType = decType; tdata = ctx.Adapter.GetTypeDisplayData(ctx, decType); } DebuggerBrowsableState state = tdata.GetMemberBrowsableState(val.Name); if (state == DebuggerBrowsableState.Never) { continue; } ObjectValue oval = val.CreateObjectValue(options); list.Add(oval); } List <ObjectValue> nestedTypes = new List <ObjectValue> (); foreach (object t in ctx.Adapter.GetNestedTypes(ctx, type)) { nestedTypes.Add(new TypeValueReference(ctx, t).CreateObjectValue(options)); } nestedTypes.Sort(delegate(ObjectValue v1, ObjectValue v2) { return(v1.Name.CompareTo(v2.Name)); }); list.AddRange(nestedTypes); if (groupPrivateMembers) { list.Add(FilteredMembersSource.CreateNonPublicsNode(ctx, this, type, null, BindingFlags.NonPublic | BindingFlags.Static | flattenFlag)); } if (!options.FlattenHierarchy) { object baseType = ctx.Adapter.GetBaseType(ctx, type, false); if (baseType != null) { TypeValueReference baseRef = new TypeValueReference(ctx, baseType); ObjectValue baseVal = baseRef.CreateObjectValue(false); baseVal.Name = "base"; list.Insert(0, baseVal); } } return(list.ToArray()); } catch (Exception ex) { Console.WriteLine(ex); ctx.WriteDebuggerOutput(ex.Message); return(new ObjectValue [0]); } }
protected override TypeDisplayData OnGetTypeDisplayData (EvaluationContext gctx, object type) { MdbEvaluationContext ctx = (MdbEvaluationContext) gctx; TargetType tt = (TargetType) type; if (tt.HasClassType) { TypeDisplayData data = new TypeDisplayData (); if (tt.ClassType.DebuggerTypeProxyAttribute != null) { data.ProxyType = tt.ClassType.DebuggerTypeProxyAttribute.ProxyTypeName; } if (tt.ClassType.DebuggerDisplayAttribute != null) { data.NameDisplayString = tt.ClassType.DebuggerDisplayAttribute.Name; data.TypeDisplayString = tt.ClassType.DebuggerDisplayAttribute.Type; data.ValueDisplayString = tt.ClassType.DebuggerDisplayAttribute.Value; } foreach (MemberReference mem in ObjectUtil.GetTypeMembers (ctx, tt, true, true, true, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) { if (mem.Member.DebuggerBrowsableState.HasValue) { if (data.MemberData == null) data.MemberData = new Dictionary<string, DebuggerBrowsableState> (); data.MemberData [mem.Member.Name] = mem.Member.DebuggerBrowsableState.Value; } } return data; } return base.OnGetTypeDisplayData (ctx, type); }