Exemple #1
0
        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);
        }
Exemple #2
0
 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);
        }
Exemple #5
0
        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;
		}
Exemple #7
0
        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);
        }
Exemple #9
0
        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);
        }
Exemple #10
0
		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;
		}
Exemple #11
0
		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;
		}
Exemple #12
0
		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;
		}
Exemple #13
0
        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;
        }
Exemple #14
0
        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());
            }
            }
        }
Exemple #15
0
		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;
		}
Exemple #16
0
		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;
		}
Exemple #17
0
        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();
                }
            }
        }
Exemple #18
0
        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);
        }
Exemple #19
0
		public virtual ExpressionNode VisitFunctionInvocationExpression(FunctionInvocationExpression expression)
		{
			for (int i = 0; i < expression.Arguments.Length; i++)
				expression.Arguments[i] = VisitExpression(expression.Arguments[i]);
			return expression;
		}