[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 / Internal / Metadata / AttributeData.cs
1 //----------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //----------------------------------------------------------------
4 namespace System.Activities.Presentation.Internal.Metadata 
5 {
6     using System;
7     using System.Collections.Generic;
8     using System.Text;
9     using System.Diagnostics;
10     using System.Runtime;
11
12     // This class groups Attribute with its AttributeUsageAttributes that we care about.
13     // Basically, each Attribute has characteristics that are useful to know about,
14     // such as whether it can be inherited and whether there can be more than
15     // one instance of that attribute extending whatever it is the attribute
16     // is extending (class, method, property, or event).  Those characteristics
17     // are stored as attributes themselves and, as such, are costly to retrieve.
18     // This class retrieves that information exactly once, on demand, and caches it for
19     // further use.
20     internal class AttributeData 
21     {
22
23         private Type _attributeType;
24         private bool? _isInheritable;
25         private bool? _allowsMultiple;
26
27         // <summary>
28         // Creates an AttributeData wrapper around Attribute type to expose its
29         // Inherit and AllowMultiple characteristics
30         // </summary>
31         // <param name="attributeType">Attribute type to wrap around</param>
32         internal AttributeData(Type attributeType) 
33         {
34             Fx.Assert(attributeType != null, "attributeType parameter should not be null");
35             _attributeType = attributeType;
36         }
37
38         // <summary>
39         // Gets the contained attribute type
40         // </summary>
41         internal Type AttributeType 
42         {
43             get {
44                 return _attributeType;
45             }
46         }
47
48         // <summary>
49         // Gets the AllowMultiple characteristic of the
50         // contained attribute and caches the result for subsequent
51         // calls to this property.
52         // </summary>
53         internal bool AllowsMultiple 
54         {
55             get {
56                 if (_allowsMultiple == null)
57                 {
58                     ParseUsageAttributes();
59                 }
60
61                 return (bool)_allowsMultiple;
62             }
63         }
64
65         // <summary>
66         // Gets the Inherit characteristic of the
67         // contained attribute and caches the result for subsequent
68         // calls to this property.
69         // </summary>
70         internal bool IsInheritable 
71         {
72             get {
73                 if (_isInheritable == null)
74                 {
75                     ParseUsageAttributes();
76                 }
77
78                 return (bool)_isInheritable;
79             }
80         }
81
82         private void ParseUsageAttributes() 
83         {
84             _isInheritable = false;
85             _allowsMultiple = false;
86             object[] usageAttributes = _attributeType.GetCustomAttributes(typeof(AttributeUsageAttribute), true);
87
88             if (usageAttributes != null && usageAttributes.Length > 0) 
89             {
90                 for (int i = 0; i < usageAttributes.Length; i++) 
91                 {
92                     Fx.Assert(usageAttributes[i] is AttributeUsageAttribute, "usageAttributes should be of type AttributeUsageAttribute");
93                     AttributeUsageAttribute usageAttribute = (AttributeUsageAttribute)usageAttributes[i];
94                     _isInheritable = usageAttribute.Inherited;
95                     _allowsMultiple = usageAttribute.AllowMultiple;
96                 }
97             }
98         }
99     }
100 }