MonoGenericClass.cs 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060
  1. //
  2. // System.Reflection.MonoGenericClass
  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. using System.Text;
  39. namespace System.Reflection
  40. {
  41. /*
  42. * MonoGenericClass represents an instantiation of a generic TypeBuilder. MS
  43. * calls this class TypeBuilderInstantiation (a much better name). MS returns
  44. * NotImplementedException for many of the methods but we can't do that as gmcs
  45. * depends on them.
  46. */
  47. internal class MonoGenericClass : Type
  48. {
  49. #region Keep in sync with object-internals.h
  50. #pragma warning disable 649
  51. internal Type generic_type;
  52. Type[] type_arguments;
  53. bool initialized;
  54. #pragma warning restore 649
  55. #endregion
  56. Hashtable fields, ctors, methods;
  57. int event_count;
  58. int is_compiler_context;
  59. internal MonoGenericClass ()
  60. {
  61. // this should not be used
  62. throw new InvalidOperationException ();
  63. }
  64. internal MonoGenericClass (Type tb, Type[] args)
  65. {
  66. this.generic_type = tb;
  67. this.type_arguments = args;
  68. register_with_runtime (this); /*Temporary hack while*/
  69. }
  70. internal override bool IsCompilerContext {
  71. get {
  72. if (is_compiler_context == 0) {
  73. bool is_cc = generic_type.IsCompilerContext;
  74. foreach (Type t in type_arguments)
  75. is_cc |= t.IsCompilerContext;
  76. is_compiler_context = is_cc ? 1 : -1;
  77. }
  78. return is_compiler_context == 1;
  79. }
  80. }
  81. internal override Type InternalResolve ()
  82. {
  83. Type gtd = generic_type.InternalResolve ();
  84. Type[] args = new Type [type_arguments.Length];
  85. for (int i = 0; i < type_arguments.Length; ++i)
  86. args [i] = type_arguments [i].InternalResolve ();
  87. return gtd.MakeGenericType (args);
  88. }
  89. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  90. extern void initialize (MethodInfo[] methods, ConstructorInfo[] ctors, FieldInfo[] fields, PropertyInfo[] properties, EventInfo[] events);
  91. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  92. internal static extern void register_with_runtime (Type type);
  93. EventInfo[] GetEventsFromGTD (BindingFlags flags) {
  94. TypeBuilder tb = generic_type as TypeBuilder;
  95. if (tb == null)
  96. return generic_type.GetEvents (flags);
  97. return tb.GetEvents_internal (flags);
  98. }
  99. ConstructorInfo[] GetConstructorsFromGTD (BindingFlags flags)
  100. {
  101. TypeBuilder tb = generic_type as TypeBuilder;
  102. if (tb == null)
  103. return generic_type.GetConstructors (flags);
  104. return tb.GetConstructorsInternal (flags);
  105. }
  106. /*
  107. MethodInfo[] GetMethodsFromGTD (BindingFlags bf)
  108. {
  109. TypeBuilder tb = generic_type as TypeBuilder;
  110. if (tb == null)
  111. return generic_type.GetMethods (bf);
  112. MethodInfo[] res = new MethodInfo [tb.num_methods];
  113. if (tb.num_methods > 0)
  114. Array.Copy (tb.methods, res, tb.num_methods);
  115. return res;
  116. }
  117. */
  118. FieldInfo[] GetFieldsFromGTD (BindingFlags bf)
  119. {
  120. TypeBuilder tb = generic_type as TypeBuilder;
  121. if (tb == null)
  122. return generic_type.GetFields (bf);
  123. FieldInfo[] res = new FieldInfo [tb.num_fields];
  124. if (tb.num_fields > 0)
  125. Array.Copy (tb.fields, res, tb.num_fields);
  126. return res;
  127. }
  128. /*@hint might not be honored so it required aditional filtering
  129. TODO move filtering into here for the TypeBuilder case and remove the hint ugliness
  130. */
  131. MethodInfo[] GetMethodsFromGTDWithHint (BindingFlags hint)
  132. {
  133. TypeBuilder tb = generic_type as TypeBuilder;
  134. if (tb == null)
  135. return generic_type.GetMethods (hint);
  136. if (tb.num_methods == 0)
  137. return new MethodInfo [0];
  138. MethodInfo[] res = new MethodInfo [tb.num_methods];
  139. Array.Copy (tb.methods, 0, res, 0, tb.num_methods);
  140. return res;
  141. }
  142. /*@hint might not be honored so it required aditional filtering
  143. TODO move filtering into here for the TypeBuilder case and remove the hint ugliness
  144. */
  145. ConstructorInfo[] GetConstructorsFromGTDWithHint (BindingFlags hint)
  146. {
  147. TypeBuilder tb = generic_type as TypeBuilder;
  148. if (tb == null)
  149. return generic_type.GetConstructors (hint);
  150. if (tb.ctors == null)
  151. return new ConstructorInfo [0];
  152. ConstructorInfo[] res = new ConstructorInfo [tb.ctors.Length];
  153. tb.ctors.CopyTo (res, 0);
  154. return res;
  155. }
  156. static Type PeelType (Type t) {
  157. if (t.HasElementType)
  158. return PeelType (t.GetElementType ());
  159. if (t.IsGenericType && !t.IsGenericParameter)
  160. return t.GetGenericTypeDefinition ();
  161. return t;
  162. }
  163. static PropertyInfo[] GetPropertiesInternal (Type type, BindingFlags bf)
  164. {
  165. TypeBuilder tb = type as TypeBuilder;
  166. if (tb != null)
  167. return tb.properties;
  168. return type.GetProperties (bf);
  169. }
  170. Type[] GetInterfacesFromGTD ()
  171. {
  172. TypeBuilder tb = generic_type as TypeBuilder;
  173. if (tb != null)
  174. return tb.interfaces;
  175. return generic_type.GetInterfaces ();
  176. }
  177. internal bool IsCreated {
  178. get {
  179. TypeBuilder tb = generic_type as TypeBuilder;
  180. return tb != null ? tb.is_created : true;
  181. }
  182. }
  183. private const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic |
  184. BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
  185. void initialize ()
  186. {
  187. if (initialized)
  188. return;
  189. MonoGenericClass parent = GetParentType () as MonoGenericClass;
  190. if (parent != null)
  191. parent.initialize ();
  192. EventInfo[] events = GetEventsFromGTD (flags);
  193. event_count = events.Length;
  194. initialize (generic_type.GetMethods (flags),
  195. GetConstructorsFromGTD (flags),
  196. generic_type.GetFields (flags),
  197. generic_type.GetProperties (flags),
  198. events);
  199. initialized = true;
  200. }
  201. Type GetParentType ()
  202. {
  203. return InflateType (generic_type.BaseType);
  204. }
  205. internal Type InflateType (Type type)
  206. {
  207. return InflateType (type, type_arguments, null);
  208. }
  209. internal Type InflateType (Type type, Type[] method_args)
  210. {
  211. return InflateType (type, type_arguments, method_args);
  212. }
  213. internal static Type InflateType (Type type, Type[] type_args, Type[] method_args)
  214. {
  215. if (type == null)
  216. return null;
  217. if (!type.IsGenericParameter && !type.ContainsGenericParameters)
  218. return type;
  219. if (type.IsGenericParameter) {
  220. if (type.DeclaringMethod == null)
  221. return type_args == null ? type : type_args [type.GenericParameterPosition];
  222. return method_args == null ? type : method_args [type.GenericParameterPosition];
  223. }
  224. if (type.IsPointer)
  225. return InflateType (type.GetElementType (), type_args, method_args).MakePointerType ();
  226. if (type.IsByRef)
  227. return InflateType (type.GetElementType (), type_args, method_args).MakeByRefType ();
  228. if (type.IsArray) {
  229. if (type.GetArrayRank () > 1)
  230. return InflateType (type.GetElementType (), type_args, method_args).MakeArrayType (type.GetArrayRank ());
  231. #if BOOTSTRAP_NET_2_0
  232. if (type.ToString ().EndsWith ("[*]"))
  233. #else
  234. if (type.ToString ().EndsWith ("[*]", StringComparison.Ordinal)) /*FIXME, the reflection API doesn't offer a way around this*/
  235. #endif
  236. return InflateType (type.GetElementType (), type_args, method_args).MakeArrayType (1);
  237. return InflateType (type.GetElementType (), type_args, method_args).MakeArrayType ();
  238. }
  239. Type[] args = type.GetGenericArguments ();
  240. for (int i = 0; i < args.Length; ++i)
  241. args [i] = InflateType (args [i], type_args, method_args);
  242. Type gtd = type.IsGenericTypeDefinition ? type : type.GetGenericTypeDefinition ();
  243. return gtd.MakeGenericType (args);
  244. }
  245. public override Type BaseType {
  246. get {
  247. Type parent = GetParentType ();
  248. return parent != null ? parent : generic_type.BaseType;
  249. }
  250. }
  251. Type[] GetInterfacesInternal ()
  252. {
  253. Type[] ifaces = GetInterfacesFromGTD ();
  254. if (ifaces == null)
  255. return new Type [0];
  256. Type[] res = new Type [ifaces.Length];
  257. for (int i = 0; i < res.Length; ++i)
  258. res [i] = InflateType (ifaces [i]);
  259. return res;
  260. }
  261. public override Type[] GetInterfaces ()
  262. {
  263. if (!IsCompilerContext) {
  264. Console.WriteLine ("--FAIL {0}", this);
  265. Console.WriteLine ("\tgt {0}/{1}/{2}", generic_type, generic_type.IsCompilerContext, generic_type.GetType ());
  266. foreach (Type t in type_arguments)
  267. Console.WriteLine ("\targ {0}/{1}/{2}", t, t.IsCompilerContext, t.GetType ());
  268. throw new NotSupportedException ();
  269. }
  270. return GetInterfacesInternal ();
  271. }
  272. protected override bool IsValueTypeImpl ()
  273. {
  274. return generic_type.IsValueType;
  275. }
  276. internal override MethodInfo GetMethod (MethodInfo fromNoninstanciated)
  277. {
  278. initialize ();
  279. if (methods == null)
  280. methods = new Hashtable ();
  281. if (!methods.ContainsKey (fromNoninstanciated))
  282. methods [fromNoninstanciated] = new MethodOnTypeBuilderInst (this, fromNoninstanciated);
  283. return (MethodInfo)methods [fromNoninstanciated];
  284. }
  285. internal override ConstructorInfo GetConstructor (ConstructorInfo fromNoninstanciated)
  286. {
  287. initialize ();
  288. if (ctors == null)
  289. ctors = new Hashtable ();
  290. if (!ctors.ContainsKey (fromNoninstanciated))
  291. ctors [fromNoninstanciated] = new ConstructorOnTypeBuilderInst (this, fromNoninstanciated);
  292. return (ConstructorInfo)ctors [fromNoninstanciated];
  293. }
  294. internal override FieldInfo GetField (FieldInfo fromNoninstanciated)
  295. {
  296. initialize ();
  297. if (fields == null)
  298. fields = new Hashtable ();
  299. if (!fields.ContainsKey (fromNoninstanciated))
  300. fields [fromNoninstanciated] = new FieldOnTypeBuilderInst (this, fromNoninstanciated);
  301. return (FieldInfo)fields [fromNoninstanciated];
  302. }
  303. public override MethodInfo[] GetMethods (BindingFlags bf)
  304. {
  305. if (!IsCompilerContext)
  306. throw new NotSupportedException ();
  307. ArrayList l = new ArrayList ();
  308. //
  309. // Walk up our class hierarchy and retrieve methods from our
  310. // parent classes.
  311. //
  312. if (!(generic_type is TypeBuilder)) {
  313. foreach (var method in generic_type.GetMethods (bf)) {
  314. var m = method;
  315. if (m.DeclaringType.IsGenericTypeDefinition)
  316. m = TypeBuilder.GetMethod (this, m);
  317. l.Add (m);
  318. }
  319. } else {
  320. Type current_type = this;
  321. do {
  322. MonoGenericClass gi = current_type as MonoGenericClass;
  323. if (gi != null)
  324. l.AddRange (gi.GetMethodsInternal (bf, this));
  325. else if (current_type is TypeBuilder)
  326. l.AddRange (current_type.GetMethods (bf));
  327. else {
  328. // If we encounter a `MonoType', its
  329. // GetMethodsByName() will return all the methods
  330. // from its parent type(s), so we can stop here.
  331. MonoType mt = (MonoType) current_type;
  332. l.AddRange (mt.GetMethodsByName (null, bf, false, this));
  333. break;
  334. }
  335. if ((bf & BindingFlags.DeclaredOnly) != 0)
  336. break;
  337. current_type = current_type.BaseType;
  338. } while (current_type != null);
  339. }
  340. MethodInfo[] result = new MethodInfo [l.Count];
  341. l.CopyTo (result);
  342. return result;
  343. }
  344. MethodInfo[] GetMethodsInternal (BindingFlags bf, MonoGenericClass reftype)
  345. {
  346. if (reftype != this)
  347. bf |= BindingFlags.DeclaredOnly; /*To avoid duplicates*/
  348. MethodInfo[] methods = GetMethodsFromGTDWithHint (bf);
  349. if (methods.Length == 0)
  350. return new MethodInfo [0];
  351. ArrayList l = new ArrayList ();
  352. bool match;
  353. MethodAttributes mattrs;
  354. initialize ();
  355. for (int i = 0; i < methods.Length; ++i) {
  356. MethodInfo c = methods [i];
  357. match = false;
  358. mattrs = c.Attributes;
  359. if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
  360. if ((bf & BindingFlags.Public) != 0)
  361. match = true;
  362. } else {
  363. if ((bf & BindingFlags.NonPublic) != 0)
  364. match = true;
  365. }
  366. if (!match)
  367. continue;
  368. match = false;
  369. if ((mattrs & MethodAttributes.Static) != 0) {
  370. if ((bf & BindingFlags.Static) != 0)
  371. match = true;
  372. } else {
  373. if ((bf & BindingFlags.Instance) != 0)
  374. match = true;
  375. }
  376. if (!match)
  377. continue;
  378. if (c.DeclaringType.IsGenericTypeDefinition)
  379. c = TypeBuilder.GetMethod (this, c);
  380. l.Add (c);
  381. }
  382. MethodInfo[] result = new MethodInfo [l.Count];
  383. l.CopyTo (result);
  384. return result;
  385. }
  386. public override ConstructorInfo[] GetConstructors (BindingFlags bf)
  387. {
  388. if (!IsCompilerContext)
  389. throw new NotSupportedException ();
  390. ArrayList l = new ArrayList ();
  391. Type current_type = this;
  392. do {
  393. MonoGenericClass gi = current_type as MonoGenericClass;
  394. if (gi != null)
  395. l.AddRange (gi.GetConstructorsInternal (bf, this));
  396. else if (current_type is TypeBuilder)
  397. l.AddRange (current_type.GetConstructors (bf));
  398. else {
  399. MonoType mt = (MonoType) current_type;
  400. l.AddRange (mt.GetConstructors_internal (bf, this));
  401. break;
  402. }
  403. if ((bf & BindingFlags.DeclaredOnly) != 0)
  404. break;
  405. current_type = current_type.BaseType;
  406. } while (current_type != null);
  407. ConstructorInfo[] result = new ConstructorInfo [l.Count];
  408. l.CopyTo (result);
  409. return result;
  410. }
  411. ConstructorInfo[] GetConstructorsInternal (BindingFlags bf, MonoGenericClass reftype)
  412. {
  413. ConstructorInfo[] ctors = GetConstructorsFromGTDWithHint (bf);
  414. if (ctors == null || ctors.Length == 0)
  415. return new ConstructorInfo [0];
  416. ArrayList l = new ArrayList ();
  417. bool match;
  418. MethodAttributes mattrs;
  419. initialize ();
  420. for (int i = 0; i < ctors.Length; i++) {
  421. ConstructorInfo c = ctors [i];
  422. match = false;
  423. mattrs = c.Attributes;
  424. if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
  425. if ((bf & BindingFlags.Public) != 0)
  426. match = true;
  427. } else {
  428. if ((bf & BindingFlags.NonPublic) != 0)
  429. match = true;
  430. }
  431. if (!match)
  432. continue;
  433. match = false;
  434. if ((mattrs & MethodAttributes.Static) != 0) {
  435. if ((bf & BindingFlags.Static) != 0)
  436. match = true;
  437. } else {
  438. if ((bf & BindingFlags.Instance) != 0)
  439. match = true;
  440. }
  441. if (!match)
  442. continue;
  443. l.Add (TypeBuilder.GetConstructor (this, c));
  444. }
  445. ConstructorInfo[] result = new ConstructorInfo [l.Count];
  446. l.CopyTo (result);
  447. return result;
  448. }
  449. public override FieldInfo[] GetFields (BindingFlags bf)
  450. {
  451. if (!IsCompilerContext)
  452. throw new NotSupportedException ();
  453. ArrayList l = new ArrayList ();
  454. Type current_type = this;
  455. do {
  456. MonoGenericClass gi = current_type as MonoGenericClass;
  457. if (gi != null)
  458. l.AddRange (gi.GetFieldsInternal (bf, this));
  459. else if (current_type is TypeBuilder)
  460. l.AddRange (current_type.GetFields (bf));
  461. else {
  462. MonoType mt = (MonoType) current_type;
  463. l.AddRange (mt.GetFields_internal (bf, this));
  464. break;
  465. }
  466. if ((bf & BindingFlags.DeclaredOnly) != 0)
  467. break;
  468. current_type = current_type.BaseType;
  469. } while (current_type != null);
  470. FieldInfo[] result = new FieldInfo [l.Count];
  471. l.CopyTo (result);
  472. return result;
  473. }
  474. FieldInfo[] GetFieldsInternal (BindingFlags bf, MonoGenericClass reftype)
  475. {
  476. FieldInfo[] fields = GetFieldsFromGTD (bf);
  477. if (fields.Length == 0)
  478. return new FieldInfo [0];
  479. ArrayList l = new ArrayList ();
  480. bool match;
  481. FieldAttributes fattrs;
  482. initialize ();
  483. for (int i = 0; i < fields.Length; i++) {
  484. FieldInfo c = fields [i];
  485. match = false;
  486. fattrs = c.Attributes;
  487. if ((fattrs & FieldAttributes.FieldAccessMask) == FieldAttributes.Public) {
  488. if ((bf & BindingFlags.Public) != 0)
  489. match = true;
  490. } else {
  491. if ((bf & BindingFlags.NonPublic) != 0)
  492. match = true;
  493. }
  494. if (!match)
  495. continue;
  496. match = false;
  497. if ((fattrs & FieldAttributes.Static) != 0) {
  498. if ((bf & BindingFlags.Static) != 0)
  499. match = true;
  500. } else {
  501. if ((bf & BindingFlags.Instance) != 0)
  502. match = true;
  503. }
  504. if (!match)
  505. continue;
  506. l.Add (TypeBuilder.GetField (this, c));
  507. }
  508. FieldInfo[] result = new FieldInfo [l.Count];
  509. l.CopyTo (result);
  510. return result;
  511. }
  512. public override PropertyInfo[] GetProperties (BindingFlags bf)
  513. {
  514. if (!IsCompilerContext)
  515. throw new NotSupportedException ();
  516. ArrayList l = new ArrayList ();
  517. Type current_type = this;
  518. do {
  519. MonoGenericClass gi = current_type as MonoGenericClass;
  520. if (gi != null)
  521. l.AddRange (gi.GetPropertiesInternal (bf, this));
  522. else if (current_type is TypeBuilder)
  523. l.AddRange (current_type.GetProperties (bf));
  524. else {
  525. MonoType mt = (MonoType) current_type;
  526. l.AddRange (mt.GetPropertiesByName (null, bf, false, this));
  527. break;
  528. }
  529. if ((bf & BindingFlags.DeclaredOnly) != 0)
  530. break;
  531. current_type = current_type.BaseType;
  532. } while (current_type != null);
  533. PropertyInfo[] result = new PropertyInfo [l.Count];
  534. l.CopyTo (result);
  535. return result;
  536. }
  537. PropertyInfo[] GetPropertiesInternal (BindingFlags bf, MonoGenericClass reftype)
  538. {
  539. PropertyInfo[] props = GetPropertiesInternal (generic_type, bf);
  540. if (props == null || props.Length == 0)
  541. return new PropertyInfo [0];
  542. ArrayList l = new ArrayList ();
  543. bool match;
  544. MethodAttributes mattrs;
  545. MethodInfo accessor;
  546. initialize ();
  547. foreach (PropertyInfo pinfo in props) {
  548. match = false;
  549. accessor = pinfo.GetGetMethod (true);
  550. if (accessor == null)
  551. accessor = pinfo.GetSetMethod (true);
  552. if (accessor == null)
  553. continue;
  554. mattrs = accessor.Attributes;
  555. if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
  556. if ((bf & BindingFlags.Public) != 0)
  557. match = true;
  558. } else {
  559. if ((bf & BindingFlags.NonPublic) != 0)
  560. match = true;
  561. }
  562. if (!match)
  563. continue;
  564. match = false;
  565. if ((mattrs & MethodAttributes.Static) != 0) {
  566. if ((bf & BindingFlags.Static) != 0)
  567. match = true;
  568. } else {
  569. if ((bf & BindingFlags.Instance) != 0)
  570. match = true;
  571. }
  572. if (!match)
  573. continue;
  574. l.Add (new PropertyOnTypeBuilderInst (reftype, pinfo));
  575. }
  576. PropertyInfo[] result = new PropertyInfo [l.Count];
  577. l.CopyTo (result);
  578. return result;
  579. }
  580. public override EventInfo[] GetEvents (BindingFlags bf)
  581. {
  582. if (!IsCompilerContext)
  583. throw new NotSupportedException ();
  584. ArrayList l = new ArrayList ();
  585. Type current_type = this;
  586. do {
  587. MonoGenericClass gi = current_type as MonoGenericClass;
  588. if (gi != null)
  589. l.AddRange (gi.GetEventsInternal (bf, this));
  590. else if (current_type is TypeBuilder)
  591. l.AddRange (current_type.GetEvents (bf));
  592. else {
  593. MonoType mt = (MonoType) current_type;
  594. l.AddRange (mt.GetEvents (bf));
  595. break;
  596. }
  597. if ((bf & BindingFlags.DeclaredOnly) != 0)
  598. break;
  599. current_type = current_type.BaseType;
  600. } while (current_type != null);
  601. EventInfo[] result = new EventInfo [l.Count];
  602. l.CopyTo (result);
  603. return result;
  604. }
  605. EventInfo[] GetEventsInternal (BindingFlags bf, MonoGenericClass reftype) {
  606. TypeBuilder tb = generic_type as TypeBuilder;
  607. if (tb == null) {
  608. EventInfo[] res = generic_type.GetEvents (bf);
  609. for (int i = 0; i < res.Length; ++i)
  610. res [i] = new EventOnTypeBuilderInst (this, res [i]);
  611. return res;
  612. }
  613. EventBuilder[] events = tb.events;
  614. if (events == null || events.Length == 0)
  615. return new EventInfo [0];
  616. initialize ();
  617. ArrayList l = new ArrayList ();
  618. bool match;
  619. MethodAttributes mattrs;
  620. MethodInfo accessor;
  621. for (int i = 0; i < event_count; ++i) {
  622. EventBuilder ev = events [i];
  623. match = false;
  624. accessor = ev.add_method;
  625. if (accessor == null)
  626. accessor = ev.remove_method;
  627. if (accessor == null)
  628. continue;
  629. mattrs = accessor.Attributes;
  630. if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
  631. if ((bf & BindingFlags.Public) != 0)
  632. match = true;
  633. } else {
  634. if ((bf & BindingFlags.NonPublic) != 0)
  635. match = true;
  636. }
  637. if (!match)
  638. continue;
  639. match = false;
  640. if ((mattrs & MethodAttributes.Static) != 0) {
  641. if ((bf & BindingFlags.Static) != 0)
  642. match = true;
  643. } else {
  644. if ((bf & BindingFlags.Instance) != 0)
  645. match = true;
  646. }
  647. if (!match)
  648. continue;
  649. l.Add (new EventOnTypeBuilderInst (this, ev));
  650. }
  651. EventInfo[] result = new EventInfo [l.Count];
  652. l.CopyTo (result);
  653. return result;
  654. }
  655. public override Type[] GetNestedTypes (BindingFlags bf)
  656. {
  657. return generic_type.GetNestedTypes (bf);
  658. }
  659. public override bool IsAssignableFrom (Type c)
  660. {
  661. if (c == this)
  662. return true;
  663. Type[] interfaces = GetInterfacesInternal ();
  664. if (c.IsInterface) {
  665. if (interfaces == null)
  666. return false;
  667. foreach (Type t in interfaces)
  668. if (c.IsAssignableFrom (t))
  669. return true;
  670. return false;
  671. }
  672. Type parent = GetParentType ();
  673. if (parent == null)
  674. return c == typeof (object);
  675. else
  676. return c.IsAssignableFrom (parent);
  677. }
  678. public override Type UnderlyingSystemType {
  679. get { return this; }
  680. }
  681. public override Assembly Assembly {
  682. get { return generic_type.Assembly; }
  683. }
  684. public override Module Module {
  685. get { return generic_type.Module; }
  686. }
  687. public override string Name {
  688. get { return generic_type.Name; }
  689. }
  690. public override string Namespace {
  691. get { return generic_type.Namespace; }
  692. }
  693. public override string FullName {
  694. get { return format_name (true, false); }
  695. }
  696. public override string AssemblyQualifiedName {
  697. get { return format_name (true, true); }
  698. }
  699. public override Guid GUID {
  700. get { throw new NotSupportedException (); }
  701. }
  702. string format_name (bool full_name, bool assembly_qualified)
  703. {
  704. StringBuilder sb = new StringBuilder (generic_type.FullName);
  705. bool compiler_ctx = IsCompilerContext;
  706. sb.Append ("[");
  707. for (int i = 0; i < type_arguments.Length; ++i) {
  708. if (i > 0)
  709. sb.Append (",");
  710. string name;
  711. if (full_name) {
  712. string assemblyName = type_arguments [i].Assembly.FullName;
  713. name = type_arguments [i].FullName;
  714. if (name != null && assemblyName != null)
  715. name = name + ", " + assemblyName;
  716. } else {
  717. name = type_arguments [i].ToString ();
  718. }
  719. if (name == null) {
  720. if (compiler_ctx && type_arguments [i].IsGenericParameter)
  721. name = type_arguments [i].Name;
  722. else
  723. return null;
  724. }
  725. if (full_name)
  726. sb.Append ("[");
  727. sb.Append (name);
  728. if (full_name)
  729. sb.Append ("]");
  730. }
  731. sb.Append ("]");
  732. if (assembly_qualified) {
  733. sb.Append (", ");
  734. sb.Append (generic_type.Assembly.FullName);
  735. }
  736. return sb.ToString ();
  737. }
  738. public override string ToString ()
  739. {
  740. return format_name (false, false);
  741. }
  742. public override Type GetGenericTypeDefinition ()
  743. {
  744. return generic_type;
  745. }
  746. public override Type[] GetGenericArguments ()
  747. {
  748. Type[] ret = new Type [type_arguments.Length];
  749. type_arguments.CopyTo (ret, 0);
  750. return ret;
  751. }
  752. public override bool ContainsGenericParameters {
  753. get {
  754. /*FIXME remove this once compound types are not instantiated using MGC*/
  755. if (HasElementType)
  756. return GetElementType ().ContainsGenericParameters;
  757. foreach (Type t in type_arguments) {
  758. if (t.ContainsGenericParameters)
  759. return true;
  760. }
  761. return false;
  762. }
  763. }
  764. public override bool IsGenericTypeDefinition {
  765. get { return false; }
  766. }
  767. public override bool IsGenericType {
  768. get { return !HasElementType; }
  769. }
  770. public override Type DeclaringType {
  771. get { return InflateType (generic_type.DeclaringType); }
  772. }
  773. public override RuntimeTypeHandle TypeHandle {
  774. get {
  775. if (!IsCompilerContext)
  776. throw new NotSupportedException ();
  777. return _impl;
  778. }
  779. }
  780. public override Type MakeArrayType ()
  781. {
  782. return new ArrayType (this, 0);
  783. }
  784. public override Type MakeArrayType (int rank)
  785. {
  786. if (rank < 1)
  787. throw new IndexOutOfRangeException ();
  788. return new ArrayType (this, rank);
  789. }
  790. public override Type MakeByRefType ()
  791. {
  792. return new ByRefType (this);
  793. }
  794. public override Type MakePointerType ()
  795. {
  796. return new PointerType (this);
  797. }
  798. public override Type GetElementType ()
  799. {
  800. throw new NotSupportedException ();
  801. }
  802. protected override bool HasElementTypeImpl ()
  803. {
  804. return false;
  805. }
  806. protected override bool IsCOMObjectImpl ()
  807. {
  808. return false;
  809. }
  810. protected override bool IsPrimitiveImpl ()
  811. {
  812. return false;
  813. }
  814. protected override bool IsArrayImpl ()
  815. {
  816. return false;
  817. }
  818. protected override bool IsByRefImpl ()
  819. {
  820. return false;
  821. }
  822. protected override bool IsPointerImpl ()
  823. {
  824. return false;
  825. }
  826. protected override TypeAttributes GetAttributeFlagsImpl ()
  827. {
  828. return generic_type.Attributes;
  829. }
  830. //stuff that throws
  831. public override Type GetInterface (string name, bool ignoreCase)
  832. {
  833. throw new NotSupportedException ();
  834. }
  835. public override EventInfo GetEvent (string name, BindingFlags bindingAttr)
  836. {
  837. if (!IsCompilerContext)
  838. throw new NotSupportedException ();
  839. foreach (var evt in GetEvents (bindingAttr)) {
  840. if (evt.Name == name)
  841. return evt;
  842. }
  843. return null;
  844. }
  845. public override FieldInfo GetField( string name, BindingFlags bindingAttr)
  846. {
  847. throw new NotSupportedException ();
  848. }
  849. public override MemberInfo[] GetMembers (BindingFlags bindingAttr)
  850. {
  851. throw new NotSupportedException ();
  852. }
  853. public override Type GetNestedType (string name, BindingFlags bindingAttr)
  854. {
  855. throw new NotSupportedException ();
  856. }
  857. public override object InvokeMember (string name, BindingFlags invokeAttr,
  858. Binder binder, object target, object[] args,
  859. ParameterModifier[] modifiers,
  860. CultureInfo culture, string[] namedParameters)
  861. {
  862. throw new NotSupportedException ();
  863. }
  864. protected override MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder,
  865. CallingConventions callConvention, Type[] types,
  866. ParameterModifier[] modifiers)
  867. {
  868. throw new NotSupportedException ();
  869. }
  870. protected override PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr, Binder binder,
  871. Type returnType, Type[] types, ParameterModifier[] modifiers)
  872. {
  873. throw new NotSupportedException ();
  874. }
  875. protected override ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr,
  876. Binder binder,
  877. CallingConventions callConvention,
  878. Type[] types,
  879. ParameterModifier[] modifiers)
  880. {
  881. if (!IsCompilerContext)
  882. throw new NotSupportedException ();
  883. return MonoType.GetConstructorImpl (GetConstructors (bindingAttr), bindingAttr, binder, callConvention, types, modifiers);
  884. }
  885. //MemberInfo
  886. public override bool IsDefined (Type attributeType, bool inherit)
  887. {
  888. if (!IsCompilerContext)
  889. throw new NotSupportedException ();
  890. return generic_type.IsDefined (attributeType, inherit);
  891. }
  892. public override object [] GetCustomAttributes (bool inherit)
  893. {
  894. if (!IsCompilerContext)
  895. throw new NotSupportedException ();
  896. return generic_type.GetCustomAttributes (inherit);
  897. }
  898. public override object [] GetCustomAttributes (Type attributeType, bool inherit)
  899. {
  900. if (!IsCompilerContext)
  901. throw new NotSupportedException ();
  902. return generic_type.GetCustomAttributes (attributeType, inherit);
  903. }
  904. }
  905. }