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;
}
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;
}
}
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;
}
Aggregations