private void ExpandClassInspectionData(InspectionData selectedData) { // Expansion for a class and class properties ProtoCore.Lang.Obj stackValue = GetStackValue(selectedData.Name); Dictionary<string, ProtoCore.Lang.Obj> classProperties = GetClassProperties(stackValue); if (null != classProperties) { ObservableCollection<InspectionData> oldDerivations = selectedData.Derivations; selectedData.ClearDerivations(); int index = 0; foreach (KeyValuePair<string, ProtoCore.Lang.Obj> property in classProperties) { InspectionData inspectionData = CreateInspectionData(property.Value, property.Key); if (null != inspectionData) { selectedData.AddDerivation(inspectionData); if (null != oldDerivations && (index < oldDerivations.Count)) inspectionData.IsExpanded = oldDerivations[index].IsExpanded; } index = index + 1; } } }
private void CreateDataRecursive(InspectionData inspectionData, ProtoCore.Lang.Obj stackValue) { if (null == stackValue || null == stackValue.Payload) { inspectionData.Type = string.Empty; inspectionData.Value = string.Empty; if (!string.IsNullOrEmpty(inspectionData.DisplayText)) inspectionData.Value = "null"; inspectionData.ClearDerivations(); return; } inspectionData.OpType = stackValue.DsasmValue.optype; switch (stackValue.DsasmValue.optype) { case ProtoCore.DSASM.AddressType.ArrayPointer: // Array type { inspectionData.Type = "array"; inspectionData.Value = "array"; if (false == inspectionData.IsExpanded) { // If we are looking at an array, then make sure it // at least have an empty child data (so that HasItems // property returns "true"). This child data can later // be replaced by the actual value upon expansion. if (false == inspectionData.HasItems) { string parentExpression = inspectionData.Expression; inspectionData.AddDerivation(parentExpression, 0); } } else { List<ProtoCore.Lang.Obj> arrayElements = GetArrayStackValues(stackValue); int elementCount = ((null == arrayElements) ? 0 : arrayElements.Count); inspectionData.Type = string.Format("array[{0}]", elementCount); inspectionData.Value = inspectionData.Type; if (inspectionData.Derivations != null) ShrinkDerivations(inspectionData, elementCount); int elementsToDisplay = elementCount; if (inspectionData.ExpansionLimit > 0) { elementsToDisplay = inspectionData.ExpansionLimit; if (elementsToDisplay > elementCount) elementsToDisplay = elementCount; } string parentExpression = inspectionData.Expression; for (int index = 0; index < elementsToDisplay; ++index) { InspectionData childData = inspectionData.GetDrivationAtIndex(index); if (null == childData) childData = inspectionData.AddDerivation(parentExpression, index); CreateDataRecursive(childData, arrayElements[index]); } } break; } case ProtoCore.DSASM.AddressType.Pointer: // Class type { if (inspectionData.Expression.Equals("this") && (Int64)stackValue.Payload == -1) { inspectionData.Type = "Invalid"; inspectionData.Value = "null"; break; } inspectionData.Type = GetStackValueType(stackValue); inspectionData.Value = GetStackValueData(stackValue); if (false == inspectionData.IsExpanded) { // If we are looking at a class, then make sure it // at least have an empty child data (so that HasItems // property returns "true"). This child data can later // be replaced by the actual value upon expansion. if (false == inspectionData.HasItems) inspectionData.AddDerivation(string.Empty, -1); } else { // Expansion for a class and class properties Dictionary<string, ProtoCore.Lang.Obj> properties = GetClassProperties(stackValue); if (null == properties || (properties.Count <= 0)) return; if (inspectionData.Derivations != null) ShrinkDerivations(inspectionData, properties.Count); int index = 0; foreach (KeyValuePair<string, ProtoCore.Lang.Obj> property in properties) { InspectionData childData = inspectionData.GetDrivationAtIndex(index); if (null == childData) childData = inspectionData.AddDerivation(property.Key, -1); // The first child data that was created before this class gets // expanded may not have the appropriate expression to begin with, // so set it here... childData.Expression = property.Key; if (null != property.Value) CreateDataRecursive(childData, property.Value); else { // This may be an external property, try evaluating it for value. string qualifiedName = childData.GetQualifiedName(); ProtoCore.Lang.Obj childStackValue = GetStackValue(qualifiedName); CreateDataRecursive(childData, childStackValue); } index = index + 1; } } break; } case ProtoCore.DSASM.AddressType.String: case ProtoCore.DSASM.AddressType.Char: { inspectionData.Type = GetStackValueType(stackValue); inspectionData.Value = GetStackValueData(stackValue); inspectionData.ClearDerivations(); break; } default: // This applies to all other primitive types. { inspectionData.Type = GetStackValueType(stackValue); inspectionData.Value = GetStackValuePayload(stackValue); inspectionData.ClearDerivations(); break; } } }