/// <summary> /// Decodes the parameter expression. /// </summary> /// <param name="expression">The expression to be decoded.</param> /// <param name="state">The current state of the decode operation.</param> /// <param name="options">The options for the decode operation.</param> /// <returns>An <see cref="Expression"/> object.</returns> internal static Expression DecodeParameterExpression(EncodedExpression expression, DecodeState state, DecodeOptions options) { return(state.GetOrAddParameter(expression)); }
/// <summary> /// Decodes the method call expression. /// </summary> /// <param name="expression">The expression to be decoded.</param> /// <param name="state">The current state of the decode operation.</param> /// <param name="options">The options for the decode operation.</param> /// <returns>An <see cref="Expression"/> object.</returns> internal static Expression DecodeMethodCallExpression(EncodedExpression expression, DecodeState state, DecodeOptions options) { var arguments = new List <Expression>(); Expression objectExpression = null; if (expression.Expressions["Object"] != null) { objectExpression = DecodeExpression(expression.Expressions["Object"], state, options); } int argumentCount = Convert.ToInt32(expression.Values["ArgumentCount"]); for (int i = 0; i < argumentCount; i++) { arguments.Add(DecodeExpression(expression.Expressions[$"a{i}"], state, options)); } var methodInfo = state.SignatureHelper.GetMethodInfoFromSignature(expression.Values["Method"]); if (methodInfo == null) { throw new MethodNotFoundException("A matching method was not found."); } if (!options.IsMethodSafe(methodInfo)) { throw new UnsafeMethodCallException("Attempted to decode an unsafe method call.", methodInfo); } return(Expression.Call(objectExpression, methodInfo, arguments)); }
/// <summary> /// Decodes the lambda expression. /// </summary> /// <param name="expression">The expression to be decoded.</param> /// <param name="state">The current state of the decode operation.</param> /// <param name="options">The options for the decode operation.</param> /// <returns>An <see cref="Expression"/> object.</returns> internal static Expression DecodeLambdaExpression(EncodedExpression expression, DecodeState state, DecodeOptions options) { var body = DecodeExpression(expression.Expressions["Body"], state, options); var parameterCount = Convert.ToInt32(expression.Values["ParameterCount"]); var parameters = new List <ParameterExpression>(); for (int i = 0; i < parameterCount; i++) { parameters.Add(( ParameterExpression )DecodeExpression(expression.Expressions[$"p{i}"], state, options)); } return(Expression.Lambda(body, parameters.ToArray())); }
/// <summary> /// Decodes the member expression. /// </summary> /// <param name="expression">The expression to be decoded.</param> /// <param name="state">The current state of the decode operation.</param> /// <param name="options">The options for the decode operation.</param> /// <returns>An <see cref="Expression"/> object.</returns> internal static Expression DecodeMemberExpression(EncodedExpression expression, DecodeState state, DecodeOptions options) { MemberInfo memberInfo; Type type = state.SignatureHelper.GetTypeFromSignature(expression.Values["Type"]); if (bool.Parse(expression.Values["IsProperty"])) { memberInfo = type.GetProperty(expression.Values["Member"]); } else { memberInfo = type.GetField(expression.Values["Member"]); } var expr = DecodeExpression(expression.Expressions["Expression"], state, options); return(Expression.MakeMemberAccess(expr, memberInfo)); }
/// <summary> /// Decodes the constant expression. /// </summary> /// <param name="expression">The expression to be decoded.</param> /// <param name="state">The current state of the decode operation.</param> /// <param name="options">The options for the decode operation.</param> /// <returns>An <see cref="Expression"/> object.</returns> internal static Expression DecodeConstantExpression(EncodedExpression expression, DecodeState state, DecodeOptions options) { var type = state.SignatureHelper.GetTypeFromSignature(expression.Values["Type"]); var Value = expression.Values["Value"]; return(Expression.Constant(Convert.ChangeType(Value, type))); }
/// <summary> /// Decodes the unary expression. /// </summary> /// <param name="expression">The expression to be decoded.</param> /// <param name="state">The current state of the decode operation.</param> /// <param name="options">The options for the decode operation.</param> /// <returns>An <see cref="Expression"/> object.</returns> internal static Expression DecodeUnaryExpression(EncodedExpression expression, DecodeState state, DecodeOptions options) { var operand = DecodeExpression(expression.Expressions["Operand"], state, options); var type = state.SignatureHelper.GetTypeFromSignature(expression.Values["Type"]); return(Expression.MakeUnary(expression.NodeType, operand, type)); }
/// <summary> /// Decodes the binary expression. /// </summary> /// <param name="expression">The expression to be decoded.</param> /// <param name="state">The current state of the decode operation.</param> /// <param name="options">The options for the decode operation.</param> /// <returns>An <see cref="Expression"/> object.</returns> internal static Expression DecodeBinaryExpression(EncodedExpression expression, DecodeState state, DecodeOptions options) { var left = DecodeExpression(expression.Expressions["Left"], state, options); var right = DecodeExpression(expression.Expressions["Right"], state, options); if (expression.Expressions["Conversion"] == null) { return(Expression.MakeBinary(expression.NodeType, left, right)); } else { var conversion = ( LambdaExpression )DecodeExpression(expression.Expressions["Conversion"], state, options); return(Expression.MakeBinary(expression.NodeType, left, right, false, null, conversion)); } }
/// <summary> /// Decodes the expression back into a LINQ expression. /// </summary> /// <param name="expression">The encoded expression to be decoded.</param> /// <param name="state">The state of the decode operation.</param> /// <param name="options">The options that will be used during decoding.</param> /// <returns>A LINQ <see cref="Expression"/> instance.</returns> internal static Expression DecodeExpression(EncodedExpression expression, DecodeState state, DecodeOptions options) { if (!ExpressionTypeMapping.ContainsKey(expression.NodeType)) { throw new ArgumentException($"Encountered unknown node type {expression.NodeType} when decoding expression.", nameof(expression)); } return(ExpressionTypeMapping[expression.NodeType].Decode(expression, state, options)); }
/// <summary> /// Decodes the expression back into a LINQ expression. /// </summary> /// <param name="expression">The encoded expression to be decoded.</param> /// <param name="options">The options that will be used during decoding.</param> /// <returns>A LINQ <see cref="Expression"/> instance.</returns> public static Expression DecodeExpression(EncodedExpression expression, DecodeOptions options) { return(DecodeExpression(expression, new DecodeState(), options)); }