Merge pull request #2543 from ermshiperete/Xamarin-31021
[mono.git] / mcs / tools / sgen / sgen.cs
1 // 
2 // sgen.cs
3 //
4 // Authors:
5 //   Lluis Sanchez Gual (lluis@ximian.com)
6 //   Atsushi Enomoto (atsushi@ximian.com)
7 //
8 // Copyright (C) 2003 Ximian, Inc.
9 // Copyright (C) 2006 Novell, Inc.
10 //
11
12 using System;
13 using System.Xml.Serialization;
14 using System.IO;
15 using System.Reflection;
16 using System.Collections;
17 using System.Collections.Specialized;
18 using System.CodeDom.Compiler;
19
20 public class Driver
21 {
22         static int Main (string[] args)
23         {
24                 Driver d = new Driver();
25                 return d.Run (args);
26         }
27                 
28         string assembly;
29         ArrayList references = new ArrayList ();
30         ArrayList types;
31         string compilerOptions;
32         bool proxyTypes;
33         bool debug;
34         bool keep;
35         bool force;
36         string outDir;
37         bool help;
38         bool silent;
39         bool nologo;
40         bool verbose;
41         string unknownArg;
42         
43
44         public int Run (string[] args)
45         {
46                 ParseArgs (args);
47                 
48                 if (!nologo)
49                 {
50                         Console.WriteLine ("Mono Xml Serializer Generator Tool");
51                         Console.WriteLine ("Mono version " + Environment.Version);
52                         Console.WriteLine ();
53                 }
54                 
55                 if (unknownArg != null)
56                 {
57                         Console.WriteLine ("Unknown option: " + unknownArg);
58                         Console.WriteLine ();
59                         return 1;
60                 }
61                 
62                 if (help)
63                 {
64                         Console.WriteLine ("Usage: sgen [options]");
65                         Console.WriteLine ();
66                         return 0;
67                 }
68                 
69                 if (assembly == null) {
70                         Console.WriteLine ("Assembly name not provided");
71                         Console.WriteLine ();
72                         return 1;
73                 }
74                 
75                 Assembly asm = null;
76                 
77                 try {
78                         asm = Assembly.Load (assembly);
79                 }
80                 catch {}
81                 
82                 if (asm == null) {
83                         try {
84                                 asm = Assembly.LoadFrom (assembly);
85                         } catch {
86                                 Console.WriteLine ("Specified assembly cannot be loaded.");
87                                 Console.WriteLine ();
88                                 return 1;
89                         }
90                 }
91                 ArrayList userTypes = new ArrayList ();
92                 ArrayList maps = new ArrayList ();
93                 XmlReflectionImporter imp = new XmlReflectionImporter ();
94                 
95                 if (verbose)
96                         Console.WriteLine ("Generating serializer for the following types:");
97
98                 if (types == null) {
99                         foreach (Type t in asm.GetTypes ()) {
100                                 try {
101                                         maps.Add (imp.ImportTypeMapping (t));
102                                         userTypes.Add (t);
103                                         if (verbose)
104                                                 Console.WriteLine( " - " + t );
105                                 } catch (InvalidOperationException ex) {
106                                         if (verbose)
107                                                 Console.WriteLine (" - Warning: " + ex.Message);
108                                 } catch (NotImplementedException ex) {
109                                         if (verbose) {
110                                                 Console.WriteLine (" - Warning: ignoring '" + t + "'");
111                                                 Console.WriteLine ("   " + ex.Message);
112                                         }
113                                 } catch (NotSupportedException ex) {
114                                         if (verbose)
115                                                 Console.WriteLine (" - Warning: " + ex.Message);
116                                 }
117                         }
118                 } else {
119                         foreach (string type in types) {
120                                 try {
121                                         Type t = asm.GetType (type);
122                                         maps.Add (imp.ImportTypeMapping (t));
123                                         userTypes.Add (t);
124                                         if (verbose)
125                                                 Console.WriteLine (" - " + t);
126                                 } catch (InvalidOperationException ex) {
127                                         if (verbose)
128                                                 Console.WriteLine (" - Warning: " + ex.Message);
129                                 } catch (NotImplementedException ex) {
130                                         if (verbose) {
131                                                 Console.WriteLine (" - Warning: ignoring '" + type + "'");
132                                                 Console.WriteLine ("   " + ex.Message);
133                                         }
134                                 } catch (NotSupportedException ex) {
135                                         if (verbose)
136                                                 Console.WriteLine (" - Warning: " + ex.Message);
137                                 }
138                         }
139                 }
140
141                 if (verbose)
142                         Console.WriteLine ();
143                         
144                 CompilerParameters parameters = new CompilerParameters ();
145                 parameters.GenerateInMemory = false;
146                 parameters.IncludeDebugInformation = debug;
147                 parameters.ReferencedAssemblies.AddRange ((string[])references.ToArray(typeof(string)));
148                 parameters.TempFiles = new TempFileCollection (Environment.CurrentDirectory, keep);
149                 parameters.CompilerOptions = compilerOptions;
150                 
151                 string file = Path.GetFileNameWithoutExtension (asm.Location) + ".XmlSerializers.dll";
152                 if (outDir == null) outDir = Path.GetDirectoryName (asm.Location);
153                 parameters.OutputAssembly = Path.Combine (outDir, file);
154                 
155                 if (File.Exists (parameters.OutputAssembly) && !force) {
156                         Console.WriteLine ("Cannot generate assembly '" + parameters.OutputAssembly + "' because it already exist. Use /force option to overwrite the existing assembly");
157                         Console.WriteLine ();
158                         return 1;
159                 }
160                 
161                 XmlSerializer.GenerateSerializer (
162                                 (Type[]) userTypes.ToArray (typeof(Type)), 
163                                 (XmlTypeMapping[]) maps.ToArray (typeof(XmlTypeMapping)), 
164                                 parameters);
165                                 
166                 if (!silent) {
167                         Console.WriteLine ("Generated assembly: " + file);
168                         Console.WriteLine ();
169                 }
170                 
171                 return 0;
172         }
173
174         void ParseArgs (string[] args)
175         {
176                 foreach (string arg in args)
177                 {
178                         int index = arg.Length > 2 && arg [0] == '-' && arg [1] == '-' ? 2 : -1;
179                         index = index >= 0 ? index : arg.Length > 0 && arg [0] == '/' ? 1 : -1;
180                         if (index < 0)
181                         {
182                                 assembly = arg;
183                                 continue;
184                         }
185                         
186                         int i = arg.IndexOf (':', index);
187                         if (i == -1) i = arg.Length;
188                         string op = arg.Substring (index, i - index).ToLowerInvariant ();
189                         string param = (i < arg.Length - index) ? arg.Substring (i + 1) : "";
190                         if (op == "assembly" || op == "a") {
191                                 assembly = param;
192                         }
193                         else if (op == "type" || op == "t") {
194                                 if (types == null) types = new ArrayList ();
195                                 types.Add (param);
196                         }
197                         else if (op == "reference" || op == "r") {
198                                 references.Add (param);
199                         }
200                         else if (op == "compiler" || op == "c") {
201                                 compilerOptions = param;
202                         }
203                         else if (op == "proxytypes" || op == "p") {
204                                 proxyTypes = true;
205                         }
206                         else if (op == "debug" || op == "d") {
207                                 debug = true;
208                         }
209                         else if (op == "keep" || op == "k") {
210                                 keep = true;
211                         }
212                         else if (op == "force" || op == "f") {
213                                 force = true;
214                         }
215                         else if (op == "out" || op == "o") {
216                                 outDir = param;
217                         }
218                         else if (op == "?" || op == "help") {
219                                 help = true;
220                         }
221                         else if (op == "nologo" || op == "n") {
222                                 nologo = true;
223                         }
224                         else if (op == "silent" || op == "s") {
225                                 silent = true;
226                         }
227                         else if (op == "verbose" || op == "v") {
228                                 verbose = true;
229                         }
230                         else if (arg.StartsWith ("/") && (arg.EndsWith (".dll") || arg.EndsWith (".exe")) && arg.IndexOfAny (Path.InvalidPathChars) == -1)
231                         {
232                                 assembly = arg;
233                                 continue;
234                         }
235                         else {
236                                 unknownArg = arg;
237                                 return;
238                         }
239                 }
240         }
241 }
242