// // monop -- a semi-clone of javap // // TODO: // Dump all attributes. // // Authors: // Ben Maurer (bmaurer@users.sourceforge.net) // John Luke (john.luke@gmail.com) // // (C) 2004 Ben Maurer // (C) 2004 John Luke // // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.CodeDom.Compiler; using System.Collections; using System.Diagnostics; using System.IO; using IKVM.Reflection; using System.Text; using Mono.CSharp; using Type=IKVM.Reflection.Type; class MonoP { static Universe universe = new Universe(UniverseOptions.EnableFunctionPointers | UniverseOptions.ResolveMissingMembers | UniverseOptions.DisablePseudoCustomAttributeRetrieval); static Assembly mscorlib; static Type obsolete_attribute; static string assembly; // very common namespaces, all in corlib static readonly string [] v_common_ns = { "System", "System.Collections", "System.Reflection", "System.Text", "System.IO", }; static readonly string [] common_assemblies = { "System.Xml.dll", "System.Web.dll", "gtk-sharp.dll", "glib-sharp.dll" }; static readonly string [] common_ns = { "System.Xml", "System.Web", "Foundation", "CoreFoundation", "CoreGraphics", "UIKit", "Gtk", "GLib", }; static Type GetType (string tname, bool ignoreCase) { Type t; if (assembly != null) { Assembly a = GetAssembly (assembly, true); t = a.GetType (tname, false, ignoreCase); } else { t = mscorlib.GetType (tname, false, ignoreCase); } return t; } static string SearchTypes (string name, ref Type retval, out int count) { StringBuilder sb = new StringBuilder (); Type current = null; count = 0; string [] assemblies = GetKnownAssemblyNames (); for (int i = 0; i < assemblies.Length; i++) { Console.WriteLine ("Loading {0}", assemblies[i]); Assembly a = GetAssembly (assemblies [i], false); if (a == null) continue; Type [] types = a.GetTypes (); for (int j = 0; j < types.Length; j++) { Type t = types [j]; if (t.IsPublic == false) continue; if (t.Name == name || t.Name.ToLower ().IndexOf (name.ToLower ()) > 0) { current = t; count ++; sb.Append (t.FullName + " from " + a.Location + "\n"); } } } if (count == 0) return null; if (count == 1) { retval = current; return String.Empty; } return sb.ToString (); } static string [] GetKnownAssemblyNames () { Console.WriteLine (options.PublicDir); if (options.Style == "xios" || options.Style == "xand"){ return Directory.GetFiles (options.PublicDir, "*.dll"); } Process p = new Process (); p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.FileName = "gacutil"; p.StartInfo.Arguments = "-l"; try { p.Start (); } catch { Console.WriteLine ("WARNING: gacutil could not be found."); return new string[0]; } string s; ArrayList names = new ArrayList (); StreamReader output = p.StandardOutput; while ((s = output.ReadLine ()) != null) names.Add (s); p.WaitForExit (); int length = names.Count - 1; string [] retval = new string [length]; retval [0] = typeof (Object).Assembly.FullName; names.CopyTo (1, retval, 1, length - 1); // skip the first and last line return retval; } static Assembly GetAssembly (string assembly, bool exit) { Assembly a = null; // if -r:~/foo.dll syntax is used the shell misses it if (assembly.StartsWith ("~/")) assembly = Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.Personal), assembly.Substring (2)); try { // if it exists try to use LoadFrom if (File.Exists (assembly)) a = universe.LoadFile (assembly); else a = LoadFromMonoPath (assembly); } catch { // ignore exception it gets handled below } if (a == null && exit) { Console.WriteLine ("Could not load {0}", MonoP.assembly); Environment.Exit (1); } return a; } static Assembly LoadFromMonoPath (string assembly) { // ; on win32, : everywhere else char sep = (Path.DirectorySeparatorChar == '/' ? ':' : ';'); string[] paths = Environment.GetEnvironmentVariable ("MONO_PATH").Split (sep); foreach (string path in paths) { string apath = Path.Combine (path, assembly); if (File.Exists (apath)) return universe.LoadFile (apath); } return null; } static Type GetType (string tname) { return GetType (tname, false); } static void PrintRefs (string assembly) { Assembly a = GetAssembly (assembly, true); foreach (AssemblyName an in a.GetReferencedAssemblies ()) Console.WriteLine (an); } static void PrintTypes (string assembly, bool show_private, bool filter_obsolete) { Assembly a = GetAssembly (assembly, true); Console.WriteLine (); Console.WriteLine ("Assembly Information:"); foreach (string ai in a.ToString ().Split (',')) Console.WriteLine (ai.Trim ()); Console.WriteLine (); Type [] types = show_private ? a.GetTypes () : a.GetExportedTypes (); Array.Sort (types, new TypeSorter ()); int obsolete_count = 0; foreach (Type t in types) { if (filter_obsolete && t.IsDefined (obsolete_attribute, false)) obsolete_count++; else Console.WriteLine (t.FullName); } Console.WriteLine ("\nTotal: {0} types.", types.Length - obsolete_count); } internal static void Completion (string prefix) { foreach (Type t in mscorlib.GetExportedTypes ()) { if (t.Name.StartsWith (prefix)) { if (Array.IndexOf (v_common_ns, t.Namespace) != -1) { Console.WriteLine (t.Name); return; } } if (t.FullName.StartsWith (prefix)) { Console.WriteLine (t.FullName); } } foreach (string assm in common_assemblies) { try { Assembly a = GetAssembly (assm, true); foreach (Type t in a.GetExportedTypes ()) { if (t.Name.StartsWith (prefix)) { if (Array.IndexOf (common_ns, t.Namespace) != -1) { Console.WriteLine (t.Name); return; } } if (t.FullName.StartsWith (prefix)) { Console.WriteLine (t.FullName); } } } catch { } } } static void ShowAll (string assembly, bool show_private, bool filter_obsolete) { Assembly a = GetAssembly (assembly, true); foreach (string ai in a.ToString ().Split (',')) Console.WriteLine (ai.Trim ()); Console.WriteLine (); Type [] types = show_private ? a.GetTypes () : a.GetExportedTypes (); Array.Sort (types, new TypeSorter ()); var sw = new StreamWriter (Console.OpenStandardOutput (), Console.Out.Encoding); foreach (Type t in types) { if (filter_obsolete && t.IsDefined (obsolete_attribute, false)) continue; new Outline (universe, mscorlib, t, sw, true, show_private, filter_obsolete).OutlineType (); } sw.Flush (); } static Options options = new Options (); static int Main (string [] args) { if (!options.ProcessArgs (args)) return 1; if (options.Style == null) mscorlib = universe.LoadFile (typeof (int).Assembly.Location); else mscorlib = universe.LoadFile (Path.Combine (options.PublicDir, "mscorlib.dll")); obsolete_attribute = mscorlib.GetType ("System.ObsoleteAttribute"); if (options.AssemblyReference != null) { assembly = options.AssemblyReference; if (options.ShowAll){ ShowAll (assembly, options.ShowPrivate, options.FilterObsolete); return 0; } else { if (options.Type == null) { if (options.PrintRefs) PrintRefs (assembly); else PrintTypes (assembly, options.ShowPrivate, options.FilterObsolete); return 0; } } } string message = null; string tname = options.Type; Type t = null; int count; if (options.Search) { string matches = SearchTypes (tname, ref t, out count); if (count == 0) goto notfound; if (count == 1) goto found; if (count > 1){ Console.WriteLine ("Found " + count + " types that match:"); Console.WriteLine (matches); return 0; } } t = GetType (tname); if (t == null) { // Try some very common ones, dont load anything foreach (string ns in v_common_ns) { t = GetType (ns + "." + tname, true); if (t != null) goto found; } } if (t == null) { foreach (string assm in GetKnownAssemblyNames ()) { try { Assembly a = GetAssembly (assm, false); if (a == null) continue; t = a.GetType (tname, false, true); if (t != null) { message = String.Format ("{0} is included in the {1} assembly.", t.FullName, t.Assembly.GetName ().Name); goto found; } foreach (string ns in common_ns) { t = a.GetType (ns + "." + tname, false, true); if (t != null) { message = String.Format ("{0} is included in the {1} assembly.", t.FullName, t.Assembly.GetName ().Name); goto found; } } } catch (Exception e){ Console.WriteLine ("Failure: " + e); } } } notfound: if (t == null) { Console.WriteLine ("Could not find {0}", tname); return 1; } found: // // This gets us nice buffering // StreamWriter sw = new StreamWriter (Console.OpenStandardOutput (), Console.Out.Encoding); new Outline (universe, mscorlib, t, sw, options.DeclaredOnly, options.ShowPrivate, options.FilterObsolete).OutlineType (); sw.Flush (); if (message != null) Console.WriteLine (message); return 0; } }