PageRenderTime 53ms CodeModel.GetById 45ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/IronPython_2_0/Src/Microsoft.Scripting.Core/Ast/ConstantExpression.cs

#
C# | 167 lines | 125 code | 21 blank | 21 comment | 29 complexity | c1d2d224920090aaa6b612a028ee6d42 MD5 | raw file
  1/* ****************************************************************************
  2 *
  3 * Copyright (c) Microsoft Corporation. 
  4 *
  5 * This source code is subject to terms and conditions of the Microsoft Public License. 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  Microsoft Public License, 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 Microsoft Public License.
 10 *
 11 * You must not remove this notice, or any other, from this software.
 12 *
 13 *
 14 * ***************************************************************************/
 15using System; using Microsoft;
 16
 17
 18using Microsoft.Scripting.Utils;
 19using System.Text;
 20using Microsoft.Scripting;
 21
 22namespace Microsoft.Linq.Expressions {
 23    //CONFORMING
 24    public sealed class ConstantExpression : Expression {
 25        internal static readonly ConstantExpression TrueLiteral = new ConstantExpression(null, true, typeof(bool));
 26        internal static readonly ConstantExpression FalseLiteral = new ConstantExpression(null, false, typeof(bool));
 27        internal static readonly ConstantExpression ZeroLiteral = new ConstantExpression(null, 0, typeof(int));
 28        internal static readonly ConstantExpression NullLiteral = new ConstantExpression(null, null, typeof(object));
 29        internal static readonly ConstantExpression EmptyStringLiteral = new ConstantExpression(null, String.Empty, typeof(string));
 30        internal static readonly ConstantExpression[] IntCache = new ConstantExpression[100];
 31
 32        private readonly object _value;
 33
 34        internal ConstantExpression(Annotations annotations, object value, Type type)
 35            : base(ExpressionType.Constant, type, annotations) {
 36            _value = value;
 37        }
 38
 39        public object Value {
 40            get { return _value; }
 41        }
 42        internal override void BuildString(StringBuilder builder) {
 43            ContractUtils.RequiresNotNull(builder, "builder");
 44
 45            if (_value != null) {
 46                if (_value is string) {
 47                    builder.Append("\"");
 48                    builder.Append(_value);
 49                    builder.Append("\"");
 50                } else if (_value.ToString() == _value.GetType().ToString()) {
 51                    builder.Append("value(");
 52                    builder.Append(_value);
 53                    builder.Append(")");
 54                } else {
 55                    builder.Append(_value);
 56                }
 57            } else {
 58                builder.Append("null");
 59            }
 60        }
 61
 62        internal override Expression Accept(ExpressionTreeVisitor visitor) {
 63            return visitor.VisitConstant(this);
 64        }
 65    }
 66
 67    public partial class Expression {
 68        public static ConstantExpression True() {
 69            return ConstantExpression.TrueLiteral;
 70        }
 71
 72        public static ConstantExpression False() {
 73            return ConstantExpression.FalseLiteral;
 74        }
 75
 76        public static ConstantExpression Zero() {
 77            return ConstantExpression.ZeroLiteral;
 78        }
 79
 80        public static ConstantExpression Null() {
 81            return ConstantExpression.NullLiteral;
 82        }
 83
 84        public static ConstantExpression Null(Type type) {
 85            ContractUtils.RequiresNotNull(type, "type");
 86            if (type.IsValueType && !TypeUtils.IsNullableType(type)) {
 87                throw Error.ArgumentTypesMustMatch();
 88            }
 89            return new ConstantExpression(Annotations.Empty, null, type);
 90        }
 91        
 92        //CONFORMING
 93        public static ConstantExpression Constant(object value) {
 94            if (value == null) {
 95                return Null();
 96            }
 97
 98            Type t = value.GetType();
 99            if (!t.IsEnum) {
100                switch (Type.GetTypeCode(t)) {
101                    case TypeCode.Boolean:
102                        if ((bool)value == true) {
103                            return True();
104                        }
105                        return False();
106                    case TypeCode.Int32:
107                        int x = (int)value;
108                        int cacheIndex = x + 2;
109                        if (cacheIndex >= 0 && cacheIndex < ConstantExpression.IntCache.Length) {
110                            ConstantExpression res;
111                            if ((res = ConstantExpression.IntCache[cacheIndex]) == null) {
112                                ConstantExpression.IntCache[cacheIndex] = res = new ConstantExpression(null, x, typeof(int));
113                            }
114                            return res;
115                        }
116                        break;
117                    case TypeCode.String:
118                        if (String.IsNullOrEmpty((string)value)) {
119                            return ConstantExpression.EmptyStringLiteral;
120                        }
121                        break;
122                }
123            }
124
125            return new ConstantExpression(Annotations.Empty, value, value == null ? typeof(object) : value.GetType());
126        }
127
128        public static ConstantExpression Constant(object value, Type type) {
129            return Constant(value, type, Annotations.Empty);
130        }
131
132        //CONFORMING
133        public static ConstantExpression Constant(object value, Type type, Annotations annotations) {
134            ContractUtils.RequiresNotNull(type, "type");
135            if (value == null && type.IsValueType && !TypeUtils.IsNullableType(type)) {
136                throw Error.ArgumentTypesMustMatch();
137            }
138            if (value != null && !TypeUtils.AreAssignable(type, value.GetType())) {
139                throw Error.ArgumentTypesMustMatch();
140            }
141            return new ConstantExpression(annotations, value, type);
142        }
143
144        [Obsolete("use Expression.Constant instead")]
145        public static ConstantExpression RuntimeConstant(object value) {
146            return Constant(value);
147        }
148
149        [Obsolete("use Expression.Constant instead")]
150        public static ConstantExpression RuntimeConstant(object value, Type type) {
151            return Constant(value, type);
152        }
153
154        /// <summary>
155        /// Wraps the given value in a WeakReference and returns a tree that will retrieve
156        /// the value from the WeakReference.
157        /// </summary>
158        [Obsolete("use Utils.WeakConstant in Microsoft.Scripting instead")]
159        public static MemberExpression WeakConstant(object value) {
160            System.Diagnostics.Debug.Assert(!(value is Expression));
161            return Expression.Property(
162                Expression.Constant(new WeakReference(value)),
163                typeof(WeakReference).GetProperty("Target")
164            );
165        }
166    }
167}