public override bool Equals(ValueNode other) { if (other == null) { return(false); } if (this.Kind != other.Kind) { return(false); } GetTypeFromStringValue otherGtfs = (GetTypeFromStringValue)other; return(this.AssemblyIdentity.Equals(otherGtfs.AssemblyIdentity) && this.NameString.Equals(otherGtfs.NameString)); }
/// <summary> /// Returns true if a ValueNode graph contains a cycle /// </summary> /// <param name="node">Node to evaluate</param> /// <param name="seenNodes">Set of nodes previously seen on the current arc. Callers may pass a non-empty set /// to test whether adding that set to this node would create a cycle. Contents will be modified by the walk /// and should not be used by the caller after returning</param> /// <param name="allNodesSeen">Optional. The set of all nodes encountered during a walk after DetectCycle returns</param> /// <returns></returns> public static bool DetectCycle(this ValueNode node, HashSet <ValueNode> seenNodes, HashSet <ValueNode> allNodesSeen) { if (node == null) { return(false); } if (seenNodes.Contains(node)) { return(true); } seenNodes.Add(node); if (allNodesSeen != null) { allNodesSeen.Add(node); } bool foundCycle = false; switch (node.Kind) { // // Leaf nodes // case ValueNodeKind.Unknown: case ValueNodeKind.Null: case ValueNodeKind.SystemType: case ValueNodeKind.RuntimeTypeHandle: case ValueNodeKind.KnownString: case ValueNodeKind.AnnotatedString: case ValueNodeKind.ConstInt: case ValueNodeKind.MethodParameter: case ValueNodeKind.MethodReturn: case ValueNodeKind.SystemTypeForGenericParameter: case ValueNodeKind.RuntimeTypeHandleForGenericParameter: case ValueNodeKind.LoadField: break; // // Nodes with children // case ValueNodeKind.MergePoint: foreach (ValueNode val in ((MergePointValue)node).Values) { if (val.DetectCycle(seenNodes, allNodesSeen)) { foundCycle = true; } } break; case ValueNodeKind.GetTypeFromString: GetTypeFromStringValue gtfsv = (GetTypeFromStringValue)node; foundCycle = gtfsv.AssemblyIdentity.DetectCycle(seenNodes, allNodesSeen); foundCycle |= gtfsv.NameString.DetectCycle(seenNodes, allNodesSeen); break; case ValueNodeKind.Array: ArrayValue av = (ArrayValue)node; foundCycle = av.Size.DetectCycle(seenNodes, allNodesSeen); break; default: throw new Exception(String.Format("Unknown node kind: {0}", node.Kind)); } seenNodes.Remove(node); return(foundCycle); }