// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. using System.Collections.Generic; using System.Linq.Expressions; using Xunit; namespace System.Web.Mvc.ExpressionUtil.Test { public class HoistingExpressionVisitorTest { [Fact] public void Hoist() { // Arrange Expression> expr = s => 2 * s.Length + 1; // Act Expression> hoisted = HoistingExpressionVisitor.Hoist(expr); // Assert // new expression should be (s, capturedConstants) => (int)(capturedConstants[0]) * s.Length + (int)(capturedConstants[1]) // with fingerprint [ LAMBDA:Hoisted, OP_ADD:int, OP_MULTIPLY:int, OP_CAST:int, INDEX(List.get_Item):object, PARAM(0):List, CONST:int, MEMBER(String.Length):int, PARAM(1):string, OP_CAST:int, INDEX(List.get_Item):object, PARAM(0):List, CONST:int, PARAM(1):string, PARAM(0):List ] List capturedConstants; ExpressionFingerprintChain fingerprint = FingerprintingExpressionVisitor.GetFingerprintChain(hoisted, out capturedConstants); Assert.Equal(new object[] { 0, 1 }, capturedConstants.ToArray()); // these are constants from the hoisted expression (array indexes), not the original expression FingerprintingExpressionVisitorTest.AssertChainEquals( fingerprint, new LambdaExpressionFingerprint(ExpressionType.Lambda, typeof(Hoisted)), new BinaryExpressionFingerprint(ExpressionType.Add, typeof(int), null /* method */), new BinaryExpressionFingerprint(ExpressionType.Multiply, typeof(int), null /* method */), new UnaryExpressionFingerprint(ExpressionType.Convert, typeof(int), null /* method */), new IndexExpressionFingerprint(ExpressionType.Index, typeof(object), typeof(List).GetProperty("Item")), new ParameterExpressionFingerprint(ExpressionType.Parameter, typeof(List), 0 /* parameterIndex */), new ConstantExpressionFingerprint(ExpressionType.Constant, typeof(int)), new MemberExpressionFingerprint(ExpressionType.MemberAccess, typeof(int), typeof(string).GetProperty("Length")), new ParameterExpressionFingerprint(ExpressionType.Parameter, typeof(string), 1 /* parameterIndex */), new UnaryExpressionFingerprint(ExpressionType.Convert, typeof(int), null /* method */), new IndexExpressionFingerprint(ExpressionType.Index, typeof(object), typeof(List).GetProperty("Item")), new ParameterExpressionFingerprint(ExpressionType.Parameter, typeof(List), 0 /* parameterIndex */), new ConstantExpressionFingerprint(ExpressionType.Constant, typeof(int)), new ParameterExpressionFingerprint(ExpressionType.Parameter, typeof(string), 1 /* parameterIndex */), new ParameterExpressionFingerprint(ExpressionType.Parameter, typeof(List), 0 /* parameterIndex */)); } } }