private MethodCallExpression constructWindowDefinitionFactoryMethodCallExpression()

in subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/provider/collection/GinqAstWalker.groovy [845:956]


    private MethodCallExpression constructWindowDefinitionFactoryMethodCallExpression(MethodCallExpression methodCallExpression, DataSourceExpression dataSourceExpression) {
        Expression classifierExpr = null
        Expression orderExpr = null
        Expression rowsExpr = null
        Expression rangeExpr = null
        ArgumentListExpression argumentListExpression = (ArgumentListExpression) methodCallExpression.arguments
        if (1 == argumentListExpression.getExpressions().size()) {
            final List<MethodCallExpression> ignoredMethodCallExpressionList = []

            argumentListExpression.visit(new CodeVisitorSupport() {
                @Override
                void visitMethodCallExpression(MethodCallExpression call) {
                    super.visitMethodCallExpression(call)
                    if ('partitionby' == call.methodAsString) {
                        classifierExpr = call.arguments
                    } else if ('orderby' == call.methodAsString) {
                        orderExpr = call.arguments
                    } else if ('rows' == call.methodAsString) {
                        rowsExpr = call.arguments
                    } else if ('range' == call.methodAsString) {
                        rangeExpr = call.arguments
                    } else {
                        ignoredMethodCallExpressionList << call
                    }
                }
            })

            validateWindowClause(classifierExpr, orderExpr, rowsExpr, rangeExpr, ignoredMethodCallExpressionList)
        }

        List<Expression> argumentExpressionList = []

        if (classifierExpr) {
            List<Expression> expressionList = ((ArgumentListExpression) classifierExpr).getExpressions()
            LambdaExpression classifierLambdaExpression = constructLambdaExpression(dataSourceExpression, new ListExpression(expressionList))
            argumentExpressionList << classifierLambdaExpression
        }

        if (orderExpr) {
            def orderCtorCallExpressions = constructOrderCtorCallExpressions(orderExpr, dataSourceExpression)
            argumentExpressionList << new ListExpression(orderCtorCallExpressions)
        }

        if (rowsExpr && rangeExpr) {
            collectSyntaxError(new GinqSyntaxError(
                    "`rows` and `range` cannot be used in the same time",
                    rangeExpr.getLineNumber(), rangeExpr.getColumnNumber()
            ))
        }

        if (rowsExpr) {
            if (2 != ((ArgumentListExpression) rowsExpr).getExpressions().size()) {
                collectSyntaxError(new GinqSyntaxError(
                        "Both lower bound and upper bound are expected for `rows`",
                        rowsExpr.getLineNumber(), rowsExpr.getColumnNumber()
                ))
            }

            def rowBoundCtorCallExpression = ctorX(ROWBOUND_TYPE, rowsExpr)
            argumentExpressionList << rowBoundCtorCallExpression
        }

        if (rangeExpr) {
            if (2 != ((ArgumentListExpression) rangeExpr).getExpressions().size()) {
                collectSyntaxError(new GinqSyntaxError(
                        "Both lower bound and upper bound are expected for `range`",
                        rangeExpr.getLineNumber(), rangeExpr.getColumnNumber()
                ))
            }

            if (!orderExpr) {
                collectSyntaxError(new GinqSyntaxError(
                        "`orderby` is expected when using `range`",
                        rangeExpr.getLineNumber(), rangeExpr.getColumnNumber()
                ))
            }
            if (((ArgumentListExpression) orderExpr).getExpressions().size() != 1) {
                collectSyntaxError(new GinqSyntaxError(
                        "Only one field is expected in the `orderby` clause when using `range`",
                        orderExpr.getLineNumber(), orderExpr.getColumnNumber()
                ))
            }

            def valueBoundCtorCallExpression = ctorX(VALUEBOUND_TYPE, rangeExpr)
            argumentExpressionList << valueBoundCtorCallExpression
        }

        String partitionByClauseText = ""
        String orderByClauseText = ""
        argumentListExpression.visit(new GinqAstBaseVisitor() {
            @Override
            void visitMethodCallExpression(MethodCallExpression call) {
                if ('partitionby' == call.methodAsString) {
                    partitionByClauseText = call.text
                } else if ('orderby' == call.methodAsString) {
                    orderByClauseText = call.text
                }

                super.visitMethodCallExpression(call)
            }
        })

        callX(
                callX(classX(WINDOW_DEFINITION_TYPE), 'of', args(argumentExpressionList)),
                'setId',
                callX(TUPLE_TYPE, 'tuple', args(
                        constX(partitionByClauseText),
                        constX(orderByClauseText),
                        constX(argumentListExpression.text)
                ))
        )
    }