1 #pragma warning disable 659 // overrides AddToHashCodeCombiner instead
\r
3 /* ****************************************************************************
\r
5 * Copyright (c) Microsoft Corporation. All rights reserved.
\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
11 * You must not remove this notice, or any other, from this software.
\r
13 * ***************************************************************************/
\r
15 namespace System.Web.Mvc.ExpressionUtil {
\r
17 using System.Diagnostics.CodeAnalysis;
\r
18 using System.Linq.Expressions;
\r
20 // ConstantExpression fingerprint class
\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
30 private ConstantExpressionFingerprint(ConstantExpression expression)
\r
31 : base(expression) {
\r
34 public int HoistedLocalsIndex {
\r
39 internal override void AddToHashCodeCombiner(HashCodeCombiner combiner) {
\r
40 base.AddToHashCodeCombiner(combiner);
\r
42 combiner.AddInt32(HoistedLocalsIndex);
\r
45 public static ConstantExpressionFingerprint Create(ConstantExpression expression, ParserContext parserContext) {
\r
46 ConstantExpressionFingerprint fingerprint = new ConstantExpressionFingerprint(expression) {
\r
47 HoistedLocalsIndex = parserContext.HoistedValues.Count
\r
50 parserContext.HoistedValues.Add(expression.Value);
\r
54 public override bool Equals(object obj) {
\r
55 ConstantExpressionFingerprint other = obj as ConstantExpressionFingerprint;
\r
56 if (other == null) {
\r
60 return (this.HoistedLocalsIndex == other.HoistedLocalsIndex
\r
61 && base.Equals(other));
\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