Example #1
0
        /// <summary>
        /// Enumerates variables from the remote connection.
        /// </summary>
        /// <param name="runtime">The Visual Studio implementation of the runtime.</param>
        /// <param name="firstBatch">Tuple of enumeration id and first batch elements.</param>
        internal static IEnumerable <Variable> EnumerateVariables(VSClrRuntime runtime, Tuple <int, Tuple <ulong, int>[]> firstBatch)
        {
            VSDebuggerProxy proxy         = runtime.Proxy;
            uint            processId     = runtime.Process.Id;
            int             enumerationId = firstBatch.Item1;

            Tuple <ulong, int>[] batch = firstBatch.Item2;
            bool destroyed             = batch.Length == EnumerationBatchSize;

            try
            {
                while (batch.Length > 0)
                {
                    foreach (Tuple <ulong, int> tuple in batch)
                    {
                        IClrType clrType = runtime.GetClrType(tuple.Item2);

                        if (clrType != null)
                        {
                            ulong    address  = tuple.Item1;
                            CodeType codeType = runtime.Process.FromClrType(clrType);
                            Variable variable;

                            if (codeType.IsPointer)
                            {
                                variable = Variable.CreatePointerNoCast(codeType, address);
                            }
                            else
                            {
                                variable = Variable.CreateNoCast(codeType, address);
                            }

                            // TODO: Can we get already upcast address and clr type from the remote connection?
                            yield return(Variable.UpcastClrVariable(variable));
                        }
                    }

                    if (destroyed)
                    {
                        break;
                    }
                    batch     = proxy.GetVariableEnumeratorNextBatch(processId, enumerationId, EnumerationBatchSize);
                    destroyed = batch.Length == EnumerationBatchSize;
                }
            }
            finally
            {
                if (!destroyed)
                {
                    proxy.DisposeVariableEnumerator(processId, enumerationId);
                }
            }
        }