MonoGenericInst.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 MonoGenericInst : MonoType
  41. {
  42. protected Type generic_type;
  43. bool initialized;
  44. [MonoTODO]
  45. internal MonoGenericInst ()
  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. MonoGenericInst 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 MonoGenericInst GetParentType ();
  88. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  89. protected extern MonoGenericInst[] GetInterfaces_internal ();
  90. public override Type BaseType {
  91. get {
  92. MonoGenericInst 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. initialize ();
  107. ArrayList l = new ArrayList ();
  108. //
  109. // Walk up our class hierarchy and retrieve methods from our
  110. // parent classes.
  111. //
  112. Type current_type = this;
  113. do {
  114. MonoGenericInst gi = current_type as MonoGenericInst;
  115. if (gi != null)
  116. l.AddRange (gi.GetMethods_impl (bf, this));
  117. else if (current_type is TypeBuilder)
  118. l.AddRange (current_type.GetMethods (bf));
  119. else {
  120. // If we encounter a `MonoType', its
  121. // GetMethodsByName() will return all the methods
  122. // from its parent type(s), so we can stop here.
  123. MonoType mt = (MonoType) current_type;
  124. l.AddRange (mt.GetMethodsByName (null, bf, false, this));
  125. break;
  126. }
  127. if ((bf & BindingFlags.DeclaredOnly) != 0)
  128. break;
  129. current_type = current_type.BaseType;
  130. } while (current_type != null);
  131. MethodInfo[] result = new MethodInfo [l.Count];
  132. l.CopyTo (result);
  133. return result;
  134. }
  135. protected MethodInfo[] GetMethods_impl (BindingFlags bf, Type reftype)
  136. {
  137. ArrayList l = new ArrayList ();
  138. bool match;
  139. MethodAttributes mattrs;
  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. initialize ();
  173. ArrayList l = new ArrayList ();
  174. Type current_type = this;
  175. do {
  176. MonoGenericInst gi = current_type as MonoGenericInst;
  177. if (gi != null)
  178. l.AddRange (gi.GetConstructors_impl (bf, this));
  179. else if (current_type is TypeBuilder)
  180. l.AddRange (current_type.GetConstructors (bf));
  181. else {
  182. MonoType mt = (MonoType) current_type;
  183. l.AddRange (mt.GetConstructors_internal (bf, this));
  184. break;
  185. }
  186. if ((bf & BindingFlags.DeclaredOnly) != 0)
  187. break;
  188. current_type = current_type.BaseType;
  189. } while (current_type != null);
  190. ConstructorInfo[] result = new ConstructorInfo [l.Count];
  191. l.CopyTo (result);
  192. return result;
  193. }
  194. protected ConstructorInfo[] GetConstructors_impl (BindingFlags bf, Type reftype)
  195. {
  196. ArrayList l = new ArrayList ();
  197. bool match;
  198. MethodAttributes mattrs;
  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. initialize ();
  232. ArrayList l = new ArrayList ();
  233. Type current_type = this;
  234. do {
  235. MonoGenericInst gi = current_type as MonoGenericInst;
  236. if (gi != null)
  237. l.AddRange (gi.GetFields_impl (bf, this));
  238. else if (current_type is TypeBuilder)
  239. l.AddRange (current_type.GetFields (bf));
  240. else {
  241. MonoType mt = (MonoType) current_type;
  242. l.AddRange (mt.GetFields_internal (bf, this));
  243. break;
  244. }
  245. if ((bf & BindingFlags.DeclaredOnly) != 0)
  246. break;
  247. current_type = current_type.BaseType;
  248. } while (current_type != null);
  249. FieldInfo[] result = new FieldInfo [l.Count];
  250. l.CopyTo (result);
  251. return result;
  252. }
  253. protected FieldInfo[] GetFields_impl (BindingFlags bf, Type reftype)
  254. {
  255. ArrayList l = new ArrayList ();
  256. bool match;
  257. FieldAttributes fattrs;
  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. initialize ();
  291. ArrayList l = new ArrayList ();
  292. Type current_type = this;
  293. do {
  294. MonoGenericInst gi = current_type as MonoGenericInst;
  295. if (gi != null)
  296. l.AddRange (gi.GetProperties_impl (bf, this));
  297. else if (current_type is TypeBuilder)
  298. l.AddRange (current_type.GetProperties (bf));
  299. else {
  300. MonoType mt = (MonoType) current_type;
  301. l.AddRange (mt.GetPropertiesByName (null, bf, false, this));
  302. break;
  303. }
  304. if ((bf & BindingFlags.DeclaredOnly) != 0)
  305. break;
  306. current_type = current_type.BaseType;
  307. } while (current_type != null);
  308. PropertyInfo[] result = new PropertyInfo [l.Count];
  309. l.CopyTo (result);
  310. return result;
  311. }
  312. protected PropertyInfo[] GetProperties_impl (BindingFlags bf, Type reftype)
  313. {
  314. ArrayList l = new ArrayList ();
  315. bool match;
  316. MethodAttributes mattrs;
  317. MethodInfo accessor;
  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. initialize ();
  356. ArrayList l = new ArrayList ();
  357. Type current_type = this;
  358. do {
  359. MonoGenericInst gi = current_type as MonoGenericInst;
  360. if (gi != null)
  361. l.AddRange (gi.GetEvents_impl (bf, this));
  362. else if (current_type is TypeBuilder)
  363. l.AddRange (current_type.GetEvents (bf));
  364. else {
  365. MonoType mt = (MonoType) current_type;
  366. l.AddRange (mt.GetEvents (bf));
  367. break;
  368. }
  369. if ((bf & BindingFlags.DeclaredOnly) != 0)
  370. break;
  371. current_type = current_type.BaseType;
  372. } while (current_type != null);
  373. EventInfo[] result = new EventInfo [l.Count];
  374. l.CopyTo (result);
  375. return result;
  376. }
  377. protected EventInfo[] GetEvents_impl (BindingFlags bf, Type reftype)
  378. {
  379. ArrayList l = new ArrayList ();
  380. bool match;
  381. MethodAttributes mattrs;
  382. MethodInfo accessor;
  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. }