use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy by apache.
the class MacroInvocationTrap method handleTargetMethodCallExpression.
@Override
protected boolean handleTargetMethodCallExpression(MethodCallExpression macroCall) {
final ClosureExpression closureExpression = getClosureArgument(macroCall);
if (closureExpression == null) {
return true;
}
if (closureExpression.getParameters() != null && closureExpression.getParameters().length > 0) {
addError("Macro closure arguments are not allowed", closureExpression);
return true;
}
final MapExpression mapExpression = buildSubstitutionMap(closureExpression);
String source = convertClosureToSource(closureExpression);
BlockStatement closureBlock = (BlockStatement) closureExpression.getCode();
Boolean asIs = false;
TupleExpression macroArguments = getMacroArguments(macroCall);
if (macroArguments == null) {
return true;
}
List<Expression> macroArgumentsExpressions = macroArguments.getExpressions();
if (macroArgumentsExpressions.size() == 2 || macroArgumentsExpressions.size() == 3) {
Expression asIsArgumentExpression = macroArgumentsExpressions.get(macroArgumentsExpressions.size() - 2);
if ((asIsArgumentExpression instanceof ConstantExpression)) {
ConstantExpression asIsConstantExpression = (ConstantExpression) asIsArgumentExpression;
if (!(asIsConstantExpression.getValue() instanceof Boolean)) {
addError("AsIs argument value should be boolean", asIsConstantExpression);
return true;
}
asIs = (Boolean) asIsConstantExpression.getValue();
}
}
macroArgumentsExpressions.remove(macroArgumentsExpressions.size() - 1);
macroArgumentsExpressions.add(new ConstantExpression(source));
macroArgumentsExpressions.add(mapExpression);
macroArgumentsExpressions.add(new ClassExpression(ClassHelper.makeWithoutCaching(MacroBuilder.getMacroValue(closureBlock, asIs).getClass(), false)));
macroCall.setObjectExpression(new PropertyExpression(new ClassExpression(ClassHelper.makeWithoutCaching(MacroBuilder.class, false)), "INSTANCE"));
macroCall.setSpreadSafe(false);
macroCall.setSafe(false);
macroCall.setImplicitThis(false);
return true;
}
use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy by apache.
the class MacroInvocationTrap method getClosureArgument.
protected ClosureExpression getClosureArgument(MethodCallExpression call) {
TupleExpression tupleArguments = getMacroArguments(call);
if (tupleArguments.getExpressions().size() < 1) {
addError("Call arguments should have at least one argument", tupleArguments);
return null;
}
Expression result = tupleArguments.getExpression(tupleArguments.getExpressions().size() - 1);
if (!(result instanceof ClosureExpression)) {
addError("Last call argument should be a closure", result);
return null;
}
return (ClosureExpression) result;
}
use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy by apache.
the class EnumCompletionVisitor method transformConstructor.
/**
* If constructor does not define a call to super, then transform constructor
* to get String,int parameters at beginning and add call super(String,int).
*/
private void transformConstructor(ConstructorNode ctor, boolean isAic) {
boolean chainedThisConstructorCall = false;
ConstructorCallExpression cce = null;
if (ctor.firstStatementIsSpecialConstructorCall()) {
Statement code = ctor.getFirstStatement();
cce = (ConstructorCallExpression) ((ExpressionStatement) code).getExpression();
if (cce.isSuperCall())
return;
// must be call to this(...)
chainedThisConstructorCall = true;
}
// we need to add parameters
Parameter[] oldP = ctor.getParameters();
Parameter[] newP = new Parameter[oldP.length + 2];
String stringParameterName = getUniqueVariableName("__str", ctor.getCode());
newP[0] = new Parameter(ClassHelper.STRING_TYPE, stringParameterName);
String intParameterName = getUniqueVariableName("__int", ctor.getCode());
newP[1] = new Parameter(ClassHelper.int_TYPE, intParameterName);
System.arraycopy(oldP, 0, newP, 2, oldP.length);
ctor.setParameters(newP);
VariableExpression stringVariable = new VariableExpression(newP[0]);
VariableExpression intVariable = new VariableExpression(newP[1]);
if (chainedThisConstructorCall) {
TupleExpression args = (TupleExpression) cce.getArguments();
List<Expression> argsExprs = args.getExpressions();
argsExprs.add(0, stringVariable);
argsExprs.add(1, intVariable);
} else {
// add a super call
List<Expression> args = new ArrayList<Expression>();
args.add(stringVariable);
args.add(intVariable);
if (isAic) {
for (Parameter parameter : oldP) {
args.add(new VariableExpression(parameter.getName()));
}
}
cce = new ConstructorCallExpression(ClassNode.SUPER, new ArgumentListExpression(args));
BlockStatement code = new BlockStatement();
code.addStatement(new ExpressionStatement(cce));
Statement oldCode = ctor.getCode();
if (oldCode != null)
code.addStatement(oldCode);
ctor.setCode(code);
}
}
use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy by apache.
the class ClassNodeUtils method hasPossibleStaticMethod.
/**
* Returns true if the given method has a possibly matching static method with the given name and arguments.
*
* @param cNode the ClassNode of interest
* @param name the name of the method of interest
* @param arguments the arguments to match against
* @param trySpread whether to try to account for SpreadExpressions within the arguments
* @return true if a matching method was found
*/
public static boolean hasPossibleStaticMethod(ClassNode cNode, String name, Expression arguments, boolean trySpread) {
int count = 0;
boolean foundSpread = false;
if (arguments instanceof TupleExpression) {
TupleExpression tuple = (TupleExpression) arguments;
for (Expression arg : tuple.getExpressions()) {
if (arg instanceof SpreadExpression) {
foundSpread = true;
} else {
count++;
}
}
} else if (arguments instanceof MapExpression) {
count = 1;
}
for (MethodNode method : cNode.getMethods(name)) {
if (method.isStatic()) {
Parameter[] parameters = method.getParameters();
// do fuzzy match for spread case: count will be number of non-spread args
if (trySpread && foundSpread && parameters.length >= count)
return true;
if (parameters.length == count)
return true;
// handle varargs case
if (parameters.length > 0 && parameters[parameters.length - 1].getType().isArray()) {
if (count >= parameters.length - 1)
return true;
// fuzzy match any spread to a varargs
if (trySpread && foundSpread)
return true;
}
// handle parameters with default values
int nonDefaultParameters = 0;
for (Parameter parameter : parameters) {
if (!parameter.hasInitialExpression()) {
nonDefaultParameters++;
}
}
if (count < parameters.length && nonDefaultParameters <= count) {
return true;
}
// TODO handle spread with nonDefaultParams?
}
}
return false;
}
use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy by apache.
the class InvocationWriter method writeNormalConstructorCall.
protected void writeNormalConstructorCall(final ConstructorCallExpression call) {
Expression arguments = call.getArguments();
if (arguments instanceof TupleExpression) {
TupleExpression tupleExpression = (TupleExpression) arguments;
int size = tupleExpression.getExpressions().size();
if (size == 0) {
arguments = MethodCallExpression.NO_ARGUMENTS;
}
}
Expression receiver = new ClassExpression(call.getType());
controller.getCallSiteWriter().makeCallSite(receiver, CallSiteWriter.CONSTRUCTOR, arguments, false, false, false, false);
}
Aggregations