Example #1
0
        public static void Main(string[] args)
        {
            var sgopts = new StubGenOptions ();
            var opts = new OptionSet () {
                { "o=|output-dir=", "Directory to generate classes in. Defaults to current directory", v => sgopts.OutputDir = v },
                { "no-header", "Do not put header with license in generated files", v => sgopts.NoHeader = true },
                { "l|license=", "Name of the license or path to a text file with license text (defaults to MIT/X11)", v => sgopts.LicenseName = v },
                { "a|author=", "Author name", v => sgopts.AuthorName = v },
                { "e|email=", "Author email", v => sgopts.AuthorEmail = v },
                { "c|copyright=", "Copyright holder", v => sgopts.CopyrightHolder = v },
                { "f|force|overwrite-all", "Overwrite all files without prompting.", v => sgopts.OverwriteAll = true },
                { "d|debug", "Show more information on errors.", v => sgopts.Debug = true },
                { "p|private|non-public", "Include private/internal members in the outline.", v => sgopts.IncludeNonPublic = true },
                { "h|help|?", "Show this help screen", v => sgopts.ShowHelp = true }
            };

            if (sgopts.ShowHelp)
                ShowHelp (opts);

            List <string> assemblies = opts.Parse (args);
            if (assemblies == null || assemblies.Count == 0)
                ShowHelp (opts);

            foreach (string ap in assemblies)
                ProcessAssembly (ap, sgopts);
        }
Example #2
0
        static void ProcessAssembly(string path, StubGenOptions opts)
        {
            string aname = Path.GetFileNameWithoutExtension (path);
            Console.Error.WriteLine ("Processing assembly {0}", aname);
            string outdir = Path.Combine (opts.OutputDir, aname);

            try {
                if (!Directory.Exists (outdir))
                    Directory.CreateDirectory (outdir);
                Generator.Run (path, opts, outdir);
            } catch (Exception ex) {
                Console.Error.WriteLine ("\tFailure. {0}", ex.Message);
                if (opts.Debug) {
                    Console.Error.WriteLine (ex.StackTrace);
                    Console.Error.WriteLine ();
                }
            }
        }
Example #3
0
        public static void Run(string filePath, string license, StreamWriter writer, TypeDefinition type, StubGenOptions opts)
        {
            string ns = type.Namespace;

            if (String.IsNullOrEmpty (ns))
                ns = null;

            if (ns != null)
                Utils.Indent++;
            try {
                List <string> usings = Utils.Usings;
                usings.Clear ();
                var sb = new StringBuilder ();

                usings.AddUsing ("System");
                WriteType (sb, usings, type, opts);

                if (usings.Count > 0) {
                    usings.Sort ();

                    foreach (string u in usings) {
                        if (ns != null && String.Compare (u, ns, StringComparison.Ordinal) == 0)
                            continue;
                        writer.WriteLine ("using {0};", u);
                    }
                    writer.WriteLine ();
                }
                if (ns != null) {
                    writer.WriteLine ("namespace {0}", ns);
                    writer.WriteLine ("{");
                }

                writer.Write (sb.ToString ());

                if (ns != null)
                    writer.WriteLine ("}");
            } finally {
                if (ns != null)
                    Utils.Indent--;
            }
        }
Example #4
0
        public static void Run(string assemblyPath, StubGenOptions opts, string outDir)
        {
            sgopts = opts;
            string license = GetLicenseBlock (opts.LicenseName);
            bool overwrite = opts.OverwriteAll;

            ModuleDefinition module = ModuleDefinition.ReadModule (assemblyPath);
            Console.Error.WriteLine ("\tTarget runtime: {0}", module.Runtime.Format ());
            if (module.HasAssemblyReferences) {
                var typesPerAsm = new SortedDictionary <string, ulong> (StringComparer.Ordinal);
                AssemblyNameReference asmname;
                foreach (ModuleDefinition m in AssemblyDefinition.ReadAssembly (assemblyPath).Modules) {
                    foreach (TypeReference tref in m.GetTypeReferences ().OnlyVisible (true)) {
                        asmname = tref.Scope as AssemblyNameReference;
                        if (asmname == null)
                            continue;
                        if (typesPerAsm.ContainsKey (asmname.FullName))
                            typesPerAsm [asmname.FullName]++;
                        else
                            typesPerAsm [asmname.FullName] = 1;
                    }
                }

                var refs = new List <string> ();
                Console.Error.WriteLine ("\tAssembly references:");
                foreach (AssemblyNameReference aref in module.AssemblyReferences)
                    refs.Add (aref.FullName);

                refs.Sort (StringComparer.Ordinal);
                var unused = new List <string> ();
                bool present;
                ulong count;
                foreach (string s in refs) {
                    present = AssemblyPresent (s);
                    if (!typesPerAsm.TryGetValue (s, out count))
                        count = 0;
                    if (count == 0)
                        unused.Add (s);
                    Console.Error.Write ("\t   [");
                    if (present)
                        Console.Error.Write ("present]");
                    else {
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.Error.Write ("missing]");
                        Console.ForegroundColor = ConsoleColor.DarkRed;
                    }
                    Console.Error.WriteLine (" {0}", s);
                    Console.ResetColor ();
                }
                if (unused.Count > 0) {
                    Console.Error.WriteLine ();
                    Console.Error.WriteLine ("\tAssemblies referenced but not used by public APIs:");
                    unused.Sort ();
                    foreach (string s in unused)
                        Console.Error.WriteLine ("\t   {0}", s);
                }
            }

            OutputAssemblyInfo (module, outDir, license, overwrite);
            foreach (TypeDefinition type in module.Types) {
                if (type.IsNotPublic)
                    continue;

                try {
                    currentFilePath = FilePathForType (outDir, type);
                    if (!overwrite && File.Exists (currentFilePath)) {
                        currentFilePath = null;
                        continue;
                    }

                    using (FileStream fs = File.Open (currentFilePath, FileMode.Create, FileAccess.Write)) {
                        using (var sw = new StreamWriter (fs, Encoding.UTF8)) {
                            WriteHeader (sw, license);
                            Outline.Run (currentFilePath, license, sw, type, opts);
                        }
                    }
                } catch (Exception ex) {
                    Console.WriteLine ("\tFailure. Unable to generate file for type {0}. {1}", type.FullName, ex.Message);
                    if (opts.Debug)
                        Console.WriteLine (ex);
                }
            }
        }
Example #5
0
        static void ClassWriter(StringBuilder sb, List <string> usings, TypeDefinition type, StubGenOptions opts)
        {
            // TODO: process nested types
            bool includePrivate = opts.IncludeNonPublic;

            if (type.HasFields) {
                foreach (FieldDefinition field in type.Fields.OnlyVisible (includePrivate))
                    sb.Append (field.FormatName ());
            }

            if (type.HasEvents) {
                foreach (EventDefinition ev in type.Events.OnlyVisible (includePrivate))
                    sb.Append (ev.FormatName ());
            }

            if (type.HasProperties) {
                foreach (PropertyDefinition prop in type.Properties.OnlyVisible (includePrivate))
                    sb.Append (prop.FormatName ());
            }

            if (type.HasMethods) {
                foreach (MethodDefinition method in type.Methods.OnlyVisible (includePrivate))
                    sb.Append (method.FormatName ());
            }
        }
Example #6
0
        static void WriteType(StringBuilder sb, List <string> usings, TypeDefinition type, StubGenOptions opts)
        {
            Action <StringBuilder, List <string>, TypeDefinition, StubGenOptions> typeWriter = null;

            // TODO: security attributes
            if (type.IsSerializable)
                sb.AppendLineIndent ("[Serializable]");

            if (type.HasCustomAttributes)
                sb.Append (type.CustomAttributes.Format ());
            sb.AppendIndent ();

            FormatTypeAttributes (sb, type);
            if (type.IsEnum) {
                sb.Append ("enum");
                typeWriter = EnumWriter;
            } else if (type.IsClass) {
                sb.Append ("class");
                typeWriter = ClassWriter;
            } else if (type.IsInterface) {
                sb.Append ("interface");
                typeWriter = InterfaceWriter;
            } else if (type.IsValueType) {
                if (type.FullName == "System.Delegate" || type.FullName == "System.MulticastDelegate")
                    sb.Append ("delegate");
                else
                    sb.Append ("struct");
            }

            sb.AppendFormat (" {0}", type.FormatName ());

            bool haveColon = false;
            bool first = true;
            TypeReference tref = type.BaseType;
            if (WritableBaseType (tref)) {
                sb.Append (" : ");
                haveColon = true;
                first = false;

                usings.AddUsing (tref.Namespace);
                sb.Append (tref.FormatName ());
            }

            if (type.HasInterfaces) {
                foreach (TypeReference tr in type.Interfaces.OnlyVisible (opts.IncludeNonPublic)) {
                    if (first) {
                        if (!haveColon)
                            sb.Append (" : ");
                        first = false;
                    } else
                        sb.Append (", ");

                    usings.AddUsing (tr.Namespace);
                    sb.Append (tr.FormatName ());
                }
            }

            // TODO: output generic parameter constraints

            sb.AppendLine ();
            sb.AppendLineIndent ("{");

            if (typeWriter != null) {
                Utils.Indent++;
                try {
                    typeWriter (sb, usings, type, opts);
                } finally {
                    Utils.Indent--;
                }
            }

            sb.AppendLineIndent ("}");
        }
Example #7
0
        static void EnumWriter(StringBuilder sb, List <string> usings, TypeDefinition type, StubGenOptions opts)
        {
            if (!type.HasFields)
                return;

            bool includePrivate = opts.IncludeNonPublic;

            int count = type.Fields.Count;
            foreach (FieldDefinition field in type.Fields.OnlyVisible (includePrivate)) {
                count--;
                if (!field.HasConstant)
                    continue;
                sb.AppendFormatIndent ("{0} = 0x{1:x2}", field.Name, field.Constant);
                if (count > 0)
                    sb.Append (",");

                sb.AppendLine ();
            }
        }