public static string Serialize(CallGraph cg) { using (var stringWriter = new StringWriter()) using (var xmlWriter = new XmlTextWriter(stringWriter)) { var reachableMethods = new Dictionary <IMethodReference, int>(MethodReferenceDefinitionComparer.Default); xmlWriter.Formatting = Formatting.Indented; xmlWriter.WriteStartElement("DirectedGraph"); xmlWriter.WriteAttributeString("xmlns", "http://schemas.microsoft.com/vs/2009/dgml"); xmlWriter.WriteStartElement("Nodes"); foreach (var method in cg.Methods) { reachableMethods.Add(method, reachableMethods.Count); } foreach (var method in cg.Roots) { var methodId = reachableMethods[method]; var nodeId = Convert.ToString(methodId); var label = MemberHelper.GetMethodSignature(method); xmlWriter.WriteStartElement("Node"); xmlWriter.WriteAttributeString("Id", nodeId); xmlWriter.WriteAttributeString("Label", label); xmlWriter.WriteAttributeString("Background", "Yellow"); xmlWriter.WriteEndElement(); } var otherMethods = cg.Methods.Except(cg.Roots); foreach (var method in otherMethods) { var methodId = reachableMethods[method]; var nodeId = Convert.ToString(methodId); var label = MemberHelper.GetMethodSignature(method); xmlWriter.WriteStartElement("Node"); xmlWriter.WriteAttributeString("Id", nodeId); xmlWriter.WriteAttributeString("Label", label); xmlWriter.WriteEndElement(); } xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Links"); foreach (var entry in reachableMethods) { var sourceId = Convert.ToString(entry.Value); var invocationsPerCallee = from inv in cg.GetInvocations(entry.Key) from callee in inv.PossibleCallees group inv by callee into g select g; foreach (var invocations in invocationsPerCallee) { var calleeId = reachableMethods[invocations.Key]; var targetId = Convert.ToString(calleeId); var label = string.Join("\n", invocations.Select(inv => inv.Label)); xmlWriter.WriteStartElement("Link"); xmlWriter.WriteAttributeString("Source", sourceId); xmlWriter.WriteAttributeString("Target", targetId); xmlWriter.WriteAttributeString("Label", label); xmlWriter.WriteEndElement(); } } xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Styles"); xmlWriter.WriteStartElement("Style"); xmlWriter.WriteAttributeString("TargetType", "Node"); xmlWriter.WriteStartElement("Setter"); xmlWriter.WriteAttributeString("Property", "FontFamily"); xmlWriter.WriteAttributeString("Value", "Consolas"); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Setter"); xmlWriter.WriteAttributeString("Property", "NodeRadius"); xmlWriter.WriteAttributeString("Value", "5"); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Setter"); xmlWriter.WriteAttributeString("Property", "MinWidth"); xmlWriter.WriteAttributeString("Value", "0"); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); xmlWriter.Flush(); return(stringWriter.ToString()); } }