Merged into single file, added assertions
[mono.git] / mcs / class / IKVM.Reflection / PropertySignature.cs
1 /*
2   Copyright (C) 2009-2011 Jeroen Frijters
3
4   This software is provided 'as-is', without any express or implied
5   warranty.  In no event will the authors be held liable for any damages
6   arising from the use of this software.
7
8   Permission is granted to anyone to use this software for any purpose,
9   including commercial applications, and to alter it and redistribute it
10   freely, subject to the following restrictions:
11
12   1. The origin of this software must not be misrepresented; you must not
13      claim that you wrote the original software. If you use this software
14      in a product, an acknowledgment in the product documentation would be
15      appreciated but is not required.
16   2. Altered source versions must be plainly marked as such, and must not be
17      misrepresented as being the original software.
18   3. This notice may not be removed or altered from any source distribution.
19
20   Jeroen Frijters
21   jeroen@frijters.net
22   
23 */
24 using System;
25 using System.Collections.Generic;
26 using System.IO;
27 using System.Text;
28 using IKVM.Reflection.Emit;
29 using IKVM.Reflection.Writer;
30 using IKVM.Reflection.Reader;
31
32 namespace IKVM.Reflection
33 {
34         sealed class PropertySignature : Signature
35         {
36                 private CallingConventions callingConvention;
37                 private readonly Type propertyType;
38                 private readonly Type[] parameterTypes;
39                 private readonly PackedCustomModifiers customModifiers;
40
41                 internal static PropertySignature Create(CallingConventions callingConvention, Type propertyType, Type[] parameterTypes, PackedCustomModifiers customModifiers)
42                 {
43                         return new PropertySignature(callingConvention, propertyType, Util.Copy(parameterTypes), customModifiers);
44                 }
45
46                 private PropertySignature(CallingConventions callingConvention, Type propertyType, Type[] parameterTypes, PackedCustomModifiers customModifiers)
47                 {
48                         this.callingConvention = callingConvention;
49                         this.propertyType = propertyType;
50                         this.parameterTypes = parameterTypes;
51                         this.customModifiers = customModifiers;
52                 }
53
54                 public override bool Equals(object obj)
55                 {
56                         PropertySignature other = obj as PropertySignature;
57                         return other != null
58                                 && other.propertyType.Equals(propertyType)
59                                 && other.customModifiers.Equals(customModifiers);
60                 }
61
62                 public override int GetHashCode()
63                 {
64                         return propertyType.GetHashCode() ^ customModifiers.GetHashCode();
65                 }
66
67                 internal int ParameterCount
68                 {
69                         get { return parameterTypes.Length; }
70                 }
71
72                 internal bool HasThis
73                 {
74                         set
75                         {
76                                 if (value)
77                                 {
78                                         callingConvention |= CallingConventions.HasThis;
79                                 }
80                                 else
81                                 {
82                                         callingConvention &= ~CallingConventions.HasThis;
83                                 }
84                         }
85                 }
86
87                 internal Type PropertyType
88                 {
89                         get { return propertyType; }
90                 }
91
92                 internal CustomModifiers GetCustomModifiers()
93                 {
94                         return customModifiers.GetReturnTypeCustomModifiers();
95                 }
96
97                 internal PropertySignature ExpandTypeParameters(Type declaringType)
98                 {
99                         return new PropertySignature(
100                                 callingConvention,
101                                 propertyType.BindTypeParameters(declaringType),
102                                 BindTypeParameters(declaringType, parameterTypes),
103                                 customModifiers.Bind(declaringType));
104                 }
105
106                 internal override void WriteSig(ModuleBuilder module, ByteBuffer bb)
107                 {
108                         byte flags = PROPERTY;
109                         if ((callingConvention & CallingConventions.HasThis) != 0)
110                         {
111                                 flags |= HASTHIS;
112                         }
113                         if ((callingConvention & CallingConventions.ExplicitThis) != 0)
114                         {
115                                 flags |= EXPLICITTHIS;
116                         }
117                         if ((callingConvention & CallingConventions.VarArgs) != 0)
118                         {
119                                 flags |= VARARG;
120                         }
121                         bb.Write(flags);
122                         bb.WriteCompressedInt(parameterTypes == null ? 0 : parameterTypes.Length);
123                         WriteCustomModifiers(module, bb, customModifiers.GetReturnTypeCustomModifiers());
124                         WriteType(module, bb, propertyType);
125                         if (parameterTypes != null)
126                         {
127                                 for (int i = 0; i < parameterTypes.Length; i++)
128                                 {
129                                         WriteCustomModifiers(module, bb, customModifiers.GetParameterCustomModifiers(i));
130                                         WriteType(module, bb, parameterTypes[i]);
131                                 }
132                         }
133                 }
134
135                 internal Type GetParameter(int parameter)
136                 {
137                         return parameterTypes[parameter];
138                 }
139
140                 internal CustomModifiers GetParameterCustomModifiers(int parameter)
141                 {
142                         return customModifiers.GetParameterCustomModifiers(parameter);
143                 }
144
145                 internal CallingConventions CallingConvention
146                 {
147                         get { return callingConvention; }
148                 }
149
150                 internal bool MatchParameterTypes(Type[] types)
151                 {
152                         return Util.ArrayEquals(types, parameterTypes);
153                 }
154
155                 internal static PropertySignature ReadSig(ModuleReader module, ByteReader br, IGenericContext context)
156                 {
157                         byte flags = br.ReadByte();
158                         if ((flags & PROPERTY) == 0)
159                         {
160                                 throw new BadImageFormatException();
161                         }
162                         CallingConventions callingConvention = CallingConventions.Standard;
163                         if ((flags & HASTHIS) != 0)
164                         {
165                                 callingConvention |= CallingConventions.HasThis;
166                         }
167                         if ((flags & EXPLICITTHIS) != 0)
168                         {
169                                 callingConvention |= CallingConventions.ExplicitThis;
170                         }
171                         Type returnType;
172                         Type[] parameterTypes;
173                         int paramCount = br.ReadCompressedInt();
174                         CustomModifiers[] mods = null;
175                         PackedCustomModifiers.Pack(ref mods, 0, CustomModifiers.Read(module, br, context), paramCount + 1);
176                         returnType = ReadRetType(module, br, context);
177                         parameterTypes = new Type[paramCount];
178                         for (int i = 0; i < parameterTypes.Length; i++)
179                         {
180                                 PackedCustomModifiers.Pack(ref mods, i + 1, CustomModifiers.Read(module, br, context), paramCount + 1);
181                                 parameterTypes[i] = ReadParam(module, br, context);
182                         }
183                         return new PropertySignature(callingConvention, returnType, parameterTypes, PackedCustomModifiers.Wrap(mods));
184                 }
185         }
186 }