Exemple #1
0
        private static List <StatementSyntax> HandleMap(string map, FieldNamesValidator fieldNamesValidator, MethodDetectorRewriter methodsDetector,
                                                        ref SyntaxList <MemberDeclarationSyntax> members)
        {
            try
            {
                map = NormalizeFunction(map);
                var expression = SyntaxFactory.ParseExpression(map).NormalizeWhitespace();

                fieldNamesValidator.Validate(map, expression);
                methodsDetector.Visit(expression);

                var queryExpression = expression as QueryExpressionSyntax;
                if (queryExpression != null)
                {
                    return(HandleSyntaxInMap(fieldNamesValidator, new MapFunctionProcessor(CollectionNameRetriever.QuerySyntax, SelectManyRewriter.QuerySyntax), queryExpression, ref members));
                }
                var invocationExpression = expression as InvocationExpressionSyntax;
                if (invocationExpression != null)
                {
                    return(HandleSyntaxInMap(fieldNamesValidator, new MapFunctionProcessor(CollectionNameRetriever.MethodSyntax, SelectManyRewriter.MethodSyntax), invocationExpression, ref members));
                }

                throw new InvalidOperationException("Not supported expression type.");
            }
            catch (Exception ex)
            {
                throw new IndexCompilationException(ex.Message, ex)
                      {
                          IndexDefinitionProperty = nameof(IndexDefinition.Maps),
                          ProblematicText         = map
                      };
            }
        }
Exemple #2
0
        private static StatementSyntax HandleReduce(string reduce, FieldNamesValidator fieldNamesValidator, MethodDetectorRewriter methodsDetector, out string[] groupByFields)
        {
            try
            {
                reduce = NormalizeFunction(reduce);
                var expression = SyntaxFactory.ParseExpression(reduce).NormalizeWhitespace();
                fieldNamesValidator?.Validate(reduce, expression);
                methodsDetector.Visit(expression);

                StatementSyntax result;

                switch (expression)
                {
                case QueryExpressionSyntax queryExpression:
                    result = HandleSyntaxInReduce(
                        new ReduceFunctionProcessor(
                            ResultsVariableNameRewriter.QuerySyntax,
                            GroupByFieldsRetriever.QuerySyntax,
                            SelectManyRewriter.QuerySyntax),
                        MethodsInGroupByValidator.QuerySyntaxValidator,
                        queryExpression, out groupByFields);
                    break;

                case InvocationExpressionSyntax invocationExpression:
                    result = HandleSyntaxInReduce(
                        new ReduceFunctionProcessor(
                            ResultsVariableNameRewriter.MethodSyntax,
                            GroupByFieldsRetriever.MethodSyntax,
                            SelectManyRewriter.MethodSyntax),
                        MethodsInGroupByValidator.MethodSyntaxValidator,
                        invocationExpression, out groupByFields);
                    break;

                default:
                    throw new InvalidOperationException("Not supported expression type.");
                }

                foreach (var groupByField in groupByFields)
                {
                    if (fieldNamesValidator?.Fields.Contains(groupByField) == false)
                    {
                        throw new InvalidOperationException($"Group by field '{groupByField}' was not found on the list of index fields ({string.Join(", ",fieldNamesValidator.Fields)})");
                    }
                }

                return(result);
            }
            catch (Exception ex)
            {
                throw new IndexCompilationException(ex.Message, ex)
                      {
                          IndexDefinitionProperty = nameof(IndexDefinition.Reduce),
                          ProblematicText         = reduce
                      };
            }
        }
        private static SyntaxNode OptimizeExpression(string str)
        {
            var expression = SyntaxFactory.ParseExpression(str.Trim());
            var result     = new RavenLinqPrettifier().Visit(expression);

            var validator = new FieldNamesValidator();

            validator.Validate(str, SyntaxFactory.ParseExpression(str).NormalizeWhitespace());

            var expr = new RavenLinqOptimizer(validator).Visit(result);

            expr = expr.ReplaceTrivia(expr.DescendantTrivia(), (t1, t2) => new SyntaxTrivia());
            return(expr.NormalizeWhitespace());
        }
Exemple #4
0
        private static StatementSyntax HandleReduce(string reduce, FieldNamesValidator fieldNamesValidator, MethodDetectorRewriter methodsDetector, out string[] groupByFields)
        {
            try
            {
                reduce = NormalizeFunction(reduce);
                var expression = SyntaxFactory.ParseExpression(reduce).NormalizeWhitespace();
                fieldNamesValidator?.Validate(reduce, expression);
                methodsDetector.Visit(expression);
                var queryExpression = expression as QueryExpressionSyntax;
                if (queryExpression != null)
                {
                    return
                        HandleSyntaxInReduce(
                            new ReduceFunctionProcessor(
                                ResultsVariableNameRewriter.QuerySyntax,
                                GroupByFieldsRetriever.QuerySyntax,
                                SelectManyRewriter.QuerySyntax),
                            MethodsInGroupByValidator.QuerySyntaxValidator,
                            queryExpression, out groupByFields);
                }

                var invocationExpression = expression as InvocationExpressionSyntax;
                if (invocationExpression != null)
                {
                    return
                        HandleSyntaxInReduce(
                            new ReduceFunctionProcessor(
                                ResultsVariableNameRewriter.MethodSyntax,
                                GroupByFieldsRetriever.MethodSyntax,
                                SelectManyRewriter.MethodSyntax),
                            MethodsInGroupByValidator.MethodSyntaxValidator,
                            invocationExpression, out groupByFields);
                }

                throw new InvalidOperationException("Not supported expression type.");
            }
            catch (Exception ex)
            {
                throw new IndexCompilationException(ex.Message, ex)
                {
                    IndexDefinitionProperty = nameof(IndexDefinition.Reduce),
                    ProblematicText = reduce
                };
            }
        }
        public override SyntaxNode VisitQueryExpression(QueryExpressionSyntax node)
        {
            var stripExpressionParentParenthesis = StripExpressionParentParenthesis(node);

            if (stripExpressionParentParenthesis != null &&
                stripExpressionParentParenthesis is QueryExpressionSyntax == false)
            {
                return(node);
            }

            ForEachStatementSyntax parent = null;
            var queryExpressionSyntax     = StripExpressionParenthesis(node.FromClause.Expression) as QueryExpressionSyntax;

            if (queryExpressionSyntax != null &&
                StripExpressionParentParenthesis(queryExpressionSyntax) is QueryExpressionSyntax)
            {
                using (RecursiveCall())
                {
                    parent = VisitQueryExpression(queryExpressionSyntax) as ForEachStatementSyntax;
                }

                if (parent != null)
                {
                    node =
                        node.WithFromClause(
                            node.FromClause.WithExpression(IdentifierName(queryExpressionSyntax.FromClause.Identifier)));
                }
            }

            var dummyYield = YieldStatement(SyntaxKind.YieldReturnStatement, LiteralExpression(SyntaxKind.NullLiteralExpression));

            var body = Block().AddStatements(dummyYield);

            foreach (var clause in node.Body.Clauses)
            {
                if (TryRewriteBodyClause(clause, dummyYield, ref body))
                {
                    continue;
                }

                return(base.VisitQueryExpression(node));
            }

            var selectClauseSyntax = node.Body.SelectOrGroup as SelectClauseSyntax;

            if (selectClauseSyntax == null)
            {
                return(base.VisitQueryExpression(node));
            }

            var continuation = node.Body.Continuation;

            while (continuation != null)
            {
                // select new {  } into

                var selectIntoVar = LocalDeclarationStatement(
                    VariableDeclaration(IdentifierName("var"), SingletonSeparatedList(VariableDeclarator(
                                                                                          continuation.Identifier)
                                                                                      .WithInitializer(
                                                                                          EqualsValueClause(selectClauseSyntax.Expression)
                                                                                          )
                                                                                      )
                                        )
                    );

                selectClauseSyntax = continuation.Body.SelectOrGroup as SelectClauseSyntax;

                if (selectClauseSyntax == null)
                {
                    return(base.VisitQueryExpression(node));
                }

                body = body.InsertNodesBefore(FindDummyYieldIn(body), new[] { selectIntoVar });

                foreach (var clause in continuation.Body.Clauses)
                {
                    if (TryRewriteBodyClause(clause, dummyYield, ref body))
                    {
                        continue;
                    }

                    return(base.VisitQueryExpression(node));
                }

                continuation = continuation.Body.Continuation;
            }

            var stmt = ForEachStatement(
                IdentifierName("var"),
                node.FromClause.Identifier,
                node.FromClause.Expression,
                body
                );

            stmt = stmt.ReplaceNode(FindDummyYieldIn(stmt),
                                    YieldStatement(SyntaxKind.YieldReturnStatement, selectClauseSyntax.Expression)
                                    );

            if (parent == null)
            {
                if (_recursiveCallCounter == 0 && _validator.Validate(stmt.ToFullString(), selectClauseSyntax.Expression, throwOnError: false) == false)
                {
                    ThrowIndexRewritingException(node, stmt);
                }

                return(stmt);
            }

            var parentBody = (BlockSyntax)parent.Statement;

            var yieldStatementSyntax = (YieldStatementSyntax)parentBody.Statements.Last();
            var parentVar            = LocalDeclarationStatement(
                VariableDeclaration(IdentifierName("var"), SingletonSeparatedList(VariableDeclarator(
                                                                                      node.FromClause.Identifier)
                                                                                  .WithInitializer(
                                                                                      EqualsValueClause(yieldStatementSyntax.Expression)
                                                                                      )
                                                                                  )
                                    )
                );

            var statementSyntax = stmt.Statement;

            if (statementSyntax is BlockSyntax bs)
            {
                statementSyntax = bs.Statements.Single();
            }

            return(parent.WithStatement(
                       parentBody.ReplaceNode(yieldStatementSyntax, parentVar).AddStatements(statementSyntax)
                       ));
        }