2 // monop -- a semi-clone of javap
5 // Ben Maurer (bmaurer@users.sourceforge.net)
6 // John Luke (john.luke@gmail.com)
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 using System.CodeDom.Compiler;
36 using System.Collections;
37 using System.Diagnostics;
39 using System.Reflection;
42 static string assembly;
43 static BindingFlags default_flags =
44 BindingFlags.Instance |
48 // very common namespaces, all in corlib
49 static readonly string [] v_common_ns = {
57 static readonly string [] common_assemblies = {
64 static readonly string [] common_ns = {
71 static Type GetType (string tname, bool ignoreCase)
74 if (assembly != null) {
75 Assembly a = GetAssembly (assembly, true);
76 t = a.GetType (tname, false, ignoreCase);
78 t = Type.GetType (tname, false, ignoreCase);
84 static string [] GetAssemblyNamesFromGAC ()
86 Process p = new Process ();
87 p.StartInfo.UseShellExecute = false;
88 p.StartInfo.RedirectStandardOutput = true;
89 p.StartInfo.FileName = "gacutil";
90 p.StartInfo.Arguments = "-l";
94 ArrayList names = new ArrayList ();
95 StreamReader output = p.StandardOutput;
97 while ((s = output.ReadLine ()) != null)
102 string [] retval = new string [names.Count - 2];
103 names.CopyTo (1, retval, 0, retval.Length); // skip the first and last line
107 static Assembly GetAssembly (string assembly, bool exit)
111 // if -r:~/foo.dll syntax is used the shell misses it
112 if (assembly.StartsWith ("~/"))
113 assembly = Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.Personal), assembly.Substring (2));
116 // if it exists try to use LoadFrom
117 if (File.Exists (assembly))
118 a = Assembly.LoadFrom (assembly);
119 // if it looks like a fullname try that
120 else if (assembly.Split (',').Length == 4)
121 a = Assembly.Load (assembly);
122 // see if MONO_PATH has it
124 a = LoadFromMonoPath (assembly);
126 // ignore exception it gets handled below
129 // last try partial name
130 // this (apparently) is exception safe
132 a = Assembly.LoadWithPartialName (assembly);
134 if (a == null && exit) {
135 Console.WriteLine ("Could not load {0}", MonoP.assembly);
136 Environment.Exit (1);
142 static Assembly LoadFromMonoPath (string assembly)
144 // ; on win32, : everywhere else
145 char sep = (Path.DirectorySeparatorChar == '/' ? ':' : ';');
146 string[] paths = Environment.GetEnvironmentVariable ("MONO_PATH").Split (sep);
147 foreach (string path in paths)
149 string apath = Path.Combine (path, assembly);
150 if (File.Exists (apath))
151 return Assembly.LoadFrom (apath);
156 static Type GetType (string tname)
158 return GetType (tname, false);
161 static void PrintTypes (string assembly)
163 Assembly a = GetAssembly (assembly, true);
165 Console.WriteLine ();
166 Console.WriteLine ("Assembly Information:");
168 object[] cls = a.GetCustomAttributes (typeof (CLSCompliantAttribute), false);
171 CLSCompliantAttribute cca = cls[0] as CLSCompliantAttribute;
173 Console.WriteLine ("[CLSCompliant]");
176 foreach (string ai in a.ToString ().Split (','))
177 Console.WriteLine (ai.Trim ());
179 Console.WriteLine ();
180 Type [] types = a.GetExportedTypes ();
181 Array.Sort (types, new TypeSorter ());
183 foreach (Type t in types)
184 Console.WriteLine (t.FullName);
186 Console.WriteLine ("\nTotal: {0} types.", types.Length);
189 static void Completion (string prefix)
191 foreach (Type t in typeof (object).Assembly.GetExportedTypes ()) {
192 if (t.Name.StartsWith (prefix)) {
193 if (Array.IndexOf (v_common_ns, t.Namespace) != -1) {
194 Console.WriteLine (t.Name);
199 if (t.FullName.StartsWith (prefix)) {
200 Console.WriteLine (t.FullName);
204 foreach (string assm in common_assemblies) {
207 Assembly a = GetAssembly (assm, true);
208 foreach (Type t in a.GetExportedTypes ()) {
210 if (t.Name.StartsWith (prefix)) {
211 if (Array.IndexOf (common_ns, t.Namespace) != -1) {
212 Console.WriteLine (t.Name);
217 if (t.FullName.StartsWith (prefix)) {
218 Console.WriteLine (t.FullName);
228 static void PrintUsage ()
230 Console.WriteLine ("Usage is: monop [option] [-c] [-r:Assembly] [class-name]");
233 static void PrintHelp ()
236 Console.WriteLine ("");
237 Console.WriteLine ("options:");
238 Console.WriteLine ("\t--declared-only,-d\tOnly show members declared in the Type");
239 Console.WriteLine ("\t--help,-h\t\tShow this information");
240 Console.WriteLine ("\t--private,-p\t\tShow private members");
243 static void Main (string [] args)
245 if (args.Length < 1) {
250 if (args.Length == 1 && (args[0] == "--help" || args[0] == "-h"))
258 if (args [0].StartsWith ("-r:") || args [0].StartsWith ("/r:")){
260 assembly = args [0].Substring (3);
262 if (args.Length == 1) {
263 PrintTypes (assembly);
268 if (args [0] == "-c") {
269 Completion (args [1]);
273 if (args [i] == "--private" || args [i] == "-p") {
274 default_flags |= BindingFlags.NonPublic;
278 if (args [i] == "--declared-only" || args [i] == "-d") {
279 default_flags |= BindingFlags.DeclaredOnly;
283 if (args.Length < i + 1) {
288 string message = null;
289 string tname = args [i];
290 Type t = GetType (tname);
293 // Try some very common ones, dont load anything
294 foreach (string ns in v_common_ns) {
295 t = GetType (ns + "." + tname, true);
302 foreach (string assm in GetAssemblyNamesFromGAC ()) {
304 Assembly a = GetAssembly (assm, false);
305 t = a.GetType (tname, false, true);
307 message = String.Format ("{0} is included in the {1} assembly.",
309 t.Assembly.GetName ().Name);
312 foreach (string ns in common_ns) {
313 t = a.GetType (ns + "." + tname, false, true);
315 message = String.Format ("{0} is included in the {1} assembly.",
317 t.Assembly.GetName ().Name);
327 Console.WriteLine ("Could not find {0}", tname);
332 // This gets us nice buffering
334 StreamWriter sw = new StreamWriter (Console.OpenStandardOutput (), Console.Out.Encoding);
335 new Outline (t, sw).OutlineType (default_flags);
339 Console.WriteLine (message);