public static IEnumerable <Node> ConnectedNodes(this BinaryDecisionTree bdt) { return(bdt.Vertices.SelectMany(v => new[] { v.Source, v.Target }) .Distinct() .ToList()); }
public static XElement ToDgml(this BinaryDecisionTree bdt) { var nodes = from n in bdt.ConnectedNodes() select n.ToDgml(); var links = from v in bdt.Vertices select v.ToDgml(); return(CreateGraph(nodes, links)); }
public string CreateGraph(TypeDefinition definition) { var nodeCache = new Dictionary <string, Node>(); var tree = new BinaryDecisionTree(); foreach (var method in definition.Methods) { nodeCache[method.FullName] = new Node(method, definition); } Func <MethodReference, Node> fromNodeCache = mr => { if (nodeCache.ContainsKey(mr.FullName)) { return(nodeCache[mr.FullName]); } nodeCache[mr.FullName] = new Node(mr, definition); return(nodeCache[mr.FullName]); }; Func <FieldReference, Node> fromNodeCacheField = fr => { if (nodeCache.ContainsKey(fr.FullName)) { return(nodeCache[fr.FullName]); } nodeCache[fr.FullName] = new Node(fr, definition); return(nodeCache[fr.FullName]); }; foreach (var method in definition.Methods.Where(m => m.HasBody)) { foreach (var instruction in method.Body.Instructions) { var mr = instruction.Operand as MethodReference; if (mr != null) { var md = instruction.Operand as MethodDefinition; if (mr.IsGenericInstance) { mr = ((GenericInstanceMethod)mr).ElementMethod; } if (mr.DeclaringType == definition || IsInheritedFrom(definition, mr.DeclaringType)) { var source = fromNodeCache(method); var target = fromNodeCache(mr); if (md != null && md.IsGetter) { tree.Add(new Vertex(source, target, VertexType.ReadProperty)); continue; } tree.Add(new Vertex(source, target)); } } var fr = instruction.Operand as FieldDefinition; if (fr != null) { if (fr.Name?.EndsWith(">k__BackingField") == true) { continue; } if (fr.DeclaringType == definition || IsInheritedFrom(definition, fr.DeclaringType)) { var source = fromNodeCache(method); var target = fromNodeCacheField(fr); if (instruction.OpCode.Code == Code.Ldfld) { tree.Add(new Vertex(source, target, VertexType.ReadProperty)); continue; } tree.Add(new Vertex(source, target)); } } } } return(tree.ToDgml().ToString()); }