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)
))
)
}