2007-08-05 Miguel de Icaza <miguel@novell.com>
[mono.git] / mcs / class / Mono.Cecil / Mono.Cecil / TypeDefinition.cs
1 //
2 // TypeDefinition.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         public sealed class TypeDefinition : TypeReference, IMemberDefinition, IHasSecurity {
32
33                 TypeAttributes m_attributes;
34                 TypeReference m_baseType;
35
36                 bool m_hasInfo;
37                 ushort m_packingSize;
38                 uint m_classSize;
39
40                 InterfaceCollection m_interfaces;
41                 NestedTypeCollection m_nestedTypes;
42                 MethodDefinitionCollection m_methods;
43                 ConstructorCollection m_ctors;
44                 FieldDefinitionCollection m_fields;
45                 EventDefinitionCollection m_events;
46                 PropertyDefinitionCollection m_properties;
47                 SecurityDeclarationCollection m_secDecls;
48
49                 public TypeAttributes Attributes {
50                         get { return m_attributes; }
51                         set { m_attributes = value; }
52                 }
53
54                 public TypeReference BaseType {
55                         get { return m_baseType; }
56                         set { m_baseType = value; }
57                 }
58
59                 public bool HasLayoutInfo {
60                         get { return m_hasInfo; }
61                 }
62
63                 public ushort PackingSize {
64                         get { return m_packingSize; }
65                         set {
66                                 m_hasInfo = true;
67                                 m_packingSize = value;
68                         }
69                 }
70
71                 public uint ClassSize {
72                         get { return m_classSize; }
73                         set {
74                                 m_hasInfo = true;
75                                 m_classSize = value;
76                         }
77                 }
78
79                 public InterfaceCollection Interfaces {
80                         get {
81                                 if (m_interfaces == null)
82                                         m_interfaces = new InterfaceCollection (this);
83
84                                 return m_interfaces;
85                         }
86                 }
87
88                 public NestedTypeCollection NestedTypes {
89                         get {
90                                 if (m_nestedTypes == null)
91                                         m_nestedTypes = new NestedTypeCollection (this);
92
93                                 return m_nestedTypes;
94                         }
95                 }
96
97                 public MethodDefinitionCollection Methods {
98                         get {
99                                 if (m_methods == null)
100                                         m_methods = new MethodDefinitionCollection (this);
101
102                                 return m_methods;
103                         }
104                 }
105
106                 public ConstructorCollection Constructors {
107                         get {
108                                 if (m_ctors == null)
109                                         m_ctors = new ConstructorCollection (this);
110
111                                 return m_ctors;
112                         }
113                 }
114
115                 public FieldDefinitionCollection Fields {
116                         get {
117                                 if (m_fields == null)
118                                         m_fields = new FieldDefinitionCollection (this);
119
120                                 return m_fields;
121                         }
122                 }
123
124                 public EventDefinitionCollection Events {
125                         get {
126                                 if (m_events == null)
127                                         m_events = new EventDefinitionCollection (this);
128
129                                 return m_events;
130                         }
131                 }
132
133                 public PropertyDefinitionCollection Properties {
134                         get {
135                                 if (m_properties == null)
136                                         m_properties = new PropertyDefinitionCollection (this);
137
138                                 return m_properties;
139                         }
140                 }
141
142                 public SecurityDeclarationCollection SecurityDeclarations {
143                         get {
144                                 if (m_secDecls == null)
145                                         m_secDecls = new SecurityDeclarationCollection (this);
146
147                                 return m_secDecls;
148                         }
149                 }
150
151                 #region TypeAttributes
152
153                 public bool IsNotPublic {
154                         get { return (m_attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic; }
155                         set {
156                                 TypeAttributes masked = (TypeAttributes.VisibilityMask & TypeAttributes.NotPublic);
157                                 if (value)
158                                         m_attributes |= masked;
159                                 else
160                                         m_attributes &= masked;
161                         }
162                 }
163
164                 public bool IsPublic {
165                         get { return (m_attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public; }
166                         set {
167                                 TypeAttributes masked = (TypeAttributes.VisibilityMask & TypeAttributes.Public);
168                                 if (value)
169                                         m_attributes |= masked;
170                                 else
171                                         m_attributes &= masked;
172                         }
173                 }
174
175                 public bool IsNestedPublic {
176                         get { return (m_attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic; }
177                         set {
178                                 TypeAttributes masked = (TypeAttributes.VisibilityMask & TypeAttributes.NestedPublic);
179                                 if (value)
180                                         m_attributes |= masked;
181                                 else
182                                         m_attributes &= masked;
183                         }
184                 }
185
186                 public bool IsNestedPrivate {
187                         get { return (m_attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate; }
188                         set {
189                                 TypeAttributes masked = (TypeAttributes.VisibilityMask & TypeAttributes.NestedPrivate);
190                                 if (value)
191                                         m_attributes |= masked;
192                                 else
193                                         m_attributes &= masked;
194                         }
195                 }
196
197                 public bool IsNestedFamily {
198                         get { return (m_attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily; }
199                         set {
200                                 TypeAttributes masked = (TypeAttributes.VisibilityMask & TypeAttributes.NestedFamily);
201                                 if (value)
202                                         m_attributes |= masked;
203                                 else
204                                         m_attributes &= masked;
205                         }
206                 }
207
208                 public bool IsNestedAssembly {
209                         get { return (m_attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly; }
210                         set {
211                                 TypeAttributes masked = (TypeAttributes.VisibilityMask & TypeAttributes.NestedAssembly);
212                                 if (value)
213                                         m_attributes |= masked;
214                                 else
215                                         m_attributes &= masked;
216                         }
217                 }
218
219                 public bool IsNestedFamilyAndAssembly {
220                         get { return (m_attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem; }
221                         set {
222                                 TypeAttributes masked = (TypeAttributes.VisibilityMask & TypeAttributes.NestedFamANDAssem);
223                                 if (value)
224                                         m_attributes |= masked;
225                                 else
226                                         m_attributes &= masked;
227                         }
228                 }
229
230                 public bool IsNestedFamilyOrAssembly {
231                         get { return (m_attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem; }
232                         set {
233                                 TypeAttributes masked = (TypeAttributes.VisibilityMask & TypeAttributes.NestedFamORAssem);
234                                 if (value)
235                                         m_attributes |= masked;
236                                 else
237                                         m_attributes &= masked;
238                         }
239                 }
240
241                 public bool IsAutoLayout {
242                         get { return (m_attributes & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout; }
243                         set {
244                                 TypeAttributes masked = (TypeAttributes.LayoutMask & TypeAttributes.AutoLayout);
245                                 if (value)
246                                         m_attributes |= masked;
247                                 else
248                                         m_attributes &= masked;
249                         }
250                 }
251
252                 public bool IsSequentialLayout {
253                         get { return (m_attributes & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout; }
254                         set {
255                                 TypeAttributes masked = (TypeAttributes.LayoutMask & TypeAttributes.SequentialLayout);
256                                 if (value)
257                                         m_attributes |= masked;
258                                 else
259                                         m_attributes &= masked;
260                         }
261                 }
262
263                 public bool IsExplicitLayout {
264                         get { return (m_attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout; }
265                         set {
266                                 TypeAttributes masked = (TypeAttributes.LayoutMask & TypeAttributes.ExplicitLayout);
267                                 if (value)
268                                         m_attributes |= masked;
269                                 else
270                                         m_attributes &= masked;
271                         }
272                 }
273
274                 public bool IsClass {
275                         get { return (m_attributes & TypeAttributes.ClassSemanticMask) == TypeAttributes.Class; }
276                         set {
277                                 TypeAttributes masked = (TypeAttributes.ClassSemanticMask & TypeAttributes.Class);
278                                 if (value)
279                                         m_attributes |= masked;
280                                 else
281                                         m_attributes &= masked;
282                         }
283                 }
284
285                 public bool IsInterface {
286                         get { return (m_attributes & TypeAttributes.ClassSemanticMask) == TypeAttributes.Interface; }
287                         set {
288                                 TypeAttributes masked = (TypeAttributes.ClassSemanticMask & TypeAttributes.Interface);
289                                 if (value)
290                                         m_attributes |= masked;
291                                 else
292                                         m_attributes &= masked;
293                         }
294                 }
295
296                 public bool IsAbstract {
297                         get { return (m_attributes & TypeAttributes.Abstract) != 0; }
298                         set {
299                                 if (value)
300                                         m_attributes |= TypeAttributes.Abstract;
301                                 else
302                                         m_attributes &= ~TypeAttributes.Abstract;
303                         }
304                 }
305
306                 public bool IsSealed {
307                         get { return (m_attributes & TypeAttributes.Sealed) != 0; }
308                         set {
309                                 if (value)
310                                         m_attributes |= TypeAttributes.Sealed;
311                                 else
312                                         m_attributes &= ~TypeAttributes.Sealed;
313                         }
314                 }
315
316                 public bool IsSpecialName {
317                         get { return (m_attributes & TypeAttributes.SpecialName) != 0; }
318                         set {
319                                 if (value)
320                                         m_attributes |= TypeAttributes.SpecialName;
321                                 else
322                                         m_attributes &= ~TypeAttributes.SpecialName;
323                         }
324                 }
325
326                 public bool IsImport {
327                         get { return (m_attributes & TypeAttributes.Import) != 0; }
328                         set {
329                                 if (value)
330                                         m_attributes |= TypeAttributes.Import;
331                                 else
332                                         m_attributes &= ~TypeAttributes.Import;
333                         }
334                 }
335
336                 public bool IsSerializable {
337                         get { return (m_attributes & TypeAttributes.Serializable) != 0; }
338                         set {
339                                 if (value)
340                                         m_attributes |= TypeAttributes.Serializable;
341                                 else
342                                         m_attributes &= ~TypeAttributes.Serializable;
343                         }
344                 }
345
346                 public bool IsAnsiClass {
347                         get { return (m_attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass; }
348                         set {
349                                 TypeAttributes masked = (TypeAttributes.StringFormatMask & TypeAttributes.AnsiClass);
350                                 if (value)
351                                         m_attributes |= masked;
352                                 else
353                                         m_attributes &= masked;
354                         }
355                 }
356
357                 public bool IsUnicodeClass {
358                         get { return (m_attributes & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass; }
359                         set {
360                                 TypeAttributes masked = (TypeAttributes.StringFormatMask & TypeAttributes.UnicodeClass);
361                                 if (value)
362                                         m_attributes |= masked;
363                                 else
364                                         m_attributes &= masked;
365                         }
366                 }
367
368                 public bool IsAutoClass {
369                         get { return (m_attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass; }
370                         set {
371                                 TypeAttributes masked = (TypeAttributes.StringFormatMask & TypeAttributes.AutoClass);
372                                 if (value)
373                                         m_attributes |= masked;
374                                 else
375                                         m_attributes &= masked;
376                         }
377                 }
378
379                 public bool IsBeforeFieldInit {
380                         get { return (m_attributes & TypeAttributes.BeforeFieldInit) != 0; }
381                         set {
382                                 if (value)
383                                         m_attributes |= TypeAttributes.BeforeFieldInit;
384                                 else
385                                         m_attributes &= ~TypeAttributes.BeforeFieldInit;
386                         }
387                 }
388
389                 public bool IsRuntimeSpecialName {
390                         get { return (m_attributes & TypeAttributes.RTSpecialName) != 0; }
391                         set {
392                                 if (value)
393                                         m_attributes |= TypeAttributes.RTSpecialName;
394                                 else
395                                         m_attributes &= ~TypeAttributes.RTSpecialName;
396                         }
397                 }
398
399                 public bool HasSecurity {
400                         get { return (m_attributes & TypeAttributes.HasSecurity) != 0; }
401                         set {
402                                 if (value)
403                                         m_attributes |= TypeAttributes.HasSecurity;
404                                 else
405                                         m_attributes &= ~TypeAttributes.HasSecurity;
406                         }
407                 }
408
409                 #endregion
410
411                 public bool IsEnum {
412                         get { return m_baseType != null && m_baseType.FullName == Constants.Enum; }
413                 }
414
415                 public override bool IsValueType {
416                         get {
417                                 return m_baseType != null && (
418                                         this.IsEnum || m_baseType.FullName == Constants.ValueType);
419                         }
420                 }
421
422                 internal TypeDefinition (string name, string ns, TypeAttributes attrs) :
423                         base (name, ns)
424                 {
425                         m_hasInfo = false;
426                         m_attributes = attrs;
427                 }
428
429                 public TypeDefinition (string name, string ns,
430                         TypeAttributes attributes, TypeReference baseType) :
431                         this (name, ns, attributes)
432                 {
433                         this.BaseType = baseType;
434                 }
435
436                 public TypeDefinition Clone ()
437                 {
438                         return Clone (this, new ImportContext (NullReferenceImporter.Instance, this));
439                 }
440
441                 internal static TypeDefinition Clone (TypeDefinition type, ImportContext context)
442                 {
443                         TypeDefinition nt = new TypeDefinition (
444                                 type.Name,
445                                 type.Namespace,
446                                 type.Attributes);
447
448                         context.GenericContext.Type = nt;
449
450                         foreach (GenericParameter p in type.GenericParameters)
451                                 nt.GenericParameters.Add (GenericParameter.Clone (p, context));
452
453                         if (type.BaseType != null)
454                                 nt.BaseType = context.Import (type.BaseType);
455
456                         if (type.HasLayoutInfo) {
457                                 nt.ClassSize = type.ClassSize;
458                                 nt.PackingSize = type.PackingSize;
459                         }
460
461                         foreach (FieldDefinition field in type.Fields)
462                                 nt.Fields.Add (FieldDefinition.Clone (field, context));
463                         foreach (MethodDefinition ctor in type.Constructors)
464                                 nt.Constructors.Add (MethodDefinition.Clone (ctor, context));
465                         foreach (MethodDefinition meth in type.Methods)
466                                 nt.Methods.Add (MethodDefinition.Clone (meth, context));
467                         foreach (EventDefinition evt in type.Events)
468                                 nt.Events.Add (EventDefinition.Clone (evt, context));
469                         foreach (PropertyDefinition prop in type.Properties)
470                                 nt.Properties.Add (PropertyDefinition.Clone (prop, context));
471                         foreach (TypeReference intf in type.Interfaces)
472                                 nt.Interfaces.Add (context.Import (intf));
473                         foreach (TypeDefinition nested in type.NestedTypes)
474                                 nt.NestedTypes.Add (Clone (nested, context));
475                         foreach (CustomAttribute ca in type.CustomAttributes)
476                                 nt.CustomAttributes.Add (CustomAttribute.Clone (ca, context));
477                         foreach (SecurityDeclaration dec in type.SecurityDeclarations)
478                                 nt.SecurityDeclarations.Add (SecurityDeclaration.Clone (dec));
479
480                         return nt;
481                 }
482
483                 public override void Accept (IReflectionVisitor visitor)
484                 {
485                         visitor.VisitTypeDefinition (this);
486
487                         this.GenericParameters.Accept (visitor);
488                         this.Interfaces.Accept (visitor);
489                         this.Constructors.Accept (visitor);
490                         this.Methods.Accept (visitor);
491                         this.Fields.Accept (visitor);
492                         this.Properties.Accept (visitor);
493                         this.Events.Accept (visitor);
494                         this.NestedTypes.Accept (visitor);
495                         this.CustomAttributes.Accept (visitor);
496                         this.SecurityDeclarations.Accept (visitor);
497                 }
498         }
499 }