/// <summary> /// For each complex property of this node, create s neighbor graph node if needed and connects the neighbor to ObjectProperty.TargetNode. /// </summary> /// <param name="thisNode"></param> /// <param name="expandedNodes"></param> private void loadNeighborsRecursive(ObjectGraphNode thisNode, ExpandedExpressions expandedNodes) { //foreach(ObjectGraphProperty complexProperty in thisNode.ComplexProperties) foreach (ObjectGraphProperty complexProperty in thisNode.Properties) { ObjectGraphNode targetNode = null; // we are only evaluating expanded nodes here // (we have to do this to know the "shape" of the graph) // property laziness makes sense, as we are not evaluating atomic and non-expanded properties out of user's view if (/*!complexProperty.IsNull && we dont know yet if it's null */ expandedNodes.IsExpanded(complexProperty.Expression)) { // if expanded, evaluate this property // complexProperty.Evaluate(); // consider Value memberValue = complexProperty.Expression.Evaluate(this.debuggerService.DebuggedProcess); if (memberValue.IsNull) { continue; } else { // if property value is not null, create neighbor memberValue = memberValue.GetPermanentReference(); bool createdNew; // get existing node (loop) or create new targetNode = ObtainNodeForValue(memberValue, complexProperty.Expression, out createdNew); if (createdNew) { // if member node is new, recursively build its subtree loadNeighborsRecursive(targetNode, expandedNodes); } } } else { targetNode = null; } // connect property to target ObjectGraphNode complexProperty.TargetNode = targetNode; } }
/// <summary> /// For each complex property of this node, create s neighbor graph node if needed and connects the neighbor to ObjectProperty.TargetNode. /// </summary> /// <param name="thisNode"></param> /// <param name="expandedNodes"></param> private void loadNeighborsRecursive(ObjectGraphNode thisNode, ExpandedExpressions expandedNodes) { // evaluate properties first in case property getters are changing some fields - the fields will then have correct values foreach (ObjectGraphProperty complexProperty in thisNode.PropertiesFirstThenFields) { ObjectGraphNode targetNode = null; // We are only evaluating expanded nodes here. // We have to do this to know the "shape" of the graph. // We do not evaluate atomic and non-expanded properties, those will be lazy evaluated when drawn. if (expandedNodes.IsExpanded(complexProperty.Expression)) { // if expanded, evaluate this property Value memberValue = complexProperty.Expression.Evaluate(this.debuggerService.DebuggedProcess); if (memberValue.IsNull) { continue; } else { // if property value is not null, create neighbor memberValue = memberValue.GetPermanentReference(); bool createdNew; // get existing node (loop) or create new targetNode = ObtainNodeForValue(memberValue, complexProperty.Expression, out createdNew); if (createdNew) { // if member node is new, recursively build its subtree loadNeighborsRecursive(targetNode, expandedNodes); } } } else { targetNode = null; } // connect property to target ObjectGraphNode complexProperty.TargetNode = targetNode; } }
/// <summary> /// For each complex property of this node, creates a neighbor graph node if needed and connects /// it using to ObjectProperty.TargetNode. /// </summary> private void loadNeighborsRecursive(ObjectGraphNode thisNode, ExpandedExpressions expandedNodes) { // evaluate properties first in case property getters are changing some fields - the fields will then have correct values foreach(ObjectGraphProperty complexProperty in thisNode.PropertiesFirstThenFields) { ObjectGraphNode targetNode = null; // We are only evaluating expanded nodes here. // We have to do this to know the "shape" of the graph. // We do not evaluate atomic and non-expanded properties, those will be lazy evaluated when drawn. if (expandedNodes.IsExpanded(complexProperty.Expression.Expr)) { // if expanded, evaluate this property Value memberValue = complexProperty.Expression.GetValue(); if (memberValue.IsNull) { continue; } else { // if property value is not null, create neighbor memberValue = memberValue.GetPermanentReference(WindowsDebugger.EvalThread); bool createdNew; // get existing node (loop) or create new targetNode = ObtainNodeForValue(memberValue, complexProperty.Expression, out createdNew); if (createdNew) { // if member node is new, recursively build its subtree loadNeighborsRecursive(targetNode, expandedNodes); } } } // connect property to target ObjectGraphNode complexProperty.TargetNode = targetNode; } }