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