[reflection] Coop handles icalls in System.Reflection and System.RuntimeTypeHandle...
[mono.git] / mcs / class / referencesource / System.Activities.Presentation / System.Activities.Presentation / System / Activities / Presentation / Base / Core / Metadata / MetadataStore.cs
1 using System.Diagnostics.CodeAnalysis;
2
3 namespace System.Activities.Presentation.Metadata
4 {
5     using System;
6     using System.Collections;
7     using System.Collections.Generic;
8     using System.ComponentModel;
9     using System.Diagnostics;
10     using System.Globalization;
11     using System.Reflection;
12     using System.Activities.Presentation.Internal.Metadata;
13     using System.Runtime;
14     using System.Activities.Presentation;
15
16     /// <summary>
17     /// The MetadataStore is a container of custom attribute metadata.
18     /// Custom attributes may be defined in an attribute table and added
19     /// to the metadata store.  Once added, these attributes will appear
20     /// in calls made to TypeDescriptor.
21     /// </summary>
22     public static class MetadataStore
23     {
24
25         private static object _syncLock = new object();
26         private static MetadataStoreProvider _objectProvider;
27         private static Dictionary<Type, Type> _interfaces;
28         private static Hashtable _typeAttributeCache;
29
30         [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline")]
31         static MetadataStore()
32         {
33             TypeDescriptor.Refreshed += TypeDescriptor_Refreshed;
34         }
35
36         static void TypeDescriptor_Refreshed(RefreshEventArgs e)
37         {
38             _typeAttributeCache = null;
39         }
40
41         /// <summary>
42         /// Adds the given table to the current AppDomain\92s attribute store.  
43         /// Once added, calls to TypeDescriptor will use attributes defined 
44         /// in the newly added table.  Multiple tables may be added to the 
45         /// attribute store.  In the case of conflicts, attributes in the 
46         /// most recently added table win.
47         /// </summary>
48         /// <param name="table">The table to add</param>
49         /// <exception cref="ArgumentNullException">if table is null</exception>
50         public static void AddAttributeTable(AttributeTable table)
51         {
52             AddAttributeTableCore(table, false);
53         }
54
55         internal static void AddSystemAttributeTable(AttributeTable table)
56         {
57             AddAttributeTableCore(table, true);
58         }
59
60         private static void AddAttributeTableCore(AttributeTable table, bool isSystemAttributeTable = false)
61         {
62             if (table == null) throw FxTrace.Exception.ArgumentNull("table");
63
64             lock (_syncLock)
65             {
66                 if (_objectProvider == null)
67                 {
68                     _objectProvider = new MetadataStoreProvider(table);
69                     TypeDescriptor.AddProvider(_objectProvider, typeof(object));
70                 }
71                 else
72                 {
73                     _objectProvider.AddTable(table, isSystemAttributeTable);
74                 }
75
76                 foreach (Type t in table.AttributedTypes)
77                 {
78
79                     // If there are any interface types in the given
80                     // table, we must add providers specifically for those
81                     // types because interfaces do not derive from object and
82                     // are therefore missed by our global hook.
83
84                     if (t.IsInterface)
85                     {
86                         if (_interfaces == null)
87                         {
88                             _interfaces = new Dictionary<Type, Type>();
89                         }
90                         if (!_interfaces.ContainsKey(t))
91                         {
92                             TypeDescriptor.AddProvider(_objectProvider, t);
93                             _interfaces.Add(t, t);
94                         }
95                     }
96                 }
97             }
98
99             // Now invalidate the types.
100             foreach (Type t in table.AttributedTypes)
101             {
102                 TypeDescriptor.Refresh(t);
103             }
104
105 #if DEBUG
106             table.DebugValidateProvider();
107 #endif
108         }
109
110         //
111         // This type description provider is used for all objects and
112         // interfaces.
113         //
114         private class MetadataStoreProvider : TypeDescriptionProvider
115         {
116
117             private Dictionary<Type, Type> _metadataTypeCache;
118             private Dictionary<Type, AttributeCollection> _attributeCache;
119             private Dictionary<DescriptorKey, MemberDescriptor> _descriptorCache;
120             private AttributeTable[] _tables;
121             private object _syncLock = new object();
122
123             internal MetadataStoreProvider(AttributeTable table)
124                 : base(TypeDescriptor.GetProvider(typeof(object)))
125             {
126                 _tables = new AttributeTable[] { table };
127             }
128
129             //
130             // Called by the metadata store to add a new table to our
131             // provider.  Guarded by a lock on the metadata store.
132             //
133             internal void AddTable(AttributeTable table, bool isSystemAttributeTable = false)
134             {
135
136                 // We don't expect a huge number of tables,
137                 // so creating a new array here is fine.  Also,
138                 // this has the added benefit of allowing code
139                 // that eumerates tables to be thread-safe 
140                 // without taking any locks.  Caller is responsible
141                 // for ensuring AddTable is synchronized.
142
143                 AttributeTable[] newTables;
144                 newTables = new AttributeTable[_tables.Length + 1];
145
146                 if (isSystemAttributeTable)
147                 {
148                     _tables.CopyTo(newTables, 0);
149                     newTables[newTables.Length - 1] = table;
150                 }
151                 else
152                 {
153                     _tables.CopyTo(newTables, 1);
154                     newTables[0] = table;
155                 }
156
157                 _tables = newTables;
158
159                 if (_attributeCache != null) _attributeCache.Clear();
160
161                 // Clear all metadata types that will change as
162                 // a result of adding this new table
163
164                 if (_metadataTypeCache != null)
165                 {
166                     List<Type> toRemove = null;
167                     foreach (Type t in table.AttributedTypes)
168                     {
169                         foreach (Type cached in _metadataTypeCache.Keys)
170                         {
171                             Type realCachedType = cached.UnderlyingSystemType;
172                             if (t.IsAssignableFrom(realCachedType))
173                             {
174                                 if (toRemove == null) toRemove = new List<Type>();
175                                 toRemove.Add(realCachedType);
176                             }
177
178                             // if a type definition is changed, clear all types defined by this type definition.
179                             // eg. if Cat<> is changed, clear Cat<int>, Cat<object> etc.
180                             if (t.IsGenericTypeDefinition
181                                 && realCachedType.IsGenericType
182                                 && t == realCachedType.GetGenericTypeDefinition())
183                             {
184                                 if (toRemove == null) toRemove = new List<Type>();
185                                 toRemove.Add(realCachedType);
186                             }
187                         }
188                     }
189
190                     if (toRemove != null)
191                     {
192                         foreach (Type t in toRemove)
193                         {
194                             _metadataTypeCache.Remove(t);
195                         }
196                     }
197                 }
198             }
199
200             //
201             // Private helper that creates an attribute collection given an array of attributes.
202             // This does the appropriate pairing down of attributes with matching TypeIds so
203             // the collection contains no redundant attributes.  Attributes should be ordered
204             // from most derived to least derived, so the first attribute reported wins.
205             //
206             private static AttributeCollection CreateAttributeCollection(Attribute[] attrArray)
207             {
208                 Dictionary<object, Attribute> dict = new Dictionary<object, Attribute>(attrArray.Length);
209
210                 // Attrs array is ordered by priority, first one in 
211                 // wins.
212
213                 int finalCount = attrArray.Length;
214
215                 for (int idx = 0; idx < attrArray.Length; idx++)
216                 {
217                     Attribute a = attrArray[idx];
218                     if (dict.ContainsKey(a.TypeId))
219                     {
220                         attrArray[idx] = null;
221                         finalCount--;
222                     }
223                     else
224                     {
225                         dict.Add(a.TypeId, a);
226                     }
227                 }
228
229                 Attribute[] finalArray;
230
231                 if (finalCount != attrArray.Length)
232                 {
233                     finalArray = new Attribute[finalCount];
234                     int finalIdx = 0;
235                     for (int idx = 0; idx < attrArray.Length; idx++)
236                     {
237                         if (attrArray[idx] != null)
238                         {
239                             finalArray[finalIdx++] = attrArray[idx];
240                         }
241                     }
242                 }
243                 else
244                 {
245                     finalArray = attrArray;
246                 }
247
248                 return new AttributeCollection(finalArray);
249             }
250
251             //
252             // Returns a cached attribute collection for the given
253             // object type and member.  Member can be null to get
254             // attributes for the class.
255             //
256             private AttributeCollection GetAttributes(Type objectType)
257             {
258                 Fx.Assert(objectType != null, "objectType parameter should not be null");
259                 AttributeCollection attributes;
260
261                 // Dictionary does not support thread-safe reads.  We need to lock on 
262                 // all access.
263
264                 lock (_syncLock)
265                 {
266                     if (_attributeCache == null) _attributeCache = new Dictionary<Type, AttributeCollection>();
267                     if (!_attributeCache.TryGetValue(objectType, out attributes))
268                     {
269                         attributes = CreateAttributeCollection(GetRawAttributes(objectType, null, null, false));
270                         _attributeCache[objectType] = attributes;
271                     }
272                 }
273
274                 return attributes;
275             }
276
277             //
278             // Raw API to return attributes.  This is used by GetAttributes to 
279             // populate the AttributeCollection (which is cached), and by
280             // the Attributes property on property and event descriptors (where
281             // caching is handled by the Member Descriptor). Attributes
282             // are returned from this ordered so the highest priority attributes
283             // are first (first in wins).
284             //
285
286             private static Attribute[] GetRawAttributes(Type objectType, string member, MemberDescriptor parentDescriptor, bool isEvent)
287             {
288                 Fx.Assert(objectType != null, "objectType parameter should not be null");
289                 Type reflectType = TypeDescriptor.GetReflectionType(objectType);
290
291                 // There is a bug in CLR reflection that does not respect the "inherit"
292                 // flag for event or property infos.  Our custom metadata type does respect
293                 // this flag and correctly does the right thing.  If the object type we
294                 // are passed is not a metadata type, just use the default behavior of the
295                 // parent member descriptor.  It will be right, and since we're not a metadata
296                 // type that means we have no overrides anyway.
297                 //
298                 // The reason we have to call our type with inherit, instead of just using
299                 // one code path is we need to support the interleaving of CLR and 
300                 // metadata table attributes up the inheritance hierarchy.  MetadataType 
301                 // does that for us.
302
303                 if (parentDescriptor != null && !(reflectType is MetadataType))
304                 {
305                     AttributeCollection attrs = parentDescriptor.Attributes;
306                     Attribute[] attrArray = new Attribute[attrs.Count];
307
308                     // CLR property descriptor reverses attribute order.  Fix it.
309                     for (int idx = 0; idx < attrArray.Length; idx++)
310                     {
311                         attrArray[idx] = attrs[attrArray.Length - idx - 1];
312                     }
313
314                     return attrArray;
315                 }
316
317                 MemberInfo reflectMember;
318                 Type reflectMemberType = null;
319
320                 Attribute[] attributes;
321
322                 if (member == null)
323                 {
324                     reflectMember = reflectType;
325                 }
326                 else if (isEvent)
327                 {
328                     EventInfo info = null;
329
330                     MemberInfo[] infos = reflectType.GetMember(member, MemberTypes.Event, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
331                     if (infos.Length > 0)
332                     {
333                         info = infos[0] as EventInfo;
334                     }
335
336                     reflectMember = info;
337                     if (info != null) reflectMemberType = TypeDescriptor.GetReflectionType(info.EventHandlerType);
338                 }
339                 else
340                 {
341                     PropertyInfo info = null;
342
343                     MemberInfo[] infos = reflectType.GetMember(member, MemberTypes.Property, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
344                     if (infos.Length > 0)
345                     {
346                         info = infos[0] as PropertyInfo;
347                     }
348
349                     reflectMember = info;
350                     if (info != null) reflectMemberType = TypeDescriptor.GetReflectionType(info.PropertyType);
351                 }
352
353                 if (reflectMember == null)
354                 {
355                     Debug.Fail("Member " + member + " is not a member of type " + objectType.Name);
356                     attributes = new Attribute[0];
357                 }
358                 else
359                 {
360                     // Cannot simply cast to Attribute[]
361                     Object[] attrs = reflectMember.GetCustomAttributes(typeof(Attribute), true);
362                     List<Object> attrList = new List<Object>(attrs);
363
364                     Hashtable cache = _typeAttributeCache;
365                     if (cache == null)
366                     {
367                         cache = new Hashtable();
368                         _typeAttributeCache = cache;
369                     }
370
371                     // Get the base type attributes if we have them
372                     if (reflectMemberType != null)
373                     {
374                         reflectType = reflectMemberType;
375
376                         attrs = (object[])cache[reflectType];
377                         if (attrs == null)
378                         {
379                             attrs = reflectType.GetCustomAttributes(typeof(Attribute), true);
380                             lock (cache.SyncRoot)
381                             {
382                                 cache[reflectType] = attrs;
383                             }
384                         }
385
386                         attrList.AddRange(attrs);
387                     }
388
389                     // Get interface attributes too.
390
391                     foreach (Type iface in reflectType.GetInterfaces())
392                     {
393                         attrs = (object[])cache[iface];
394                         if (attrs == null)
395                         {
396                             attrs = iface.GetCustomAttributes(typeof(Attribute), false);
397                             lock (cache.SyncRoot)
398                             {
399                                 cache[iface] = attrs;
400                             }
401                         }
402
403                         attrList.AddRange(attrs);
404                     }
405
406                     // Now go through the attributes and expand those that are 
407                     // AttributeProviderAttributes
408                     for (int idx = 0; idx < attrList.Count; idx++)
409                     {
410                         AttributeProviderAttribute a = attrList[idx] as AttributeProviderAttribute;
411                         if (a != null)
412                         {
413                             reflectType = Type.GetType(a.TypeName);
414                             if (reflectType != null)
415                             {
416                                 reflectType = TypeDescriptor.GetReflectionType(reflectType);
417                                 reflectMember = reflectType;
418
419                                 if (a.PropertyName != null && a.PropertyName.Length > 0)
420                                 {
421                                     MemberInfo[] infos = reflectType.GetMember(a.PropertyName);
422                                     if (infos != null && infos.Length > 0)
423                                     {
424                                         reflectMember = infos[0];
425                                     }
426                                 }
427
428                                 attrList.AddRange(reflectMember.GetCustomAttributes(typeof(Attribute), true));
429                             }
430                         }
431                     }
432
433                     attributes = new Attribute[attrList.Count];
434
435                     for (int idx = 0; idx < attrList.Count; idx++)
436                     {
437                         attributes[idx] = (Attribute)attrList[idx];
438                     }
439                 }
440
441                 return attributes;
442             }
443
444             //
445             // Access to our descriptor cache
446             //
447             private MemberDescriptor GetCachedDescriptor(Type objectType, MemberDescriptor descriptor)
448             {
449                 MemberDescriptor cached;
450                 DescriptorKey key = new DescriptorKey(objectType, descriptor);
451
452                 lock (_syncLock)
453                 {
454                     if (_descriptorCache == null || !_descriptorCache.TryGetValue(key, out cached))
455                     {
456                         cached = null;
457                     }
458                 }
459
460                 return cached;
461             }
462
463             //
464             // Access to our descriptor cache
465             //
466             private void CacheDescriptor(Type objectType, MemberDescriptor descriptor, MemberDescriptor cache)
467             {
468
469                 lock (_syncLock)
470                 {
471                     if (_descriptorCache == null)
472                     {
473                         _descriptorCache = new Dictionary<DescriptorKey, MemberDescriptor>();
474                     }
475                     DescriptorKey key = new DescriptorKey(objectType, descriptor);
476
477                     // Caller may ---- and this cache slot may already be allocated.
478                     // That's OK; we'll just replace it.
479                     _descriptorCache[key] = cache;
480                 }
481             }
482
483             //
484             // Takes a collection of events and merges them with our own descriptors.
485             //
486             private EventDescriptorCollection MergeEvents(Type objectType, EventDescriptorCollection incoming)
487             {
488                 EventDescriptor[] array = new EventDescriptor[incoming.Count];
489                 for (int idx = 0; idx < array.Length; idx++)
490                 {
491                     EventDescriptor theirs = incoming[idx];
492                     EventDescriptor ours = (EventDescriptor)GetCachedDescriptor(objectType, theirs);
493                     if (ours == null)
494                     {
495                         ours = new MetadataStoreEventDescriptor(objectType, theirs);
496                         CacheDescriptor(objectType, theirs, ours);
497                     }
498                     array[idx] = ours;
499                 }
500                 return new EventDescriptorCollection(array, true);
501             }
502
503             //
504             // Takes a collection of properties and merges them with our own descriptors.
505             //
506             private PropertyDescriptorCollection MergeProperties(Type objectType, PropertyDescriptorCollection incoming)
507             {
508                 PropertyDescriptor[] array = new PropertyDescriptor[incoming.Count];
509                 for (int idx = 0; idx < array.Length; idx++)
510                 {
511                     PropertyDescriptor theirs = incoming[idx];
512                     PropertyDescriptor ours = (PropertyDescriptor)GetCachedDescriptor(objectType, theirs);
513                     if (ours == null)
514                     {
515                         ours = new MetadataStorePropertyDescriptor(objectType, theirs);
516                         CacheDescriptor(objectType, theirs, ours);
517                     }
518                     array[idx] = ours;
519                 }
520                 return new PropertyDescriptorCollection(array, true);
521             }
522
523             //
524             // Looks at objectType and returns a wrapped type if needed.  The
525             // parameter may be null, in which case this API returns null.
526             //
527             internal Type MergeType(Type objectType)
528             {
529                 if (objectType == null) return null;
530                 return MergeTypeInternal(objectType, null);
531             }
532
533             //
534             // Helper method for both MergeType and GetReflectionType
535             //
536             private Type MergeTypeInternal(Type objectType, object instance)
537             {
538
539                 // If the incoming object type is already one of our wrapped types,
540                 // there is nothing more for us to do
541                 if (objectType is MetadataType) return objectType;
542
543                 Type baseReflectionType = base.GetReflectionType(objectType, instance);
544                 Type reflectionType;
545
546                 lock (_syncLock)
547                 {
548                     if (_metadataTypeCache == null || !_metadataTypeCache.TryGetValue(baseReflectionType, out reflectionType))
549                     {
550                         Type objectTypeDefinition = null;
551                         if (objectType.IsGenericType && !objectType.IsGenericTypeDefinition)
552                         {
553                             objectTypeDefinition = objectType.GetGenericTypeDefinition();
554                         }
555
556                         // See if we need to build a custom type for this objectType
557
558                         bool containsAttributes = false;
559                         foreach (AttributeTable table in _tables)
560                         {
561                             if (table.ContainsAttributes(objectType))
562                             {
563                                 containsAttributes = true;
564                                 break;
565                             }
566
567                             if (objectTypeDefinition != null && table.ContainsAttributes(objectTypeDefinition))
568                             {
569                                 containsAttributes = true;
570                                 break;
571                             }
572                         }
573
574                         // If we failed to find attributes quickly, we need
575                         // to check base classes and interfaces.
576
577                         if (!containsAttributes)
578                         {
579                             foreach (AttributeTable table in _tables)
580                             {
581                                 foreach (Type t in table.AttributedTypes)
582                                 {
583                                     if (t.IsAssignableFrom(objectType))
584                                     {
585                                         containsAttributes = true;
586                                         break;
587                                     }
588                                 }
589                             }
590                         }
591
592                         // If we have a table that contains attributes for this type, we need
593                         // to wrap the type in our own reflection type.  If not, we will
594                         // store baseReflectionType in the cache slot.
595
596                         if (containsAttributes)
597                         {
598                             reflectionType = new MetadataType(baseReflectionType, _tables, this);
599                         }
600                         else
601                         {
602                             reflectionType = baseReflectionType;
603                         }
604
605                         if (_metadataTypeCache == null)
606                         {
607                             _metadataTypeCache = new Dictionary<Type, Type>();
608                         }
609                         _metadataTypeCache[baseReflectionType] = reflectionType;
610                     }
611                 }
612
613                 return reflectionType;
614             }
615
616             //
617             // This method is the metadata store's "master hook".  It will return a custom
618             // "MetadataType" for all types that have custom metadata declared in the
619             // attribute table.  By infusing our custom metadata at this low level,
620             // everything that builds on top of reflection can be accomodated.
621             //
622             public override Type GetReflectionType(Type objectType, object instance)
623             {
624                 if (objectType == null) throw FxTrace.Exception.ArgumentNull("objectType");
625                 return MergeTypeInternal(objectType, instance);
626             }
627
628             //
629             // Returns a custom type descriptor for the given object
630             //
631             public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
632             {
633                 ICustomTypeDescriptor descriptor = base.GetTypeDescriptor(objectType, instance);
634                 descriptor = new MetadataStoreTypeDescriptor(this, objectType, descriptor);
635                 return descriptor;
636             }
637
638             //
639             // A descriptor key is a dictionary key used by
640             // our member descriptor cache.  The key consists of a type
641             // and a member descriptor.
642             // 
643             private struct DescriptorKey : IEquatable<DescriptorKey>
644             {
645                 internal readonly Type Type;
646                 internal readonly MemberDescriptor Member;
647
648                 internal DescriptorKey(Type type, MemberDescriptor member)
649                 {
650                     Type = type;
651                     Member = member;
652                 }
653
654                 public override int GetHashCode()
655                 {
656                     int hash = Type.GetHashCode();
657                     if (Member != null)
658                     {
659                         hash ^= Member.GetHashCode();
660                     }
661                     return hash;
662                 }
663
664                 public override bool Equals(object obj)
665                 {
666                     return Equals((DescriptorKey)obj);
667                 }
668
669                 public static bool operator ==(DescriptorKey a, DescriptorKey b)
670                 {
671                     return a.Equals(b);
672                 }
673
674                 public static bool operator !=(DescriptorKey a, DescriptorKey b)
675                 {
676                     return !a.Equals(b);
677                 }
678
679 #if DEBUG
680                 public override string ToString() {
681                     string v = Type.FullName;
682                     if (Member != null) v = string.Concat(v, ".", Member);
683                     return v;
684                 }
685 #endif
686
687                 // IEquatable<DescriptorKey> Members
688
689                 public bool Equals(DescriptorKey other)
690                 {
691                     if (Type != other.Type) return false;
692                     return object.ReferenceEquals(Member, other.Member);
693                 }
694
695             }
696
697             //
698             // This type descriptor is what provides additional metadata.
699             // We implement ICustomTypeDescriptor ourselves, rather than
700             // derive from the helper CustomTypeDescriptor class because
701             // we want this implementation to be built on a struct for
702             // performance reasons.
703             //
704             private struct MetadataStoreTypeDescriptor : ICustomTypeDescriptor
705             {
706
707                 private MetadataStoreProvider _provider;
708                 private Type _objectType;
709                 private ICustomTypeDescriptor _parent;
710
711                 internal MetadataStoreTypeDescriptor(MetadataStoreProvider provider, Type objectType, ICustomTypeDescriptor parent)
712                 {
713                     _provider = provider;
714                     _objectType = objectType;
715                     _parent = parent;
716                 }
717
718                 // ICustomTypeDescriptor Members
719
720                 // Calls that just forward the the parent API
721                 string ICustomTypeDescriptor.GetClassName() { return _parent.GetClassName(); }
722                 string ICustomTypeDescriptor.GetComponentName() { return _parent.GetComponentName(); }
723                 TypeConverter ICustomTypeDescriptor.GetConverter() { return _parent.GetConverter(); }
724                 EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() { return _parent.GetDefaultEvent(); }
725                 PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() { return _parent.GetDefaultProperty(); }
726                 object ICustomTypeDescriptor.GetEditor(Type editorBaseType) { return _parent.GetEditor(editorBaseType); }
727                 object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) { return _parent.GetPropertyOwner(pd); }
728
729                 //
730                 // Override to provide merged metadata
731                 //
732                 AttributeCollection ICustomTypeDescriptor.GetAttributes()
733                 {
734                     return _provider.GetAttributes(_objectType);
735                 }
736
737                 //
738                 // Override to provide merged metadata
739                 //
740                 EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes)
741                 {
742                     return _provider.MergeEvents(_objectType, _parent.GetEvents(attributes));
743                 }
744
745                 //
746                 // Override to provide merged metadata
747                 //
748                 EventDescriptorCollection ICustomTypeDescriptor.GetEvents()
749                 {
750                     return _provider.MergeEvents(_objectType, _parent.GetEvents());
751                 }
752
753                 //
754                 // Override to provide merged metadata
755                 //
756                 PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
757                 {
758                     return _provider.MergeProperties(_objectType, _parent.GetProperties(attributes));
759                 }
760
761                 //
762                 // Override to provide merged metadata
763                 //
764                 PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
765                 {
766                     return _provider.MergeProperties(_objectType, _parent.GetProperties());
767                 }
768
769             }
770
771             //
772             // A property descriptor that adds additional metadata to an existing
773             // property descriptor.
774             //
775             private class MetadataStorePropertyDescriptor : PropertyDescriptor
776             {
777
778                 private static readonly object _noValue = new object();
779                 private static readonly object _invalidValue = new object();
780
781                 private Type _objectType;
782                 private PropertyDescriptor _parent;
783                 private AttributeCollection _attributes;
784                 private Attribute[] _rawAttributes;
785                 private object _defaultValue = _invalidValue;
786                 private object _ambientValue = _invalidValue;
787
788                 // There are simpler base ctors we can invoke that do attribute merging for us.  However,
789                 // they do it all up front instead of deferring.  We want to defer until someone actually
790                 // asks for attributes.
791                 internal MetadataStorePropertyDescriptor(Type objectType, PropertyDescriptor parent)
792                     : base(parent.Name, null)
793                 {
794                     _objectType = objectType;
795                     _parent = parent;
796                 }
797
798                 //
799                 // Return our attribute collection.  We cache it
800                 // for speed.
801                 //
802                 public override AttributeCollection Attributes
803                 {
804                     get
805                     {
806                         CheckAttributesValid();
807                         if (_attributes == null)
808                         {
809                             _attributes = MetadataStoreProvider.CreateAttributeCollection(_rawAttributes);
810                         }
811
812                         return _attributes;
813                     }
814                 }
815
816                 //
817                 // DefaultValue and AmbientValue are two values that are used by
818                 // ReflectTypeDescriptionProvider in ResetValue(), CanResetValue(),
819                 // and ShouldSerializeValue() in such a way that by-passes any additional
820                 // values provided by the MetadataStore.  As such, we manually look up
821                 // these two attributes ourselves to keep the MetadataStore functionality
822                 // intact.
823                 //
824                 private object DefaultValue
825                 {
826                     get
827                     {
828                         if (_defaultValue == _invalidValue)
829                         {
830                             DefaultValueAttribute dva = (DefaultValueAttribute)Attributes[typeof(DefaultValueAttribute)];
831                             if (dva != null)
832                             {
833                                 _defaultValue = dva.Value;
834                             }
835                             else
836                             {
837                                 _defaultValue = _noValue;
838                             }
839                         }
840                         return _defaultValue;
841                     }
842                 }
843
844                 //
845                 // See comment for DefaultValue
846                 //
847                 private object AmbientValue
848                 {
849                     get
850                     {
851                         if (_ambientValue == _invalidValue)
852                         {
853                             AmbientValueAttribute ava = (AmbientValueAttribute)Attributes[typeof(AmbientValueAttribute)];
854                             if (ava != null)
855                             {
856                                 _ambientValue = ava.Value;
857                             }
858                             else
859                             {
860                                 _ambientValue = _noValue;
861                             }
862                         }
863                         return _ambientValue;
864                     }
865                 }
866
867                 //
868                 // This is a little strange and merits some explanation.
869                 // We want to cache our attribute collection, but we need
870                 // to know when to invalidate the cache. MemberDescriptor
871                 // has an internal version stamp that it compares with
872                 // TypeDescriptor's metadata version and automatically invalidates
873                 // its own cached values for attributes.  The trick is 
874                 // we need to know when MemberDescriptor invalidated its
875                 // cached values.  We do this by keying off the fact that
876                 // MemberDescriptor will call FillAttributes when its cache
877                 // needs to be repopulated.  But, in oder to get MemberDescriptor
878                 // to look at its cache we must access an API that requires
879                 // cached data.  AttributeArray does this in the lightest
880                 // possible way.  The actual set of attributes in the array
881                 // is always an empty set, but we don't care; we only need
882                 // to access the property.  The return value of the API
883                 // and the check for length are only here so the compiler
884                 // and FXCop do not complain about us calling a property
885                 // and not using the return value.  The attribute array
886                 // always contains zero elements.
887                 //
888                 private bool CheckAttributesValid()
889                 {
890                     Fx.Assert(AttributeArray.Length == 0, "Attribute array should always contain zero elements");
891                     return AttributeArray.Length == 0 && _attributes != null;
892                 }
893
894                 //
895                 // This method is called when we need to populate the raw set of
896                 // attributes for this property.  
897                 //
898                 protected override void FillAttributes(IList attributeList)
899                 {
900                     _attributes = null;
901                     _defaultValue = _invalidValue;
902                     _ambientValue = _invalidValue;
903
904                     _rawAttributes = MetadataStoreProvider.GetRawAttributes(_objectType, Name, _parent, false);
905                     base.FillAttributes(attributeList);
906                 }
907
908                 // PropertyDescriptor API.  
909                 public override bool CanResetValue(object component)
910                 {
911                     if (DefaultValue != _noValue)
912                     {
913                         object currentValue = GetValue(component);
914                         return !object.Equals(currentValue, DefaultValue);
915                     }
916                     else if (AmbientValue != _noValue)
917                     {
918                         object currentValue = GetValue(component);
919                         return !object.Equals(currentValue, AmbientValue);
920                     }
921                     else
922                     {
923                         return _parent.CanResetValue(component);
924                     }
925                 }
926
927                 public override void ResetValue(object component)
928                 {
929                     if (DefaultValue != _noValue)
930                     {
931                         SetValue(component, DefaultValue);
932                     }
933                     else if (AmbientValue != _noValue)
934                     {
935                         SetValue(component, AmbientValue);
936                     }
937                     else
938                     {
939                         _parent.ResetValue(component);
940                     }
941                 }
942
943                 public override bool ShouldSerializeValue(object component)
944                 {
945                     if (DefaultValue != _noValue)
946                     {
947                         object currentValue = GetValue(component);
948                         return !object.Equals(currentValue, DefaultValue);
949                     }
950                     else if (AmbientValue != _noValue)
951                     {
952                         object currentValue = GetValue(component);
953                         return !object.Equals(currentValue, AmbientValue);
954                     }
955                     else
956                     {
957                         return _parent.ShouldSerializeValue(component);
958                     }
959                 }
960
961                 public override void AddValueChanged(object component, EventHandler handler) { _parent.AddValueChanged(component, handler); }
962                 public override Type ComponentType { get { return _parent.ComponentType; } }
963                 [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Propagating the error might cause VS to crash")]
964                 [SuppressMessage("Reliability", "Reliability108", Justification = "Propagating the error might cause VS to crash")]
965                 public override object GetValue(object component)
966                 {
967                     object retValue = null;
968
969                     try
970                     {
971                         retValue = _parent.GetValue(component);
972                     }
973                     catch (System.Exception)
974                     {
975                         // GetValue throws an exception if Value is not available
976                     }
977
978                     return retValue;
979                 }
980                 public override bool IsReadOnly { get { return _parent.IsReadOnly || Attributes.Contains(ReadOnlyAttribute.Yes); } }
981                 public override Type PropertyType { get { return _parent.PropertyType; } }
982                 public override void SetValue(object component, object value) { _parent.SetValue(component, value); }
983                 public override void RemoveValueChanged(object component, EventHandler handler) { _parent.RemoveValueChanged(component, handler); }
984                 public override bool SupportsChangeEvents { get { return _parent.SupportsChangeEvents; } }
985             }
986
987             //
988             // An event descriptor that adds additional metadata to an existing 
989             // event descriptor.
990             //
991             private class MetadataStoreEventDescriptor : EventDescriptor
992             {
993                 private Type _objectType;
994                 private EventDescriptor _parent;
995
996                 // There are simpler base ctors we can invoke that do attribute merging for us.  However,
997                 // they do it all up front instead of deferring.  We want to defer until someone actually
998                 // asks for attributes.
999                 internal MetadataStoreEventDescriptor(Type objectType, EventDescriptor parent)
1000                     : base(parent.Name, null)
1001                 {
1002                     _objectType = objectType;
1003                     _parent = parent;
1004                 }
1005
1006                 //
1007                 // We override this so we can merge in our additional attributes.
1008                 // By overriding here, we wait until someone actually asks for
1009                 // attributes before merging.
1010                 //
1011                 protected override AttributeCollection CreateAttributeCollection()
1012                 {
1013                     Attribute[] attrs = MetadataStoreProvider.GetRawAttributes(_objectType, Name, _parent, true);
1014
1015                     // We must let MemberDescriptor build its attributes, even if we're going
1016                     // to replace them.  The reason for this is that MemberDescriptor keeps an
1017                     // internal version stamp.  This version stamp changes when someone adds
1018                     // a new TypeDescriptionProvider.  If we don't let MemberDescriptor maintain
1019                     // this version stamp it won't invalidate metadata when someone adds or removes
1020                     // a TypeDescriptionProvider, which can cause us to return stale data.
1021
1022                     AttributeArray = attrs;
1023                     AttributeCollection attributes = base.CreateAttributeCollection(); // do not delete this
1024                     attributes = MetadataStoreProvider.CreateAttributeCollection(attrs);
1025                     return attributes;
1026                 }
1027
1028                 // EventDescriptor API
1029                 public override void AddEventHandler(object component, Delegate value) { _parent.AddEventHandler(component, value); }
1030                 public override Type ComponentType { get { return _parent.ComponentType; } }
1031                 public override Type EventType { get { return _parent.EventType; } }
1032                 public override bool IsMulticast { get { return _parent.IsMulticast; } }
1033                 public override void RemoveEventHandler(object component, Delegate value) { _parent.RemoveEventHandler(component, value); }
1034             }
1035         }
1036
1037         //
1038         // This type is the core of our metadata store.  We offer this through our type 
1039         // description provider as the "reflection type" that should be used during
1040         // reflection operations.  All things within TypeDescriptor will use this
1041         // type to get metadata, which gives us a big hook into their mechanism.
1042         // By hooking at this low level we can be sure to cover all of our bases.
1043         //
1044         private class MetadataType : Type
1045         {
1046
1047             private Type _baseReflectionType;
1048             private AttributeTable[] _tables;
1049             private MetadataStoreProvider _provider;
1050             private Dictionary<MemberInfo, MemberInfo> _memberCache;
1051             private Hashtable _seenAttributes;
1052             private AttributeMergeCache _cache;
1053             private object _syncLock = new object();
1054
1055             internal MetadataType(Type baseReflectionType, AttributeTable[] tables, MetadataStoreProvider provider)
1056             {
1057                 _baseReflectionType = baseReflectionType;
1058                 _tables = tables;
1059                 _provider = provider;
1060             }
1061
1062             // Type Forward APIs
1063             //
1064             // The majority of Type's API is just forwarded to our base reflection 
1065             // type.
1066             //
1067             public override Guid GUID { get { return _baseReflectionType.GUID; } }
1068             public override Assembly Assembly { get { return _baseReflectionType.Assembly; } }
1069             public override string AssemblyQualifiedName { get { return _baseReflectionType.AssemblyQualifiedName; } }
1070             public override bool ContainsGenericParameters { get { return _baseReflectionType.ContainsGenericParameters; } }
1071             public override MethodBase DeclaringMethod { get { return _baseReflectionType.DeclaringMethod; } }
1072             public override RuntimeTypeHandle TypeHandle { get { return _baseReflectionType.TypeHandle; } }
1073             public override int GetHashCode() { return _baseReflectionType.GetHashCode(); }
1074             public override string FullName { get { return _baseReflectionType.FullName; } }
1075             public override GenericParameterAttributes GenericParameterAttributes { get { return _baseReflectionType.GenericParameterAttributes; } }
1076             public override int GenericParameterPosition { get { return _baseReflectionType.GenericParameterPosition; } }
1077             public override int GetArrayRank() { return _baseReflectionType.GetArrayRank(); }
1078             protected override TypeAttributes GetAttributeFlagsImpl() { return _baseReflectionType.Attributes; }
1079             protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) { return _baseReflectionType.GetConstructor(bindingAttr, binder, callConvention, types, modifiers); }
1080             public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) { return _baseReflectionType.GetConstructors(bindingAttr); }
1081             public override FieldInfo GetField(string name, BindingFlags bindingAttr) { return _baseReflectionType.GetField(name, bindingAttr); }
1082             public override FieldInfo[] GetFields(BindingFlags bindingAttr) { return _baseReflectionType.GetFields(bindingAttr); }
1083             protected override bool HasElementTypeImpl() { return _baseReflectionType.HasElementType; }
1084             public override object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters) { return _baseReflectionType.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters); }
1085             protected override bool IsArrayImpl() { return _baseReflectionType.IsArray; }
1086             protected override bool IsByRefImpl() { return _baseReflectionType.IsByRef; }
1087             protected override bool IsCOMObjectImpl() { return _baseReflectionType.IsCOMObject; }
1088             protected override bool IsPointerImpl() { return _baseReflectionType.IsPointer; }
1089             protected override bool IsPrimitiveImpl() { return _baseReflectionType.IsPrimitive; }
1090             public override Module Module { get { return _baseReflectionType.Module; } }
1091             public override string Namespace { get { return _baseReflectionType.Namespace; } }
1092             public override Type UnderlyingSystemType { get { return _baseReflectionType.UnderlyingSystemType; } }
1093             public override string Name { get { return _baseReflectionType.Name; } }
1094             public override InterfaceMapping GetInterfaceMap(Type interfaceType) { return _baseReflectionType.GetInterfaceMap(interfaceType); }
1095             public override bool IsAssignableFrom(Type c) { return _baseReflectionType.IsAssignableFrom(c); }
1096             protected override bool IsContextfulImpl() { return _baseReflectionType.IsContextful; }
1097             public override bool IsGenericParameter { get { return _baseReflectionType.IsGenericParameter; } }
1098             public override bool IsGenericType { get { return _baseReflectionType.IsGenericType; } }
1099             public override bool IsGenericTypeDefinition { get { return _baseReflectionType.IsGenericTypeDefinition; } }
1100             public override bool IsInstanceOfType(object o) { return _baseReflectionType.IsInstanceOfType(o); }
1101             protected override bool IsMarshalByRefImpl() { return _baseReflectionType.IsMarshalByRef; }
1102             public override bool IsSubclassOf(Type c) { return _baseReflectionType.IsSubclassOf(c); }
1103             protected override bool IsValueTypeImpl() { return _baseReflectionType.IsValueType; }
1104             public override Type MakeArrayType() { return _baseReflectionType.MakeArrayType(); }
1105             public override Type MakeArrayType(int rank) { return _baseReflectionType.MakeArrayType(rank); }
1106             public override Type MakeByRefType() { return _baseReflectionType.MakeByRefType(); }
1107             public override Type MakeGenericType(params Type[] typeArguments) { return _baseReflectionType.MakeGenericType(typeArguments); }
1108             public override Type MakePointerType() { return _baseReflectionType.MakePointerType(); }
1109             public override MemberTypes MemberType { get { return _baseReflectionType.MemberType; } }
1110             public override int MetadataToken { get { return _baseReflectionType.MetadataToken; } }
1111             public override Type ReflectedType { get { return _baseReflectionType.ReflectedType; } }
1112             public override System.Runtime.InteropServices.StructLayoutAttribute StructLayoutAttribute { get { return _baseReflectionType.StructLayoutAttribute; } }
1113             public override string ToString() { return _baseReflectionType.ToString(); }
1114
1115
1116             // Type APIs
1117
1118             //
1119             // Wrap returned types
1120             //
1121             public override Type GetElementType()
1122             {
1123                 return _provider.MergeType(_baseReflectionType.GetElementType());
1124             }
1125
1126             //
1127             // Wrap returned types
1128             //
1129             public override Type DeclaringType
1130             {
1131                 get { return _provider.MergeType(_baseReflectionType.DeclaringType); }
1132             }
1133
1134             //
1135             // Wrap returned types
1136             //
1137             public override Type[] FindInterfaces(TypeFilter filter, object filterCriteria)
1138             {
1139                 Type[] ifaces = _baseReflectionType.FindInterfaces(filter, filterCriteria);
1140                 for (int idx = 0; idx < ifaces.Length; idx++)
1141                 {
1142                     ifaces[idx] = _provider.MergeType(ifaces[idx]);
1143                 }
1144                 return ifaces;
1145             }
1146
1147             //
1148             // Wrap returned types
1149             //
1150             public override Type BaseType
1151             {
1152                 get { return _provider.MergeType(_baseReflectionType.BaseType); }
1153             }
1154
1155             //
1156             // Wrap returned types
1157             //
1158             public override Type GetInterface(string name, bool ignoreCase)
1159             {
1160                 return _provider.MergeType(_baseReflectionType.GetInterface(name, ignoreCase));
1161             }
1162
1163             //
1164             // Wrap returned types
1165             //
1166             public override Type[] GetInterfaces()
1167             {
1168                 Type[] ifaces = _baseReflectionType.GetInterfaces();
1169                 for (int idx = 0; idx < ifaces.Length; idx++)
1170                 {
1171                     ifaces[idx] = _provider.MergeType(ifaces[idx]);
1172                 }
1173                 return ifaces;
1174             }
1175
1176             //
1177             // Wrap returned types
1178             //
1179             public override Type GetNestedType(string name, BindingFlags bindingAttr)
1180             {
1181                 return _provider.MergeType(_baseReflectionType.GetNestedType(name, bindingAttr));
1182             }
1183
1184             //
1185             // Wrap returned types
1186             //
1187             public override Type[] GetNestedTypes(BindingFlags bindingAttr)
1188             {
1189                 Type[] ifaces = _baseReflectionType.GetNestedTypes(bindingAttr);
1190                 for (int idx = 0; idx < ifaces.Length; idx++)
1191                 {
1192                     ifaces[idx] = _provider.MergeType(ifaces[idx]);
1193                 }
1194                 return ifaces;
1195             }
1196
1197             //
1198             // Wrap returned types
1199             //
1200             public override Type[] GetGenericArguments()
1201             {
1202                 Type[] ifaces = _baseReflectionType.GetGenericArguments();
1203                 for (int idx = 0; idx < ifaces.Length; idx++)
1204                 {
1205                     ifaces[idx] = _provider.MergeType(ifaces[idx]);
1206                 }
1207                 return ifaces;
1208             }
1209
1210             //
1211             // Wrap returned types
1212             //
1213             public override Type[] GetGenericParameterConstraints()
1214             {
1215                 Type[] ifaces = _baseReflectionType.GetGenericParameterConstraints();
1216                 for (int idx = 0; idx < ifaces.Length; idx++)
1217                 {
1218                     ifaces[idx] = _provider.MergeType(ifaces[idx]);
1219                 }
1220                 return ifaces;
1221             }
1222
1223             //
1224             // Wrap returned types
1225             //
1226             public override Type GetGenericTypeDefinition()
1227             {
1228                 return _provider.MergeType(_baseReflectionType.GetGenericTypeDefinition());
1229             }
1230
1231             //
1232             // Custom attribute access
1233             //
1234             public override object[] GetCustomAttributes(bool inherit)
1235             {
1236                 return MergeAttributes(null, _baseReflectionType, inherit, ref _cache);
1237             }
1238
1239             //
1240             // Custom attribute access
1241             //
1242             public override object[] GetCustomAttributes(Type attributeType, bool inherit)
1243             {
1244                 return MergeAttributes(attributeType, _baseReflectionType, inherit, ref _cache);
1245             }
1246
1247             //
1248             // Custom attribute access
1249             //
1250             public override bool IsDefined(Type attributeType, bool inherit)
1251             {
1252                 bool isDefined = _baseReflectionType.IsDefined(attributeType, inherit);
1253                 if (!isDefined) isDefined = IsDefinedInTable(attributeType, null, inherit);
1254                 return isDefined;
1255             }
1256
1257             //
1258             // Member access
1259             //
1260             public override MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria)
1261             {
1262                 MemberInfo[] infos = _baseReflectionType.FindMembers(memberType, bindingAttr, filter, filterCriteria);
1263                 return MergeMembers(infos);
1264             }
1265
1266             //
1267             // Member access
1268             //
1269             public override MemberInfo[] GetDefaultMembers()
1270             {
1271                 MemberInfo[] infos = _baseReflectionType.GetDefaultMembers();
1272                 return MergeMembers(infos);
1273             }
1274
1275             //
1276             // Member access
1277             //
1278             public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr)
1279             {
1280                 MemberInfo[] infos = _baseReflectionType.GetMember(name, type, bindingAttr);
1281                 return MergeMembers(infos);
1282             }
1283
1284             //
1285             // Member access
1286             //
1287             public override MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
1288             {
1289                 MemberInfo[] infos = _baseReflectionType.GetMember(name, bindingAttr);
1290                 return MergeMembers(infos);
1291             }
1292
1293             //
1294             // Member access
1295             //
1296             public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
1297             {
1298                 MemberInfo[] infos = _baseReflectionType.GetMembers(bindingAttr);
1299                 return MergeMembers(infos);
1300             }
1301
1302             //
1303             // Event access
1304             //
1305             public override EventInfo GetEvent(string name, BindingFlags bindingAttr)
1306             {
1307                 EventInfo info = _baseReflectionType.GetEvent(name, bindingAttr);
1308                 return MergeEvent(info);
1309             }
1310
1311             //
1312             // Event access
1313             //
1314             public override EventInfo[] GetEvents()
1315             {
1316                 EventInfo[] infos = _baseReflectionType.GetEvents();
1317                 return MergeEvents(infos);
1318             }
1319
1320             //
1321             // Event access
1322             //
1323             public override EventInfo[] GetEvents(BindingFlags bindingAttr)
1324             {
1325                 EventInfo[] infos = _baseReflectionType.GetEvents(bindingAttr);
1326                 return MergeEvents(infos);
1327             }
1328
1329             //
1330             // Method access
1331             //
1332             protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
1333             {
1334                 MethodInfo info;
1335
1336                 if (types == null)
1337                 {
1338                     info = _baseReflectionType.GetMethod(name, bindingAttr);
1339                 }
1340                 else
1341                 {
1342                     info = _baseReflectionType.GetMethod(name, bindingAttr, binder, callConvention, types, modifiers);
1343                 }
1344
1345                 if (info != null)
1346                 {
1347                     info = MergeMethod(info);
1348                 }
1349
1350                 return info;
1351             }
1352
1353             //
1354             // Method access
1355             //
1356             public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
1357             {
1358                 MethodInfo[] infos = _baseReflectionType.GetMethods(bindingAttr);
1359                 return MergeMethods(infos);
1360             }
1361
1362             //
1363             // Property access
1364             //
1365             public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
1366             {
1367                 PropertyInfo[] infos = _baseReflectionType.GetProperties(bindingAttr);
1368                 return MergeProperties(infos);
1369             }
1370
1371             //
1372             // Property access
1373             //
1374             protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
1375             {
1376                 PropertyInfo info;
1377                 if (types != null)
1378                 {
1379                     info = _baseReflectionType.GetProperty(name, bindingAttr, binder, returnType, types, modifiers);
1380                 }
1381                 else
1382                 {
1383                     info = _baseReflectionType.GetProperty(name, bindingAttr);
1384                 }
1385
1386                 return MergeProperty(info);
1387             }
1388
1389
1390             // Merging APIs
1391
1392             //
1393             // Returns true if the given attribute type is defined in any attribute table.
1394             // This can take null for the member, in which case it searches type attributes.
1395             // Table is assigned at construction and read-only, so no locking required.
1396             //
1397             private bool IsDefinedInTable(Type attributeType, MemberInfo member, bool inherit)
1398             {
1399                 bool isDefined = false;
1400                 for (Type t = UnderlyingSystemType; t != null && !isDefined; t = t.BaseType)
1401                 {
1402                     foreach (AttributeTable table in _tables)
1403                     {
1404                         IEnumerable attrEnum;
1405                         if (member == null)
1406                         {
1407                             attrEnum = table.GetCustomAttributes(t);
1408                         }
1409                         else
1410                         {
1411                             attrEnum = table.GetCustomAttributes(t, member);
1412                         }
1413
1414                         foreach (object a in attrEnum)
1415                         {
1416                             if (attributeType.IsInstanceOfType(a))
1417                             {
1418                                 isDefined = true;
1419                                 break;
1420                             }
1421                         }
1422
1423                         if (isDefined) break;
1424                     }
1425
1426                     if (!inherit) break;
1427                 }
1428                 return isDefined;
1429             }
1430
1431             //
1432             // Merging of an array of attributes.  This is called from 
1433             // GetCustomAttributes for both types and members.  Attributes
1434             // must be merged so the most derived and highest priority
1435             // attributes are first in the list.  Metadata store attributes
1436             // always take higher precidence than CLR attributes.
1437             //
1438             [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
1439             private object[] MergeAttributes(Type filterType, MemberInfo member, bool inherit, ref AttributeMergeCache cache)
1440             {
1441
1442                 Type currentType = UnderlyingSystemType;
1443                 MemberInfo currentMember = member;
1444
1445                 if (cache == null) cache = new AttributeMergeCache();
1446                 if (cache.FilterType != filterType ||
1447                     cache.Member != member ||
1448                     cache.Inherit != inherit)
1449                 {
1450
1451                     cache.FilterType = filterType;
1452                     cache.Member = member;
1453                     cache.Inherit = inherit;
1454                     if (cache.Cache != null) cache.Cache.Clear();
1455                 }
1456                 else if (cache.Cache != null)
1457                 {
1458                     // Cache is valid; return it
1459                     return (object[])cache.Cache.ToArray(filterType ?? typeof(object));
1460                 }
1461
1462
1463                 // Cache is invalid or null.  Walk attributes.
1464
1465                 if (cache.Cache == null) cache.Cache = new ArrayList();
1466                 ArrayList compiledAttributes = cache.Cache;
1467
1468                 lock (_syncLock)
1469                 {
1470
1471                     if (_seenAttributes == null)
1472                     {
1473                         _seenAttributes = new Hashtable();
1474                     }
1475                     else
1476                     {
1477                         _seenAttributes.Clear();
1478                     }
1479
1480                     bool firstIteration = true;
1481                     bool isType = member is Type;
1482                     bool includeClrAttributes = (isType || currentMember.DeclaringType == currentType);
1483
1484                     while (currentType != null && currentMember != null)
1485                     {
1486
1487                         foreach (object attr in MergeAttributesIterator(currentType, currentMember, includeClrAttributes))
1488                         {
1489
1490                             if (filterType != null && !filterType.IsAssignableFrom(attr.GetType()))
1491                                 continue;
1492
1493                             AttributeData attrData = AttributeDataCache.GetAttributeData(attr.GetType());
1494                             bool haveSeenBefore = _seenAttributes.ContainsKey(attrData.AttributeType);
1495
1496                             // Can we have more than one?
1497                             if (haveSeenBefore &&
1498                                 !attrData.AllowsMultiple)
1499                                 continue;
1500
1501                             // Is this attribute inheritable?
1502                             if (!firstIteration &&
1503                                 !attrData.IsInheritable)
1504                                 continue;
1505
1506                             // We do a scan here for TypeDescriptionProviderAttribute.  Because we
1507                             // are creating a custom type here and gathering metadata from 
1508                             // our base type, it is very important that we don't offer this attribute.
1509                             // Doing so could cause TypeDescriptor to add a provider for this type
1510                             // and create a cycle
1511                             if (attrData.AttributeType.Equals(typeof(TypeDescriptionProviderAttribute)))
1512                                 continue;
1513
1514                             compiledAttributes.Add(attr);
1515                             _seenAttributes[attrData.AttributeType] = attr;
1516                         }
1517
1518                         // Continue?
1519                         if (!inherit)
1520                             break;
1521
1522                         // Advance up the type hierarchy
1523                         // 
1524                         // Note: CLR attributes key off of currentMember.  MetadataStore attributes key
1525                         // off of currentType and memberName.  Because we advance currentType independent of 
1526                         // currentMember, it is possible for the currentMember to belong to some
1527                         // ancestor of currentType.  As such, we wait with advancing currentMember until
1528                         // currentType catches up.  While we wait, we do not include the CLR attributes in
1529                         // the mix because they would be added multiple times as a result.
1530
1531                         // Is currentType caught up to currentMember.DeclaringType?
1532                         if (isType || currentMember.DeclaringType == currentType)
1533                         {
1534                             currentMember = AttributeDataCache.GetBaseMemberInfo(currentMember);
1535                         }
1536
1537                         currentType = currentType.BaseType;
1538
1539                         if (isType || currentMember == null || currentMember.DeclaringType == currentType)
1540                         {
1541                             includeClrAttributes = true;
1542                         }
1543                         else
1544                         {
1545                             includeClrAttributes = false;
1546                         }
1547
1548                         firstIteration = false;
1549                     }
1550                 }
1551
1552                 return (object[])compiledAttributes.ToArray(filterType ?? typeof(object));
1553             }
1554
1555             // 
1556             // Enumerates through values contained in the attribute cache in 
1557             // an order that returns the MetadataStore attributes before returning
1558             // the CLR attributes (if requested)
1559             //
1560             private IEnumerable<object> MergeAttributesIterator(Type type, MemberInfo member, bool includeClrAttributes)
1561             {
1562                 // MetadataStore uses member name string, instead of MemberInfo to store custom attributes,
1563                 // so figure out what the member name is.  For types, it will be null.
1564                 string memberName = GetMemberName(member);
1565
1566                 // Go through the MetadataStore attributes first, as they take precedence over CLR attributes
1567                 foreach (object attr in AttributeDataCache.GetMetadataStoreAttributes(type, memberName, _tables))
1568                     yield return attr;
1569
1570                 if (type.IsGenericType && !type.IsGenericTypeDefinition && !string.IsNullOrEmpty(memberName))
1571                 {
1572                     foreach (object attr in AttributeDataCache.GetMetadataStoreAttributes(type.GetGenericTypeDefinition(), memberName, _tables))
1573                         yield return attr;
1574                 }
1575
1576                 if (includeClrAttributes)
1577                 {
1578                     // Go through the CLR attributes second
1579                     foreach (object attr in AttributeDataCache.GetClrAttributes(member))
1580                         yield return attr;
1581                 }
1582             }
1583
1584             //
1585             // Gets the member name from the specified MemberInfo that we use as key
1586             // to get custom attributes from the MetadataStore.  Types will return null.
1587             //
1588             private static string GetMemberName(MemberInfo member)
1589             {
1590                 if (member is Type)
1591                     return null;
1592
1593                 // The only methods supported in metadata store are those related to
1594                 // Get methods for DependencyProperties and they start with a "Get..."
1595                 if (member.MemberType == MemberTypes.Method)
1596                 {
1597                     Fx.Assert(
1598                         member.Name.StartsWith("Get", StringComparison.Ordinal) &&
1599                         member.Name.Length > 3,
1600                         "MetadataStore expects to only see Get[Foo] or Set[Foo] MethodInfos");
1601
1602                     return member.Name.Substring(3);
1603                 }
1604
1605                 return member.Name;
1606             }
1607
1608             //
1609             // Merging of an event.
1610             //
1611             private EventInfo MergeEvent(EventInfo info)
1612             {
1613                 if (info == null) return null;
1614
1615                 MemberInfo cache;
1616
1617                 lock (_syncLock)
1618                 {
1619                     if (_memberCache == null || !_memberCache.TryGetValue(info, out cache))
1620                     {
1621
1622                         if (_memberCache == null)
1623                         {
1624                             _memberCache = new Dictionary<MemberInfo, MemberInfo>();
1625                         }
1626
1627                         EventInfo newInfo = new MetadataEventInfo(info, this);
1628                         _memberCache[info] = newInfo;
1629                         info = newInfo;
1630                     }
1631                     else
1632                     {
1633                         info = (EventInfo)cache;
1634                     }
1635                 }
1636
1637                 return info;
1638             }
1639
1640             //
1641             // Merging of an array of events.
1642             //
1643             private EventInfo[] MergeEvents(EventInfo[] infos)
1644             {
1645                 for (int idx = 0; idx < infos.Length; idx++)
1646                 {
1647                     infos[idx] = MergeEvent(infos[idx]);
1648                 }
1649                 return infos;
1650             }
1651
1652             //
1653             // Merging a generic member calls down to specific
1654             // merge functions based on the type of the member.
1655             // 
1656             private MemberInfo MergeMember(MemberInfo info)
1657             {
1658                 MethodInfo m;
1659                 PropertyInfo p;
1660                 EventInfo e;
1661
1662                 if ((m = info as MethodInfo) != null)
1663                 {
1664                     return MergeMethod(m);
1665                 }
1666                 else if ((p = info as PropertyInfo) != null)
1667                 {
1668                     return MergeProperty(p);
1669                 }
1670                 else if ((e = info as EventInfo) != null)
1671                 {
1672                     return MergeEvent(e);
1673                 }
1674
1675                 return info;
1676             }
1677
1678             //
1679             // Merging a generic member calls down to specific
1680             // merge functions based on the type of the member.
1681             // 
1682             private MemberInfo[] MergeMembers(MemberInfo[] infos)
1683             {
1684                 for (int idx = 0; idx < infos.Length; idx++)
1685                 {
1686                     infos[idx] = MergeMember(infos[idx]);
1687                 }
1688                 return infos;
1689             }
1690
1691             //
1692             // Merging of a method.  We only deal with 
1693             // static methods in the format Get<member name>
1694             // so we can support attached properties.  Otherwise,
1695             // we let the method be.
1696             //
1697             private MethodInfo MergeMethod(MethodInfo info)
1698             {
1699                 if (info == null) return null;
1700
1701                 if (info.IsStatic && info.Name.StartsWith("Get", StringComparison.Ordinal))
1702                 {
1703                     MemberInfo cache;
1704
1705                     lock (_syncLock)
1706                     {
1707                         if (_memberCache == null || !_memberCache.TryGetValue(info, out cache))
1708                         {
1709
1710                             if (_memberCache == null)
1711                             {
1712                                 _memberCache = new Dictionary<MemberInfo, MemberInfo>();
1713                             }
1714
1715                             MethodInfo newInfo = new MetadataMethodInfo(info, this);
1716                             _memberCache[info] = newInfo;
1717                             info = newInfo;
1718                         }
1719                         else
1720                         {
1721                             info = (MethodInfo)cache;
1722                         }
1723                     }
1724                 }
1725                 return info;
1726             }
1727
1728             //
1729             // Merging of an array of methods.
1730             //
1731             private MethodInfo[] MergeMethods(MethodInfo[] infos)
1732             {
1733                 for (int idx = 0; idx < infos.Length; idx++)
1734                 {
1735                     infos[idx] = MergeMethod(infos[idx]);
1736                 }
1737                 return infos;
1738             }
1739
1740             //
1741             // Merging of a property.
1742             //
1743             private PropertyInfo MergeProperty(PropertyInfo info)
1744             {
1745                 if (info == null) return null;
1746
1747                 MemberInfo cache;
1748
1749                 lock (_syncLock)
1750                 {
1751                     if (_memberCache == null || !_memberCache.TryGetValue(info, out cache))
1752                     {
1753
1754                         if (_memberCache == null)
1755                         {
1756                             _memberCache = new Dictionary<MemberInfo, MemberInfo>();
1757                         }
1758
1759                         PropertyInfo newInfo = new MetadataPropertyInfo(info, this);
1760                         _memberCache[info] = newInfo;
1761                         info = newInfo;
1762                     }
1763                     else
1764                     {
1765                         info = (PropertyInfo)cache;
1766                     }
1767                 }
1768
1769                 return info;
1770             }
1771
1772             //
1773             // Merging of an array of properties.
1774             //
1775             private PropertyInfo[] MergeProperties(PropertyInfo[] infos)
1776             {
1777                 for (int idx = 0; idx < infos.Length; idx++)
1778                 {
1779                     infos[idx] = MergeProperty(infos[idx]);
1780                 }
1781                 return infos;
1782             }
1783
1784
1785             //
1786             // A simple class that holds merged attribute data.
1787             //
1788             private class AttributeMergeCache
1789             {
1790                 internal Type FilterType;
1791                 internal bool Inherit;
1792                 internal ArrayList Cache;
1793                 internal MemberInfo Member;
1794             }
1795
1796             //
1797             // A property info that contains our custom metadata.
1798             //
1799             private class MetadataPropertyInfo : PropertyInfo
1800             {
1801
1802                 private PropertyInfo _info;
1803                 private MetadataType _type;
1804                 private AttributeMergeCache _cache;
1805
1806                 internal MetadataPropertyInfo(PropertyInfo info, MetadataType type)
1807                 {
1808                     _info = info;
1809                     _type = type;
1810                 }
1811
1812                 //
1813                 // PropertyInfo overrides
1814                 //
1815                 public override PropertyAttributes Attributes { get { return _info.Attributes; } }
1816                 public override bool CanRead { get { return _info.CanRead; } }
1817                 public override bool CanWrite { get { return _info.CanWrite; } }
1818                 public override MethodInfo[] GetAccessors(bool nonPublic) { return _info.GetAccessors(nonPublic); }
1819                 public override MethodInfo GetGetMethod(bool nonPublic) { return _info.GetGetMethod(nonPublic); }
1820                 public override ParameterInfo[] GetIndexParameters() { return _info.GetIndexParameters(); }
1821                 public override MethodInfo GetSetMethod(bool nonPublic) { return _info.GetSetMethod(nonPublic); }
1822                 public override object GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture) { return _info.GetValue(obj, invokeAttr, binder, index, culture); }
1823                 public override Type PropertyType { get { return _info.PropertyType; } }
1824                 public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture) { _info.SetValue(obj, value, invokeAttr, binder, index, culture); }
1825                 public override Type DeclaringType { get { return _info.DeclaringType; } }
1826                 public override string Name { get { return _info.Name; } }
1827                 public override Type ReflectedType { get { return _info.ReflectedType; } }
1828                 public override bool Equals(object obj) { return object.ReferenceEquals(this, obj); }
1829                 public override int GetHashCode() { return _info.GetHashCode(); }
1830                 public override object GetConstantValue() { return _info.GetConstantValue(); }
1831                 public override Type[] GetOptionalCustomModifiers() { return _info.GetOptionalCustomModifiers(); }
1832                 public override object GetRawConstantValue() { return _info.GetRawConstantValue(); }
1833                 public override Type[] GetRequiredCustomModifiers() { return _info.GetRequiredCustomModifiers(); }
1834                 public override object GetValue(object obj, object[] index) { return _info.GetValue(obj, index); }
1835                 public override MemberTypes MemberType { get { return _info.MemberType; } }
1836                 public override int MetadataToken { get { return _info.MetadataToken; } }
1837                 public override Module Module { get { return _info.Module; } }
1838                 public override void SetValue(object obj, object value, object[] index) { _info.SetValue(obj, value, index); }
1839                 public override string ToString() { return _info.ToString(); }
1840
1841                 //
1842                 // Merges our custom attributes in with those of the member info.
1843                 //
1844                 public override object[] GetCustomAttributes(Type attributeType, bool inherit)
1845                 {
1846                     return _type.MergeAttributes(attributeType, _info, inherit, ref _cache);
1847                 }
1848
1849                 //
1850                 // Merges our custom attributes in with those of the member info.
1851                 //
1852                 public override object[] GetCustomAttributes(bool inherit)
1853                 {
1854                     return _type.MergeAttributes(null, _info, inherit, ref _cache);
1855                 }
1856
1857                 //
1858                 // Determines if an attribute exists in the member info
1859                 // or in our own code.
1860                 //
1861                 public override bool IsDefined(Type attributeType, bool inherit)
1862                 {
1863                     bool isDefined = _info.IsDefined(attributeType, inherit);
1864                     if (!isDefined) isDefined = _type.IsDefinedInTable(attributeType, _info, inherit);
1865                     return isDefined;
1866                 }
1867             }
1868
1869             //
1870             // An EventInfo that provides our custom attributes.
1871             //
1872             private class MetadataEventInfo : EventInfo
1873             {
1874
1875                 private EventInfo _info;
1876                 private MetadataType _type;
1877                 private AttributeMergeCache _cache;
1878
1879                 internal MetadataEventInfo(EventInfo info, MetadataType type)
1880                 {
1881                     _info = info;
1882                     _type = type;
1883                 }
1884
1885                 //
1886                 // EventInfo overrides
1887                 //
1888                 public override EventAttributes Attributes { get { return _info.Attributes; } }
1889                 public override string Name { get { return _info.Name; } }
1890                 public override Type ReflectedType { get { return _info.ReflectedType; } }
1891                 public override bool Equals(object obj) { return object.ReferenceEquals(this, obj); }
1892                 public override int GetHashCode() { return _info.GetHashCode(); }
1893                 public override MethodInfo[] GetOtherMethods(bool nonPublic) { return _info.GetOtherMethods(nonPublic); }
1894                 public override MemberTypes MemberType { get { return _info.MemberType; } }
1895                 public override int MetadataToken { get { return _info.MetadataToken; } }
1896                 public override Module Module { get { return _info.Module; } }
1897                 public override string ToString() { return _info.ToString(); }
1898                 public override MethodInfo GetAddMethod(bool nonPublic) { return _info.GetAddMethod(nonPublic); }
1899                 public override MethodInfo GetRaiseMethod(bool nonPublic) { return _info.GetRaiseMethod(nonPublic); }
1900                 public override MethodInfo GetRemoveMethod(bool nonPublic) { return _info.GetRemoveMethod(nonPublic); }
1901                 public override Type DeclaringType { get { return _info.DeclaringType; } }
1902
1903                 //
1904                 // Merges our custom attributes in with those of the member info.
1905                 //
1906                 public override object[] GetCustomAttributes(Type attributeType, bool inherit)
1907                 {
1908                     return _type.MergeAttributes(attributeType, _info, inherit, ref _cache);
1909                 }
1910
1911                 //
1912                 // Merges our custom attributes in with those of the member info.
1913                 //
1914                 public override object[] GetCustomAttributes(bool inherit)
1915                 {
1916                     return _type.MergeAttributes(null, _info, inherit, ref _cache);
1917                 }
1918
1919                 //
1920                 // Determines if an attribute exists in the member info
1921                 // or in our own code.
1922                 //
1923                 public override bool IsDefined(Type attributeType, bool inherit)
1924                 {
1925                     bool isDefined = _info.IsDefined(attributeType, inherit);
1926                     if (!isDefined) isDefined = _type.IsDefinedInTable(attributeType, _info, inherit);
1927                     return isDefined;
1928                 }
1929             }
1930
1931             //
1932             // A MethodInfo that provides our custom attributes.
1933             //
1934             private class MetadataMethodInfo : MethodInfo
1935             {
1936
1937                 private MethodInfo _info;
1938                 private MetadataType _type;
1939                 private AttributeMergeCache _cache;
1940
1941                 internal MetadataMethodInfo(MethodInfo info, MetadataType type)
1942                 {
1943                     _info = info;
1944                     _type = type;
1945                 }
1946
1947                 //
1948                 // MethodInfo overrides
1949                 //
1950                 public override ICustomAttributeProvider ReturnTypeCustomAttributes { get { return _info.ReturnTypeCustomAttributes; } }
1951                 public override MethodAttributes Attributes { get { return _info.Attributes; } }
1952                 public override MethodImplAttributes GetMethodImplementationFlags() { return _info.GetMethodImplementationFlags(); }
1953                 public override ParameterInfo[] GetParameters() { return _info.GetParameters(); }
1954                 public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture) { return _info.Invoke(obj, invokeAttr, binder, parameters, culture); }
1955                 public override RuntimeMethodHandle MethodHandle { get { return _info.MethodHandle; } }
1956                 public override Type DeclaringType { get { return _info.DeclaringType; } }
1957                 public override string Name { get { return _info.Name; } }
1958                 public override Type ReflectedType { get { return _info.ReflectedType; } }
1959                 public override bool Equals(object obj) { return object.ReferenceEquals(this, obj); }
1960                 public override int GetHashCode() { return _info.GetHashCode(); }
1961                 public override CallingConventions CallingConvention { get { return _info.CallingConvention; } }
1962                 public override bool ContainsGenericParameters { get { return _info.ContainsGenericParameters; } }
1963                 public override MethodInfo GetBaseDefinition() { return _info.GetBaseDefinition(); }
1964                 public override Type[] GetGenericArguments() { return _info.GetGenericArguments(); }
1965                 public override MethodInfo GetGenericMethodDefinition() { return _info.GetGenericMethodDefinition(); }
1966                 public override MethodBody GetMethodBody() { return _info.GetMethodBody(); }
1967                 public override bool IsGenericMethod { get { return _info.IsGenericMethod; } }
1968                 public override bool IsGenericMethodDefinition { get { return _info.IsGenericMethodDefinition; } }
1969                 public override MethodInfo MakeGenericMethod(params Type[] typeArguments) { return _info.MakeGenericMethod(typeArguments); }
1970                 public override MemberTypes MemberType { get { return _info.MemberType; } }
1971                 public override int MetadataToken { get { return _info.MetadataToken; } }
1972                 public override Module Module { get { return _info.Module; } }
1973                 public override ParameterInfo ReturnParameter { get { return _info.ReturnParameter; } }
1974                 public override Type ReturnType { get { return _info.ReturnType; } }
1975                 public override string ToString() { return _info.ToString(); }
1976
1977                 //
1978                 // Merges our custom attributes in with those of the member info.
1979                 //
1980                 public override object[] GetCustomAttributes(Type attributeType, bool inherit)
1981                 {
1982                     return _type.MergeAttributes(attributeType, _info, inherit, ref _cache);
1983                 }
1984
1985                 //
1986                 // Merges our custom attributes in with those of the member info.
1987                 //
1988                 public override object[] GetCustomAttributes(bool inherit)
1989                 {
1990                     return _type.MergeAttributes(null, _info, inherit, ref _cache);
1991                 }
1992
1993                 //
1994                 // Determines if an attribute exists in the member info
1995                 // or in our own code.
1996                 //
1997                 public override bool IsDefined(Type attributeType, bool inherit)
1998                 {
1999                     bool isDefined = _info.IsDefined(attributeType, inherit);
2000                     if (!isDefined) isDefined = _type.IsDefinedInTable(attributeType, _info, inherit);
2001                     return isDefined;
2002                 }
2003             }
2004         }
2005     }
2006 }