PageRenderTime 40ms CodeModel.GetById 24ms app.highlight 11ms RepoModel.GetById 2ms app.codeStats 0ms

/Microsoft.Scripting.Core/Ast/ParameterExpression.cs

https://bitbucket.org/stefanrusek/xronos
C# | 228 lines | 129 code | 28 blank | 71 comment | 16 complexity | 7d3b5f1e559086e2f9f4daa6861bce64 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 System.Diagnostics;
 19#if CODEPLEX_40
 20using System.Dynamic.Utils;
 21#else
 22using Microsoft.Scripting.Utils;
 23#endif
 24
 25#if CODEPLEX_40
 26namespace System.Linq.Expressions {
 27#else
 28namespace Microsoft.Linq.Expressions {
 29#endif
 30
 31    /// <summary>
 32    /// Base class for specialized parameter expressions.  This version only holds onto the
 33    /// name which all subclasses need.  Specialized subclasses provide the type and by ref
 34    /// flags.
 35    /// </summary>
 36#if !SILVERLIGHT
 37    [DebuggerTypeProxy(typeof(Expression.ParameterExpressionProxy))]
 38#endif
 39    public class ParameterExpression : Expression {
 40        private readonly string _name;
 41
 42        internal ParameterExpression(string name) {
 43            _name = name;
 44        }
 45
 46        internal static ParameterExpression Make(Type type, string name, bool isByRef) {
 47            if (isByRef) {
 48                return new ByRefParameterExpression(type, name);
 49            } else {
 50                if (!type.IsEnum) {
 51                    switch (Type.GetTypeCode(type)) {
 52                        case TypeCode.Boolean: return new PrimitiveParameterExpression<Boolean>(name);
 53                        case TypeCode.Byte: return new PrimitiveParameterExpression<Byte>(name);
 54                        case TypeCode.Char: return new PrimitiveParameterExpression<Char>(name);
 55                        case TypeCode.DateTime: return new PrimitiveParameterExpression<DateTime>(name);
 56                        case TypeCode.DBNull: return new PrimitiveParameterExpression<DBNull>(name);
 57                        case TypeCode.Decimal: return new PrimitiveParameterExpression<Decimal>(name);
 58                        case TypeCode.Double: return new PrimitiveParameterExpression<Double>(name);
 59                        case TypeCode.Int16: return new PrimitiveParameterExpression<Int16>(name);
 60                        case TypeCode.Int32: return new PrimitiveParameterExpression<Int32>(name);
 61                        case TypeCode.Int64: return new PrimitiveParameterExpression<Int64>(name);
 62                        case TypeCode.Object:
 63                            // common reference types which we optimize go here.  Of course object is in
 64                            // the list, the others are driven by profiling of various workloads.  This list
 65                            // should be kept short.
 66                            if (type == typeof(object)) {
 67                                return new ParameterExpression(name);
 68                            } else if (type == typeof(Exception)) {
 69                                return new PrimitiveParameterExpression<Exception>(name);
 70                            } else if (type == typeof(object[])) {
 71                                return new PrimitiveParameterExpression<object[]>(name);
 72                            }
 73                            break;
 74                        case TypeCode.SByte: return new PrimitiveParameterExpression<SByte>(name);
 75                        case TypeCode.Single: return new PrimitiveParameterExpression<Single>(name);
 76                        case TypeCode.String: return new PrimitiveParameterExpression<String>(name);
 77                        case TypeCode.UInt16: return new PrimitiveParameterExpression<UInt16>(name);
 78                        case TypeCode.UInt32: return new PrimitiveParameterExpression<UInt32>(name);
 79                        case TypeCode.UInt64: return new PrimitiveParameterExpression<UInt64>(name);
 80                    }
 81                }
 82            }
 83
 84            return new TypedParameterExpression(type, name);
 85        }
 86
 87        /// <summary>
 88        /// Gets the static type of the expression that this <see cref="Expression" /> represents. (Inherited from <see cref="Expression"/>.)
 89        /// </summary>
 90        /// <returns>The <see cref="Type"/> that represents the static type of the expression.</returns>
 91        protected override Type TypeImpl() {
 92            return typeof(object);
 93        }
 94
 95        /// <summary>
 96        /// Returns the node type of this <see cref="Expression" />. (Inherited from <see cref="Expression" />.)
 97        /// </summary>
 98        /// <returns>The <see cref="ExpressionType"/> that represents this expression.</returns>
 99        protected override ExpressionType NodeTypeImpl() {
100            return ExpressionType.Parameter;
101        }
102
103        /// <summary>
104        /// The Name of the parameter or variable.
105        /// </summary>
106        public string Name {
107            get { return _name; }
108        }
109
110        /// <summary>
111        /// Indicates that this ParameterExpression is to be treated as a ByRef parameter.
112        /// </summary>
113        public bool IsByRef {
114            get {
115                return GetIsByRef();
116            }
117        }
118
119        internal virtual bool GetIsByRef() {
120            return false;
121        }
122
123        internal override Expression Accept(ExpressionVisitor visitor) {
124            return visitor.VisitParameter(this);
125        }
126    }
127
128    /// <summary>
129    /// Specialized subclass to avoid holding onto the byref flag in a 
130    /// parameter expression.  This version always holds onto the expression
131    /// type explicitly and therefore derives from TypedParameterExpression.
132    /// </summary>
133    internal sealed class ByRefParameterExpression : TypedParameterExpression {
134        internal ByRefParameterExpression(Type type, string name)
135            : base(type, name) {
136        }
137
138        internal override bool GetIsByRef() {
139            return true;
140        }
141    }
142
143    /// <summary>
144    /// Specialized subclass which holds onto the type of the expression for
145    /// uncommon types.
146    /// </summary>
147    internal class TypedParameterExpression : ParameterExpression {
148        private readonly Type _paramType;
149
150        internal TypedParameterExpression(Type type, string name)
151            : base(name) {
152            _paramType = type;
153        }
154
155        protected override Type TypeImpl() {
156            return _paramType;
157        }
158    }
159
160    /// <summary>
161    /// Generic type to avoid needing explicit storage for primitive data types
162    /// which are commonly used.
163    /// </summary>
164    internal sealed class PrimitiveParameterExpression<T> : ParameterExpression {
165        internal PrimitiveParameterExpression(string name)
166            : base(name) {
167        }
168
169        protected override Type TypeImpl() {
170            return typeof(T);
171        }
172    }
173
174    public partial class Expression {
175
176        /// <summary>
177        /// Creates a ParameterExpression node that can be used to identify a parameter or a variable in an expression tree.
178        /// </summary>
179        /// <param name="type">The type of the parameter or variable.</param>
180        /// <returns>A ParameterExpression node with the specified name and type.</returns>
181        public static ParameterExpression Parameter(Type type) {
182            return Parameter(type, null);
183        }
184
185        /// <summary>
186        /// Creates a ParameterExpression node that can be used to identify a parameter or a variable in an expression tree.
187        /// </summary>
188        /// <param name="type">The type of the parameter or variable.</param>
189        /// <returns>A ParameterExpression node with the specified name and type.</returns>
190        public static ParameterExpression Variable(Type type) {
191            return Variable(type, null);
192        }
193
194        /// <summary>
195        /// Creates a ParameterExpression node that can be used to identify a parameter or a variable in an expression tree.
196        /// </summary>
197        /// <param name="type">The type of the parameter or variable.</param>
198        /// <param name="name">The name of the parameter or variable, used for debugging or pretty printing purpose only.</param>
199        /// <returns>A ParameterExpression node with the specified name and type.</returns>
200        public static ParameterExpression Parameter(Type type, string name) {
201            ContractUtils.RequiresNotNull(type, "type");
202
203            if (type == typeof(void)) {
204                throw Error.ArgumentCannotBeOfTypeVoid();
205            }
206
207            bool byref = type.IsByRef;
208            if (byref) {
209                type = type.GetElementType();
210            }
211
212            return ParameterExpression.Make(type, name, byref);
213        }
214
215        /// <summary>
216        /// Creates a ParameterExpression node that can be used to identify a parameter or a variable in an expression tree.
217        /// </summary>
218        /// <param name="type">The type of the parameter or variable.</param>
219        /// <param name="name">The name of the parameter or variable, used for debugging or pretty printing purpose only.</param>
220        /// <returns>A ParameterExpression node with the specified name and type.</returns>
221        public static ParameterExpression Variable(Type type, string name) {
222            ContractUtils.RequiresNotNull(type, "type");
223            ContractUtils.Requires(type != typeof(void), "type", Strings.ArgumentCannotBeOfTypeVoid);
224            ContractUtils.Requires(!type.IsByRef, "type", Strings.TypeMustNotBeByRef);
225            return ParameterExpression.Make(type, name, false);
226        }
227    }
228}