Update PointConverter.cs
[mono.git] / mcs / class / System.ServiceModel / Mono.CodeGeneration / CodeLiteral.cs
1 //
2 // Permission is hereby granted, free of charge, to any person obtaining
3 // a copy of this software and associated documentation files (the
4 // "Software"), to deal in the Software without restriction, including
5 // without limitation the rights to use, copy, modify, merge, publish,
6 // distribute, sublicense, and/or sell copies of the Software, and to
7 // permit persons to whom the Software is furnished to do so, subject to
8 // the following conditions:
9 // 
10 // The above copyright notice and this permission notice shall be
11 // included in all copies or substantial portions of the Software.
12 // 
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
17 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
18 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
19 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 //
21 // Copyright (C) Lluis Sanchez Gual, 2004
22 //
23
24 #if !MONOTOUCH
25 using System;
26 using System.Globalization;
27 using System.Reflection;
28 using System.Reflection.Emit;
29
30 namespace Mono.CodeGeneration
31 {
32         public class CodeLiteral: CodeExpression
33         {
34                 object value;
35                 Type type;
36                 
37                 public CodeLiteral (object value)
38                 {
39                         this.value = value;
40                         if (value != null) type = value.GetType ();
41                         else type = typeof(object);
42                 }
43                         
44                 public CodeLiteral (object value, Type type)
45                 {
46                         this.value = value;
47                         this.type = type;
48                 }
49
50                 public object Value {
51                         get { return value; }
52                 }
53
54                 public override void Generate (ILGenerator gen)
55                 {
56                         object value = this.value;
57                         
58                         if (value == null)
59                         {
60                                 gen.Emit (OpCodes.Ldnull);
61                                 return;
62                         }
63                         
64                         if (value is Enum)
65                                 value = Convert.ChangeType (value, (value.GetType().UnderlyingSystemType), CultureInfo.InvariantCulture);
66                         
67                         if (value is Type) {
68                                 gen.Emit (OpCodes.Ldtoken, (Type)value);
69                                 gen.Emit (OpCodes.Call, typeof(Type).GetMethod ("GetTypeFromHandle"));
70                                 return;
71                         }
72                         
73                         switch (Type.GetTypeCode (type))
74                         {
75                                 case TypeCode.String:
76                                         gen.Emit (OpCodes.Ldstr, (string)value);
77                                         break;
78                                         
79                                 case TypeCode.Byte:
80                                 case TypeCode.SByte:
81                                 case TypeCode.Int16:
82                                 case TypeCode.UInt16:
83                                 case TypeCode.Int32:
84                                 case TypeCode.UInt32:
85                                         int i = (int)value;
86                                         switch (i)
87                                         {
88                                                 case 0: gen.Emit (OpCodes.Ldc_I4_0); break;
89                                                 case 1: gen.Emit (OpCodes.Ldc_I4_1); break;
90                                                 case 2: gen.Emit (OpCodes.Ldc_I4_2); break;
91                                                 case 3: gen.Emit (OpCodes.Ldc_I4_3); break;
92                                                 case 4: gen.Emit (OpCodes.Ldc_I4_4); break;
93                                                 case 5: gen.Emit (OpCodes.Ldc_I4_5); break;
94                                                 case 6: gen.Emit (OpCodes.Ldc_I4_6); break;
95                                                 case 7: gen.Emit (OpCodes.Ldc_I4_7); break;
96                                                 case 8: gen.Emit (OpCodes.Ldc_I4_8); break;
97                                                 case -1: gen.Emit (OpCodes.Ldc_I4_M1); break;
98                                                 default: gen.Emit (OpCodes.Ldc_I4, i); break;
99                                         }
100                                         break;
101                                         
102                                 case TypeCode.Int64:
103                                 case TypeCode.UInt64:
104                                         gen.Emit (OpCodes.Ldc_I8, (long)value);
105                                         break;
106                                         
107                                 case TypeCode.Single:
108                                         gen.Emit (OpCodes.Ldc_R4, (float)value);
109                                         break;
110                                         
111                                 case TypeCode.Double:
112                                         gen.Emit (OpCodes.Ldc_R8, (double)value);
113                                         break;
114                                         
115                                 case TypeCode.Boolean:
116                                         if ((bool)value)
117                                                 gen.Emit (OpCodes.Ldc_I4_1);
118                                         else
119                                                 gen.Emit (OpCodes.Ldc_I4_0);
120                                         break;
121                                         
122                                 default:
123                                         throw new InvalidOperationException ("Literal type " + value.GetType() + " not supported");
124                         }
125                 }
126                 
127                 public override void PrintCode (CodeWriter cp)
128                 {
129                         if (value is string)
130                                 cp.Write ("\"").Write (value.ToString ()).Write ("\"");
131                         else if (value == null)
132                                 cp.Write ("null");
133                         else if (value is Type)
134                                 cp.Write ("typeof(" + ((Type)value).Name + ")");
135                         else if (value is Enum)
136                                 cp.Write (value.GetType().Name + "." + value);
137                         else
138                                 cp.Write (value.ToString ());
139                 }
140                 
141                 public override Type GetResultType ()
142                 {
143                         return type;
144                 }
145         }
146 }
147 #endif