public override void Reset() { contextStack.Clear(); rootNode = null; references.Clear(); checkedNodes.Clear(); base.Reset(); }
/// <summary> /// Reset the visitor in order to use it to generate another model. /// </summary> public override void Reset() { rootNode = null; rootGuid = Guid.Empty; contextStack.Clear(); referenceContents.Clear(); base.Reset(); }
/// <summary> /// Add a child to this node. The node must not have been sealed yet. /// </summary> /// <param name="child">The child node to add.</param> /// <param name="allowIfReference">if set to <c>false</c> throw an exception if <see cref="IContent.Reference"/> is not null.</param> public void AddChild(GraphNode child, bool allowIfReference = false) { if (isSealed) throw new InvalidOperationException("Unable to add a child to a GraphNode that has been sealed"); if (child.Parent != null) throw new ArgumentException(@"This node has already been registered to a different parent", nameof(child)); if (Content.Reference != null && !allowIfReference) throw new InvalidOperationException("A GraphNode cannot have children when its content hold a reference."); child.Parent = this; children.Add(child); }
public void Check(GraphNode node, object obj, Type type, bool checkReferences) { Reset(); if (node.Content.Value != obj) throw new QuantumConsistencyException("The node content value [{0}]", obj.ToStringSafe(), "The node content value [{0}]", node.Content.Value.ToStringSafe(), node); if (node.Content.Type != type) throw new QuantumConsistencyException("The node content type [{0}]", type.Name, "The node content value [{0}]", node.Content.Type.Name, node); rootNode = node; while (rootNode != null) { if (rootNode.Parent != null) throw new QuantumConsistencyException("A root node", "A node with a parent", rootNode); if (rootNode.Content.Value != null) { var typeDescriptor = TypeDescriptorFactory.Find(rootNode.Content.Type); PushContextNode(rootNode); VisitObject(rootNode.Content.Value, typeDescriptor as ObjectDescriptor, true); PopContextNode(); } checkedNodes.Add(rootNode); rootNode = null; if (checkReferences) { while (references.Count > 0) { var reference = references.Dequeue(); if (!checkedNodes.Contains(reference.TargetNode)) { rootNode = (GraphNode)reference.TargetNode; break; } } } } }
private void PushContextNode(GraphNode node) { contextStack.Push(node); }
/// <inheritdoc/> public override void VisitObject(object obj, ObjectDescriptor descriptor, bool visitMembers) { ITypeDescriptor currentDescriptor = descriptor; bool isRootNode = contextStack.Count == 0; if (isRootNode) { bool shouldProcessReference; if (!NotifyNodeConstructing(descriptor, out shouldProcessReference)) return; // If we are in the case of a collection of collections, we might have a root node that is actually an enumerable reference // This would be the case for each collection within the base collection. IContent content = descriptor.Type.IsStruct() ? ContentFactory.CreateBoxedContent(this, obj, descriptor, IsPrimitiveType(descriptor.Type)) : ContentFactory.CreateObjectContent(this, obj, descriptor, IsPrimitiveType(descriptor.Type), shouldProcessReference); currentDescriptor = content.Descriptor; rootNode = (GraphNode)NodeFactory(currentDescriptor.Type.Name, content, rootGuid); if (content.IsReference && currentDescriptor.Type.IsStruct()) throw new QuantumConsistencyException("A collection type", "A structure type", rootNode); if (content.IsReference) referenceContents.Add(content); AvailableCommands.Where(x => x.CanAttach(currentDescriptor, null)).ForEach(rootNode.AddCommand); NotifyNodeConstructed(content); if (obj == null) { rootNode.Seal(); return; } PushContextNode(rootNode); } if (!IsPrimitiveType(currentDescriptor.Type)) { base.VisitObject(obj, descriptor, true); } if (isRootNode) { PopContextNode(); rootNode.Seal(); } }