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();
}
}
}