private async Task InternalFetchChildren()

in src/MIDebugEngine/Engine.Impl/Variables.cs [668:778]


        private async Task InternalFetchChildren()
        {
            this.VerifyNotDisposed();

            Results results = await _engine.DebuggedProcess.MICommandFactory.VarListChildren(_internalName, PropertyInfoFlags, ResultClass.None);

            if (results.ResultClass == ResultClass.done)
            {
                TupleValue[] children = results.Contains("children")
                    ? results.Find<ResultListValue>("children").FindAll<TupleValue>("child")
                    : new TupleValue[0];
                int i = 0;
                bool isArray = IsArrayType();
                if (isArray)
                {
                    CountChildren = results.FindUint("numchild");
                    Children = new VariableInformation[CountChildren];
                    foreach (var c in children)
                    {
                        Children[i] = new VariableInformation(c, this);
                        i++;
                    }
                }
                else if (IsMapType())
                {
                    //
                    // support for gdb's pretty-printing built-in displayHint "map", from the gdb docs:
                    //      'Indicate that the object being printed is “map-like”, and that the 
                    //      children of this value can be assumed to alternate between keys and values.'
                    //
                    List<VariableInformation> listChildren = new List<VariableInformation>();
                    for (int p = 0; (p + 1) < children.Length; p += 2)
                    {
                        if (children[p].TryFindUint("numchild") > 0)
                        {
                            var variable = new VariableInformation("[" + (p / 2).ToString(CultureInfo.InvariantCulture) + "]", this);
                            variable.CountChildren = 2;
                            var first = new VariableInformation(children[p], variable, "first");
                            var second = new VariableInformation(children[p + 1], this, "second");

                            variable.Children = new VariableInformation[] { first, second };
                            variable.TypeName = FormattableString.Invariant($"std::pair<{first.TypeName}, {second.TypeName}>");

                            listChildren.Add(variable);
                        }
                        else
                        {
                            // One Variable is created for each pair returned with the first element (p) being the name of the child
                            // and the second element (p+1) becoming the value.
                            string name = children[p].TryFindString("value");
                            var variable = new VariableInformation(children[p + 1], this, '[' + name + ']');
                            listChildren.Add(variable);
                        }
                    }
                    Children = listChildren.ToArray();
                    CountChildren = (uint)Children.Length;
                }
                else
                {
                    List<VariableInformation> listChildren = new List<VariableInformation>();
                    foreach (var c in children)
                    {
                        var variable = new VariableInformation(c, this);
                        enum_DBG_ATTRIB_FLAGS access = enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_NONE;
                        if (variable.Name == "public")
                        {
                            access = enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_ACCESS_PUBLIC;
                            variable.VariableNodeType = NodeType.AccessQualifier;
                        }
                        else if (variable.Name == "private")
                        {
                            access = enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_ACCESS_PRIVATE;
                            variable.VariableNodeType = NodeType.AccessQualifier;
                        }
                        else if (variable.Name == "protected")
                        {
                            access = enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_ACCESS_PROTECTED;
                            variable.VariableNodeType = NodeType.AccessQualifier;
                        }
                        if (access != enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_NONE)
                        {
                            // Add this child's children
                            await variable.InternalFetchChildren();
                            foreach (var child in variable.Children)
                            {
                                ((VariableInformation)child).Access = access;
                                listChildren.Add(child);
                            }
                        }
                        else
                        {
                            listChildren.Add(variable);
                        }
                    }
                    Children = listChildren.ToArray();
                    CountChildren = (uint)Children.Length;
                }
            }
            else
            {
                Children = new VariableInformation[0];
                CountChildren = 0;
            }
            if (_format != null)
            {
                foreach (var child in Children)
                {
                    await child.Format();
                }
            }
        }