X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Ftools%2Fcorcompare%2Fmono-api-info.cs;h=c43437fe40d869165c5b7d20f02eaa036c58a85f;hb=266345ec8f312b59cbd0bd1026d7304e30a91a2a;hp=b32394dd5f79d0b8aec634b48cb236b5981f15d3;hpb=28f473c41df72b278eaf9784c29c2b8fa2cbe06a;p=mono.git diff --git a/mcs/tools/corcompare/mono-api-info.cs b/mcs/tools/corcompare/mono-api-info.cs index b32394dd5f7..c43437fe40d 100644 --- a/mcs/tools/corcompare/mono-api-info.cs +++ b/mcs/tools/corcompare/mono-api-info.cs @@ -28,38 +28,64 @@ namespace CorCompare { public static int Main (string [] args) { - if (args.Length == 0) - return 1; - + bool showHelp = false; AbiMode = false; - - AssemblyCollection acoll = new AssemblyCollection (); + FollowForwarders = false; + + var acoll = new AssemblyCollection (); + + var options = new Mono.Options.OptionSet { + "usage: mono-api-info [OPTIONS+] ASSEMBLY+", + "", + "Expose IL structure of CLR assemblies as XML.", + "", + "Available Options:", + { "abi", + "Generate ABI, not API; contains only classes with instance fields which are not [NonSerialized].", + v => AbiMode = v != null }, + { "f|follow-forwarders", + "Follow type forwarders.", + v => FollowForwarders = v != null }, + { "d|L|lib|search-directory=", + "Check for assembly references in {DIRECTORY}.", + v => TypeHelper.Resolver.AddSearchDirectory (v) }, + { "r=", + "Read and register the file {ASSEMBLY}, and add the directory containing ASSEMBLY to the search path.", + v => TypeHelper.Resolver.ResolveFile (v) }, + { "h|?|help", + "Show this message and exit.", + v => showHelp = v != null }, + }; + + var asms = options.Parse (args); + + if (showHelp || asms.Count == 0) { + options.WriteOptionDescriptions (Console.Out); + Console.WriteLine (); + return showHelp? 0 :1; + } string windir = Environment.GetFolderPath(Environment.SpecialFolder.Windows); string pf = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); TypeHelper.Resolver.AddSearchDirectory (Path.Combine (windir, @"assembly\GAC\MSDATASRC\7.0.3300.0__b03f5f7f11d50a3a")); - foreach (string arg in args) { - if (arg == "--abi") { - AbiMode = true; - } else { - acoll.Add (arg); - - if (arg.Contains ("v3.0")) { - TypeHelper.Resolver.AddSearchDirectory (Path.Combine (windir, @"Microsoft.NET\Framework\v2.0.50727")); - } else if (arg.Contains ("v3.5")) { - TypeHelper.Resolver.AddSearchDirectory (Path.Combine (windir, @"Microsoft.NET\Framework\v2.0.50727")); - TypeHelper.Resolver.AddSearchDirectory (Path.Combine (windir, @"Microsoft.NET\Framework\v3.0\Windows Communication Foundation")); - } else if (arg.Contains ("v4.0")) { - if (arg.Contains ("Silverlight")) { - TypeHelper.Resolver.AddSearchDirectory (Path.Combine (pf, @"Microsoft Silverlight\4.0.51204.0")); - } else { - TypeHelper.Resolver.AddSearchDirectory (Path.Combine (windir, @"Microsoft.NET\Framework\v4.0.30319")); - TypeHelper.Resolver.AddSearchDirectory (Path.Combine (windir, @"Microsoft.NET\Framework\v4.0.30319\WPF")); - } + foreach (string arg in asms) { + acoll.Add (arg); + + if (arg.Contains ("v3.0")) { + TypeHelper.Resolver.AddSearchDirectory (Path.Combine (windir, @"Microsoft.NET\Framework\v2.0.50727")); + } else if (arg.Contains ("v3.5")) { + TypeHelper.Resolver.AddSearchDirectory (Path.Combine (windir, @"Microsoft.NET\Framework\v2.0.50727")); + TypeHelper.Resolver.AddSearchDirectory (Path.Combine (windir, @"Microsoft.NET\Framework\v3.0\Windows Communication Foundation")); + } else if (arg.Contains ("v4.0")) { + if (arg.Contains ("Silverlight")) { + TypeHelper.Resolver.AddSearchDirectory (Path.Combine (pf, @"Microsoft Silverlight\4.0.51204.0")); } else { - TypeHelper.Resolver.AddSearchDirectory (Path.GetDirectoryName (arg)); + TypeHelper.Resolver.AddSearchDirectory (Path.Combine (windir, @"Microsoft.NET\Framework\v4.0.30319")); + TypeHelper.Resolver.AddSearchDirectory (Path.Combine (windir, @"Microsoft.NET\Framework\v4.0.30319\WPF")); } + } else { + TypeHelper.Resolver.AddSearchDirectory (Path.GetDirectoryName (arg)); } } @@ -75,6 +101,7 @@ namespace CorCompare } internal static bool AbiMode { get; private set; } + internal static bool FollowForwarders { get; private set; } } public class Utils { @@ -223,16 +250,33 @@ namespace CorCompare AddAttribute (nassembly, "name", aname.Name); AddAttribute (nassembly, "version", aname.Version.ToString ()); parent.AppendChild (nassembly); - TypeForwardedToData.OutputForwarders (document, nassembly, ass); + + if (!Driver.FollowForwarders) { + TypeForwardedToData.OutputForwarders (document, nassembly, ass); + } + AttributeData.OutputAttributes (document, nassembly, ass); - var typesCollection = ass.MainModule.Types; - if (typesCollection == null || typesCollection.Count == 0) + + var types = new List (); + if (ass.MainModule.Types != null) { + types.AddRange (ass.MainModule.Types); + } + + if (Driver.FollowForwarders && ass.MainModule.ExportedTypes != null) { + foreach (var t in ass.MainModule.ExportedTypes) { + var forwarded = t.Resolve (); + if (forwarded == null) { + throw new Exception ("Could not resolve forwarded type " + t.FullName + " in " + ass.Name); + } + types.Add (forwarded); + } + } + + if (types.Count == 0) { return; - var typesArray = new TypeDefinition [typesCollection.Count]; - for (int i = 0; i < typesCollection.Count; i++) { - typesArray [i] = typesCollection [i]; } - Array.Sort (typesArray, TypeReferenceComparer.Default); + + types.Sort (TypeReferenceComparer.Default); XmlNode nss = document.CreateElement ("namespaces", null); nassembly.AppendChild (nss); @@ -240,7 +284,7 @@ namespace CorCompare string current_namespace = "$%&$&"; XmlNode ns = null; XmlNode classes = null; - foreach (TypeDefinition t in typesArray) { + foreach (TypeDefinition t in types) { if (string.IsNullOrEmpty (t.Namespace)) continue; @@ -452,7 +496,7 @@ namespace CorCompare PropertyDefinition[] properties = GetProperties (type); if (properties.Length > 0) { - Array.Sort (properties, MemberReferenceComparer.Default); + Array.Sort (properties, PropertyDefinitionComparer.Default); members.Add (new PropertyData (document, nclass, properties)); } @@ -1000,9 +1044,7 @@ namespace CorCompare parent.AppendChild (natts); } - for (int i = 0; i < atts.Count; ++i) { - CustomAttribute att = atts [i]; - + foreach (var att in atts.OrderBy ((a) => a.Constructor.DeclaringType.FullName)) { string attName = Utils.CleanupTypeName (att.Constructor.DeclaringType); if (SkipAttribute (att)) continue; @@ -1340,19 +1382,17 @@ namespace CorCompare } - class TypeReferenceComparer : IComparer + class TypeReferenceComparer : IComparer { public static TypeReferenceComparer Default = new TypeReferenceComparer (); - public int Compare (object a, object b) + public int Compare (TypeReference a, TypeReference b) { - TypeReference ta = (TypeReference) a; - TypeReference tb = (TypeReference) b; - int result = String.Compare (ta.Namespace, tb.Namespace); + int result = String.Compare (a.Namespace, b.Namespace, StringComparison.Ordinal); if (result != 0) return result; - return String.Compare (ta.Name, tb.Name); + return String.Compare (a.Name, b.Name, StringComparison.Ordinal); } } @@ -1364,7 +1404,30 @@ namespace CorCompare { MemberReference ma = (MemberReference) a; MemberReference mb = (MemberReference) b; - return String.Compare (ma.Name, mb.Name); + return String.Compare (ma.Name, mb.Name, StringComparison.Ordinal); + } + } + + class PropertyDefinitionComparer : IComparer + { + public static PropertyDefinitionComparer Default = new PropertyDefinitionComparer (); + + public int Compare (PropertyDefinition ma, PropertyDefinition mb) + { + int res = String.Compare (ma.Name, mb.Name); + if (res != 0) + return res; + + if (!ma.HasParameters && !mb.HasParameters) + return 0; + + if (!ma.HasParameters) + return -1; + + if (!mb.HasParameters) + return 1; + + return MethodDefinitionComparer.Compare (ma.Parameters, mb.Parameters); } } @@ -1389,9 +1452,17 @@ namespace CorCompare if (!mb.HasParameters) return 1; - IList pia = ma.Parameters ; - IList pib = mb.Parameters; - res = pia.Count - pib.Count; + res = Compare (ma.Parameters, mb.Parameters); + if (res != 0) + return res; + + // operators can differ by only return type + return string.CompareOrdinal (ma.ReturnType.FullName, mb.ReturnType.FullName); + } + + public static int Compare (IList pia, IList pib) + { + var res = pia.Count - pib.Count; if (res != 0) return res;