예제 #1
0
        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());
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        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);
            }
        }
예제 #5
0
 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) + "}"));
 }
예제 #6
0
        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());
        }
예제 #7
0
        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);
		}