svn path=/trunk/mcs/; revision=104772
[mono.git] / mcs / class / Mono.Cecil / Mono.Cecil / PropertyDefinition.cs
1 //
2 // PropertyDefinition.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         using System.Text;
33
34         public sealed class PropertyDefinition : PropertyReference,
35                 IMemberDefinition, ICustomAttributeProvider, IHasConstant {
36
37                 PropertyAttributes m_attributes;
38
39                 CustomAttributeCollection m_customAttrs;
40
41                 MethodDefinition m_getMeth;
42                 MethodDefinition m_setMeth;
43
44                 bool m_hasConstant;
45                 object m_const;
46
47                 public PropertyAttributes Attributes {
48                         get { return m_attributes; }
49                         set { m_attributes = value; }
50                 }
51
52                 public CustomAttributeCollection CustomAttributes {
53                         get {
54                                 if (m_customAttrs == null)
55                                         m_customAttrs = new CustomAttributeCollection (this);
56
57                                 return m_customAttrs;
58                         }
59                 }
60
61                 public override ParameterDefinitionCollection Parameters {
62                         get {
63                                 if (this.GetMethod != null)
64                                         return CloneParameterCollection (this.GetMethod.Parameters);
65                                 else if (this.SetMethod != null) {
66                                         ParameterDefinitionCollection parameters =
67                                                 CloneParameterCollection (this.SetMethod.Parameters);
68                                         if (parameters.Count > 0)
69                                                 parameters.RemoveAt (parameters.Count - 1);
70                                         return parameters;
71                                 }
72
73                                 if (m_parameters == null)
74                                         m_parameters = new ParameterDefinitionCollection (this);
75
76                                 return m_parameters;
77                         }
78                 }
79
80                 public MethodDefinition GetMethod {
81                         get { return m_getMeth; }
82                         set { m_getMeth = value; }
83                 }
84
85                 public MethodDefinition SetMethod {
86                         get { return m_setMeth; }
87                         set { m_setMeth = value; }
88                 }
89
90                 ParameterDefinitionCollection CloneParameterCollection (ParameterDefinitionCollection original)
91                 {
92                         ParameterDefinitionCollection clone = new ParameterDefinitionCollection (
93                                 original.Container);
94                         foreach (ParameterDefinition param in original)
95                                 clone.Add (param);
96                         return clone;
97                 }
98
99                 public bool HasConstant {
100                         get { return m_hasConstant; }
101                 }
102
103                 public object Constant {
104                         get { return m_const; }
105                         set {
106                                 m_hasConstant = true;
107                                 m_const = value;
108                         }
109                 }
110
111                 #region PropertyAttributes
112
113                 public bool IsSpecialName {
114                         get { return (m_attributes & PropertyAttributes.SpecialName) != 0; }
115                         set {
116                                 if (value)
117                                         m_attributes |= PropertyAttributes.SpecialName;
118                                 else
119                                         m_attributes &= ~PropertyAttributes.SpecialName;
120                         }
121                 }
122
123                 public bool IsRuntimeSpecialName {
124                         get { return (m_attributes & PropertyAttributes.RTSpecialName) != 0; }
125                         set {
126                                 if (value)
127                                         m_attributes |= PropertyAttributes.RTSpecialName;
128                                 else
129                                         m_attributes &= ~PropertyAttributes.RTSpecialName;
130                         }
131                 }
132
133                 public bool HasDefault {
134                         get { return (m_attributes & PropertyAttributes.HasDefault) != 0; }
135                         set {
136                                 if (value)
137                                         m_attributes |= PropertyAttributes.HasDefault;
138                                 else
139                                         m_attributes &= ~PropertyAttributes.HasDefault;
140                         }
141                 }
142
143                 #endregion
144
145                 public PropertyDefinition (string name, TypeReference propertyType, PropertyAttributes attrs) : base (name, propertyType)
146                 {
147                         m_attributes = attrs;
148                 }
149
150                 public static MethodDefinition CreateGetMethod (PropertyDefinition prop)
151                 {
152                         MethodDefinition get = new MethodDefinition (
153                                 string.Concat ("get_", prop.Name), (MethodAttributes) 0, prop.PropertyType);
154                         prop.GetMethod = get;
155                         return get;
156                 }
157
158                 public static MethodDefinition CreateSetMethod (PropertyDefinition prop)
159                 {
160                         MethodDefinition set = new MethodDefinition (
161                                 string.Concat ("set_", prop.Name), (MethodAttributes) 0, prop.PropertyType);
162                         prop.SetMethod = set;
163                         return set;
164                 }
165
166                 public PropertyDefinition Clone ()
167                 {
168                         return Clone (this, new ImportContext (NullReferenceImporter.Instance, this.DeclaringType));
169                 }
170
171                 internal static PropertyDefinition Clone (PropertyDefinition prop, ImportContext context)
172                 {
173                         PropertyDefinition np = new PropertyDefinition (
174                                 prop.Name,
175                                 context.Import (prop.PropertyType),
176                                 prop.Attributes);
177
178                         if (prop.HasConstant)
179                                 np.Constant = prop.Constant;
180
181                         if (context.GenericContext.Type is TypeDefinition) {
182                                 TypeDefinition type = context.GenericContext.Type as TypeDefinition;
183                                 if (prop.SetMethod != null)
184                                         np.SetMethod = type.Methods.GetMethod (prop.SetMethod.Name, prop.SetMethod.Parameters);
185                                 if (prop.GetMethod != null)
186                                         np.GetMethod = type.Methods.GetMethod (prop.GetMethod.Name, prop.GetMethod.Parameters);
187                         }
188
189                         foreach (CustomAttribute ca in prop.CustomAttributes)
190                                 np.CustomAttributes.Add (CustomAttribute.Clone (ca, context));
191
192                         return np;
193                 }
194
195                 public override string ToString ()
196                 {
197                         StringBuilder sb = new StringBuilder ();
198                         sb.Append (PropertyType.ToString ());
199                         sb.Append (' ');
200
201                         if (this.DeclaringType != null) {
202                                 sb.Append (this.DeclaringType.ToString ());
203                                 sb.Append ("::");
204                         }
205
206                         sb.Append (this.Name);
207                         sb.Append ('(');
208                         ParameterDefinitionCollection parameters = this.Parameters;
209                         for (int i = 0; i < parameters.Count; i++) {
210                                 if (i > 0)
211                                         sb.Append (',');
212                                 sb.Append (parameters [i].ParameterType.ToString ());
213                         }
214                         sb.Append (')');
215                         return sb.ToString ();
216                 }
217
218                 public override void Accept (IReflectionVisitor visitor)
219                 {
220                         visitor.VisitPropertyDefinition (this);
221
222                         this.CustomAttributes.Accept (visitor);
223                 }
224         }
225 }