5 // Jb Evain (jbevain@gmail.com)
7 // Copyright (c) 2008 - 2010 Jb Evain
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
31 using Mono.Cecil.Metadata;
33 namespace Mono.Cecil {
35 public abstract class TypeSystem {
37 sealed class CorlibTypeSystem : TypeSystem {
39 public CorlibTypeSystem (ModuleDefinition module)
44 internal override TypeReference LookupType (string @namespace, string name)
46 var metadata = module.MetadataSystem;
47 if (metadata.Types == null)
48 Initialize (module.Types);
50 return module.Read (this, (_, reader) => {
51 var types = reader.metadata.Types;
53 for (int i = 0; i < types.Length; i++) {
54 if (types [i] == null)
55 types [i] = reader.GetTypeDefinition ((uint) i + 1);
59 if (type.Name == name && type.Namespace == @namespace)
67 static void Initialize (object obj)
72 sealed class CommonTypeSystem : TypeSystem {
74 AssemblyNameReference corlib;
76 public CommonTypeSystem (ModuleDefinition module)
81 internal override TypeReference LookupType (string @namespace, string name)
83 return CreateTypeReference (@namespace, name);
86 public AssemblyNameReference GetCorlibReference ()
91 const string mscorlib = "mscorlib";
93 var references = module.AssemblyReferences;
95 for (int i = 0; i < references.Count; i++) {
96 var reference = references [i];
97 if (reference.Name == mscorlib)
98 return corlib = reference;
101 corlib = new AssemblyNameReference {
103 Version = GetCorlibVersion (),
104 PublicKeyToken = new byte [] { 0xb7, 0x7a, 0x5c, 0x56, 0x19, 0x34, 0xe0, 0x89 },
107 references.Add (corlib);
112 Version GetCorlibVersion ()
114 switch (module.Runtime) {
115 case TargetRuntime.Net_1_0:
116 case TargetRuntime.Net_1_1:
117 return new Version (1, 0, 0, 0);
118 case TargetRuntime.Net_2_0:
119 return new Version (2, 0, 0, 0);
120 case TargetRuntime.Net_4_0:
121 return new Version (4, 0, 0, 0);
123 throw new NotSupportedException ();
127 TypeReference CreateTypeReference (string @namespace, string name)
129 return new TypeReference (@namespace, name, module, GetCorlibReference ());
133 readonly ModuleDefinition module;
135 TypeReference type_object;
136 TypeReference type_void;
137 TypeReference type_bool;
138 TypeReference type_char;
139 TypeReference type_sbyte;
140 TypeReference type_byte;
141 TypeReference type_int16;
142 TypeReference type_uint16;
143 TypeReference type_int32;
144 TypeReference type_uint32;
145 TypeReference type_int64;
146 TypeReference type_uint64;
147 TypeReference type_single;
148 TypeReference type_double;
149 TypeReference type_intptr;
150 TypeReference type_uintptr;
151 TypeReference type_string;
152 TypeReference type_typedref;
154 TypeSystem (ModuleDefinition module)
156 this.module = module;
159 internal static TypeSystem CreateTypeSystem (ModuleDefinition module)
161 if (IsCorlib (module))
162 return new CorlibTypeSystem (module);
164 return new CommonTypeSystem (module);
167 static bool IsCorlib (ModuleDefinition module)
169 if (module.Assembly == null)
172 return module.Assembly.Name.Name == "mscorlib";
175 internal abstract TypeReference LookupType (string @namespace, string name);
177 TypeReference LookupSystemType (string name, ElementType element_type)
179 var type = LookupType ("System", name);
180 type.etype = element_type;
184 TypeReference LookupSystemValueType (string name, ElementType element_type)
186 var type = LookupSystemType (name, element_type);
187 type.IsValueType = true;
191 public IMetadataScope Corlib {
193 var common = this as CommonTypeSystem;
197 return common.GetCorlibReference ();
201 public TypeReference Object {
202 get { return type_object ?? (type_object = LookupSystemType ("Object", ElementType.Object)); }
205 public TypeReference Void {
206 get { return type_void ?? (type_void = LookupSystemType ("Void", ElementType.Void)); }
209 public TypeReference Boolean {
210 get { return type_bool ?? (type_bool = LookupSystemValueType ("Boolean", ElementType.Boolean)); }
213 public TypeReference Char {
214 get { return type_char ?? (type_char = LookupSystemValueType ("Char", ElementType.Char)); }
217 public TypeReference SByte {
218 get { return type_sbyte ?? (type_sbyte = LookupSystemValueType ("SByte", ElementType.I1)); }
221 public TypeReference Byte {
222 get { return type_byte ?? (type_byte = LookupSystemValueType ("Byte", ElementType.U1)); }
225 public TypeReference Int16 {
226 get { return type_int16 ?? (type_int16 = LookupSystemValueType ("Int16", ElementType.I2)); }
229 public TypeReference UInt16 {
230 get { return type_uint16 ?? (type_uint16 = LookupSystemValueType ("UInt16", ElementType.U2)); }
233 public TypeReference Int32 {
234 get { return type_int32 ?? (type_int32 = LookupSystemValueType ("Int32", ElementType.I4)); }
237 public TypeReference UInt32 {
238 get { return type_uint32 ?? (type_uint32 = LookupSystemValueType ("UInt32", ElementType.U4)); }
241 public TypeReference Int64 {
242 get { return type_int64 ?? (type_int64 = LookupSystemValueType ("Int64", ElementType.I8)); }
245 public TypeReference UInt64 {
246 get { return type_uint64 ?? (type_uint64 = LookupSystemValueType ("UInt64", ElementType.U8)); }
249 public TypeReference Single {
250 get { return type_single ?? (type_single = LookupSystemValueType ("Single", ElementType.R4)); }
253 public TypeReference Double {
254 get { return type_double ?? (type_double = LookupSystemValueType ("Double", ElementType.R8)); }
257 public TypeReference IntPtr {
258 get { return type_intptr ?? (type_intptr = LookupSystemValueType ("IntPtr", ElementType.I)); }
261 public TypeReference UIntPtr {
262 get { return type_uintptr ?? (type_uintptr = LookupSystemValueType ("UIntPtr", ElementType.U)); }
265 public TypeReference String {
266 get { return type_string ?? (type_string = LookupSystemType ("String", ElementType.String)); }
269 public TypeReference TypedReference {
270 get { return type_typedref ?? (type_typedref = LookupSystemValueType ("TypedReference", ElementType.TypedByRef)); }