public ObjectValue CreateElementValue (ArrayElementGroup grp, ObjectPath path, int[] indices)
		{
			if (array != null) {
				CorValRef elem = (CorValRef) GetElement (indices);
				return ctx.Adapter.CreateObjectValue (ctx, grp, path, elem, ObjectValueFlags.ArrayElement);
			}
			else
				return ObjectValue.CreateUnknown ("?");
		}
		public virtual ObjectValue[] GetObjectValueChildren (EvaluationContext ctx, IObjectSource objectSource, object type, object obj, int firstItemIndex, int count, bool dereferenceProxy)
		{
			if (obj is EvaluationResult)
				return new ObjectValue[0];
			
			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));
			var names = new ObjectValueNameTracker (ctx);
			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);
						names.Disambiguate (val, oval);
						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 ();
		}
Exemple #3
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());
        }
Exemple #4
0
 public ArrayObjectSource(ICollectionAdaptor source, int[] index)
 {
     this.source = source;
     this.path   = ArrayElementGroup.IndicesToString(index);
 }
Exemple #5
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 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 (bounds.Length > 1) {
				int rank = baseIndices.Length;
				lowerBound = 0;
				upperBound = bounds [rank] - 1;
				isLastDimension = rank == bounds.Length - 1;
			} else {
				lowerBound = 0;
				upperBound = bounds [0] - 1;
				isLastDimension = true;
			}
			
			int len;
			int initalIndex;
			
			if (!IsRange) {
				initalIndex = lowerBound;
				len = upperBound + 1;
			}
			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 += ",";
				
				for (int n=0; n < values.Length; n++) {
					int index = n + initalIndex + firstItemIndex;
					string sidx = curIndexStr + index.ToString ();
					ObjectValue val;
					string ename = "[" + sidx.Replace (",",", ") + "]";
					if (index > upperBound)
						val = ObjectValue.CreateUnknown (sidx);
					else {
						curIndex [curIndex.Length - 1] = index;
						object elem = array.GetElement (curIndex);
						val = cctx.Adapter.CreateObjectValue (cctx, this, newPath.Append (sidx), 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))
								ename = cctx.Adapter.EvaluateDisplayString (cctx, elem, tdata.NameDisplayString);
						}
					}
					val.Name = ename;
					values [n] = val;
				}
				return values;
			}
			else if (!isLastDimension && div == 1) {
				// Return an array element group for each index
				
				List<ObjectValue> 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;
				List<ObjectValue> 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 ();
			}
		}