MonoGenericClass.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  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. extern MethodInfo GetCorrespondingInflatedMethod (MethodInfo generic);
  55. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  56. extern ConstructorInfo GetCorrespondingInflatedConstructor (ConstructorInfo generic);
  57. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  58. extern FieldInfo GetCorrespondingInflatedField (string generic);
  59. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  60. protected extern MethodInfo[] GetMethods_internal (Type reflected_type);
  61. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  62. protected extern ConstructorInfo[] GetConstructors_internal (Type reflected_type);
  63. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  64. protected extern FieldInfo[] GetFields_internal (Type reflected_type);
  65. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  66. protected extern PropertyInfo[] GetProperties_internal (Type reflected_type);
  67. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  68. protected extern EventInfo[] GetEvents_internal (Type reflected_type);
  69. private const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic |
  70. BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
  71. EventInfo[] get_event_info ()
  72. {
  73. if (generic_type is TypeBuilder)
  74. return ((TypeBuilder) generic_type).GetEvents_internal (flags);
  75. else
  76. return generic_type.GetEvents (flags);
  77. }
  78. void initialize ()
  79. {
  80. if (initialized)
  81. return;
  82. MonoGenericClass parent = GetParentType ();
  83. if (parent != null)
  84. parent.initialize ();
  85. initialize (generic_type.GetMethods (flags),
  86. generic_type.GetConstructors (flags),
  87. generic_type.GetFields (flags),
  88. generic_type.GetProperties (flags),
  89. get_event_info ());
  90. initialized = true;
  91. }
  92. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  93. protected extern MonoGenericClass GetParentType ();
  94. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  95. protected extern MonoGenericClass[] GetInterfaces_internal ();
  96. public override Type BaseType {
  97. get {
  98. MonoGenericClass parent = GetParentType ();
  99. return parent != null ? parent : generic_type.BaseType;
  100. }
  101. }
  102. public override Type[] GetInterfaces ()
  103. {
  104. return GetInterfaces_internal ();
  105. }
  106. protected override bool IsValueTypeImpl ()
  107. {
  108. return generic_type.IsValueType;
  109. }
  110. internal override MethodInfo GetMethod (MethodInfo fromNoninstanciated)
  111. {
  112. initialize ();
  113. return GetCorrespondingInflatedMethod (fromNoninstanciated);
  114. }
  115. internal override ConstructorInfo GetConstructor (ConstructorInfo fromNoninstanciated)
  116. {
  117. initialize ();
  118. return GetCorrespondingInflatedConstructor (fromNoninstanciated);
  119. }
  120. internal override FieldInfo GetField (FieldInfo fromNoninstanciated)
  121. {
  122. initialize ();
  123. return GetCorrespondingInflatedField (fromNoninstanciated.Name);
  124. }
  125. public override MethodInfo[] GetMethods (BindingFlags bf)
  126. {
  127. ArrayList l = new ArrayList ();
  128. //
  129. // Walk up our class hierarchy and retrieve methods from our
  130. // parent classes.
  131. //
  132. Type current_type = this;
  133. do {
  134. MonoGenericClass gi = current_type as MonoGenericClass;
  135. if (gi != null)
  136. l.AddRange (gi.GetMethods_impl (bf, this));
  137. else if (current_type is TypeBuilder)
  138. l.AddRange (current_type.GetMethods (bf));
  139. else {
  140. // If we encounter a `MonoType', its
  141. // GetMethodsByName() will return all the methods
  142. // from its parent type(s), so we can stop here.
  143. MonoType mt = (MonoType) current_type;
  144. l.AddRange (mt.GetMethodsByName (null, bf, false, this));
  145. break;
  146. }
  147. if ((bf & BindingFlags.DeclaredOnly) != 0)
  148. break;
  149. current_type = current_type.BaseType;
  150. } while (current_type != null);
  151. MethodInfo[] result = new MethodInfo [l.Count];
  152. l.CopyTo (result);
  153. return result;
  154. }
  155. protected MethodInfo[] GetMethods_impl (BindingFlags bf, Type reftype)
  156. {
  157. ArrayList l = new ArrayList ();
  158. bool match;
  159. MethodAttributes mattrs;
  160. initialize ();
  161. MethodInfo[] methods = GetMethods_internal (reftype);
  162. for (int i = 0; i < methods.Length; i++) {
  163. MethodInfo c = methods [i];
  164. match = false;
  165. mattrs = c.Attributes;
  166. if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
  167. if ((bf & BindingFlags.Public) != 0)
  168. match = true;
  169. } else {
  170. if ((bf & BindingFlags.NonPublic) != 0)
  171. match = true;
  172. }
  173. if (!match)
  174. continue;
  175. match = false;
  176. if ((mattrs & MethodAttributes.Static) != 0) {
  177. if ((bf & BindingFlags.Static) != 0)
  178. match = true;
  179. } else {
  180. if ((bf & BindingFlags.Instance) != 0)
  181. match = true;
  182. }
  183. if (!match)
  184. continue;
  185. l.Add (c);
  186. }
  187. MethodInfo[] result = new MethodInfo [l.Count];
  188. l.CopyTo (result);
  189. return result;
  190. }
  191. public override ConstructorInfo[] GetConstructors (BindingFlags bf)
  192. {
  193. ArrayList l = new ArrayList ();
  194. Type current_type = this;
  195. do {
  196. MonoGenericClass gi = current_type as MonoGenericClass;
  197. if (gi != null)
  198. l.AddRange (gi.GetConstructors_impl (bf, this));
  199. else if (current_type is TypeBuilder)
  200. l.AddRange (current_type.GetConstructors (bf));
  201. else {
  202. MonoType mt = (MonoType) current_type;
  203. l.AddRange (mt.GetConstructors_internal (bf, this));
  204. break;
  205. }
  206. if ((bf & BindingFlags.DeclaredOnly) != 0)
  207. break;
  208. current_type = current_type.BaseType;
  209. } while (current_type != null);
  210. ConstructorInfo[] result = new ConstructorInfo [l.Count];
  211. l.CopyTo (result);
  212. return result;
  213. }
  214. protected ConstructorInfo[] GetConstructors_impl (BindingFlags bf, Type reftype)
  215. {
  216. ArrayList l = new ArrayList ();
  217. bool match;
  218. MethodAttributes mattrs;
  219. initialize ();
  220. ConstructorInfo[] ctors = GetConstructors_internal (reftype);
  221. for (int i = 0; i < ctors.Length; i++) {
  222. ConstructorInfo c = ctors [i];
  223. match = false;
  224. mattrs = c.Attributes;
  225. if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
  226. if ((bf & BindingFlags.Public) != 0)
  227. match = true;
  228. } else {
  229. if ((bf & BindingFlags.NonPublic) != 0)
  230. match = true;
  231. }
  232. if (!match)
  233. continue;
  234. match = false;
  235. if ((mattrs & MethodAttributes.Static) != 0) {
  236. if ((bf & BindingFlags.Static) != 0)
  237. match = true;
  238. } else {
  239. if ((bf & BindingFlags.Instance) != 0)
  240. match = true;
  241. }
  242. if (!match)
  243. continue;
  244. l.Add (c);
  245. }
  246. ConstructorInfo[] result = new ConstructorInfo [l.Count];
  247. l.CopyTo (result);
  248. return result;
  249. }
  250. public override FieldInfo[] GetFields (BindingFlags bf)
  251. {
  252. ArrayList l = new ArrayList ();
  253. Type current_type = this;
  254. do {
  255. MonoGenericClass gi = current_type as MonoGenericClass;
  256. if (gi != null)
  257. l.AddRange (gi.GetFields_impl (bf, this));
  258. else if (current_type is TypeBuilder)
  259. l.AddRange (current_type.GetFields (bf));
  260. else {
  261. MonoType mt = (MonoType) current_type;
  262. l.AddRange (mt.GetFields_internal (bf, this));
  263. break;
  264. }
  265. if ((bf & BindingFlags.DeclaredOnly) != 0)
  266. break;
  267. current_type = current_type.BaseType;
  268. } while (current_type != null);
  269. FieldInfo[] result = new FieldInfo [l.Count];
  270. l.CopyTo (result);
  271. return result;
  272. }
  273. protected FieldInfo[] GetFields_impl (BindingFlags bf, Type reftype)
  274. {
  275. ArrayList l = new ArrayList ();
  276. bool match;
  277. FieldAttributes fattrs;
  278. initialize ();
  279. FieldInfo[] fields = GetFields_internal (reftype);
  280. for (int i = 0; i < fields.Length; i++) {
  281. FieldInfo c = fields [i];
  282. match = false;
  283. fattrs = c.Attributes;
  284. if ((fattrs & FieldAttributes.FieldAccessMask) == FieldAttributes.Public) {
  285. if ((bf & BindingFlags.Public) != 0)
  286. match = true;
  287. } else {
  288. if ((bf & BindingFlags.NonPublic) != 0)
  289. match = true;
  290. }
  291. if (!match)
  292. continue;
  293. match = false;
  294. if ((fattrs & FieldAttributes.Static) != 0) {
  295. if ((bf & BindingFlags.Static) != 0)
  296. match = true;
  297. } else {
  298. if ((bf & BindingFlags.Instance) != 0)
  299. match = true;
  300. }
  301. if (!match)
  302. continue;
  303. l.Add (c);
  304. }
  305. FieldInfo[] result = new FieldInfo [l.Count];
  306. l.CopyTo (result);
  307. return result;
  308. }
  309. public override PropertyInfo[] GetProperties (BindingFlags bf)
  310. {
  311. ArrayList l = new ArrayList ();
  312. Type current_type = this;
  313. do {
  314. MonoGenericClass gi = current_type as MonoGenericClass;
  315. if (gi != null)
  316. l.AddRange (gi.GetProperties_impl (bf, this));
  317. else if (current_type is TypeBuilder)
  318. l.AddRange (current_type.GetProperties (bf));
  319. else {
  320. MonoType mt = (MonoType) current_type;
  321. l.AddRange (mt.GetPropertiesByName (null, bf, false, this));
  322. break;
  323. }
  324. if ((bf & BindingFlags.DeclaredOnly) != 0)
  325. break;
  326. current_type = current_type.BaseType;
  327. } while (current_type != null);
  328. PropertyInfo[] result = new PropertyInfo [l.Count];
  329. l.CopyTo (result);
  330. return result;
  331. }
  332. protected PropertyInfo[] GetProperties_impl (BindingFlags bf, Type reftype)
  333. {
  334. ArrayList l = new ArrayList ();
  335. bool match;
  336. MethodAttributes mattrs;
  337. MethodInfo accessor;
  338. initialize ();
  339. PropertyInfo[] properties = GetProperties_internal (reftype);
  340. for (int i = 0; i < properties.Length; i++) {
  341. PropertyInfo c = properties [i];
  342. match = false;
  343. accessor = c.GetGetMethod (true);
  344. if (accessor == null)
  345. accessor = c.GetSetMethod (true);
  346. if (accessor == null)
  347. continue;
  348. mattrs = accessor.Attributes;
  349. if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
  350. if ((bf & BindingFlags.Public) != 0)
  351. match = true;
  352. } else {
  353. if ((bf & BindingFlags.NonPublic) != 0)
  354. match = true;
  355. }
  356. if (!match)
  357. continue;
  358. match = false;
  359. if ((mattrs & MethodAttributes.Static) != 0) {
  360. if ((bf & BindingFlags.Static) != 0)
  361. match = true;
  362. } else {
  363. if ((bf & BindingFlags.Instance) != 0)
  364. match = true;
  365. }
  366. if (!match)
  367. continue;
  368. l.Add (c);
  369. }
  370. PropertyInfo[] result = new PropertyInfo [l.Count];
  371. l.CopyTo (result);
  372. return result;
  373. }
  374. public override EventInfo[] GetEvents (BindingFlags bf)
  375. {
  376. ArrayList l = new ArrayList ();
  377. Type current_type = this;
  378. do {
  379. MonoGenericClass gi = current_type as MonoGenericClass;
  380. if (gi != null)
  381. l.AddRange (gi.GetEvents_impl (bf, this));
  382. else if (current_type is TypeBuilder)
  383. l.AddRange (current_type.GetEvents (bf));
  384. else {
  385. MonoType mt = (MonoType) current_type;
  386. l.AddRange (mt.GetEvents (bf));
  387. break;
  388. }
  389. if ((bf & BindingFlags.DeclaredOnly) != 0)
  390. break;
  391. current_type = current_type.BaseType;
  392. } while (current_type != null);
  393. EventInfo[] result = new EventInfo [l.Count];
  394. l.CopyTo (result);
  395. return result;
  396. }
  397. protected EventInfo[] GetEvents_impl (BindingFlags bf, Type reftype)
  398. {
  399. ArrayList l = new ArrayList ();
  400. bool match;
  401. MethodAttributes mattrs;
  402. MethodInfo accessor;
  403. initialize ();
  404. EventInfo[] events = GetEvents_internal (reftype);
  405. for (int i = 0; i < events.Length; i++) {
  406. EventInfo c = events [i];
  407. match = false;
  408. accessor = c.GetAddMethod (true);
  409. if (accessor == null)
  410. accessor = c.GetRemoveMethod (true);
  411. if (accessor == null)
  412. continue;
  413. mattrs = accessor.Attributes;
  414. if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
  415. if ((bf & BindingFlags.Public) != 0)
  416. match = true;
  417. } else {
  418. if ((bf & BindingFlags.NonPublic) != 0)
  419. match = true;
  420. }
  421. if (!match)
  422. continue;
  423. match = false;
  424. if ((mattrs & MethodAttributes.Static) != 0) {
  425. if ((bf & BindingFlags.Static) != 0)
  426. match = true;
  427. } else {
  428. if ((bf & BindingFlags.Instance) != 0)
  429. match = true;
  430. }
  431. if (!match)
  432. continue;
  433. l.Add (c);
  434. }
  435. EventInfo[] result = new EventInfo [l.Count];
  436. l.CopyTo (result);
  437. return result;
  438. }
  439. public override Type[] GetNestedTypes (BindingFlags bf)
  440. {
  441. return generic_type.GetNestedTypes (bf);
  442. }
  443. }
  444. }