1 //
2 // CoreSystemTypes.cs
3 //
4 // Authors:
5 // 	Alexander Chebaturkin (chebaturkin@gmail.com)
6 //
7 // Copyright (C) 2011 Alexander Chebaturkin
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 using System;
30 using Mono.Cecil;
31 
32 namespace Mono.CodeContracts.Static.AST {
33 	sealed class CoreSystemTypes {
34 		private static CoreSystemTypes _instance;
35 
36 		private readonly ModuleDefinition Module;
37 		private Lazy<AssemblyNode> systemAssembly;
38 		private Lazy<TypeNode> typeArray;
39 		private Lazy<TypeNode> typeBoolean;
40 		private Lazy<TypeNode> typeByte;
41 		private Lazy<TypeNode> typeChar;
42 		private Lazy<TypeNode> typeDouble;
43 		private Lazy<TypeNode> typeInt16;
44 		private Lazy<TypeNode> typeInt32;
45 		private Lazy<TypeNode> typeInt64;
46 		private Lazy<TypeNode> typeIntPtr;
47 		private Lazy<TypeNode> typeObject;
48 		private Lazy<TypeNode> typeSByte;
49 		private Lazy<TypeNode> typeSingle;
50 		private Lazy<TypeNode> typeString;
51 		private Lazy<TypeNode> typeSystemType;
52 		private Lazy<TypeNode> typeUInt16;
53 		private Lazy<TypeNode> typeUInt32;
54 		private Lazy<TypeNode> typeUInt64;
55 
56 		private Lazy<TypeNode> typeUIntPtr;
57 		private Lazy<TypeNode> typeVoid;
58 
CoreSystemTypes(ModuleDefinition module)59 		public CoreSystemTypes (ModuleDefinition module)
60 		{
61 			this.Module = module;
62 
63 			InitializeLazyTypes ();
64 		}
65 
66 		public static ModuleDefinition ModuleDefinition { get; set; }
67 
68 		public static CoreSystemTypes Instance
69 		{
70 			get { return GetOrCreateInstance (ModuleDefinition); }
71 		}
72 
73 		public TypeNode TypeObject
74 		{
75 			get { return this.typeObject.Value; }
76 		}
77 
78 		public TypeNode TypeString
79 		{
80 			get { return this.typeString.Value; }
81 		}
82 
83 		public TypeNode TypeBoolean
84 		{
85 			get { return this.typeBoolean.Value; }
86 		}
87 
88 		public TypeNode TypeVoid
89 		{
90 			get { return this.typeVoid.Value; }
91 		}
92 
93 		public TypeNode TypeSByte
94 		{
95 			get { return this.typeSByte.Value; }
96 		}
97 
98 		public TypeNode TypeByte
99 		{
100 			get { return this.typeByte.Value; }
101 		}
102 
103 		public TypeNode TypeInt16
104 		{
105 			get { return this.typeInt16.Value; }
106 		}
107 
108 		public TypeNode TypeInt32
109 		{
110 			get { return this.typeInt32.Value; }
111 		}
112 
113 		public TypeNode TypeInt64
114 		{
115 			get { return this.typeInt64.Value; }
116 		}
117 
118 		public TypeNode TypeSingle
119 		{
120 			get { return this.typeSingle.Value; }
121 		}
122 
123 		public TypeNode TypeDouble
124 		{
125 			get { return this.typeDouble.Value; }
126 		}
127 
128 		public TypeNode TypeUInt16
129 		{
130 			get { return this.typeUInt16.Value; }
131 		}
132 
133 		public TypeNode TypeUInt32
134 		{
135 			get { return this.typeUInt32.Value; }
136 		}
137 
138 		public TypeNode TypeUInt64
139 		{
140 			get { return this.typeUInt64.Value; }
141 		}
142 
143 		public AssemblyNode SystemAssembly
144 		{
145 			get { return this.systemAssembly.Value; }
146 		}
147 
148 		public TypeNode TypeIntPtr
149 		{
150 			get { return this.typeIntPtr.Value; }
151 		}
152 
153 		public TypeNode TypeArray
154 		{
155 			get { return this.typeArray.Value; }
156 		}
157 
158 		public TypeNode TypeUIntPtr
159 		{
160 			get { return this.typeUIntPtr.Value; }
161 		}
162 
163 		public TypeNode TypeChar
164 		{
165 			get { return this.typeChar.Value; }
166 		}
167 
168 		public TypeNode TypeSystemType
169 		{
170 			get { return this.typeSystemType.Value; }
171 		}
172 
GetOrCreateInstance(ModuleDefinition module)173 		private static CoreSystemTypes GetOrCreateInstance (ModuleDefinition module)
174 		{
175 			if (_instance == null)
176 				_instance = new CoreSystemTypes (module);
177 
178 			return _instance;
179 		}
180 
InitializeLazyTypes()181 		private void InitializeLazyTypes ()
182 		{
183 			this.typeVoid = new Lazy<TypeNode> (() => TypeNode.Create (this.Module.Import (typeof (void))));
184 			this.typeSByte = new Lazy<TypeNode> (() => TypeNode.Create (this.Module.Import (typeof (SByte))));
185 			this.typeByte = new Lazy<TypeNode> (() => TypeNode.Create (this.Module.Import (typeof (Byte))));
186 			this.typeInt16 = new Lazy<TypeNode> (() => TypeNode.Create (this.Module.Import (typeof (Int16))));
187 			this.typeInt32 = new Lazy<TypeNode> (() => TypeNode.Create (this.Module.Import (typeof (Int32))));
188 			this.typeInt64 = new Lazy<TypeNode> (() => TypeNode.Create (this.Module.Import (typeof (Int64))));
189 			this.typeUInt16 = new Lazy<TypeNode> (() => TypeNode.Create (this.Module.Import (typeof (UInt16))));
190 			this.typeUInt32 = new Lazy<TypeNode> (() => TypeNode.Create (this.Module.Import (typeof (UInt32))));
191 			this.typeUInt64 = new Lazy<TypeNode> (() => TypeNode.Create (this.Module.Import (typeof (UInt64))));
192 			this.typeSingle = new Lazy<TypeNode> (() => TypeNode.Create (this.Module.Import (typeof (Single))));
193 			this.typeDouble = new Lazy<TypeNode> (() => TypeNode.Create (this.Module.Import (typeof (Double))));
194 			this.typeBoolean = new Lazy<TypeNode> (() => TypeNode.Create (this.Module.Import (typeof (Boolean))));
195 			this.typeObject = new Lazy<TypeNode> (() => TypeNode.Create (this.Module.Import (typeof (object))));
196 			this.typeString = new Lazy<TypeNode> (() => TypeNode.Create (this.Module.Import (typeof (string))));
197 			this.typeArray = new Lazy<TypeNode> (() => TypeNode.Create (this.Module.Import (typeof (Array))));
198 			this.typeIntPtr = new Lazy<TypeNode> (() => TypeNode.Create (this.Module.Import (typeof (IntPtr))));
199 			this.typeUIntPtr = new Lazy<TypeNode> (() => TypeNode.Create (this.Module.Import (typeof (UIntPtr))));
200 			this.typeChar = new Lazy<TypeNode> (() => TypeNode.Create (this.Module.Import (typeof (char))));
201 			this.typeSystemType = new Lazy<TypeNode> (() => TypeNode.Create (this.Module.Import (typeof (Type))));
202 
203 			this.systemAssembly = new Lazy<AssemblyNode> (() => AssemblyNode.GetSystemAssembly ());
204 		}
205 	}
206 }
207