/NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/outline.cs

http://github.com/icsharpcode/ILSpy · C# · 1038 lines · 748 code · 206 blank · 84 comment · 214 complexity · c52c7deb826d99ed8cc3cacda975c2ed MD5 · raw file

  1. //
  2. // outline -- support for rendering in monop
  3. // Some code stolen from updater.cs in monodoc.
  4. //
  5. // Authors:
  6. // Ben Maurer (bmaurer@users.sourceforge.net)
  7. //
  8. // (C) 2004 Ben Maurer
  9. //
  10. //
  11. // Permission is hereby granted, free of charge, to any person obtaining
  12. // a copy of this software and associated documentation files (the
  13. // "Software"), to deal in the Software without restriction, including
  14. // without limitation the rights to use, copy, modify, merge, publish,
  15. // distribute, sublicense, and/or sell copies of the Software, and to
  16. // permit persons to whom the Software is furnished to do so, subject to
  17. // the following conditions:
  18. //
  19. // The above copyright notice and this permission notice shall be
  20. // included in all copies or substantial portions of the Software.
  21. //
  22. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  23. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  24. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  25. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  26. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  27. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  28. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  29. //
  30. using System;
  31. using System.Reflection;
  32. using System.Collections;
  33. using System.CodeDom.Compiler;
  34. using System.IO;
  35. using System.Text;
  36. namespace Mono.CSharp {
  37. public class Outline {
  38. bool declared_only;
  39. bool show_private;
  40. bool filter_obsolete;
  41. IndentedTextWriter o;
  42. Type t;
  43. public Outline (Type t, TextWriter output, bool declared_only, bool show_private, bool filter_obsolete)
  44. {
  45. this.t = t;
  46. this.o = new IndentedTextWriter (output, "\t");
  47. this.declared_only = declared_only;
  48. this.show_private = show_private;
  49. this.filter_obsolete = filter_obsolete;
  50. }
  51. public void OutlineType ()
  52. {
  53. bool first;
  54. OutlineAttributes ();
  55. o.Write (GetTypeVisibility (t));
  56. if (t.IsClass && !t.IsSubclassOf (typeof (System.MulticastDelegate))) {
  57. if (t.IsSealed)
  58. o.Write (t.IsAbstract ? " static" : " sealed");
  59. else if (t.IsAbstract)
  60. o.Write (" abstract");
  61. }
  62. o.Write (" ");
  63. o.Write (GetTypeKind (t));
  64. o.Write (" ");
  65. Type [] interfaces = (Type []) Comparer.Sort (TypeGetInterfaces (t, declared_only));
  66. Type parent = t.BaseType;
  67. if (t.IsSubclassOf (typeof (System.MulticastDelegate))) {
  68. MethodInfo method;
  69. method = t.GetMethod ("Invoke");
  70. o.Write (FormatType (method.ReturnType));
  71. o.Write (" ");
  72. o.Write (GetTypeName (t));
  73. o.Write (" (");
  74. OutlineParams (method.GetParameters ());
  75. o.Write (")");
  76. #if NET_2_0
  77. WriteGenericConstraints (t.GetGenericArguments ());
  78. #endif
  79. o.WriteLine (";");
  80. return;
  81. }
  82. o.Write (GetTypeName (t));
  83. if (((parent != null && parent != typeof (object) && parent != typeof (ValueType)) || interfaces.Length != 0) && ! t.IsEnum) {
  84. first = true;
  85. o.Write (" : ");
  86. if (parent != null && parent != typeof (object) && parent != typeof (ValueType)) {
  87. o.Write (FormatType (parent));
  88. first = false;
  89. }
  90. foreach (Type intf in interfaces) {
  91. if (!first) o.Write (", ");
  92. first = false;
  93. o.Write (FormatType (intf));
  94. }
  95. }
  96. if (t.IsEnum) {
  97. Type underlyingType = System.Enum.GetUnderlyingType (t);
  98. if (underlyingType != typeof (int))
  99. o.Write (" : {0}", FormatType (underlyingType));
  100. }
  101. #if NET_2_0
  102. WriteGenericConstraints (t.GetGenericArguments ());
  103. #endif
  104. o.WriteLine (" {");
  105. o.Indent++;
  106. if (t.IsEnum) {
  107. bool is_first = true;
  108. foreach (FieldInfo fi in t.GetFields (BindingFlags.Public | BindingFlags.Static)) {
  109. if (! is_first)
  110. o.WriteLine (",");
  111. is_first = false;
  112. o.Write (fi.Name);
  113. }
  114. o.WriteLine ();
  115. o.Indent--; o.WriteLine ("}");
  116. return;
  117. }
  118. first = true;
  119. foreach (ConstructorInfo ci in t.GetConstructors (DefaultFlags)) {
  120. if (! ShowMember (ci))
  121. continue;
  122. if (first)
  123. o.WriteLine ();
  124. first = false;
  125. OutlineMemberAttribute (ci);
  126. OutlineConstructor (ci);
  127. o.WriteLine ();
  128. }
  129. first = true;
  130. foreach (MethodInfo m in Comparer.Sort (t.GetMethods (DefaultFlags))) {
  131. if (! ShowMember (m))
  132. continue;
  133. if ((m.Attributes & MethodAttributes.SpecialName) != 0)
  134. continue;
  135. if (first)
  136. o.WriteLine ();
  137. first = false;
  138. OutlineMemberAttribute (m);
  139. OutlineMethod (m);
  140. o.WriteLine ();
  141. }
  142. first = true;
  143. foreach (MethodInfo m in t.GetMethods (DefaultFlags)) {
  144. if (! ShowMember (m))
  145. continue;
  146. if ((m.Attributes & MethodAttributes.SpecialName) == 0)
  147. continue;
  148. if (!(m.Name.StartsWith ("op_")))
  149. continue;
  150. if (first)
  151. o.WriteLine ();
  152. first = false;
  153. OutlineMemberAttribute (m);
  154. OutlineOperator (m);
  155. o.WriteLine ();
  156. }
  157. first = true;
  158. foreach (PropertyInfo pi in Comparer.Sort (t.GetProperties (DefaultFlags))) {
  159. if (! ((pi.CanRead && ShowMember (pi.GetGetMethod (true))) ||
  160. (pi.CanWrite && ShowMember (pi.GetSetMethod (true)))))
  161. continue;
  162. if (first)
  163. o.WriteLine ();
  164. first = false;
  165. OutlineMemberAttribute (pi);
  166. OutlineProperty (pi);
  167. o.WriteLine ();
  168. }
  169. first = true;
  170. foreach (FieldInfo fi in t.GetFields (DefaultFlags)) {
  171. if (! ShowMember (fi))
  172. continue;
  173. if (first)
  174. o.WriteLine ();
  175. first = false;
  176. OutlineMemberAttribute (fi);
  177. OutlineField (fi);
  178. o.WriteLine ();
  179. }
  180. first = true;
  181. foreach (EventInfo ei in Comparer.Sort (t.GetEvents (DefaultFlags))) {
  182. if (! ShowMember (ei.GetAddMethod (true)))
  183. continue;
  184. if (first)
  185. o.WriteLine ();
  186. first = false;
  187. OutlineMemberAttribute (ei);
  188. OutlineEvent (ei);
  189. o.WriteLine ();
  190. }
  191. first = true;
  192. foreach (Type ntype in Comparer.Sort (t.GetNestedTypes (DefaultFlags))) {
  193. if (! ShowMember (ntype))
  194. continue;
  195. if (first)
  196. o.WriteLine ();
  197. first = false;
  198. new Outline (ntype, o, declared_only, show_private, filter_obsolete).OutlineType ();
  199. }
  200. o.Indent--; o.WriteLine ("}");
  201. }
  202. BindingFlags DefaultFlags {
  203. get {
  204. BindingFlags f = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
  205. if (declared_only)
  206. f |= BindingFlags.DeclaredOnly;
  207. return f;
  208. }
  209. }
  210. // FIXME: add other interesting attributes?
  211. void OutlineAttributes ()
  212. {
  213. if (t.IsSerializable)
  214. o.WriteLine ("[Serializable]");
  215. if (t.IsDefined (typeof (System.FlagsAttribute), true))
  216. o.WriteLine ("[Flags]");
  217. if (t.IsDefined (typeof (System.ObsoleteAttribute), true))
  218. o.WriteLine ("[Obsolete]");
  219. }
  220. void OutlineMemberAttribute (MemberInfo mi)
  221. {
  222. if (!mi.IsDefined (typeof (System.ObsoleteAttribute), false))
  223. return;
  224. var oa = mi.GetCustomAttributes (typeof (System.ObsoleteAttribute), false) [0] as ObsoleteAttribute;
  225. var msg = oa.Message;
  226. o.WriteLine ("[Obsolete{0}]", msg == null || msg == "" ? "" : string.Format ("(\"{0}\")", msg));
  227. }
  228. void OutlineEvent (EventInfo ei)
  229. {
  230. MethodBase accessor = ei.GetAddMethod (true);
  231. o.Write (GetMethodVisibility (accessor));
  232. o.Write ("event ");
  233. o.Write (FormatType (ei.EventHandlerType));
  234. o.Write (" ");
  235. o.Write (ei.Name);
  236. o.Write (";");
  237. }
  238. void OutlineConstructor (ConstructorInfo ci)
  239. {
  240. o.Write (GetMethodVisibility (ci));
  241. o.Write (RemoveGenericArity (t.Name));
  242. o.Write (" (");
  243. OutlineParams (ci.GetParameters ());
  244. o.Write (");");
  245. }
  246. void OutlineProperty (PropertyInfo pi)
  247. {
  248. ParameterInfo [] idxp = pi.GetIndexParameters ();
  249. MethodBase g = pi.GetGetMethod (true);
  250. MethodBase s = pi.GetSetMethod (true);
  251. MethodBase accessor = g != null ? g : s;
  252. if (pi.CanRead && pi.CanWrite) {
  253. // Get the more accessible accessor
  254. if ((g.Attributes & MethodAttributes.MemberAccessMask) !=
  255. (s.Attributes & MethodAttributes.MemberAccessMask)) {
  256. if (g.IsPublic) accessor = g;
  257. else if (s.IsPublic) accessor = s;
  258. else if (g.IsFamilyOrAssembly) accessor = g;
  259. else if (s.IsFamilyOrAssembly) accessor = s;
  260. else if (g.IsAssembly || g.IsFamily) accessor = g;
  261. else if (s.IsAssembly || s.IsFamily) accessor = s;
  262. }
  263. }
  264. o.Write (GetMethodVisibility (accessor));
  265. o.Write (GetMethodModifiers (accessor));
  266. o.Write (FormatType (pi.PropertyType));
  267. o.Write (" ");
  268. if (idxp.Length == 0)
  269. o.Write (pi.Name);
  270. else {
  271. o.Write ("this [");
  272. OutlineParams (idxp);
  273. o.Write ("]");
  274. }
  275. o.WriteLine (" {");
  276. o.Indent ++;
  277. if (g != null && ShowMember (g)) {
  278. if ((g.Attributes & MethodAttributes.MemberAccessMask) !=
  279. (accessor.Attributes & MethodAttributes.MemberAccessMask))
  280. o.Write (GetMethodVisibility (g));
  281. o.WriteLine ("get;");
  282. }
  283. if (s != null && ShowMember (s)) {
  284. if ((s.Attributes & MethodAttributes.MemberAccessMask) !=
  285. (accessor.Attributes & MethodAttributes.MemberAccessMask))
  286. o.Write (GetMethodVisibility (s));
  287. o.WriteLine ("set;");
  288. }
  289. o.Indent --;
  290. o.Write ("}");
  291. }
  292. void OutlineMethod (MethodInfo mi)
  293. {
  294. if (MethodIsExplicitIfaceImpl (mi)) {
  295. o.Write (FormatType (mi.ReturnType));
  296. o.Write (" ");
  297. // MSFT has no way to get the method that we are overriding
  298. // from the interface. this would allow us to pretty print
  299. // the type name (and be more correct if there compiler
  300. // were to do some strange naming thing).
  301. } else {
  302. o.Write (GetMethodVisibility (mi));
  303. o.Write (GetMethodModifiers (mi));
  304. o.Write (FormatType (mi.ReturnType));
  305. o.Write (" ");
  306. }
  307. o.Write (mi.Name);
  308. #if NET_2_0
  309. o.Write (FormatGenericParams (mi.GetGenericArguments ()));
  310. #endif
  311. o.Write (" (");
  312. OutlineParams (mi.GetParameters ());
  313. o.Write (")");
  314. #if NET_2_0
  315. WriteGenericConstraints (mi.GetGenericArguments ());
  316. #endif
  317. o.Write (";");
  318. }
  319. void OutlineOperator (MethodInfo mi)
  320. {
  321. o.Write (GetMethodVisibility (mi));
  322. o.Write (GetMethodModifiers (mi));
  323. if (mi.Name == "op_Explicit" || mi.Name == "op_Implicit") {
  324. o.Write (mi.Name.Substring (3).ToLower ());
  325. o.Write (" operator ");
  326. o.Write (FormatType (mi.ReturnType));
  327. } else {
  328. o.Write (FormatType (mi.ReturnType));
  329. o.Write (" operator ");
  330. o.Write (OperatorFromName (mi.Name));
  331. }
  332. o.Write (" (");
  333. OutlineParams (mi.GetParameters ());
  334. o.Write (");");
  335. }
  336. void OutlineParams (ParameterInfo [] pi)
  337. {
  338. int i = 0;
  339. foreach (ParameterInfo p in pi) {
  340. if (p.ParameterType.IsByRef) {
  341. o.Write (p.IsOut ? "out " : "ref ");
  342. o.Write (FormatType (p.ParameterType.GetElementType ()));
  343. } else if (p.IsDefined (typeof (ParamArrayAttribute), false)) {
  344. o.Write ("params ");
  345. o.Write (FormatType (p.ParameterType));
  346. } else {
  347. o.Write (FormatType (p.ParameterType));
  348. }
  349. o.Write (" ");
  350. o.Write (p.Name);
  351. if (i + 1 < pi.Length)
  352. o.Write (", ");
  353. i++;
  354. }
  355. }
  356. void OutlineField (FieldInfo fi)
  357. {
  358. if (fi.IsPublic) o.Write ("public ");
  359. if (fi.IsFamily) o.Write ("protected ");
  360. if (fi.IsPrivate) o.Write ("private ");
  361. if (fi.IsAssembly) o.Write ("internal ");
  362. if (fi.IsLiteral) o.Write ("const ");
  363. else if (fi.IsStatic) o.Write ("static ");
  364. if (fi.IsInitOnly) o.Write ("readonly ");
  365. o.Write (FormatType (fi.FieldType));
  366. o.Write (" ");
  367. o.Write (fi.Name);
  368. if (fi.IsLiteral) {
  369. object v = fi.GetValue (this);
  370. // TODO: Escape values here
  371. o.Write (" = ");
  372. if (v is char)
  373. o.Write ("'{0}'", v);
  374. else if (v is string)
  375. o.Write ("\"{0}\"", v);
  376. else
  377. o.Write (fi.GetValue (this));
  378. }
  379. o.Write (";");
  380. }
  381. static string GetMethodVisibility (MethodBase m)
  382. {
  383. // itnerfaces have no modifiers here
  384. if (m.DeclaringType.IsInterface)
  385. return "";
  386. if (m.IsPublic) return "public ";
  387. if (m.IsFamily) return "protected ";
  388. if (m.IsPrivate) return "private ";
  389. if (m.IsAssembly) return "internal ";
  390. return null;
  391. }
  392. static string GetMethodModifiers (MethodBase method)
  393. {
  394. if (method.IsStatic)
  395. return "static ";
  396. if (method.IsFinal) {
  397. // This will happen if you have
  398. // class X : IA {
  399. // public void A () {}
  400. // static void Main () {}
  401. // }
  402. // interface IA {
  403. // void A ();
  404. // }
  405. //
  406. // A needs to be virtual (the CLR requires
  407. // methods implementing an iface be virtual),
  408. // but can not be inherited. It also can not
  409. // be inherited. In C# this is represented
  410. // with no special modifiers
  411. if (method.IsVirtual)
  412. return null;
  413. return "sealed ";
  414. }
  415. // all interface methods are "virtual" but we don't say that in c#
  416. if (method.IsVirtual && !method.DeclaringType.IsInterface) {
  417. if (method.IsAbstract)
  418. return "abstract ";
  419. return ((method.Attributes & MethodAttributes.NewSlot) != 0) ?
  420. "virtual " :
  421. "override ";
  422. }
  423. return null;
  424. }
  425. static string GetTypeKind (Type t)
  426. {
  427. if (t.IsEnum)
  428. return "enum";
  429. if (t.IsClass) {
  430. if (t.IsSubclassOf (typeof (System.MulticastDelegate)))
  431. return "delegate";
  432. else
  433. return "class";
  434. }
  435. if (t.IsInterface)
  436. return "interface";
  437. if (t.IsValueType)
  438. return "struct";
  439. return "class";
  440. }
  441. static string GetTypeVisibility (Type t)
  442. {
  443. switch (t.Attributes & TypeAttributes.VisibilityMask){
  444. case TypeAttributes.Public:
  445. case TypeAttributes.NestedPublic:
  446. return "public";
  447. case TypeAttributes.NestedFamily:
  448. case TypeAttributes.NestedFamANDAssem:
  449. case TypeAttributes.NestedFamORAssem:
  450. return "protected";
  451. default:
  452. return "internal";
  453. }
  454. }
  455. #if NET_2_0
  456. string FormatGenericParams (Type [] args)
  457. {
  458. StringBuilder sb = new StringBuilder ();
  459. if (args.Length == 0)
  460. return "";
  461. sb.Append ("<");
  462. for (int i = 0; i < args.Length; i++) {
  463. if (i > 0)
  464. sb.Append (",");
  465. sb.Append (FormatType (args [i]));
  466. }
  467. sb.Append (">");
  468. return sb.ToString ();
  469. }
  470. #endif
  471. // TODO: fine tune this so that our output is less verbose. We need to figure
  472. // out a way to do this while not making things confusing.
  473. string FormatType (Type t)
  474. {
  475. if (t == null)
  476. return "";
  477. string type = GetFullName (t);
  478. if (type == null)
  479. return t.ToString ();
  480. if (!type.StartsWith ("System.")) {
  481. if (t.Namespace == this.t.Namespace)
  482. return t.Name;
  483. return type;
  484. }
  485. if (t.HasElementType) {
  486. Type et = t.GetElementType ();
  487. if (t.IsArray)
  488. return FormatType (et) + " []";
  489. if (t.IsPointer)
  490. return FormatType (et) + " *";
  491. if (t.IsByRef)
  492. return "ref " + FormatType (et);
  493. }
  494. switch (type) {
  495. case "System.Byte": return "byte";
  496. case "System.SByte": return "sbyte";
  497. case "System.Int16": return "short";
  498. case "System.Int32": return "int";
  499. case "System.Int64": return "long";
  500. case "System.UInt16": return "ushort";
  501. case "System.UInt32": return "uint";
  502. case "System.UInt64": return "ulong";
  503. case "System.Single": return "float";
  504. case "System.Double": return "double";
  505. case "System.Decimal": return "decimal";
  506. case "System.Boolean": return "bool";
  507. case "System.Char": return "char";
  508. case "System.String": return "string";
  509. case "System.Object": return "object";
  510. case "System.Void": return "void";
  511. }
  512. if (type.LastIndexOf(".") == 6)
  513. return type.Substring(7);
  514. //
  515. // If the namespace of the type is the namespace of what
  516. // we are printing (or is a member of one if its children
  517. // don't print it. This basically means that in C# we would
  518. // automatically get the namespace imported by virtue of the
  519. // namespace {} block.
  520. //
  521. if (this.t.Namespace.StartsWith (t.Namespace + ".") || t.Namespace == this.t.Namespace)
  522. return type.Substring (t.Namespace.Length + 1);
  523. return type;
  524. }
  525. public static string RemoveGenericArity (string name)
  526. {
  527. int start = 0;
  528. StringBuilder sb = new StringBuilder ();
  529. while (start < name.Length) {
  530. int pos = name.IndexOf ('`', start);
  531. if (pos < 0) {
  532. sb.Append (name.Substring (start));
  533. break;
  534. }
  535. sb.Append (name.Substring (start, pos-start));
  536. pos++;
  537. while ((pos < name.Length) && Char.IsNumber (name [pos]))
  538. pos++;
  539. start = pos;
  540. }
  541. return sb.ToString ();
  542. }
  543. string GetTypeName (Type t)
  544. {
  545. StringBuilder sb = new StringBuilder ();
  546. GetTypeName (sb, t);
  547. return sb.ToString ();
  548. }
  549. void GetTypeName (StringBuilder sb, Type t)
  550. {
  551. sb.Append (RemoveGenericArity (t.Name));
  552. #if NET_2_0
  553. sb.Append (FormatGenericParams (t.GetGenericArguments ()));
  554. #endif
  555. }
  556. string GetFullName (Type t)
  557. {
  558. StringBuilder sb = new StringBuilder ();
  559. GetFullName_recursed (sb, t, false);
  560. return sb.ToString ();
  561. }
  562. void GetFullName_recursed (StringBuilder sb, Type t, bool recursed)
  563. {
  564. #if NET_2_0
  565. if (t.IsGenericParameter) {
  566. sb.Append (t.Name);
  567. return;
  568. }
  569. #endif
  570. if (t.DeclaringType != null) {
  571. GetFullName_recursed (sb, t.DeclaringType, true);
  572. sb.Append (".");
  573. }
  574. if (!recursed) {
  575. string ns = t.Namespace;
  576. if ((ns != null) && (ns != "")) {
  577. sb.Append (ns);
  578. sb.Append (".");
  579. }
  580. }
  581. GetTypeName (sb, t);
  582. }
  583. #if NET_2_0
  584. void WriteGenericConstraints (Type [] args)
  585. {
  586. foreach (Type t in args) {
  587. bool first = true;
  588. Type[] ifaces = TypeGetInterfaces (t, true);
  589. GenericParameterAttributes attrs = t.GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask;
  590. GenericParameterAttributes [] interesting = {
  591. GenericParameterAttributes.ReferenceTypeConstraint,
  592. GenericParameterAttributes.NotNullableValueTypeConstraint,
  593. GenericParameterAttributes.DefaultConstructorConstraint
  594. };
  595. if (t.BaseType != typeof (object) || ifaces.Length != 0 || attrs != 0) {
  596. o.Write (" where ");
  597. o.Write (FormatType (t));
  598. o.Write (" : ");
  599. }
  600. if (t.BaseType != typeof (object)) {
  601. o.Write (FormatType (t.BaseType));
  602. first = false;
  603. }
  604. foreach (Type iface in ifaces) {
  605. if (!first)
  606. o.Write (", ");
  607. first = false;
  608. o.Write (FormatType (iface));
  609. }
  610. foreach (GenericParameterAttributes a in interesting) {
  611. if ((attrs & a) == 0)
  612. continue;
  613. if (!first)
  614. o.Write (", ");
  615. first = false;
  616. switch (a) {
  617. case GenericParameterAttributes.ReferenceTypeConstraint:
  618. o.Write ("class");
  619. break;
  620. case GenericParameterAttributes.NotNullableValueTypeConstraint:
  621. o.Write ("struct");
  622. break;
  623. case GenericParameterAttributes.DefaultConstructorConstraint:
  624. o.Write ("new ()");
  625. break;
  626. }
  627. }
  628. }
  629. }
  630. #endif
  631. string OperatorFromName (string name)
  632. {
  633. switch (name) {
  634. case "op_UnaryPlus": return "+";
  635. case "op_UnaryNegation": return "-";
  636. case "op_LogicalNot": return "!";
  637. case "op_OnesComplement": return "~";
  638. case "op_Increment": return "++";
  639. case "op_Decrement": return "--";
  640. case "op_True": return "true";
  641. case "op_False": return "false";
  642. case "op_Addition": return "+";
  643. case "op_Subtraction": return "-";
  644. case "op_Multiply": return "*";
  645. case "op_Division": return "/";
  646. case "op_Modulus": return "%";
  647. case "op_BitwiseAnd": return "&";
  648. case "op_BitwiseOr": return "|";
  649. case "op_ExclusiveOr": return "^";
  650. case "op_LeftShift": return "<<";
  651. case "op_RightShift": return ">>";
  652. case "op_Equality": return "==";
  653. case "op_Inequality": return "!=";
  654. case "op_GreaterThan": return ">";
  655. case "op_LessThan": return "<";
  656. case "op_GreaterThanOrEqual": return ">=";
  657. case "op_LessThanOrEqual": return "<=";
  658. default: return name;
  659. }
  660. }
  661. bool MethodIsExplicitIfaceImpl (MethodBase mb)
  662. {
  663. if (!(mb.IsFinal && mb.IsVirtual && mb.IsPrivate))
  664. return false;
  665. // UGH msft has no way to get the info about what method is
  666. // getting overriden. Another reason to use cecil :-)
  667. //
  668. //MethodInfo mi = mb as MethodInfo;
  669. //if (mi == null)
  670. // return false;
  671. //
  672. //Console.WriteLine (mi.GetBaseDefinition ().DeclaringType);
  673. //return mi.GetBaseDefinition ().DeclaringType.IsInterface;
  674. // So, we guess that virtual final private methods only come
  675. // from ifaces :-)
  676. return true;
  677. }
  678. bool ShowMember (MemberInfo mi)
  679. {
  680. if (mi.MemberType == MemberTypes.Constructor && ((MethodBase) mi).IsStatic)
  681. return false;
  682. if (show_private)
  683. return true;
  684. if (filter_obsolete && mi.IsDefined (typeof (ObsoleteAttribute), false))
  685. return false;
  686. switch (mi.MemberType) {
  687. case MemberTypes.Constructor:
  688. case MemberTypes.Method:
  689. MethodBase mb = mi as MethodBase;
  690. if (mb.IsFamily || mb.IsPublic || mb.IsFamilyOrAssembly)
  691. return true;
  692. if (MethodIsExplicitIfaceImpl (mb))
  693. return true;
  694. return false;
  695. case MemberTypes.Field:
  696. FieldInfo fi = mi as FieldInfo;
  697. if (fi.IsFamily || fi.IsPublic || fi.IsFamilyOrAssembly)
  698. return true;
  699. return false;
  700. case MemberTypes.NestedType:
  701. case MemberTypes.TypeInfo:
  702. Type t = mi as Type;
  703. switch (t.Attributes & TypeAttributes.VisibilityMask){
  704. case TypeAttributes.Public:
  705. case TypeAttributes.NestedPublic:
  706. case TypeAttributes.NestedFamily:
  707. case TypeAttributes.NestedFamORAssem:
  708. return true;
  709. }
  710. return false;
  711. }
  712. // What am I !!!
  713. return true;
  714. }
  715. static Type [] TypeGetInterfaces (Type t, bool declonly)
  716. {
  717. if (t.IsGenericParameter)
  718. return new Type [0];
  719. Type [] ifaces = t.GetInterfaces ();
  720. if (! declonly)
  721. return ifaces;
  722. // Handle Object. Also, optimize for no interfaces
  723. if (t.BaseType == null || ifaces.Length == 0)
  724. return ifaces;
  725. ArrayList ar = new ArrayList ();
  726. foreach (Type i in ifaces)
  727. if (! i.IsAssignableFrom (t.BaseType))
  728. ar.Add (i);
  729. return (Type []) ar.ToArray (typeof (Type));
  730. }
  731. }
  732. public class Comparer : IComparer {
  733. delegate int ComparerFunc (object a, object b);
  734. ComparerFunc cmp;
  735. Comparer (ComparerFunc f)
  736. {
  737. this.cmp = f;
  738. }
  739. public int Compare (object a, object b)
  740. {
  741. return cmp (a, b);
  742. }
  743. static int CompareType (object a, object b)
  744. {
  745. Type type1 = (Type) a;
  746. Type type2 = (Type) b;
  747. if (type1.IsSubclassOf (typeof (System.MulticastDelegate)) != type2.IsSubclassOf (typeof (System.MulticastDelegate)))
  748. return (type1.IsSubclassOf (typeof (System.MulticastDelegate)))? -1:1;
  749. return string.Compare (type1.Name, type2.Name);
  750. }
  751. // static Comparer TypeComparer = new Comparer (new ComparerFunc (CompareType));
  752. // static Type [] Sort (Type [] types)
  753. // {
  754. // Array.Sort (types, TypeComparer);
  755. // return types;
  756. // }
  757. static int CompareMemberInfo (object a, object b)
  758. {
  759. return string.Compare (((MemberInfo) a).Name, ((MemberInfo) b).Name);
  760. }
  761. static Comparer MemberInfoComparer = new Comparer (new ComparerFunc (CompareMemberInfo));
  762. public static MemberInfo [] Sort (MemberInfo [] inf)
  763. {
  764. Array.Sort (inf, MemberInfoComparer);
  765. return inf;
  766. }
  767. static int CompareMethodBase (object a, object b)
  768. {
  769. MethodBase aa = (MethodBase) a, bb = (MethodBase) b;
  770. if (aa.IsStatic == bb.IsStatic) {
  771. int c = CompareMemberInfo (a, b);
  772. if (c != 0)
  773. return c;
  774. ParameterInfo [] ap, bp;
  775. //
  776. // Sort overloads by the names of their types
  777. // put methods with fewer params first.
  778. //
  779. ap = aa.GetParameters ();
  780. bp = bb.GetParameters ();
  781. int n = System.Math.Min (ap.Length, bp.Length);
  782. for (int i = 0; i < n; i ++)
  783. if ((c = CompareType (ap [i].ParameterType, bp [i].ParameterType)) != 0)
  784. return c;
  785. return ap.Length.CompareTo (bp.Length);
  786. }
  787. if (aa.IsStatic)
  788. return -1;
  789. return 1;
  790. }
  791. static Comparer MethodBaseComparer = new Comparer (new ComparerFunc (CompareMethodBase));
  792. public static MethodBase [] Sort (MethodBase [] inf)
  793. {
  794. Array.Sort (inf, MethodBaseComparer);
  795. return inf;
  796. }
  797. static int ComparePropertyInfo (object a, object b)
  798. {
  799. PropertyInfo aa = (PropertyInfo) a, bb = (PropertyInfo) b;
  800. bool astatic = (aa.CanRead ? aa.GetGetMethod (true) : aa.GetSetMethod (true)).IsStatic;
  801. bool bstatic = (bb.CanRead ? bb.GetGetMethod (true) : bb.GetSetMethod (true)).IsStatic;
  802. if (astatic == bstatic)
  803. return CompareMemberInfo (a, b);
  804. if (astatic)
  805. return -1;
  806. return 1;
  807. }
  808. static Comparer PropertyInfoComparer = new Comparer (new ComparerFunc (ComparePropertyInfo));
  809. public static PropertyInfo [] Sort (PropertyInfo [] inf)
  810. {
  811. Array.Sort (inf, PropertyInfoComparer);
  812. return inf;
  813. }
  814. static int CompareEventInfo (object a, object b)
  815. {
  816. EventInfo aa = (EventInfo) a, bb = (EventInfo) b;
  817. bool astatic = aa.GetAddMethod (true).IsStatic;
  818. bool bstatic = bb.GetAddMethod (true).IsStatic;
  819. if (astatic == bstatic)
  820. return CompareMemberInfo (a, b);
  821. if (astatic)
  822. return -1;
  823. return 1;
  824. }
  825. static Comparer EventInfoComparer = new Comparer (new ComparerFunc (CompareEventInfo));
  826. public static EventInfo [] Sort (EventInfo [] inf)
  827. {
  828. Array.Sort (inf, EventInfoComparer);
  829. return inf;
  830. }
  831. }
  832. }