New test.
[mono.git] / mcs / class / System.Web.Mvc2 / System.Web.Mvc / ExpressionUtil / ConstantExpressionFingerprint.cs
1 #pragma warning disable 659 // overrides AddToHashCodeCombiner instead\r
2 \r
3 /* ****************************************************************************\r
4  *\r
5  * Copyright (c) Microsoft Corporation. All rights reserved.\r
6  *\r
7  * This software is subject to the Microsoft Public License (Ms-PL). \r
8  * A copy of the license can be found in the license.htm file included \r
9  * in this distribution.\r
10  *\r
11  * You must not remove this notice, or any other, from this software.\r
12  *\r
13  * ***************************************************************************/\r
14 \r
15 namespace System.Web.Mvc.ExpressionUtil {\r
16     using System;\r
17     using System.Diagnostics.CodeAnalysis;\r
18     using System.Linq.Expressions;\r
19 \r
20     // ConstantExpression fingerprint class\r
21     //\r
22     // A ConstantExpression might represent a captured local variable, so we can't compile\r
23     // the value directly into the cached function. Instead, a placeholder is generated\r
24     // and the value is hoisted into a local variables array. This placeholder can then\r
25     // be compiled and cached, and the array lookup happens at runtime.\r
26     [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals",\r
27         Justification = "Overrides AddToHashCodeCombiner() instead.")]\r
28     internal sealed class ConstantExpressionFingerprint : ExpressionFingerprint {\r
29 \r
30         private ConstantExpressionFingerprint(ConstantExpression expression)\r
31             : base(expression) {\r
32         }\r
33 \r
34         public int HoistedLocalsIndex {\r
35             get;\r
36             private set;\r
37         }\r
38 \r
39         internal override void AddToHashCodeCombiner(HashCodeCombiner combiner) {\r
40             base.AddToHashCodeCombiner(combiner);\r
41 \r
42             combiner.AddInt32(HoistedLocalsIndex);\r
43         }\r
44 \r
45         public static ConstantExpressionFingerprint Create(ConstantExpression expression, ParserContext parserContext) {\r
46             ConstantExpressionFingerprint fingerprint = new ConstantExpressionFingerprint(expression) {\r
47                 HoistedLocalsIndex = parserContext.HoistedValues.Count\r
48             };\r
49 \r
50             parserContext.HoistedValues.Add(expression.Value);\r
51             return fingerprint;\r
52         }\r
53 \r
54         public override bool Equals(object obj) {\r
55             ConstantExpressionFingerprint other = obj as ConstantExpressionFingerprint;\r
56             if (other == null) {\r
57                 return false;\r
58             }\r
59 \r
60             return (this.HoistedLocalsIndex == other.HoistedLocalsIndex\r
61                 && base.Equals(other));\r
62         }\r
63 \r
64         public override Expression ToExpression(ParserContext parserContext) {\r
65             // (Type) HoistedValues[HoistedLocalsIndex]\r
66             BinaryExpression arrayIndex = Expression.ArrayIndex(ParserContext.HoistedValuesParameter, Expression.Constant(HoistedLocalsIndex));\r
67             UnaryExpression castExpr = Expression.Convert(arrayIndex, Type);\r
68             return castExpr;\r
69         }\r
70 \r
71     }\r
72 }\r