Merge pull request #347 from JamesB7/master
[mono.git] / mcs / class / dlr / Runtime / Microsoft.Scripting.Core / Ast / ConstantExpression.cs
1 /* ****************************************************************************
2  *
3  * Copyright (c) Microsoft Corporation. 
4  *
5  * This source code is subject to terms and conditions of the Apache License, Version 2.0. A 
6  * copy of the license can be found in the License.html file at the root of this distribution. If 
7  * you cannot locate the  Apache License, Version 2.0, please send an email to 
8  * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
9  * by the terms of the Apache License, Version 2.0.
10  *
11  * You must not remove this notice, or any other, from this software.
12  *
13  *
14  * ***************************************************************************/
15
16 using System;
17 using System.Diagnostics;
18 using System.Dynamic.Utils;
19
20 #if SILVERLIGHT
21 using System.Core;
22 #endif
23
24 #if !FEATURE_CORE_DLR
25 namespace Microsoft.Scripting.Ast {
26 #else
27 namespace System.Linq.Expressions {
28 #endif
29
30     /// <summary>
31     /// Represents an expression that has a constant value.
32     /// </summary>
33     [DebuggerTypeProxy(typeof(Expression.ConstantExpressionProxy))]
34     public class ConstantExpression : Expression {
35         // Possible optimization: we could have a Constant<T> subclass that
36         // stores the unboxed value.
37         private readonly object _value;
38
39         internal ConstantExpression(object value) {
40             _value = value;
41         }
42
43         internal static ConstantExpression Make(object value, Type type) {
44             if ((value == null && type == typeof(object)) || (value != null && value.GetType() == type)) {
45                 return new ConstantExpression(value);
46             } else {
47                 return new TypedConstantExpression(value, type);
48             }
49         }
50
51         /// <summary>
52         /// Gets the static type of the expression that this <see cref="Expression" /> represents.
53         /// </summary>
54         /// <returns>The <see cref="Type"/> that represents the static type of the expression.</returns>
55         public override Type Type {
56             get {
57                 if (_value == null) {
58                     return typeof(object);
59                 }
60                 return _value.GetType();
61             }
62         }
63
64         /// <summary>
65         /// Returns the node type of this Expression. Extension nodes should return
66         /// ExpressionType.Extension when overriding this method.
67         /// </summary>
68         /// <returns>The <see cref="ExpressionType"/> of the expression.</returns>
69         public sealed override ExpressionType NodeType {
70             get { return ExpressionType.Constant; }
71         }
72         /// <summary>
73         /// Gets the value of the constant expression.
74         /// </summary>
75         public object Value {
76             get { return _value; }
77         }
78
79         /// <summary>
80         /// Dispatches to the specific visit method for this node type.
81         /// </summary>
82         protected internal override Expression Accept(ExpressionVisitor visitor) {
83             return visitor.VisitConstant(this);
84         }
85     }
86
87     internal class TypedConstantExpression : ConstantExpression {
88         private readonly Type _type;
89
90         internal TypedConstantExpression(object value, Type type)
91             : base(value) {
92             _type = type;
93         }
94
95         public sealed override Type Type {
96             get { return _type; }
97         }
98     }
99
100     public partial class Expression {
101         /// <summary>
102         /// Creates a <see cref="ConstantExpression"/> that has the <see cref="P:ConstantExpression.Value"/> property set to the specified value. .
103         /// </summary>
104         /// <param name="value">An <see cref="System.Object"/> to set the <see cref="P:ConstantExpression.Value"/> property equal to.</param>
105         /// <returns>
106         /// A <see cref="ConstantExpression"/> that has the <see cref="P:Expression.NodeType"/> property equal to 
107         /// <see cref="F:ExpressionType.Constant"/> and the <see cref="P:Expression.Value"/> property set to the specified value.
108         /// </returns>
109         public static ConstantExpression Constant(object value) {
110             return ConstantExpression.Make(value, value == null ? typeof(object) : value.GetType());
111         }
112
113
114         /// <summary>
115         /// Creates a <see cref="ConstantExpression"/> that has the <see cref="P:ConstantExpression.Value"/> 
116         /// and <see cref="P:ConstantExpression.Type"/> properties set to the specified values. .
117         /// </summary>
118         /// <param name="value">An <see cref="System.Object"/> to set the <see cref="P:ConstantExpression.Value"/> property equal to.</param>
119         /// <param name="type">A <see cref="System.Type"/> to set the <see cref="P:Expression.Type"/> property equal to.</param>
120         /// <returns>
121         /// A <see cref="ConstantExpression"/> that has the <see cref="P:Expression.NodeType"/> property equal to 
122         /// <see cref="F:ExpressionType.Constant"/> and the <see cref="P:ConstantExpression.Value"/> and 
123         /// <see cref="P:Expression.Type"/> properties set to the specified values.
124         /// </returns>
125         public static ConstantExpression Constant(object value, Type type) {
126             ContractUtils.RequiresNotNull(type, "type");
127             if (value == null && type.IsValueType && !TypeUtils.IsNullableType(type)) {
128                 throw Error.ArgumentTypesMustMatch();
129             }
130             if (value != null && !type.IsAssignableFrom(value.GetType())) {
131                 throw Error.ArgumentTypesMustMatch();
132             }
133             return ConstantExpression.Make(value, type);
134         }
135     }
136 }