Search in sources :

Example 76 with TupleExpression

use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy by apache.

the class ClassNode method tryFindPossibleMethod.

public MethodNode tryFindPossibleMethod(final String name, final Expression arguments) {
    if (!(arguments instanceof TupleExpression)) {
        return null;
    }
    // TODO: this won't strictly be true when using list expansion in argument calls
    TupleExpression args = (TupleExpression) arguments;
    int nArgs = args.getExpressions().size();
    MethodNode method = null;
    for (ClassNode cn = this; cn != null; cn = cn.getSuperClass()) {
        for (MethodNode mn : cn.getDeclaredMethods(name)) {
            if (hasCompatibleNumberOfArgs(mn, nArgs)) {
                boolean match = true;
                for (int i = 0; i < nArgs; i += 1) {
                    if (!hasCompatibleType(args, mn, i)) {
                        match = false;
                        break;
                    }
                }
                if (match) {
                    if (method == null) {
                        method = mn;
                    } else if (cn.equals(this) || method.getParameters().length != nArgs) {
                        return null;
                    } else {
                        for (int i = 0; i < nArgs; i += 1) {
                            // prefer super method if it matches better
                            if (!hasExactMatchingCompatibleType(method, mn, i)) {
                                return null;
                            }
                        }
                    }
                }
            }
        }
    }
    return method;
}
Also used : TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression)

Example 77 with TupleExpression

use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy by apache.

the class GinqAstBuilder method visitMethodCallExpression.

@Override
public void visitMethodCallExpression(MethodCallExpression call) {
    final String methodName = call.getMethodAsString();
    if (KW_OVER.equals(methodName)) {
        visitingOverClause = true;
    }
    super.visitMethodCallExpression(call);
    if (KW_OVER.equals(methodName)) {
        visitingOverClause = false;
    }
    if (!KEYWORD_SET.contains(methodName)) {
        ignoredMethodCallExpressionList.add(call);
        return;
    }
    if (KW_FROM.equals(methodName)) {
        final GinqExpression ginqExpression = new GinqExpression();
        ginqExpression.setSourcePosition(call);
        // store the result
        ginqExpressionStack.push(ginqExpression);
    }
    GinqExpression currentGinqExpression = ginqExpressionStack.peek();
    AbstractGinqExpression latestGinqExpressionClause = getLatestGinqExpressionClause(call);
    if (KW_FROM.equals(methodName) || JoinExpression.isJoinExpression(methodName)) {
        ArgumentListExpression arguments = (ArgumentListExpression) call.getArguments();
        if (arguments.getExpressions().size() != 1) {
            this.collectSyntaxError(new GinqSyntaxError("Only 1 argument expected for `" + methodName + "`, e.g. `" + methodName + " n in nums`", call.getLineNumber(), call.getColumnNumber()));
        }
        final Expression expression = arguments.getExpression(0);
        if (!(expression instanceof BinaryExpression && ((BinaryExpression) expression).getOperation().getType() == Types.KEYWORD_IN)) {
            this.collectSyntaxError(new GinqSyntaxError("`in` is expected for `" + methodName + "`, e.g. `" + methodName + " n in nums`", call.getLineNumber(), call.getColumnNumber()));
        }
        BinaryExpression binaryExpression = (BinaryExpression) expression;
        Expression aliasExpr = binaryExpression.getLeftExpression();
        Expression dataSourceExpr = binaryExpression.getRightExpression();
        DataSourceExpression dataSourceExpression;
        if (KW_FROM.equals(methodName)) {
            dataSourceExpression = new FromExpression(aliasExpr, dataSourceExpr);
            currentGinqExpression.setFromExpression((FromExpression) dataSourceExpression);
        } else {
            dataSourceExpression = new JoinExpression(methodName, aliasExpr, dataSourceExpr);
            currentGinqExpression.addJoinExpression((JoinExpression) dataSourceExpression);
        }
        dataSourceExpression.setSourcePosition(call.getMethod());
        setLatestGinqExpressionClause(dataSourceExpression);
        return;
    }
    if (KW_WHERE.equals(methodName) || KW_ON.equals(methodName) || KW_HAVING.equals(methodName)) {
        Expression filterExpr = ((ArgumentListExpression) call.getArguments()).getExpression(0);
        FilterExpression filterExpression;
        if (KW_WHERE.equals(methodName)) {
            filterExpression = new WhereExpression(filterExpr);
        } else if (KW_ON.equals(methodName)) {
            filterExpression = new OnExpression(filterExpr);
        } else {
            filterExpression = new HavingExpression(filterExpr);
        }
        filterExpression.setSourcePosition(call.getMethod());
        if (latestGinqExpressionClause instanceof JoinExpression && filterExpression instanceof OnExpression) {
            ((JoinExpression) latestGinqExpressionClause).setOnExpression((OnExpression) filterExpression);
        } else if (latestGinqExpressionClause instanceof DataSourceHolder && filterExpression instanceof WhereExpression) {
            if (null != currentGinqExpression.getGroupExpression() || null != currentGinqExpression.getOrderExpression() || null != currentGinqExpression.getLimitExpression()) {
                this.collectSyntaxError(new GinqSyntaxError("The preceding clause of `" + methodName + "` should be `from`/" + "join clause", call.getLineNumber(), call.getColumnNumber()));
            }
            currentGinqExpression.setWhereExpression((WhereExpression) filterExpression);
        } else if (latestGinqExpressionClause instanceof GroupExpression && filterExpression instanceof HavingExpression) {
            ((GroupExpression) latestGinqExpressionClause).setHavingExpression((HavingExpression) filterExpression);
        } else {
            this.collectSyntaxError(new GinqSyntaxError("The preceding clause of `" + methodName + "` should be " + (KW_ON.equals(methodName) ? "" : "`from`/") + "join clause", call.getLineNumber(), call.getColumnNumber()));
        }
        if (latestGinqExpressionClause instanceof DataSourceHolder) {
            if (latestGinqExpressionClause instanceof DataSourceExpression) {
                filterExpression.setDataSourceExpression(((DataSourceExpression) latestGinqExpressionClause));
            } else {
                filterExpression.setDataSourceExpression(((DataSourceHolder) latestGinqExpressionClause).getDataSourceExpression());
            }
        }
        setLatestGinqExpressionClause(filterExpression);
        return;
    }
    if (KW_EXISTS.equals(methodName)) {
        if (null != latestGinqExpression) {
            ArgumentListExpression argumentListExpression = (ArgumentListExpression) call.getArguments();
            if (argumentListExpression.getExpressions().isEmpty() && isSelectMethodCallExpression(call.getObjectExpression())) {
                call.setObjectExpression(latestGinqExpression);
                // use the nested ginq and clear it
                latestGinqExpression = null;
            }
        }
    }
    if (KW_GROUPBY.equals(methodName)) {
        GroupExpression groupExpression = new GroupExpression(call.getArguments());
        groupExpression.setSourcePosition(call.getMethod());
        currentGinqExpression.setGroupExpression(groupExpression);
        if (latestGinqExpressionClause instanceof OrderExpression) {
            this.collectSyntaxError(new GinqSyntaxError("The clause `" + methodName + "` should be in front of `orderby`", call.getLineNumber(), call.getColumnNumber()));
        } else if (latestGinqExpressionClause instanceof LimitExpression) {
            this.collectSyntaxError(new GinqSyntaxError("The clause `" + methodName + "` should be in front of `limit`", call.getLineNumber(), call.getColumnNumber()));
        }
        if (latestGinqExpressionClause instanceof DataSourceHolder) {
            groupExpression.setDataSourceExpression(((DataSourceHolder) latestGinqExpressionClause).getDataSourceExpression());
        }
        setLatestGinqExpressionClause(groupExpression);
        return;
    }
    if (KW_ORDERBY.equals(methodName) && !visitingOverClause) {
        OrderExpression orderExpression = new OrderExpression(call.getArguments());
        orderExpression.setSourcePosition(call.getMethod());
        currentGinqExpression.setOrderExpression(orderExpression);
        if (latestGinqExpressionClause instanceof LimitExpression) {
            this.collectSyntaxError(new GinqSyntaxError("The clause `" + methodName + "` should be in front of `limit`", call.getLineNumber(), call.getColumnNumber()));
        }
        if (latestGinqExpressionClause instanceof DataSourceHolder) {
            orderExpression.setDataSourceExpression(((DataSourceHolder) latestGinqExpressionClause).getDataSourceExpression());
        }
        setLatestGinqExpressionClause(orderExpression);
        return;
    }
    if (KW_LIMIT.equals(methodName)) {
        LimitExpression limitExpression = new LimitExpression(call.getArguments());
        limitExpression.setSourcePosition(call.getMethod());
        currentGinqExpression.setLimitExpression(limitExpression);
        if (latestGinqExpressionClause instanceof DataSourceHolder) {
            limitExpression.setDataSourceExpression(((DataSourceHolder) latestGinqExpressionClause).getDataSourceExpression());
        }
        setLatestGinqExpressionClause(limitExpression);
        return;
    }
    if (KW_SELECT.equals(methodName)) {
        TupleExpression tupleExpression = (TupleExpression) call.getArguments();
        if (1 == tupleExpression.getExpressions().size()) {
            Expression firstExpression = tupleExpression.getExpressions().get(0);
            if (firstExpression instanceof MethodCallExpression) {
                MethodCallExpression mce = (MethodCallExpression) firstExpression;
                if (KW_DISTINCT.equals(mce.getMethodAsString())) {
                    tupleExpression = (TupleExpression) mce.getArguments();
                    currentGinqExpression.putNodeMetaData(GINQ_SELECT_DISTINCT, true);
                }
            }
        } else {
            for (Expression expression : tupleExpression.getExpressions()) {
                if (expression instanceof MethodCallExpression) {
                    MethodCallExpression mce = (MethodCallExpression) expression;
                    if (KW_DISTINCT.equals(mce.getMethodAsString())) {
                        this.collectSyntaxError(new GinqSyntaxError("Invalid usage of `distinct`", mce.getLineNumber(), mce.getColumnNumber()));
                    }
                }
            }
        }
        SelectExpression selectExpression = new SelectExpression(tupleExpression);
        selectExpression.setSourcePosition(call.getMethod());
        currentGinqExpression.setSelectExpression(selectExpression);
        if (latestGinqExpressionClause instanceof DataSourceHolder) {
            selectExpression.setDataSourceExpression(((DataSourceHolder) latestGinqExpressionClause).getDataSourceExpression());
        }
        setLatestGinqExpressionClause(selectExpression);
        latestGinqExpression = ginqExpressionStack.pop();
        latestGinqExpression.setSourcePosition(call);
        return;
    }
}
Also used : LimitExpression(org.apache.groovy.ginq.dsl.expression.LimitExpression) OrderExpression(org.apache.groovy.ginq.dsl.expression.OrderExpression) GinqExpression(org.apache.groovy.ginq.dsl.expression.GinqExpression) AbstractGinqExpression(org.apache.groovy.ginq.dsl.expression.AbstractGinqExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) SelectExpression(org.apache.groovy.ginq.dsl.expression.SelectExpression) GroupExpression(org.apache.groovy.ginq.dsl.expression.GroupExpression) FromExpression(org.apache.groovy.ginq.dsl.expression.FromExpression) OnExpression(org.apache.groovy.ginq.dsl.expression.OnExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) GinqExpression(org.apache.groovy.ginq.dsl.expression.GinqExpression) JoinExpression(org.apache.groovy.ginq.dsl.expression.JoinExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) LimitExpression(org.apache.groovy.ginq.dsl.expression.LimitExpression) Expression(org.codehaus.groovy.ast.expr.Expression) WhereExpression(org.apache.groovy.ginq.dsl.expression.WhereExpression) FilterExpression(org.apache.groovy.ginq.dsl.expression.FilterExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) DataSourceExpression(org.apache.groovy.ginq.dsl.expression.DataSourceExpression) OrderExpression(org.apache.groovy.ginq.dsl.expression.OrderExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) SelectExpression(org.apache.groovy.ginq.dsl.expression.SelectExpression) AbstractGinqExpression(org.apache.groovy.ginq.dsl.expression.AbstractGinqExpression) GroupExpression(org.apache.groovy.ginq.dsl.expression.GroupExpression) HavingExpression(org.apache.groovy.ginq.dsl.expression.HavingExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) ShutdownExpression(org.apache.groovy.ginq.dsl.expression.ShutdownExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) OnExpression(org.apache.groovy.ginq.dsl.expression.OnExpression) FromExpression(org.apache.groovy.ginq.dsl.expression.FromExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) HavingExpression(org.apache.groovy.ginq.dsl.expression.HavingExpression) AbstractGinqExpression(org.apache.groovy.ginq.dsl.expression.AbstractGinqExpression) JoinExpression(org.apache.groovy.ginq.dsl.expression.JoinExpression) DataSourceHolder(org.apache.groovy.ginq.dsl.expression.DataSourceHolder) FilterExpression(org.apache.groovy.ginq.dsl.expression.FilterExpression) DataSourceExpression(org.apache.groovy.ginq.dsl.expression.DataSourceExpression) WhereExpression(org.apache.groovy.ginq.dsl.expression.WhereExpression)

Example 78 with TupleExpression

use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy by apache.

the class AutoNewLineTransformer method visitMethodCallExpression.

@Override
public void visitMethodCallExpression(final MethodCallExpression call) {
    boolean old = inBuilderMethod;
    inBuilderMethod = false;
    if (call.isImplicitThis() && call.getArguments() instanceof TupleExpression) {
        List<Expression> expressions = ((TupleExpression) call.getArguments()).getExpressions();
        if (!expressions.isEmpty()) {
            Expression lastArg = expressions.get(expressions.size() - 1);
            if (lastArg instanceof ClosureExpression) {
                call.getObjectExpression().visit(this);
                call.getMethod().visit(this);
                for (Expression expression : expressions) {
                    inBuilderMethod = (expression == lastArg);
                    expression.visit(this);
                }
            }
        }
    } else {
        super.visitMethodCallExpression(call);
    }
    inBuilderMethod = old;
}
Also used : VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression)

Aggregations

TupleExpression (org.codehaus.groovy.ast.expr.TupleExpression)78 Expression (org.codehaus.groovy.ast.expr.Expression)65 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)56 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)48 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)44 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)42 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)41 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)40 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)35 ClassNode (org.codehaus.groovy.ast.ClassNode)34 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)34 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)31 ArrayExpression (org.codehaus.groovy.ast.expr.ArrayExpression)23 DeclarationExpression (org.codehaus.groovy.ast.expr.DeclarationExpression)23 MapExpression (org.codehaus.groovy.ast.expr.MapExpression)22 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)20 Parameter (org.codehaus.groovy.ast.Parameter)20 ListExpression (org.codehaus.groovy.ast.expr.ListExpression)18 MapEntryExpression (org.codehaus.groovy.ast.expr.MapEntryExpression)18 CastExpression (org.codehaus.groovy.ast.expr.CastExpression)17