public override ExpressionNode VisitFunctionInvocationExpression(FunctionInvocationExpression expression) { _writer.WriteIdentifier(expression.Name); if (expression.HasAsteriskModifier) { _writer.Write("(*)"); } else { _writer.Write("("); for (int i = 0; i < expression.Arguments.Length; i++) { if (i > 0) { _writer.Write(","); } Visit(expression.Arguments[i]); } _writer.Write(")"); } return(expression); }
public virtual ExpressionNode VisitFunctionInvocationExpression(FunctionInvocationExpression expression) { for (int i = 0; i < expression.Arguments.Length; i++) { expression.Arguments[i] = VisitExpression(expression.Arguments[i]); } return(expression); }
public override AstElement Clone(Dictionary<AstElement, AstElement> alreadyClonedElements) { FunctionInvocationExpression result = new FunctionInvocationExpression(); result.Name = _name; result.NameSourceRange = _nameSourceRange; result.HasAsteriskModifier = _hasAsteriskModifier; result.Arguments = ArrayHelpers.CreateDeepCopyOfAstElementArray(_arguments, alreadyClonedElements); result.Function = _function; return result; }
public override AstElement Clone(Dictionary <AstElement, AstElement> alreadyClonedElements) { FunctionInvocationExpression result = new FunctionInvocationExpression(); result.Name = _name; result.NameSourceRange = _nameSourceRange; result.HasAsteriskModifier = _hasAsteriskModifier; result.Arguments = ArrayHelpers.CreateDeepCopyOfAstElementArray(_arguments, alreadyClonedElements); result.Function = _function; return(result); }
public override ExpressionNode VisitFunctionInvocationExpression(FunctionInvocationExpression expression) { base.VisitFunctionInvocationExpression(expression); // Constant folding must not be applied if the function is non-deterministic. if (!expression.Function.IsDeterministic) { return(expression); } // Check if all arguments are constants or at least one argument // is null. ConstantExpression[] constantArguments = new ConstantExpression[expression.Arguments.Length]; bool allArgumentsAreConstants = true; for (int i = 0; i < constantArguments.Length; i++) { constantArguments[i] = expression.Arguments[i] as ConstantExpression; if (constantArguments[i] == null) { // Ok, one argument is not a constant // But don't stop: If an argument is null we can still calculate the result! allArgumentsAreConstants = false; } else if (constantArguments[i].IsNullValue) { // We found a null. That means the invocation will also yield null. return(LiteralExpression.FromTypedNull(expression.ExpressionType)); } } if (allArgumentsAreConstants) { try { return(LiteralExpression.FromTypedValue(expression.GetValue(), expression.ExpressionType)); } catch (RuntimeException ex) { _errorReporter.CannotFoldConstants(ex); } } return(expression); }
public override ExpressionNode VisitFunctionInvocationExpression(FunctionInvocationExpression expression) { base.VisitFunctionInvocationExpression(expression); ReflectionFunctionBinding reflectionFunctionBinding = expression.Function as ReflectionFunctionBinding; if (reflectionFunctionBinding != null) { if (reflectionFunctionBinding.Instance != null) _ilEmitContext.AddParameter(expression, reflectionFunctionBinding.Instance, reflectionFunctionBinding.Instance.GetType()); } else { _ilEmitContext.AddParameter(expression, expression.Function, typeof (FunctionBinding)); object[] args = new object[expression.Arguments.Length]; _ilEmitContext.AddParameter(expression, args, typeof(object[])); } return expression; }
public override ExpressionNode VisitFunctionInvocationExpression(FunctionInvocationExpression expression) { _xmlWriter.WriteStartElement("functionInvocationExpression"); _xmlWriter.WriteAttributeString("identifier", expression.Name.ToSource()); WriteTypeAttribute(expression.ExpressionType); for (int i = 0; i < expression.Arguments.Length; i++) { _xmlWriter.WriteStartElement("argument"); _xmlWriter.WriteAttributeString("index", XmlConvert.ToString(i)); Visit(expression.Arguments[i]); _xmlWriter.WriteEndElement(); } _xmlWriter.WriteEndElement(); return(expression); }
public override ExpressionNode VisitFunctionInvocationExpression(FunctionInvocationExpression expression) { base.VisitFunctionInvocationExpression(expression); ReflectionFunctionBinding reflectionFunctionBinding = expression.Function as ReflectionFunctionBinding; if (reflectionFunctionBinding != null) { if (reflectionFunctionBinding.Instance != null) { _ilEmitContext.AddParameter(expression, reflectionFunctionBinding.Instance, reflectionFunctionBinding.Instance.GetType()); } } else { _ilEmitContext.AddParameter(expression, expression.Function, typeof(FunctionBinding)); object[] args = new object[expression.Arguments.Length]; _ilEmitContext.AddParameter(expression, args, typeof(object[])); } return(expression); }
private static bool VisitFunctionInvocationExpression(FunctionInvocationExpression node1, FunctionInvocationExpression node2) { if (node2 == null) { return(false); } if (node1.HasAsteriskModifier != node2.HasAsteriskModifier || node1.Arguments.Length != node2.Arguments.Length || node1.Name != node2.Name) { return(false); } for (int i = 0; i < node1.Arguments.Length; i++) { if (!Visit(node1.Arguments[i], node2.Arguments[i])) { return(false); } } return(true); }
public override ExpressionNode VisitFunctionInvocationExpression(FunctionInvocationExpression expression) { _xmlWriter.WriteStartElement("functionInvocationExpression"); _xmlWriter.WriteAttributeString("identifier", expression.Name.ToSource()); WriteTypeAttribute(expression.ExpressionType); for (int i = 0; i < expression.Arguments.Length; i++) { _xmlWriter.WriteStartElement("argument"); _xmlWriter.WriteAttributeString("index", XmlConvert.ToString(i)); Visit(expression.Arguments[i]); _xmlWriter.WriteEndElement(); } _xmlWriter.WriteEndElement(); return expression; }
public override ExpressionNode VisitFunctionInvocationExpression(FunctionInvocationExpression expression) { base.VisitFunctionInvocationExpression(expression); // Constant folding must not be applied if the function is non-deterministic. if (!expression.Function.IsDeterministic) return expression; // Check if all arguments are constants or at least one argument // is null. ConstantExpression[] constantArguments = new ConstantExpression[expression.Arguments.Length]; bool allArgumentsAreConstants = true; for (int i = 0; i < constantArguments.Length; i++) { constantArguments[i] = expression.Arguments[i] as ConstantExpression; if (constantArguments[i] == null) { // Ok, one argument is not a constant // But don't stop: If an argument is null we can still calculate the result! allArgumentsAreConstants = false; } else if (constantArguments[i].IsNullValue) { // We found a null. That means the invocation will also yield null. return LiteralExpression.FromTypedNull(expression.ExpressionType); } } if (allArgumentsAreConstants) { try { return LiteralExpression.FromTypedValue(expression.GetValue(), expression.ExpressionType); } catch (RuntimeException ex) { _errorReporter.CannotFoldConstants(ex); } } return expression; }
public override ExpressionNode VisitFunctionInvocationExpression(FunctionInvocationExpression expression) { ReflectionFunctionBinding reflectionFunctionBinding = expression.Function as ReflectionFunctionBinding; if (reflectionFunctionBinding != null) { MethodInfo method = reflectionFunctionBinding.Method; ParameterInfo[] parameterInfos = method.GetParameters(); ILParameterDeclaration instance; if (reflectionFunctionBinding.Instance != null) instance = _ilEmitContext.GetParameters(expression)[0]; else instance = null; int[] argLocalIndexes = new int[expression.Arguments.Length]; for (int i = 0; i < expression.Arguments.Length; i++) argLocalIndexes[i] = DeclareLocal(); for (int i = 0; i < expression.Arguments.Length; i++) { Visit(expression.Arguments[i]); _ilEmitContext.ILGenerator.Emit(OpCodes.Stloc, argLocalIndexes[i]); } Label loadNullLabel = _ilEmitContext.ILGenerator.DefineLabel(); Label finishLabel = _ilEmitContext.ILGenerator.DefineLabel(); for (int i = 0; i < expression.Arguments.Length; i++) { _ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, argLocalIndexes[i]); _ilEmitContext.ILGenerator.Emit(OpCodes.Brfalse, loadNullLabel); } if (instance != null) { EmitLoadParameter(instance); EmitThisArgumentPointer(instance.Type); } for (int i = 0; i < expression.Arguments.Length; i++) { _ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, argLocalIndexes[i]); if (parameterInfos[i].ParameterType != typeof(object)) EmitConversion(parameterInfos[i].ParameterType); } EmitRawCall(method, instance == null ? null : instance.Type); if (method.ReturnType.IsValueType) _ilEmitContext.ILGenerator.Emit(OpCodes.Box, method.ReturnType); _ilEmitContext.ILGenerator.EmitCall(OpCodes.Call, _unifyNullsMethod, null); _ilEmitContext.ILGenerator.Emit(OpCodes.Br, finishLabel); _ilEmitContext.ILGenerator.MarkLabel(loadNullLabel); _ilEmitContext.ILGenerator.Emit(OpCodes.Ldnull); _ilEmitContext.ILGenerator.MarkLabel(finishLabel); } else { int[] argLocalIndexes = new int[expression.Arguments.Length]; for (int i = 0; i < expression.Arguments.Length; i++) argLocalIndexes[i] = DeclareLocal(); for (int i = 0; i < expression.Arguments.Length; i++) { Visit(expression.Arguments[i]); _ilEmitContext.ILGenerator.Emit(OpCodes.Stloc, argLocalIndexes[i]); } Label loadNullLabel = _ilEmitContext.ILGenerator.DefineLabel(); Label finishLabel = _ilEmitContext.ILGenerator.DefineLabel(); for (int i = 0; i < expression.Arguments.Length; i++) { _ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, argLocalIndexes[i]); _ilEmitContext.ILGenerator.Emit(OpCodes.Brfalse, loadNullLabel); } ILParameterDeclaration customFunctionBinding = _ilEmitContext.GetParameters(expression)[0]; ILParameterDeclaration argsArray = _ilEmitContext.GetParameters(expression)[1]; int argsArrayIndex = DeclareLocal(); EmitLoadParameter(argsArray); _ilEmitContext.ILGenerator.Emit(OpCodes.Stloc, argsArrayIndex); for (int i = 0; i < expression.Arguments.Length; i++) { _ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, argsArrayIndex); _ilEmitContext.ILGenerator.Emit(OpCodes.Ldc_I4, i); _ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, argLocalIndexes[i]); _ilEmitContext.ILGenerator.Emit(OpCodes.Stelem_Ref); } EmitLoadParameter(customFunctionBinding); EmitThisArgumentPointer(typeof(FunctionBinding)); _ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, argsArrayIndex); _ilEmitContext.ILGenerator.EmitCall(OpCodes.Callvirt, _functionBindingInvokeMethod, null); _ilEmitContext.ILGenerator.EmitCall(OpCodes.Call, _unifyNullsMethod, null); _ilEmitContext.ILGenerator.Emit(OpCodes.Br, finishLabel); _ilEmitContext.ILGenerator.MarkLabel(loadNullLabel); _ilEmitContext.ILGenerator.Emit(OpCodes.Ldnull); _ilEmitContext.ILGenerator.MarkLabel(finishLabel); } return expression; }
public override ExpressionNode VisitFunctionInvocationExpression(FunctionInvocationExpression expression) { // Resolve aggregation // -- or -- // Resolve method // First all parameters must be resolved. base.VisitFunctionInvocationExpression(expression); // If the type of any argument could not be resolved we cannot resolve the method. foreach (ExpressionNode argument in expression.Arguments) { if (argument.ExpressionType == null) return expression; } // Resolve aggregate bool canBeAggregate = expression.Arguments.Length == 1 || (expression.Arguments.Length == 0 && expression.HasAsteriskModifier); if (canBeAggregate) { AggregateBinding aggregateBinding = ResolveAggregate(expression.NameSourceRange, expression.Name); if (aggregateBinding != null) { ExpressionNode aggregateArgument; if (!expression.HasAsteriskModifier) { aggregateArgument = expression.Arguments[0]; } else { // Only COUNT can have the asterisk modifier. Identifier countName = Identifier.CreateNonVerbatim("COUNT"); if (!countName.Matches(aggregateBinding.Name)) ErrorReporter.AsteriskModifierNotAllowed(expression.NameSourceRange, expression); // The semantic of COUNT(*) says that it counts all rows of the bound // query. The same result can be accomplished by using COUNT(0) (or any // otherc onstant non-null expression as argument). Therefore we use a // literal zero as the argument. aggregateArgument = LiteralExpression.FromInt32(0); } IAggregator aggregator = aggregateBinding.CreateAggregator(aggregateArgument.ExpressionType); if (aggregator == null) { ErrorReporter.AggregateDoesNotSupportType(aggregateBinding, aggregateArgument.ExpressionType); return expression; } AggregateExpression aggregateExpression = new AggregateExpression(); aggregateExpression.Aggregate = aggregateBinding; aggregateExpression.Aggregator = aggregator; aggregateExpression.Argument = aggregateArgument; aggregateExpression.HasAsteriskModifier = expression.HasAsteriskModifier; return aggregateExpression; } } // Resolve method if (expression.HasAsteriskModifier) { // Simple invocations cannot have asterisk modifier. ErrorReporter.AsteriskModifierNotAllowed(expression.NameSourceRange, expression); // Leave to avoid cascading errors. return expression; } Type[] argumentTypes = new Type[expression.Arguments.Length]; for (int i = 0; i < argumentTypes.Length; i++) argumentTypes[i] = expression.Arguments[i].ExpressionType; expression.Function = ResolveFunction(expression.Name, argumentTypes); if (expression.Function == null) { ErrorReporter.UndeclaredFunction(expression.NameSourceRange, expression.Name, argumentTypes); } else { // Convert all arguments if necessary Type[] parameterTypes = expression.Function.GetParameterTypes(); for (int i = 0; i < expression.Arguments.Length; i++) expression.Arguments[i] = Binder.ConvertExpressionIfRequired(expression.Arguments[i], parameterTypes[i]); } return expression; }
private ExpressionNode ParsePrimaryExpression() { switch (_token.Id) { case TokenId.NULL: NextToken(); return(LiteralExpression.FromNull()); case TokenId.TRUE: case TokenId.FALSE: return(ParseBooleanLiteral()); case TokenId.Date: return(ParseDateLiteral()); case TokenId.Number: return(ParseNumberLiteral()); case TokenId.String: return(LiteralExpression.FromString(ParseString())); case TokenId.EXISTS: { ExistsSubselect result = new ExistsSubselect(); NextToken(); Match(TokenId.LeftParentheses); result.Query = ParseQuery(); Match(TokenId.RightParentheses); return(result); } case TokenId.ParameterMarker: { _rangeRecorder.Begin(); NextToken(); Identifier name = ParseIdentifier(); SourceRange nameSourceRange = _rangeRecorder.End(); ParameterExpression result = new ParameterExpression(); result.Name = name; result.NameSourceRange = nameSourceRange; return(result); } case TokenId.CAST: { NextToken(); CastExpression castExpression = new CastExpression(); Match(TokenId.LeftParentheses); castExpression.Expression = ParseExpression(); Match(TokenId.AS); castExpression.TypeReference = ParseTypeReference(); Match(TokenId.RightParentheses); return(castExpression); } case TokenId.CASE: { NextToken(); CaseExpression caseExpression = new CaseExpression(); if (_token.Id != TokenId.WHEN && _token.Id != TokenId.ELSE && _token.Id != TokenId.END) { caseExpression.InputExpression = ParseExpression(); } List <ExpressionNode> whenExpressionList = new List <ExpressionNode>(); List <ExpressionNode> expressionList = new List <ExpressionNode>(); if (_token.Id != TokenId.WHEN) { Match(TokenId.WHEN); } else { while (_token.Id == TokenId.WHEN) { NextToken(); whenExpressionList.Add(ParseExpression()); Match(TokenId.THEN); expressionList.Add(ParseExpression()); } } caseExpression.WhenExpressions = whenExpressionList.ToArray(); caseExpression.ThenExpressions = expressionList.ToArray(); if (_token.Id == TokenId.ELSE) { NextToken(); caseExpression.ElseExpression = ParseExpression(); } Match(TokenId.END); return(caseExpression); } case TokenId.COALESCE: { NextToken(); CoalesceExpression coalesceExpression = new CoalesceExpression(); coalesceExpression.Expressions = ParseExpressionList(); return(coalesceExpression); } case TokenId.NULLIF: { NextToken(); NullIfExpression nullIfExpression = new NullIfExpression(); Match(TokenId.LeftParentheses); nullIfExpression.LeftExpression = ParseExpression(); Match(TokenId.Comma); nullIfExpression.RightExpression = ParseExpression(); Match(TokenId.RightParentheses); return(nullIfExpression); } case TokenId.Identifier: { _rangeRecorder.Begin(); Identifier name = ParseIdentifier(); SourceRange nameSourceRange = _rangeRecorder.End(); if (_token.Id != TokenId.LeftParentheses) { NameExpression result = new NameExpression(); result.Name = name; result.NameSourceRange = nameSourceRange; return(result); } else { bool hasAsteriskModifier; ExpressionNode[] args; if (_lookahead.Id != TokenId.Multiply) { hasAsteriskModifier = false; args = ParseExpressionList(); } else { NextToken(); NextToken(); Match(TokenId.RightParentheses); hasAsteriskModifier = true; args = new ExpressionNode[0]; } FunctionInvocationExpression result = new FunctionInvocationExpression(); result.Name = name; result.NameSourceRange = nameSourceRange; result.Arguments = args; result.HasAsteriskModifier = hasAsteriskModifier; return(result); } } case TokenId.LeftParentheses: { NextToken(); ExpressionNode expr; if (_token.Id != TokenId.SELECT) { expr = ParseExpression(); } else { SingleRowSubselect singleRowSubselect = new SingleRowSubselect(); singleRowSubselect.Query = ParseQuery(); expr = singleRowSubselect; } Match(TokenId.RightParentheses); return(expr); } default: { _errorReporter.SimpleExpressionExpected(_token.Range, _token.Text); return(LiteralExpression.FromNull()); } } }
private static bool VisitFunctionInvocationExpression(FunctionInvocationExpression node1, FunctionInvocationExpression node2) { if (node2 == null) return false; if (node1.HasAsteriskModifier != node2.HasAsteriskModifier || node1.Arguments.Length != node2.Arguments.Length || node1.Name != node2.Name) return false; for (int i = 0; i < node1.Arguments.Length; i++) if (!Visit(node1.Arguments[i], node2.Arguments[i])) return false; return true; }
public override ExpressionNode VisitFunctionInvocationExpression(FunctionInvocationExpression expression) { _writer.WriteIdentifier(expression.Name); if (expression.HasAsteriskModifier) { _writer.Write("(*)"); } else { _writer.Write("("); for (int i = 0; i < expression.Arguments.Length; i++) { if (i > 0) _writer.Write(","); Visit(expression.Arguments[i]); } _writer.Write(")"); } return expression; }
private ExpressionNode ParsePrimaryExpression() { switch (_token.Id) { case TokenId.NULL: NextToken(); return LiteralExpression.FromNull(); case TokenId.TRUE: case TokenId.FALSE: return ParseBooleanLiteral(); case TokenId.Date: return ParseDateLiteral(); case TokenId.Number: return ParseNumberLiteral(); case TokenId.String: return LiteralExpression.FromString(ParseString()); case TokenId.EXISTS: { ExistsSubselect result = new ExistsSubselect(); NextToken(); Match(TokenId.LeftParentheses); result.Query = ParseQuery(); Match(TokenId.RightParentheses); return result; } case TokenId.ParameterMarker: { _rangeRecorder.Begin(); NextToken(); Identifier name = ParseIdentifier(); SourceRange nameSourceRange = _rangeRecorder.End(); ParameterExpression result = new ParameterExpression(); result.Name = name; result.NameSourceRange = nameSourceRange; return result; } case TokenId.CAST: { NextToken(); CastExpression castExpression = new CastExpression(); Match(TokenId.LeftParentheses); castExpression.Expression = ParseExpression(); Match(TokenId.AS); castExpression.TypeReference = ParseTypeReference(); Match(TokenId.RightParentheses); return castExpression; } case TokenId.CASE: { NextToken(); CaseExpression caseExpression = new CaseExpression(); if (_token.Id != TokenId.WHEN && _token.Id != TokenId.ELSE && _token.Id != TokenId.END) caseExpression.InputExpression = ParseExpression(); List<ExpressionNode> whenExpressionList = new List<ExpressionNode>(); List<ExpressionNode> expressionList = new List<ExpressionNode>(); if (_token.Id != TokenId.WHEN) { Match(TokenId.WHEN); } else { while (_token.Id == TokenId.WHEN) { NextToken(); whenExpressionList.Add(ParseExpression()); Match(TokenId.THEN); expressionList.Add(ParseExpression()); } } caseExpression.WhenExpressions = whenExpressionList.ToArray(); caseExpression.ThenExpressions = expressionList.ToArray(); if (_token.Id == TokenId.ELSE) { NextToken(); caseExpression.ElseExpression = ParseExpression(); } Match(TokenId.END); return caseExpression; } case TokenId.COALESCE: { NextToken(); CoalesceExpression coalesceExpression = new CoalesceExpression(); coalesceExpression.Expressions = ParseExpressionList(); return coalesceExpression; } case TokenId.NULLIF: { NextToken(); NullIfExpression nullIfExpression = new NullIfExpression(); Match(TokenId.LeftParentheses); nullIfExpression.LeftExpression = ParseExpression(); Match(TokenId.Comma); nullIfExpression.RightExpression = ParseExpression(); Match(TokenId.RightParentheses); return nullIfExpression; } case TokenId.Identifier: { _rangeRecorder.Begin(); Identifier name = ParseIdentifier(); SourceRange nameSourceRange = _rangeRecorder.End(); if (_token.Id != TokenId.LeftParentheses) { NameExpression result = new NameExpression(); result.Name = name; result.NameSourceRange = nameSourceRange; return result; } else { bool hasAsteriskModifier; ExpressionNode[] args; if (_lookahead.Id != TokenId.Multiply) { hasAsteriskModifier = false; args = ParseExpressionList(); } else { NextToken(); NextToken(); Match(TokenId.RightParentheses); hasAsteriskModifier = true; args = new ExpressionNode[0]; } FunctionInvocationExpression result = new FunctionInvocationExpression(); result.Name = name; result.NameSourceRange = nameSourceRange; result.Arguments = args; result.HasAsteriskModifier = hasAsteriskModifier; return result; } } case TokenId.LeftParentheses: { NextToken(); ExpressionNode expr; if (_token.Id != TokenId.SELECT) { expr = ParseExpression(); } else { SingleRowSubselect singleRowSubselect = new SingleRowSubselect(); singleRowSubselect.Query = ParseQuery(); expr = singleRowSubselect; } Match(TokenId.RightParentheses); return expr; } default: { _errorReporter.SimpleExpressionExpected(_token.Range, _token.Text); return LiteralExpression.FromNull(); } } }
public override ExpressionNode VisitFunctionInvocationExpression(FunctionInvocationExpression expression) { ReflectionFunctionBinding reflectionFunctionBinding = expression.Function as ReflectionFunctionBinding; if (reflectionFunctionBinding != null) { MethodInfo method = reflectionFunctionBinding.Method; ParameterInfo[] parameterInfos = method.GetParameters(); ILParameterDeclaration instance; if (reflectionFunctionBinding.Instance != null) { instance = _ilEmitContext.GetParameters(expression)[0]; } else { instance = null; } int[] argLocalIndexes = new int[expression.Arguments.Length]; for (int i = 0; i < expression.Arguments.Length; i++) { argLocalIndexes[i] = DeclareLocal(); } for (int i = 0; i < expression.Arguments.Length; i++) { Visit(expression.Arguments[i]); _ilEmitContext.ILGenerator.Emit(OpCodes.Stloc, argLocalIndexes[i]); } Label loadNullLabel = _ilEmitContext.ILGenerator.DefineLabel(); Label finishLabel = _ilEmitContext.ILGenerator.DefineLabel(); for (int i = 0; i < expression.Arguments.Length; i++) { _ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, argLocalIndexes[i]); _ilEmitContext.ILGenerator.Emit(OpCodes.Brfalse, loadNullLabel); } if (instance != null) { EmitLoadParameter(instance); EmitThisArgumentPointer(instance.Type); } for (int i = 0; i < expression.Arguments.Length; i++) { _ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, argLocalIndexes[i]); if (parameterInfos[i].ParameterType != typeof(object)) { EmitConversion(parameterInfos[i].ParameterType); } } EmitRawCall(method, instance == null ? null : instance.Type); if (method.ReturnType.IsValueType) { _ilEmitContext.ILGenerator.Emit(OpCodes.Box, method.ReturnType); } _ilEmitContext.ILGenerator.EmitCall(OpCodes.Call, _unifyNullsMethod, null); _ilEmitContext.ILGenerator.Emit(OpCodes.Br, finishLabel); _ilEmitContext.ILGenerator.MarkLabel(loadNullLabel); _ilEmitContext.ILGenerator.Emit(OpCodes.Ldnull); _ilEmitContext.ILGenerator.MarkLabel(finishLabel); } else { int[] argLocalIndexes = new int[expression.Arguments.Length]; for (int i = 0; i < expression.Arguments.Length; i++) { argLocalIndexes[i] = DeclareLocal(); } for (int i = 0; i < expression.Arguments.Length; i++) { Visit(expression.Arguments[i]); _ilEmitContext.ILGenerator.Emit(OpCodes.Stloc, argLocalIndexes[i]); } Label loadNullLabel = _ilEmitContext.ILGenerator.DefineLabel(); Label finishLabel = _ilEmitContext.ILGenerator.DefineLabel(); for (int i = 0; i < expression.Arguments.Length; i++) { _ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, argLocalIndexes[i]); _ilEmitContext.ILGenerator.Emit(OpCodes.Brfalse, loadNullLabel); } ILParameterDeclaration customFunctionBinding = _ilEmitContext.GetParameters(expression)[0]; ILParameterDeclaration argsArray = _ilEmitContext.GetParameters(expression)[1]; int argsArrayIndex = DeclareLocal(); EmitLoadParameter(argsArray); _ilEmitContext.ILGenerator.Emit(OpCodes.Stloc, argsArrayIndex); for (int i = 0; i < expression.Arguments.Length; i++) { _ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, argsArrayIndex); _ilEmitContext.ILGenerator.Emit(OpCodes.Ldc_I4, i); _ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, argLocalIndexes[i]); _ilEmitContext.ILGenerator.Emit(OpCodes.Stelem_Ref); } EmitLoadParameter(customFunctionBinding); EmitThisArgumentPointer(typeof(FunctionBinding)); _ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, argsArrayIndex); _ilEmitContext.ILGenerator.EmitCall(OpCodes.Callvirt, _functionBindingInvokeMethod, null); _ilEmitContext.ILGenerator.EmitCall(OpCodes.Call, _unifyNullsMethod, null); _ilEmitContext.ILGenerator.Emit(OpCodes.Br, finishLabel); _ilEmitContext.ILGenerator.MarkLabel(loadNullLabel); _ilEmitContext.ILGenerator.Emit(OpCodes.Ldnull); _ilEmitContext.ILGenerator.MarkLabel(finishLabel); } return(expression); }
public virtual ExpressionNode VisitFunctionInvocationExpression(FunctionInvocationExpression expression) { for (int i = 0; i < expression.Arguments.Length; i++) expression.Arguments[i] = VisitExpression(expression.Arguments[i]); return expression; }