LogGenerator.cs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. using System;
  2. using System.Text;
  3. using System.Reflection;
  4. using System.Collections;
  5. namespace Logger
  6. {
  7. class LogGenerator
  8. {
  9. [STAThread()]
  10. #if INDEVENV
  11. static int Main2(string[] args)
  12. #else
  13. static int Main(string[] args)
  14. #endif
  15. {
  16. Type type = null;
  17. System.Text.StringBuilder code = new StringBuilder ();
  18. bool is_2_0 = false;
  19. try {
  20. //if (args.Length >= 1 && args [0].ToLower () == "all") {
  21. // if (args.Length == 1) {
  22. // GenerateAll ();
  23. // return 0;
  24. // } else if (args.Length == 2) {
  25. // GenerateAll (args [1], false);
  26. // return 0;
  27. // }
  28. //}
  29. if (args.Length != 2 && args.Length != 3) {
  30. Console.WriteLine("Must supply at least two arguments: ");
  31. Console.WriteLine("\t Type to log ('all' to log all overrides and events for all types in System.Windows.Forms.dll)");
  32. Console.WriteLine("\t What to log [overrides|events|overridesevents]");
  33. Console.WriteLine("\t [output filename]");
  34. return 1;
  35. }
  36. Assembly a = typeof(System.Windows.Forms.Control).Assembly;
  37. type = a.GetType (args [0]);
  38. is_2_0 = a.FullName.IndexOf ("2.0") >= 0;
  39. if (type == null)
  40. throw new Exception (String.Format("Type '{0}' not found.", args[0]));
  41. code.Append ("// Automatically generated for assembly: " + a.FullName + Environment.NewLine);
  42. code.Append ("// To regenerate:" + Environment.NewLine);
  43. code.Append ("// " + (is_2_0 ? "gmcs" : "mcs") + " -r:System.Windows.Forms.dll LogGenerator.cs && mono LogGenerator.exe " + type.FullName + " " + args [1] + " " + (args.Length > 2 ? args [2] : " outfile.cs") + Environment.NewLine);
  44. if (is_2_0) {
  45. code.Append ("#if NET_2_0" + Environment.NewLine);
  46. } else {
  47. code.Append ("#if !NET_2_0" + Environment.NewLine);
  48. }
  49. if (args[1] == "overrides" || args[1] == "overridesevents")
  50. {
  51. code.Append (override_logger.GenerateLog (type));
  52. }
  53. if (args[1] == "events" || args[1] == "overridesevents")
  54. {
  55. code.Append (event_logger.GenerateLog (type));
  56. }
  57. code.Append ("#endif" + Environment.NewLine);
  58. if (args.Length > 2) {
  59. using (System.IO.StreamWriter writer = new System.IO.StreamWriter(args[2], false))
  60. {
  61. writer.Write(code);
  62. }
  63. } else {
  64. Console.WriteLine(code);
  65. }
  66. return 0;
  67. } catch (Exception ex) {
  68. Console.WriteLine (ex.Message);
  69. Console.WriteLine (ex.StackTrace);
  70. return 1;
  71. }
  72. }
  73. }
  74. class override_logger
  75. {
  76. public static string GenerateLog (Type type)
  77. {
  78. StringBuilder members = new StringBuilder ();
  79. string code =
  80. @"
  81. #region {0}OverrideLogger
  82. using System;
  83. using System.Collections;
  84. using System.Drawing;
  85. using System.Windows.Forms;
  86. using System.ComponentModel;
  87. using System.Runtime.Remoting;
  88. #if NET_2_0
  89. using System.Windows.Forms.Layout;
  90. #endif
  91. using System.Text;
  92. namespace MonoTests.System.Windows.Forms
  93. {{
  94. public class {0}OverrideLogger : {2}{0}
  95. {{
  96. public StringBuilder Log = new StringBuilder ();
  97. void ShowLocation(string message)
  98. {{
  99. Log.Append (message + Environment.NewLine);
  100. //Console.WriteLine(DateTime.Now.ToLongTimeString() + "" {2}{0}."" + message);
  101. }}
  102. {1}
  103. }}
  104. #endregion
  105. }}
  106. ";
  107. string method_impl =
  108. @"
  109. {1} override {2} {0}({3})
  110. {{
  111. {4};
  112. {5};
  113. }}
  114. ";
  115. string property_impl =
  116. @"
  117. {1} override {2} {0}
  118. {{{3}{4}}}
  119. ";
  120. string get_impl =
  121. @"
  122. get {{
  123. {1};
  124. return base.{0};
  125. }}
  126. ";
  127. string set_impl =
  128. @"
  129. set {{
  130. {1};
  131. base.{0} = value;
  132. }}
  133. ";
  134. foreach (MemberInfo member in type.GetMembers (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) {
  135. switch (member.MemberType) {
  136. case MemberTypes.Constructor:
  137. case MemberTypes.Event:
  138. case MemberTypes.Field:
  139. case MemberTypes.NestedType:
  140. case MemberTypes.TypeInfo:
  141. case MemberTypes.Custom:
  142. continue;
  143. case MemberTypes.Property:
  144. case MemberTypes.Method:
  145. break;
  146. default:
  147. continue;
  148. }
  149. MethodInfo method = member as MethodInfo;
  150. PropertyInfo property = member as PropertyInfo;
  151. string returnType;
  152. string access;
  153. string parameters;
  154. string message = "";
  155. string membercode;
  156. string basecall;
  157. if (method != null) {
  158. if (!getData (method, out returnType, out access, out parameters, ref message, out basecall, false))
  159. continue;
  160. membercode = string.Format (method_impl, method.Name, access, returnType, parameters, message, basecall);
  161. } else {
  162. string getstr = "";
  163. string setstr = "";
  164. MethodInfo get = (property.CanRead ? property.GetGetMethod () : null);
  165. if (get == null)
  166. continue;
  167. if (!getData (get, out returnType, out access, out parameters, ref message, out basecall, true))
  168. continue;
  169. getstr = string.Format (get_impl, property.Name, message);
  170. setstr = string.Format (set_impl, property.Name, message);
  171. if (!property.CanRead)
  172. getstr = "";
  173. if (!property.CanWrite)
  174. setstr = "";
  175. membercode = string.Format (property_impl, property.Name, access, returnType, getstr, setstr);
  176. }
  177. members.Append (membercode + "\n");
  178. }
  179. code = String.Format (code, type.Name, members.ToString (), "");
  180. return code;
  181. }
  182. static bool getData (MethodInfo method, out string returnType, out string access, out string parameters, ref string message, out string basecall, bool allow_specialname)
  183. {
  184. returnType = "";
  185. access = "";
  186. parameters = "";
  187. message = "";
  188. basecall = "";
  189. if (method.IsPrivate)
  190. return false;
  191. if (method.IsAssembly)
  192. return false;
  193. if (!method.IsVirtual)
  194. return false;
  195. if (method.IsFinal)
  196. return false;
  197. if (method.IsSpecialName && !allow_specialname)
  198. return false;
  199. //if (method.Name.StartsWith("get_"))
  200. // return false;
  201. //if (method.Name.StartsWith("set_"))
  202. // return false;
  203. if (method.Name == "Finalize")
  204. return false;
  205. if (method.Name == "GetLifetimeService")
  206. return false;
  207. returnType = method.ReturnType.FullName.Replace ("+", ".");
  208. returnType = method.ReturnType.Name;//.Replace ("+", ".");
  209. if (returnType == "Void")
  210. returnType = "void";
  211. if (method.IsPublic)
  212. access = "public";
  213. else if (method.IsFamilyOrAssembly)
  214. access = "protected";
  215. else if (method.IsFamily)
  216. access = "protected";
  217. else
  218. access = "?";
  219. string msgParams = "";
  220. string baseParams = "";
  221. string formatParams = "";
  222. ParameterInfo [] ps = method.GetParameters ();
  223. parameters = "";
  224. for (int i = 0; i < ps.Length; i++) {
  225. ParameterInfo param = ps [i];
  226. if (parameters != "") {
  227. parameters += ", ";
  228. msgParams += ", ";
  229. formatParams += ", ";
  230. baseParams += ", ";
  231. }
  232. string parameterType;
  233. if (param.ParameterType.IsByRef) {
  234. parameterType = param.ParameterType.GetElementType ().Name + " ";//sparam.ParameterType.FullName.Replace ("+", ".") + " ";
  235. baseParams += "ref ";
  236. parameters += "ref ";
  237. } else {
  238. parameterType = param.ParameterType.Name + " ";
  239. }
  240. parameters += parameterType;
  241. string name;
  242. if (param.Name != null && param.Name != "")
  243. name = param.Name;
  244. else
  245. name = "parameter" + (i + 1).ToString ();
  246. parameters += param.Name + " ";
  247. msgParams += param.Name;
  248. baseParams += param.Name;
  249. formatParams += param.Name + "=<{" + i.ToString () + "}>";
  250. }
  251. if (!method.IsAbstract) {
  252. basecall = "base." + method.Name + "(" + baseParams + ");";
  253. if (returnType != "void")
  254. basecall = "return " + basecall;
  255. }
  256. if (msgParams != "")
  257. msgParams = ", " + msgParams;
  258. message = "ShowLocation (string.Format(\"" + method.Name + " (" + formatParams + ") \"" + msgParams + "))";
  259. return true;
  260. }
  261. }
  262. class event_logger
  263. {
  264. public static string GenerateLog (Type type)
  265. {
  266. StringBuilder adders = new StringBuilder ();
  267. StringBuilder handlers = new StringBuilder ();
  268. string code =
  269. @"
  270. #region {0}EventLogger
  271. using System;
  272. using System.Reflection;
  273. using System.Diagnostics;
  274. namespace MonoTests.System.Windows.Forms
  275. {{
  276. public class {0}EventLogger
  277. {{
  278. private {3}{0} _obj;
  279. public {0}EventLogger({3}{0} obj)
  280. {{
  281. _obj = obj;
  282. {1}
  283. }}
  284. void ShowLocation()
  285. {{
  286. MethodBase method = new StackFrame (1, true).GetMethod ();
  287. Console.WriteLine (DateTime.Now.ToLongTimeString () + "" {0}."" + method.Name.Replace (""_ctrl_"", """"));
  288. }}
  289. {2}
  290. }}
  291. }}
  292. #endregion
  293. ";
  294. string method =
  295. @"
  296. void _obj_{0} ({1} sender, {2} e)
  297. {{
  298. ShowLocation ();
  299. }}
  300. ";
  301. foreach (EventInfo ev in type.GetEvents ()) {
  302. string handler;
  303. string adder;
  304. ParameterInfo [] ps = ev.EventHandlerType.GetMethod ("Invoke").GetParameters ();
  305. handler = string.Format (method, ev.Name, ps [0].ParameterType.Name, ps [1].ParameterType.Name);
  306. adder = "\t\t_obj." + ev.Name + " += new " + ev.EventHandlerType.Name + " (_obj_" + ev.Name + ");";
  307. adders.Append (adder + Environment.NewLine);
  308. handlers.Append (handler);
  309. }
  310. code = String.Format (code, type.Name, adders.ToString (), handlers.ToString (), "");//type.Namespace + ".");
  311. return code;
  312. }
  313. }
  314. }