2014-08-13 10:39:27 +01:00
|
|
|
//
|
|
|
|
// monop -- a semi-clone of javap
|
|
|
|
//
|
2015-04-07 09:35:12 +01:00
|
|
|
// TODO:
|
|
|
|
// Dump all attributes.
|
|
|
|
//
|
2014-08-13 10:39:27 +01:00
|
|
|
// 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;
|
2015-04-07 09:35:12 +01:00
|
|
|
using IKVM.Reflection;
|
2014-08-13 10:39:27 +01:00
|
|
|
using System.Text;
|
|
|
|
using Mono.CSharp;
|
2015-04-07 09:35:12 +01:00
|
|
|
using Type=IKVM.Reflection.Type;
|
2014-08-13 10:39:27 +01:00
|
|
|
|
|
|
|
class MonoP {
|
2015-04-07 09:35:12 +01:00
|
|
|
static Universe universe = new Universe(UniverseOptions.EnableFunctionPointers | UniverseOptions.ResolveMissingMembers | UniverseOptions.DisablePseudoCustomAttributeRetrieval);
|
|
|
|
static Assembly mscorlib;
|
|
|
|
static Type obsolete_attribute;
|
2014-08-13 10:39:27 +01:00
|
|
|
static string assembly;
|
|
|
|
|
|
|
|
// very common namespaces, all in corlib
|
|
|
|
static readonly string [] v_common_ns = {
|
|
|
|
"System",
|
|
|
|
"System.Collections",
|
|
|
|
"System.Reflection",
|
|
|
|
"System.Text",
|
2015-04-07 09:35:12 +01:00
|
|
|
"System.IO",
|
2014-08-13 10:39:27 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
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",
|
2015-04-07 09:35:12 +01:00
|
|
|
"Foundation",
|
|
|
|
"CoreFoundation",
|
|
|
|
"CoreGraphics",
|
|
|
|
"UIKit",
|
2014-08-13 10:39:27 +01:00
|
|
|
"Gtk",
|
2015-04-07 09:35:12 +01:00
|
|
|
"GLib",
|
2014-08-13 10:39:27 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
static Type GetType (string tname, bool ignoreCase)
|
|
|
|
{
|
|
|
|
Type t;
|
|
|
|
if (assembly != null) {
|
|
|
|
Assembly a = GetAssembly (assembly, true);
|
|
|
|
t = a.GetType (tname, false, ignoreCase);
|
2015-04-07 09:35:12 +01:00
|
|
|
} else {
|
|
|
|
t = mscorlib.GetType (tname, false, ignoreCase);
|
|
|
|
}
|
2014-08-13 10:39:27 +01:00
|
|
|
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++) {
|
2015-04-07 09:35:12 +01:00
|
|
|
Console.WriteLine ("Loading {0}", assemblies[i]);
|
2014-08-13 10:39:27 +01:00
|
|
|
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 ()
|
|
|
|
{
|
2015-04-07 09:35:12 +01:00
|
|
|
Console.WriteLine (options.PublicDir);
|
|
|
|
if (options.Style == "xios" || options.Style == "xand"){
|
|
|
|
return Directory.GetFiles (options.PublicDir, "*.dll");
|
|
|
|
}
|
|
|
|
|
2014-08-13 10:39:27 +01:00
|
|
|
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))
|
2015-04-07 09:35:12 +01:00
|
|
|
a = universe.LoadFile (assembly);
|
2014-08-13 10:39:27 +01:00
|
|
|
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))
|
2015-04-07 09:35:12 +01:00
|
|
|
return universe.LoadFile (apath);
|
2014-08-13 10:39:27 +01:00
|
|
|
}
|
|
|
|
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) {
|
2015-04-07 09:35:12 +01:00
|
|
|
if (filter_obsolete && t.IsDefined (obsolete_attribute, false))
|
|
|
|
obsolete_count++;
|
|
|
|
else
|
2014-08-13 10:39:27 +01:00
|
|
|
Console.WriteLine (t.FullName);
|
|
|
|
}
|
|
|
|
|
|
|
|
Console.WriteLine ("\nTotal: {0} types.", types.Length - obsolete_count);
|
|
|
|
}
|
|
|
|
|
|
|
|
internal static void Completion (string prefix)
|
|
|
|
{
|
2015-04-07 09:35:12 +01:00
|
|
|
foreach (Type t in mscorlib.GetExportedTypes ()) {
|
2014-08-13 10:39:27 +01:00
|
|
|
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) {
|
2015-04-07 09:35:12 +01:00
|
|
|
if (filter_obsolete && t.IsDefined (obsolete_attribute, false))
|
2014-08-13 10:39:27 +01:00
|
|
|
continue;
|
|
|
|
|
2015-04-07 09:35:12 +01:00
|
|
|
new Outline (universe, mscorlib, t, sw, true, show_private, filter_obsolete).OutlineType ();
|
2014-08-13 10:39:27 +01:00
|
|
|
}
|
|
|
|
sw.Flush ();
|
|
|
|
}
|
2015-04-07 09:35:12 +01:00
|
|
|
|
|
|
|
static Options options = new Options ();
|
2014-08-13 10:39:27 +01:00
|
|
|
|
2015-06-10 19:29:21 -04:00
|
|
|
static int Main (string [] args)
|
2014-08-13 10:39:27 +01:00
|
|
|
{
|
|
|
|
if (!options.ProcessArgs (args))
|
2015-06-10 19:29:21 -04:00
|
|
|
return 1;
|
2014-08-13 10:39:27 +01:00
|
|
|
|
2015-04-07 09:35:12 +01:00
|
|
|
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");
|
|
|
|
|
2014-08-13 10:39:27 +01:00
|
|
|
if (options.AssemblyReference != null) {
|
|
|
|
assembly = options.AssemblyReference;
|
|
|
|
|
|
|
|
if (options.ShowAll){
|
|
|
|
ShowAll (assembly, options.ShowPrivate, options.FilterObsolete);
|
2015-06-10 19:29:21 -04:00
|
|
|
return 0;
|
2014-08-13 10:39:27 +01:00
|
|
|
} else {
|
|
|
|
if (options.Type == null) {
|
|
|
|
if (options.PrintRefs)
|
|
|
|
PrintRefs (assembly);
|
|
|
|
else
|
|
|
|
PrintTypes (assembly, options.ShowPrivate, options.FilterObsolete);
|
2015-06-10 19:29:21 -04:00
|
|
|
return 0;
|
2014-08-13 10:39:27 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-04-07 09:35:12 +01:00
|
|
|
|
2014-08-13 10:39:27 +01:00
|
|
|
string message = null;
|
|
|
|
string tname = options.Type;
|
|
|
|
Type t = null;
|
|
|
|
int count;
|
|
|
|
|
2015-04-07 09:35:12 +01:00
|
|
|
|
2014-08-13 10:39:27 +01:00
|
|
|
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);
|
2015-06-10 19:29:21 -04:00
|
|
|
return 0;
|
2014-08-13 10:39:27 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2015-04-07 09:35:12 +01:00
|
|
|
if (a == null)
|
|
|
|
continue;
|
2014-08-13 10:39:27 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2015-04-07 09:35:12 +01:00
|
|
|
} catch (Exception e){
|
|
|
|
Console.WriteLine ("Failure: " + e);
|
2014-08-13 10:39:27 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
notfound:
|
|
|
|
if (t == null) {
|
|
|
|
Console.WriteLine ("Could not find {0}", tname);
|
2015-06-10 19:29:21 -04:00
|
|
|
return 1;
|
2014-08-13 10:39:27 +01:00
|
|
|
}
|
|
|
|
found:
|
|
|
|
//
|
|
|
|
// This gets us nice buffering
|
|
|
|
//
|
|
|
|
StreamWriter sw = new StreamWriter (Console.OpenStandardOutput (), Console.Out.Encoding);
|
2015-04-07 09:35:12 +01:00
|
|
|
new Outline (universe, mscorlib, t, sw, options.DeclaredOnly, options.ShowPrivate, options.FilterObsolete).OutlineType ();
|
2014-08-13 10:39:27 +01:00
|
|
|
sw.Flush ();
|
|
|
|
|
|
|
|
if (message != null)
|
|
|
|
Console.WriteLine (message);
|
2015-06-10 19:29:21 -04:00
|
|
|
return 0;
|
2014-08-13 10:39:27 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|