From eff079b2ec84d9cc0557cd0008e428f429bdb89f Mon Sep 17 00:00:00 2001 From: Mathias Kluba Date: Wed, 29 Feb 2012 08:28:11 +0100 Subject: [PATCH] add type to type dependency --- DependencyParser/Program.cs | 220 ++++++++++++++------ DependencyParser/Properties/AssemblyInfo.cs | 4 +- 2 files changed, 153 insertions(+), 71 deletions(-) diff --git a/DependencyParser/Program.cs b/DependencyParser/Program.cs index 42309e9..b9f2786 100644 --- a/DependencyParser/Program.cs +++ b/DependencyParser/Program.cs @@ -16,9 +16,7 @@ class Program private static readonly List parsed = new List(); private static readonly List toParse = new List(); - - private static readonly Dictionary> dependencies = new Dictionary>(); - + static void Main(string[] args) { bool show_help = false; @@ -58,7 +56,7 @@ static void Main(string[] args) writer.WriteAttributeString("name", definition.MainModule.Assembly.Name.Name); writer.WriteAttributeString("version", definition.MainModule.Assembly.Name.Version.ToString()); - Analysis(writer, definition.MainModule, assemblyName); + Analysis(writer, definition.MainModule, assemblyName, true); while (toParse.Count > 0) { @@ -95,7 +93,7 @@ static void Main(string[] args) } else { - Analysis(writer, definition.MainModule, targetFile.FullName); + Analysis(writer, definition.MainModule, targetFile.FullName, false); } } } @@ -115,7 +113,7 @@ static void Main(string[] args) } } - static void Analysis(XmlTextWriter writer, ModuleDefinition module, string fullPath) + static void Analysis(XmlTextWriter writer, ModuleDefinition module, string fullPath, bool withTypes) { try { @@ -146,98 +144,182 @@ static void Analysis(XmlTextWriter writer, ModuleDefinition module, string fullP { toParse.Add(item.FullName); } + } + writer.WriteEndElement(); - /*foreach (var t in module.Types) + if (withTypes) + { + writer.WriteStartElement("TypeReferences"); + foreach (var t in module.Types) { - foreach (var c in t.CustomAttributes) - { - AddDependency(t, c.AttributeType); - } + ParseType(writer, t); + } - if (t.BaseType != null) - { - AddDependency(t, t.BaseType); - } + writer.WriteEndElement(); + } - foreach (var i in t.Interfaces) - { - AddDependency(t, i); - } + writer.WriteEndElement(); - foreach (var e in t.Events) - { - AddDependency(t, e.EventType); - } + if (toParse.Contains(module.Assembly.Name.FullName)) + { + toParse.Remove(module.Assembly.Name.FullName); + } - foreach (var f in t.Fields) - { - AddDependency(t, f.FieldType); - } + parsed.Add(module.Assembly.Name.FullName); + } + + public static void ParseType(XmlTextWriter writer, TypeDefinition t) + { + // ignore generated types + if (t.DeclaringType == null && t.Namespace.Equals(string.Empty)) + { + return; + } - foreach (var p in t.Properties) + if (t.Name.StartsWith("<>")) + { + return; + } + + foreach (var n in t.NestedTypes) + { + ParseType(writer, n); + } + + Dictionary> cache = new Dictionary>(); + writer.WriteStartElement("From"); + writer.WriteAttributeString("fullname", t.FullName); + + foreach (var c in t.CustomAttributes) + { + AddDependency(writer, cache, t, c.AttributeType); + } + + if (t.BaseType != null) + { + AddDependency(writer, cache, t, t.BaseType); + } + + foreach (var i in t.Interfaces) + { + AddDependency(writer, cache, t, i); + } + + foreach (var e in t.Events) + { + AddDependency(writer, cache, t, e.EventType); + } + + foreach (var f in t.Fields) + { + AddDependency(writer, cache, t, f.FieldType); + } + + foreach (var p in t.Properties) + { + AddDependency(writer, cache, t, p.PropertyType); + } + + foreach (var m in t.Methods) + { + AddDependency(writer, cache, t, m.ReturnType); + + foreach (var p in m.Parameters) + { + AddDependency(writer, cache, t, p.ParameterType); + } + + if (m.Body != null) + { + //m.Body.Instructions[0].SequencePoint.Document + + foreach (var v in m.Body.Variables) { - AddDependency(t, p.PropertyType); + AddDependency(writer, cache, t, v.VariableType); } - foreach (var m in t.Methods) + foreach (var e in m.Body.ExceptionHandlers) { - AddDependency(t, m.ReturnType); - - foreach (var p in m.Parameters) + if (e.CatchType != null) { - AddDependency(t, p.ParameterType); + AddDependency(writer, cache, t, e.CatchType); } + } + } + } - if (m.Body != null) - { - //m.Body.Instructions[0].SequencePoint.Document + writer.WriteEndElement(); + } - foreach (var v in m.Body.Variables) - { - AddDependency(t, v.VariableType); - } + public static void AddDependency(XmlTextWriter writer, IDictionary> cache, TypeDefinition from, TypeReference to) + { + if (from.FullName.Equals(to.FullName)) + { + return; + } - foreach (var e in m.Body.ExceptionHandlers) - { - if (e.CatchType != null) - { - AddDependency(t, e.CatchType); - } - } - } - } - }*/ + // ignore generic parameters + if (to.IsGenericParameter) + { + return; } - writer.WriteEndElement(); - writer.WriteEndElement(); - if (toParse.Contains(module.Assembly.Name.FullName)) + // ignore generated types, without namespace + if (to.Namespace.Equals(string.Empty)) { - toParse.Remove(module.Assembly.Name.FullName); + return; } - parsed.Add(module.Assembly.Name.FullName); - } + if (to.IsArray) + { + to = to.GetElementType(); + } + + if (to.IsGenericInstance) + { + var generic = (GenericInstanceType)to; + foreach (var a in generic.GenericArguments) + { + AddDependency(writer, cache, from, a); + } + to = to.GetElementType(); + } + + // ignore types from .Net framework + if (to.Scope.Name.Equals("mscorlib") || to.Scope.Name.StartsWith("System") || to.Scope.Name.StartsWith("Microsoft")) + { + return; + } - public static void AddDependency(TypeDefinition from, TypeReference to) - { IList toList; - if (!dependencies.TryGetValue(from.FullName, out toList)) + if (!cache.TryGetValue(from.FullName, out toList)) { toList = new List(); - dependencies.Add(from.FullName, toList); + cache.Add(from.FullName, toList); } - if (!to.FullName.StartsWith("System") && !to.FullName.StartsWith("Microsoft")) + if (toList.Contains(to.FullName)) { - if (!to.IsGenericParameter) - { - if (!toList.Contains(to.FullName)) - { - toList.Add(to.FullName); - } - } + return; + } + + + writer.WriteStartElement("To"); + writer.WriteAttributeString("fullname", to.FullName); + if (to.Scope is ModuleDefinition) + { + writer.WriteAttributeString("assemblyname", ((ModuleDefinition)to.Scope).Assembly.Name.Name); + writer.WriteAttributeString("assemblyversion", ((ModuleDefinition)to.Scope).Assembly.Name.Version.ToString()); + } + else if(to.Scope is AssemblyNameReference) + { + writer.WriteAttributeString("assemblyname", ((AssemblyNameReference)to.Scope).Name); + writer.WriteAttributeString("assemblyversion", ((AssemblyNameReference)to.Scope).Version.ToString()); } + + writer.WriteEndElement(); + + toList.Add(to.FullName); } } } diff --git a/DependencyParser/Properties/AssemblyInfo.cs b/DependencyParser/Properties/AssemblyInfo.cs index 21c422f..f8b1241 100644 --- a/DependencyParser/Properties/AssemblyInfo.cs +++ b/DependencyParser/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("1.1.0.0")] +[assembly: AssemblyFileVersion("1.1.0.0")]