2009-06-05 Jb Evain <jbevain@novell.com>
[mono.git] / mcs / class / Mono.Cecil / Mono.Cecil / GenericParameter.cs
1 //
2 // GenericParameter.cs
3 //
4 // Author:
5 //   Jb Evain (jbevain@gmail.com)
6 //
7 // (C) 2005 Jb Evain
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 namespace Mono.Cecil {
30
31         using System;
32
33         public sealed class GenericParameter : TypeReference {
34
35                 int m_position;
36                 string m_name;
37                 GenericParameterAttributes m_attributes;
38                 IGenericParameterProvider m_owner;
39                 ConstraintCollection m_constraints;
40
41                 public int Position {
42                         get { return m_position; }
43                         set { m_position = value; }
44                 }
45
46                 public GenericParameterAttributes Attributes {
47                         get { return m_attributes; }
48                         set { m_attributes = value; }
49                 }
50
51                 public IGenericParameterProvider Owner {
52                         get { return m_owner; }
53                 }
54
55                 public bool HasConstraints {
56                         get { return (m_constraints == null) ? false : (m_constraints.Count > 0); }
57                 }
58
59                 public ConstraintCollection Constraints {
60                         get {
61                                 if (m_constraints == null)
62                                         m_constraints = new ConstraintCollection (this);
63
64                                 return m_constraints;
65                         }
66                 }
67
68                 public override IMetadataScope Scope {
69                         get {
70                                 if (m_owner is TypeReference)
71                                         return ((TypeReference) m_owner).Scope;
72                                 if (m_owner is MethodReference)
73                                         return ((MethodReference) m_owner).DeclaringType.Scope;
74
75                                 throw new InvalidOperationException ();
76                         }
77                 }
78
79                 public override string Name {
80                         get {
81                                 if (m_name != null)
82                                         return m_name;
83
84                                 if (m_owner is TypeReference)
85                                         return string.Concat ("!", m_position.ToString ());
86                                 else if (m_owner is MethodReference)
87                                         return string.Concat ("!!", m_position.ToString ());
88                                 else
89                                         throw new InvalidOperationException ();
90                         }
91                         set { m_name = value; }
92                 }
93
94                 public override string Namespace {
95                         get { return string.Empty; }
96                         set { throw new InvalidOperationException (); }
97                 }
98
99                 public override string FullName {
100                         get { return Name; }
101                 }
102
103                 #region GenericParameterAttributes
104
105                 public bool IsNonVariant {
106                         get { return (m_attributes & GenericParameterAttributes.VarianceMask) == GenericParameterAttributes.NonVariant; }
107                         set {
108                                 if (value) {
109                                         m_attributes &= ~GenericParameterAttributes.VarianceMask;
110                                         m_attributes |= GenericParameterAttributes.NonVariant;
111                                 } else
112                                         m_attributes &= ~(GenericParameterAttributes.VarianceMask & GenericParameterAttributes.NonVariant);
113                         }
114                 }
115
116                 public bool IsCovariant {
117                         get { return (m_attributes & GenericParameterAttributes.VarianceMask) == GenericParameterAttributes.Covariant; }
118                         set {
119                                 if (value) {
120                                         m_attributes &= ~GenericParameterAttributes.VarianceMask;
121                                         m_attributes |= GenericParameterAttributes.Covariant;
122                                 } else
123                                         m_attributes &= ~(GenericParameterAttributes.VarianceMask & GenericParameterAttributes.Covariant);
124                         }
125                 }
126
127                 public bool IsContravariant {
128                         get { return (m_attributes & GenericParameterAttributes.VarianceMask) == GenericParameterAttributes.Contravariant; }
129                         set {
130                                 if (value) {
131                                         m_attributes &= ~GenericParameterAttributes.VarianceMask;
132                                         m_attributes |= GenericParameterAttributes.Contravariant;
133                                 } else
134                                         m_attributes &= ~(GenericParameterAttributes.VarianceMask & GenericParameterAttributes.Contravariant);
135                         }
136                 }
137
138                 public bool HasReferenceTypeConstraint {
139                         get { return (m_attributes & GenericParameterAttributes.ReferenceTypeConstraint) != 0; }
140                         set {
141                                 if (value) {
142                                         m_attributes |= GenericParameterAttributes.ReferenceTypeConstraint;
143                                 } else
144                                         m_attributes &= ~GenericParameterAttributes.ReferenceTypeConstraint;
145                         }
146                 }
147
148                 public bool HasNotNullableValueTypeConstraint {
149                         get { return (m_attributes & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0; }
150                         set {
151                                 if (value) {
152                                         m_attributes |= GenericParameterAttributes.NotNullableValueTypeConstraint;
153                                 } else
154                                         m_attributes &= ~GenericParameterAttributes.NotNullableValueTypeConstraint;
155                         }
156                 }
157
158                 public bool HasDefaultConstructorConstraint {
159                         get { return (m_attributes & GenericParameterAttributes.DefaultConstructorConstraint) != 0; }
160                         set {
161                                 if (value) {
162                                         m_attributes |= GenericParameterAttributes.DefaultConstructorConstraint;
163                                 } else
164                                         m_attributes &= ~GenericParameterAttributes.DefaultConstructorConstraint;
165                         }
166                 }
167
168                 #endregion
169
170                 internal GenericParameter (int pos, IGenericParameterProvider owner) :
171                         base (string.Empty, string.Empty)
172                 {
173                         m_position = pos;
174                         m_owner = owner;
175                 }
176
177                 public GenericParameter (string name, IGenericParameterProvider owner) :
178                         base (string.Empty, string.Empty)
179                 {
180                         m_name = name;
181                         m_owner = owner;
182                 }
183
184                 public override TypeDefinition Resolve ()
185                 {
186                         return null;
187                 }
188
189                 internal static void CloneInto (IGenericParameterProvider old, IGenericParameterProvider np, ImportContext context)
190                 {
191                         foreach (GenericParameter gp in old.GenericParameters) {
192                                 GenericParameter ngp = Clone (gp, context);
193                                 np.GenericParameters.Add (ngp);
194                                 CloneConstraints (gp, ngp, context);
195                         }
196                 }
197
198                 internal static GenericParameter Clone (GenericParameter gp, ImportContext context)
199                 {
200                         GenericParameter ngp;
201                         if (gp.Owner is TypeReference)
202                                 ngp = new GenericParameter (gp.m_name, context.GenericContext.Type);
203                         else if (gp.Owner is MethodReference)
204                                 ngp = new GenericParameter (gp.m_name, context.GenericContext.Method);
205                         else
206                                 throw new NotSupportedException ();
207
208                         ngp.Position = gp.Owner.GenericParameters.IndexOf (gp);
209                         ngp.Attributes = gp.Attributes;
210
211                         if (gp.HasCustomAttributes) {
212                                 foreach (CustomAttribute ca in gp.CustomAttributes)
213                                         ngp.CustomAttributes.Add (CustomAttribute.Clone (ca, context));
214                         }
215
216                         return ngp;
217                 }
218
219                 static void CloneConstraints (GenericParameter gp, GenericParameter ngp, ImportContext context)
220                 {
221                         if (gp.HasConstraints) {
222                                 foreach (TypeReference constraint in gp.Constraints)
223                                         ngp.Constraints.Add (context.Import (constraint));
224                         }
225                 }
226         }
227 }