Merge pull request #5353 from jonpryor/jonp-mono-api-html-ignore-class-removal
[mono.git] / mcs / tools / linker-analyzer / LinkerAnalyzerCore / DependencyGraph.cs
1 //
2 // DependencyGraph.cs: linker dependencies graph
3 //
4 // Author:
5 //   Radek Doulik (rodo@xamarin.com)
6 //
7 // Copyright 2015 Xamarin Inc (http://www.xamarin.com).
8 //
9 using System;
10 using System.Collections.Generic;
11 using System.IO;
12 using System.IO.Compression;
13 using System.Xml;
14
15 namespace LinkerAnalyzer.Core
16 {
17         public class VertexData {
18                 public string value;
19                 public List<int> parentIndexes;
20                 public int index;
21
22                 public string DepsCount {
23                         get {
24                                 if (parentIndexes == null || parentIndexes.Count < 1)
25                                         return "";
26                                 return string.Format (" [{0} deps]", parentIndexes.Count);
27                         }
28                 }
29         };
30
31         public class DependencyGraph
32         {
33                 protected List<VertexData> vertices = new List<VertexData> ();
34                 public List<VertexData> Types = new List<VertexData> ();
35                 Dictionary<string, int> indexes = new Dictionary<string, int> ();
36                 protected Dictionary<string, int> counts = new Dictionary<string, int> ();
37
38                 public void Load (string filename)
39                 {
40                         Console.WriteLine ("Loading dependency tree from: {0}", filename);
41
42                         using (var fileStream = File.OpenRead (filename))
43                         using (var zipStream = new GZipStream (fileStream, CompressionMode.Decompress)) {
44                                 try {
45                                         Load (zipStream);
46                                 } catch (Exception) {
47                                         Console.WriteLine ("Unable to open and read the dependecies.");
48                                         Environment.Exit (1);
49                                 }
50                         }
51                 }
52
53                 void Load (GZipStream zipStream) {
54                         using (XmlReader reader = XmlReader.Create (zipStream)) {
55                                 while (reader.Read ()) {
56                                         switch (reader.NodeType) {
57                                         case XmlNodeType.Element:
58                                                 //Console.WriteLine (reader.Name);
59                                                 if (reader.Name == "edge" && reader.IsStartElement ()) {
60                                                         string b = reader.GetAttribute ("b");
61                                                         string e = reader.GetAttribute ("e");
62                                                         //Console.WriteLine ("edge value " + b + "  -->  " + e);
63
64                                                         if (e != b) {
65                                                                 VertexData begin = Vertex (b, true);
66                                                                 VertexData end = Vertex (e, true);
67
68                                                                 if (end.parentIndexes == null)
69                                                                         end.parentIndexes = new List<int> ();
70                                                                 if (!end.parentIndexes.Contains (begin.index)) {
71                                                                         end.parentIndexes.Add (begin.index);
72                                                                         //Console.WriteLine (" end parent index: {0}", end.parentIndexes);
73                                                                 }
74                                                         }
75                                                 }
76                                                 break;
77                                         default:
78                                                 //Console.WriteLine ("node: " + reader.NodeType);
79                                                 break;
80                                         }
81                                 }
82                         }
83                 }
84
85                 public VertexData Vertex (string vertexName, bool create = false)
86                 {
87                         VertexData vertex;
88
89                         try {
90                                 vertex = vertices [indexes [vertexName]];
91                         } catch (KeyNotFoundException) {
92                                 if (create) {
93                                         int index = vertices.Count;
94                                         vertex = new VertexData () { value = vertexName, index = index };
95                                         vertices.Add (vertex);
96                                         indexes.Add (vertexName, index);
97                                         string prefix = vertexName.Substring (0, vertexName.IndexOf (':'));
98                                         if (counts.ContainsKey (prefix))
99                                                 counts [prefix]++;
100                                         else
101                                                 counts [prefix] = 1;
102                                         //Console.WriteLine ("prefix " + prefix + " count " + counts[prefix]);
103                                         if (prefix == "TypeDef") {
104                                                 Types.Add (vertex);
105                                         }
106                                 } else
107                                         return null;
108                         }
109
110                         return vertex;
111                 }
112
113                 public VertexData Vertex (int index)
114                 {
115                         return vertices [index];
116                 }
117         }
118 }