Merge pull request #249 from pcc/xgetinputfocus
[mono.git] / mcs / mcs / literal.cs
1 //
2 // literal.cs: Literal representation for the IL tree.
3 //
4 // Author:
5 //   Miguel de Icaza (miguel@ximian.com)
6 //   Marek Safar (marek.safar@seznam.cz)
7 //
8 // Copyright 2001 Ximian, Inc.
9 // Copyright 2011 Xamarin Inc
10 //
11 //
12 // Notice that during parsing we create objects of type Literal, but the
13 // types are not loaded (thats why the Resolve method has to assign the
14 // type at that point).
15 //
16 // Literals differ from the constants in that we know we encountered them
17 // as a literal in the source code (and some extra rules apply there) and
18 // they have to be resolved (since during parsing we have not loaded the
19 // types yet) while constants are created only after types have been loaded
20 // and are fully resolved when born.
21 //
22
23 #if STATIC
24 using IKVM.Reflection.Emit;
25 #else
26 using System.Reflection.Emit;
27 #endif
28
29 namespace Mono.CSharp
30 {
31         public interface ILiteralConstant
32         {
33 #if FULL_AST
34                 char[] ParsedValue { get; set; }
35 #endif
36         }
37
38         //
39         // The null literal
40         //
41         // Note: C# specification null-literal is NullLiteral of NullType type
42         //
43         public class NullLiteral : NullConstant
44         {
45                 //
46                 // Default type of null is an object
47                 //
48                 public NullLiteral (Location loc)
49                         : base (InternalType.NullLiteral, loc)
50                 {
51                 }
52
53                 public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec t, bool expl)
54                 {
55                         if (t.IsGenericParameter) {
56                                 ec.Report.Error(403, loc,
57                                         "Cannot convert null to the type parameter `{0}' because it could be a value " +
58                                         "type. Consider using `default ({0})' instead", t.Name);
59                                 return;
60                         }
61
62                         if (TypeSpec.IsValueType (t)) {
63                                 ec.Report.Error(37, loc, "Cannot convert null to `{0}' because it is a value type",
64                                         TypeManager.CSharpName(t));
65                                 return;
66                         }
67
68                         base.Error_ValueCannotBeConverted (ec, t, expl);
69                 }
70
71                 public override string GetValueAsLiteral ()
72                 {
73                         return "null";
74                 }
75
76                 public override bool IsLiteral {
77                         get { return true; }
78                 }
79
80                 public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx)
81                 {
82                         return System.Linq.Expressions.Expression.Constant (null);
83                 }
84         }
85
86         public class BoolLiteral : BoolConstant, ILiteralConstant
87         {
88                 public BoolLiteral (BuiltinTypes types, bool val, Location loc)
89                         : base (types, val, loc)
90                 {
91                 }
92
93                 public override bool IsLiteral {
94                         get { return true; }
95                 }
96
97 #if FULL_AST
98                 public char[] ParsedValue { get; set; }
99 #endif
100
101                 public override object Accept (StructuralVisitor visitor)
102                 {
103                         return visitor.Visit (this);
104                 }
105         }
106
107         public class CharLiteral : CharConstant, ILiteralConstant
108         {
109                 public CharLiteral (BuiltinTypes types, char c, Location loc)
110                         : base (types, c, loc)
111                 {
112                 }
113
114                 public override bool IsLiteral {
115                         get { return true; }
116                 }
117
118 #if FULL_AST
119                 public char[] ParsedValue { get; set; }
120 #endif
121
122                 public override object Accept (StructuralVisitor visitor)
123                 {
124                         return visitor.Visit (this);
125                 }
126         }
127
128         public class IntLiteral : IntConstant, ILiteralConstant
129         {
130                 public IntLiteral (BuiltinTypes types, int l, Location loc)
131                         : base (types, l, loc)
132                 {
133                 }
134
135                 public override Constant ConvertImplicitly (TypeSpec type)
136                 {
137                         //
138                         // The 0 literal can be converted to an enum value
139                         //
140                         if (Value == 0 && type.IsEnum) {
141                                 Constant c = ConvertImplicitly (EnumSpec.GetUnderlyingType (type));
142                                 if (c == null)
143                                         return null;
144
145                                 return new EnumConstant (c, type);
146                         }
147
148                         return base.ConvertImplicitly (type);
149                 }
150
151                 public override bool IsLiteral {
152                         get { return true; }
153                 }
154
155 #if FULL_AST
156                 public char[] ParsedValue { get; set; }
157 #endif
158
159                 public override object Accept (StructuralVisitor visitor)
160                 {
161                         return visitor.Visit (this);
162                 }
163         }
164
165         public class UIntLiteral : UIntConstant, ILiteralConstant
166         {
167                 public UIntLiteral (BuiltinTypes types, uint l, Location loc)
168                         : base (types, l, loc)
169                 {
170                 }
171
172                 public override bool IsLiteral {
173                         get { return true; }
174                 }
175
176 #if FULL_AST
177                 public char[] ParsedValue { get; set; }
178 #endif
179
180                 public override object Accept (StructuralVisitor visitor)
181                 {
182                         return visitor.Visit (this);
183                 }
184         }
185
186         public class LongLiteral : LongConstant, ILiteralConstant
187         {
188                 public LongLiteral (BuiltinTypes types, long l, Location loc)
189                         : base (types, l, loc)
190                 {
191                 }
192
193                 public override bool IsLiteral {
194                         get { return true; }
195                 }
196
197 #if FULL_AST
198                 public char[] ParsedValue { get; set; }
199 #endif
200
201                 public override object Accept (StructuralVisitor visitor)
202                 {
203                         return visitor.Visit (this);
204                 }
205         }
206
207         public class ULongLiteral : ULongConstant, ILiteralConstant
208         {
209                 public ULongLiteral (BuiltinTypes types, ulong l, Location loc)
210                         : base (types, l, loc)
211                 {
212                 }
213
214                 public override bool IsLiteral {
215                         get { return true; }
216                 }
217
218 #if FULL_AST
219                 public char[] ParsedValue { get; set; }
220 #endif
221
222                 public override object Accept (StructuralVisitor visitor)
223                 {
224                         return visitor.Visit (this);
225                 }
226         }
227
228         public class FloatLiteral : FloatConstant, ILiteralConstant
229         {
230                 public FloatLiteral (BuiltinTypes types, float f, Location loc)
231                         : base (types, f, loc)
232                 {
233                 }
234
235                 public override bool IsLiteral {
236                         get { return true; }
237                 }
238
239 #if FULL_AST
240                 public char[] ParsedValue { get; set; }
241 #endif
242
243                 public override object Accept (StructuralVisitor visitor)
244                 {
245                         return visitor.Visit (this);
246                 }
247         }
248
249         public class DoubleLiteral : DoubleConstant, ILiteralConstant
250         {
251                 public DoubleLiteral (BuiltinTypes types, double d, Location loc)
252                         : base (types, d, loc)
253                 {
254                 }
255
256                 public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
257                 {
258                         if (target.BuiltinType == BuiltinTypeSpec.Type.Float) {
259                                 Error_664 (ec, loc, "float", "f");
260                                 return;
261                         }
262
263                         if (target.BuiltinType == BuiltinTypeSpec.Type.Decimal) {
264                                 Error_664 (ec, loc, "decimal", "m");
265                                 return;
266                         }
267
268                         base.Error_ValueCannotBeConverted (ec, target, expl);
269                 }
270
271                 static void Error_664 (ResolveContext ec, Location loc, string type, string suffix)
272                 {
273                         ec.Report.Error (664, loc,
274                                 "Literal of type double cannot be implicitly converted to type `{0}'. Add suffix `{1}' to create a literal of this type",
275                                 type, suffix);
276                 }
277
278                 public override bool IsLiteral {
279                         get { return true; }
280                 }
281
282 #if FULL_AST
283                 public char[] ParsedValue { get; set; }
284 #endif
285
286                 public override object Accept (StructuralVisitor visitor)
287                 {
288                         return visitor.Visit (this);
289                 }
290         }
291
292         public class DecimalLiteral : DecimalConstant, ILiteralConstant
293         {
294                 public DecimalLiteral (BuiltinTypes types, decimal d, Location loc)
295                         : base (types, d, loc)
296                 {
297                 }
298
299                 public override bool IsLiteral {
300                         get { return true; }
301                 }
302
303 #if FULL_AST
304                 public char[] ParsedValue { get; set; }
305 #endif
306
307                 public override object Accept (StructuralVisitor visitor)
308                 {
309                         return visitor.Visit (this);
310                 }
311         }
312
313         public class StringLiteral : StringConstant, ILiteralConstant
314         {
315                 public StringLiteral (BuiltinTypes types, string s, Location loc)
316                         : base (types, s, loc)
317                 {
318                 }
319
320                 public override bool IsLiteral {
321                         get { return true; }
322                 }
323
324 #if FULL_AST
325                 public char[] ParsedValue { get; set; }
326 #endif
327
328                 public override object Accept (StructuralVisitor visitor)
329                 {
330                         return visitor.Visit (this);
331                 }
332         }
333 }