MonoGenericClass.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. //
  2. // System.MonoType
  3. //
  4. // Sean MacIsaac ([email protected])
  5. // Paolo Molaro ([email protected])
  6. // Patrik Torstensson ([email protected])
  7. //
  8. // (C) 2001 Ximian, Inc.
  9. //
  10. //
  11. // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
  12. //
  13. // Permission is hereby granted, free of charge, to any person obtaining
  14. // a copy of this software and associated documentation files (the
  15. // "Software"), to deal in the Software without restriction, including
  16. // without limitation the rights to use, copy, modify, merge, publish,
  17. // distribute, sublicense, and/or sell copies of the Software, and to
  18. // permit persons to whom the Software is furnished to do so, subject to
  19. // the following conditions:
  20. //
  21. // The above copyright notice and this permission notice shall be
  22. // included in all copies or substantial portions of the Software.
  23. //
  24. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  25. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  26. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  27. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  28. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  29. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  30. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  31. //
  32. using System.Reflection;
  33. using System.Reflection.Emit;
  34. using System.Collections;
  35. using System.Runtime.CompilerServices;
  36. using System.Globalization;
  37. using System.Runtime.Serialization;
  38. namespace System.Reflection
  39. {
  40. internal class MonoGenericClass : MonoType
  41. {
  42. protected Type generic_type;
  43. bool initialized;
  44. [MonoTODO]
  45. internal MonoGenericClass ()
  46. : base (null)
  47. {
  48. // this should not be used
  49. throw new InvalidOperationException ();
  50. }
  51. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  52. protected extern void initialize (MethodInfo[] methods, ConstructorInfo[] ctors, FieldInfo[] fields, PropertyInfo[] properties, EventInfo[] events);
  53. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  54. protected extern MethodInfo[] GetMethods_internal (Type reflected_type);
  55. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  56. protected extern ConstructorInfo[] GetConstructors_internal (Type reflected_type);
  57. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  58. protected extern FieldInfo[] GetFields_internal (Type reflected_type);
  59. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  60. protected extern PropertyInfo[] GetProperties_internal (Type reflected_type);
  61. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  62. protected extern EventInfo[] GetEvents_internal (Type reflected_type);
  63. private const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic |
  64. BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
  65. EventInfo[] get_event_info ()
  66. {
  67. if (generic_type is TypeBuilder)
  68. return ((TypeBuilder) generic_type).GetEvents_internal (flags);
  69. else
  70. return generic_type.GetEvents (flags);
  71. }
  72. void initialize ()
  73. {
  74. if (initialized)
  75. return;
  76. MonoGenericClass parent = GetParentType ();
  77. if (parent != null)
  78. parent.initialize ();
  79. initialize (generic_type.GetMethods (flags),
  80. generic_type.GetConstructors (flags),
  81. generic_type.GetFields (flags),
  82. generic_type.GetProperties (flags),
  83. get_event_info ());
  84. initialized = true;
  85. }
  86. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  87. protected extern MonoGenericClass GetParentType ();
  88. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  89. protected extern MonoGenericClass[] GetInterfaces_internal ();
  90. public override Type BaseType {
  91. get {
  92. MonoGenericClass parent = GetParentType ();
  93. return parent != null ? parent : generic_type.BaseType;
  94. }
  95. }
  96. public override Type[] GetInterfaces ()
  97. {
  98. return GetInterfaces_internal ();
  99. }
  100. protected override bool IsValueTypeImpl ()
  101. {
  102. return generic_type.IsValueType;
  103. }
  104. public override MethodInfo[] GetMethods (BindingFlags bf)
  105. {
  106. ArrayList l = new ArrayList ();
  107. //
  108. // Walk up our class hierarchy and retrieve methods from our
  109. // parent classes.
  110. //
  111. Type current_type = this;
  112. do {
  113. MonoGenericClass gi = current_type as MonoGenericClass;
  114. if (gi != null)
  115. l.AddRange (gi.GetMethods_impl (bf, this));
  116. else if (current_type is TypeBuilder)
  117. l.AddRange (current_type.GetMethods (bf));
  118. else {
  119. // If we encounter a `MonoType', its
  120. // GetMethodsByName() will return all the methods
  121. // from its parent type(s), so we can stop here.
  122. MonoType mt = (MonoType) current_type;
  123. l.AddRange (mt.GetMethodsByName (null, bf, false, this));
  124. break;
  125. }
  126. if ((bf & BindingFlags.DeclaredOnly) != 0)
  127. break;
  128. current_type = current_type.BaseType;
  129. } while (current_type != null);
  130. MethodInfo[] result = new MethodInfo [l.Count];
  131. l.CopyTo (result);
  132. return result;
  133. }
  134. protected MethodInfo[] GetMethods_impl (BindingFlags bf, Type reftype)
  135. {
  136. ArrayList l = new ArrayList ();
  137. bool match;
  138. MethodAttributes mattrs;
  139. initialize ();
  140. MethodInfo[] methods = GetMethods_internal (reftype);
  141. for (int i = 0; i < methods.Length; i++) {
  142. MethodInfo c = methods [i];
  143. match = false;
  144. mattrs = c.Attributes;
  145. if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
  146. if ((bf & BindingFlags.Public) != 0)
  147. match = true;
  148. } else {
  149. if ((bf & BindingFlags.NonPublic) != 0)
  150. match = true;
  151. }
  152. if (!match)
  153. continue;
  154. match = false;
  155. if ((mattrs & MethodAttributes.Static) != 0) {
  156. if ((bf & BindingFlags.Static) != 0)
  157. match = true;
  158. } else {
  159. if ((bf & BindingFlags.Instance) != 0)
  160. match = true;
  161. }
  162. if (!match)
  163. continue;
  164. l.Add (c);
  165. }
  166. MethodInfo[] result = new MethodInfo [l.Count];
  167. l.CopyTo (result);
  168. return result;
  169. }
  170. public override ConstructorInfo[] GetConstructors (BindingFlags bf)
  171. {
  172. ArrayList l = new ArrayList ();
  173. Type current_type = this;
  174. do {
  175. MonoGenericClass gi = current_type as MonoGenericClass;
  176. if (gi != null)
  177. l.AddRange (gi.GetConstructors_impl (bf, this));
  178. else if (current_type is TypeBuilder)
  179. l.AddRange (current_type.GetConstructors (bf));
  180. else {
  181. MonoType mt = (MonoType) current_type;
  182. l.AddRange (mt.GetConstructors_internal (bf, this));
  183. break;
  184. }
  185. if ((bf & BindingFlags.DeclaredOnly) != 0)
  186. break;
  187. current_type = current_type.BaseType;
  188. } while (current_type != null);
  189. ConstructorInfo[] result = new ConstructorInfo [l.Count];
  190. l.CopyTo (result);
  191. return result;
  192. }
  193. protected ConstructorInfo[] GetConstructors_impl (BindingFlags bf, Type reftype)
  194. {
  195. ArrayList l = new ArrayList ();
  196. bool match;
  197. MethodAttributes mattrs;
  198. initialize ();
  199. ConstructorInfo[] ctors = GetConstructors_internal (reftype);
  200. for (int i = 0; i < ctors.Length; i++) {
  201. ConstructorInfo c = ctors [i];
  202. match = false;
  203. mattrs = c.Attributes;
  204. if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
  205. if ((bf & BindingFlags.Public) != 0)
  206. match = true;
  207. } else {
  208. if ((bf & BindingFlags.NonPublic) != 0)
  209. match = true;
  210. }
  211. if (!match)
  212. continue;
  213. match = false;
  214. if ((mattrs & MethodAttributes.Static) != 0) {
  215. if ((bf & BindingFlags.Static) != 0)
  216. match = true;
  217. } else {
  218. if ((bf & BindingFlags.Instance) != 0)
  219. match = true;
  220. }
  221. if (!match)
  222. continue;
  223. l.Add (c);
  224. }
  225. ConstructorInfo[] result = new ConstructorInfo [l.Count];
  226. l.CopyTo (result);
  227. return result;
  228. }
  229. public override FieldInfo[] GetFields (BindingFlags bf)
  230. {
  231. ArrayList l = new ArrayList ();
  232. Type current_type = this;
  233. do {
  234. MonoGenericClass gi = current_type as MonoGenericClass;
  235. if (gi != null)
  236. l.AddRange (gi.GetFields_impl (bf, this));
  237. else if (current_type is TypeBuilder)
  238. l.AddRange (current_type.GetFields (bf));
  239. else {
  240. MonoType mt = (MonoType) current_type;
  241. l.AddRange (mt.GetFields_internal (bf, this));
  242. break;
  243. }
  244. if ((bf & BindingFlags.DeclaredOnly) != 0)
  245. break;
  246. current_type = current_type.BaseType;
  247. } while (current_type != null);
  248. FieldInfo[] result = new FieldInfo [l.Count];
  249. l.CopyTo (result);
  250. return result;
  251. }
  252. protected FieldInfo[] GetFields_impl (BindingFlags bf, Type reftype)
  253. {
  254. ArrayList l = new ArrayList ();
  255. bool match;
  256. FieldAttributes fattrs;
  257. initialize ();
  258. FieldInfo[] fields = GetFields_internal (reftype);
  259. for (int i = 0; i < fields.Length; i++) {
  260. FieldInfo c = fields [i];
  261. match = false;
  262. fattrs = c.Attributes;
  263. if ((fattrs & FieldAttributes.FieldAccessMask) == FieldAttributes.Public) {
  264. if ((bf & BindingFlags.Public) != 0)
  265. match = true;
  266. } else {
  267. if ((bf & BindingFlags.NonPublic) != 0)
  268. match = true;
  269. }
  270. if (!match)
  271. continue;
  272. match = false;
  273. if ((fattrs & FieldAttributes.Static) != 0) {
  274. if ((bf & BindingFlags.Static) != 0)
  275. match = true;
  276. } else {
  277. if ((bf & BindingFlags.Instance) != 0)
  278. match = true;
  279. }
  280. if (!match)
  281. continue;
  282. l.Add (c);
  283. }
  284. FieldInfo[] result = new FieldInfo [l.Count];
  285. l.CopyTo (result);
  286. return result;
  287. }
  288. public override PropertyInfo[] GetProperties (BindingFlags bf)
  289. {
  290. ArrayList l = new ArrayList ();
  291. Type current_type = this;
  292. do {
  293. MonoGenericClass gi = current_type as MonoGenericClass;
  294. if (gi != null)
  295. l.AddRange (gi.GetProperties_impl (bf, this));
  296. else if (current_type is TypeBuilder)
  297. l.AddRange (current_type.GetProperties (bf));
  298. else {
  299. MonoType mt = (MonoType) current_type;
  300. l.AddRange (mt.GetPropertiesByName (null, bf, false, this));
  301. break;
  302. }
  303. if ((bf & BindingFlags.DeclaredOnly) != 0)
  304. break;
  305. current_type = current_type.BaseType;
  306. } while (current_type != null);
  307. PropertyInfo[] result = new PropertyInfo [l.Count];
  308. l.CopyTo (result);
  309. return result;
  310. }
  311. protected PropertyInfo[] GetProperties_impl (BindingFlags bf, Type reftype)
  312. {
  313. ArrayList l = new ArrayList ();
  314. bool match;
  315. MethodAttributes mattrs;
  316. MethodInfo accessor;
  317. initialize ();
  318. PropertyInfo[] properties = GetProperties_internal (reftype);
  319. for (int i = 0; i < properties.Length; i++) {
  320. PropertyInfo c = properties [i];
  321. match = false;
  322. accessor = c.GetGetMethod (true);
  323. if (accessor == null)
  324. accessor = c.GetSetMethod (true);
  325. if (accessor == null)
  326. continue;
  327. mattrs = accessor.Attributes;
  328. if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
  329. if ((bf & BindingFlags.Public) != 0)
  330. match = true;
  331. } else {
  332. if ((bf & BindingFlags.NonPublic) != 0)
  333. match = true;
  334. }
  335. if (!match)
  336. continue;
  337. match = false;
  338. if ((mattrs & MethodAttributes.Static) != 0) {
  339. if ((bf & BindingFlags.Static) != 0)
  340. match = true;
  341. } else {
  342. if ((bf & BindingFlags.Instance) != 0)
  343. match = true;
  344. }
  345. if (!match)
  346. continue;
  347. l.Add (c);
  348. }
  349. PropertyInfo[] result = new PropertyInfo [l.Count];
  350. l.CopyTo (result);
  351. return result;
  352. }
  353. public override EventInfo[] GetEvents (BindingFlags bf)
  354. {
  355. ArrayList l = new ArrayList ();
  356. Type current_type = this;
  357. do {
  358. MonoGenericClass gi = current_type as MonoGenericClass;
  359. if (gi != null)
  360. l.AddRange (gi.GetEvents_impl (bf, this));
  361. else if (current_type is TypeBuilder)
  362. l.AddRange (current_type.GetEvents (bf));
  363. else {
  364. MonoType mt = (MonoType) current_type;
  365. l.AddRange (mt.GetEvents (bf));
  366. break;
  367. }
  368. if ((bf & BindingFlags.DeclaredOnly) != 0)
  369. break;
  370. current_type = current_type.BaseType;
  371. } while (current_type != null);
  372. EventInfo[] result = new EventInfo [l.Count];
  373. l.CopyTo (result);
  374. return result;
  375. }
  376. protected EventInfo[] GetEvents_impl (BindingFlags bf, Type reftype)
  377. {
  378. ArrayList l = new ArrayList ();
  379. bool match;
  380. MethodAttributes mattrs;
  381. MethodInfo accessor;
  382. initialize ();
  383. EventInfo[] events = GetEvents_internal (reftype);
  384. for (int i = 0; i < events.Length; i++) {
  385. EventInfo c = events [i];
  386. match = false;
  387. accessor = c.GetAddMethod (true);
  388. if (accessor == null)
  389. accessor = c.GetRemoveMethod (true);
  390. if (accessor == null)
  391. continue;
  392. mattrs = accessor.Attributes;
  393. if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
  394. if ((bf & BindingFlags.Public) != 0)
  395. match = true;
  396. } else {
  397. if ((bf & BindingFlags.NonPublic) != 0)
  398. match = true;
  399. }
  400. if (!match)
  401. continue;
  402. match = false;
  403. if ((mattrs & MethodAttributes.Static) != 0) {
  404. if ((bf & BindingFlags.Static) != 0)
  405. match = true;
  406. } else {
  407. if ((bf & BindingFlags.Instance) != 0)
  408. match = true;
  409. }
  410. if (!match)
  411. continue;
  412. l.Add (c);
  413. }
  414. EventInfo[] result = new EventInfo [l.Count];
  415. l.CopyTo (result);
  416. return result;
  417. }
  418. public override Type[] GetNestedTypes (BindingFlags bf)
  419. {
  420. return generic_type.GetNestedTypes (bf);
  421. }
  422. }
  423. }