use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy by apache.
the class InvocationWriter method makeUncachedCall.
protected void makeUncachedCall(Expression origin, ClassExpression sender, Expression receiver, Expression message, Expression arguments, MethodCallerMultiAdapter adapter, boolean safe, boolean spreadSafe, boolean implicitThis, boolean containsSpreadExpression) {
CompileStack compileStack = controller.getCompileStack();
OperandStack operandStack = controller.getOperandStack();
AsmClassGenerator acg = controller.getAcg();
// ensure VariableArguments are read, not stored
compileStack.pushLHS(false);
// sender only for call sites
if (adapter == AsmClassGenerator.setProperty) {
ConstantExpression.NULL.visit(acg);
} else {
sender.visit(acg);
}
String methodName = getMethodName(message);
if (adapter == invokeMethodOnSuper && methodName != null) {
// for MOP method
controller.getSuperMethodNames().add(methodName);
}
// receiver
compileStack.pushImplicitThis(implicitThis);
receiver.visit(acg);
operandStack.box();
compileStack.popImplicitThis();
int operandsToRemove = 2;
// message
if (message != null) {
message.visit(acg);
operandStack.box();
operandsToRemove += 1;
}
// arguments
int numberOfArguments = containsSpreadExpression ? -1 : AsmClassGenerator.argumentSize(arguments);
if (numberOfArguments > MethodCallerMultiAdapter.MAX_ARGS || containsSpreadExpression) {
ArgumentListExpression ae = makeArgumentList(arguments);
if (containsSpreadExpression) {
acg.despreadList(ae.getExpressions(), true);
} else {
ae.visit(acg);
}
} else if (numberOfArguments > 0) {
operandsToRemove += numberOfArguments;
TupleExpression te = (TupleExpression) arguments;
for (int i = 0; i < numberOfArguments; i += 1) {
Expression argument = te.getExpression(i);
argument.visit(acg);
operandStack.box();
if (argument instanceof CastExpression)
acg.loadWrapper(argument);
}
}
if (adapter == null)
adapter = invokeMethod;
adapter.call(controller.getMethodVisitor(), numberOfArguments, safe, spreadSafe);
compileStack.popLHS();
operandStack.replace(ClassHelper.OBJECT_TYPE, operandsToRemove);
}
use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy by apache.
the class InvocationWriter method writeDirectConstructorCall.
private boolean writeDirectConstructorCall(final ConstructorCallExpression call) {
if (!controller.isFastPath())
return false;
OptimizingStatementWriter.StatementMeta meta = call.getNodeMetaData(OptimizingStatementWriter.StatementMeta.class);
ConstructorNode cn = null;
if (meta != null)
cn = (ConstructorNode) meta.target;
if (cn == null)
return false;
String ownerDescriptor = prepareConstructorCall(cn);
TupleExpression args = makeArgumentList(call.getArguments());
loadArguments(args.getExpressions(), cn.getParameters());
finnishConstructorCall(cn, ownerDescriptor, args.getExpressions().size());
return true;
}
use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy by apache.
the class InvocationWriter method makeDirectConstructorCall.
private boolean makeDirectConstructorCall(final List<ConstructorNode> constructors, final ConstructorCallExpression call, final ClassNode callNode) {
if (!controller.isConstructor())
return false;
Expression arguments = call.getArguments();
List<Expression> argumentList;
if (arguments instanceof TupleExpression) {
argumentList = ((TupleExpression) arguments).getExpressions();
} else {
argumentList = new ArrayList<>();
argumentList.add(arguments);
}
for (Expression expression : argumentList) {
if (expression instanceof SpreadExpression)
return false;
}
ConstructorNode cn = getMatchingConstructor(constructors, argumentList);
if (cn == null)
return false;
MethodVisitor mv = controller.getMethodVisitor();
OperandStack operandStack = controller.getOperandStack();
Parameter[] params = cn.getParameters();
mv.visitVarInsn(ALOAD, 0);
for (int i = 0, n = params.length; i < n; i += 1) {
Expression expression = argumentList.get(i);
expression.visit(controller.getAcg());
if (!isNullConstant(expression)) {
operandStack.doGroovyCast(params[i].getType());
}
operandStack.remove(1);
}
String descriptor = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, params);
mv.visitMethodInsn(INVOKESPECIAL, BytecodeHelper.getClassInternalName(callNode), "<init>", descriptor, false);
return true;
}
use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy by apache.
the class OptimizingStatementWriter method writeDeclarationExtraction.
private boolean writeDeclarationExtraction(final Statement statement) {
Expression ex = null;
if (statement instanceof ReturnStatement) {
ReturnStatement rs = (ReturnStatement) statement;
ex = rs.getExpression();
} else if (statement instanceof ExpressionStatement) {
ExpressionStatement es = (ExpressionStatement) statement;
ex = es.getExpression();
} else {
throw new GroovyBugError("unknown statement type :" + statement.getClass());
}
if (!(ex instanceof DeclarationExpression))
return true;
DeclarationExpression declaration = (DeclarationExpression) ex;
ex = declaration.getLeftExpression();
if (ex instanceof TupleExpression)
return false;
// stash declared variable in case we do subsequent visits after we
// change to assignment only
StatementMeta meta = statement.getNodeMetaData(StatementMeta.class);
if (meta != null) {
meta.declaredVariableExpression = declaration.getVariableExpression();
}
// change statement to do assignment only
BinaryExpression assignment = new BinaryExpression(declaration.getLeftExpression(), declaration.getOperation(), declaration.getRightExpression());
assignment.setSourcePosition(declaration);
assignment.copyNodeMetaData(declaration);
// replace statement code
if (statement instanceof ReturnStatement) {
ReturnStatement rs = (ReturnStatement) statement;
rs.setExpression(assignment);
} else if (statement instanceof ExpressionStatement) {
ExpressionStatement es = (ExpressionStatement) statement;
es.setExpression(assignment);
} else {
throw new GroovyBugError("unknown statement type :" + statement.getClass());
}
return true;
}
use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy by apache.
the class StaticTypeCheckingVisitor method typeCheckAssignment.
protected void typeCheckAssignment(final BinaryExpression assignmentExpression, final Expression leftExpression, final ClassNode leftExpressionType, final Expression rightExpression, final ClassNode rightExpressionType) {
if (leftExpression instanceof TupleExpression) {
if (!typeCheckMultipleAssignmentAndContinue(leftExpression, rightExpression))
return;
}
// TODO: need errors for write-only too!
if (addedReadOnlyPropertyError(leftExpression))
return;
ClassNode rTypeWrapped = adjustTypeForSpreading(rightExpressionType, leftExpression);
if (!checkCompatibleAssignmentTypes(leftExpressionType, rTypeWrapped, rightExpression)) {
if (!extension.handleIncompatibleAssignment(leftExpressionType, rightExpressionType, assignmentExpression)) {
addAssignmentError(leftExpressionType, rightExpressionType, rightExpression);
}
} else {
ClassNode lTypeRedirect = leftExpressionType.redirect();
addPrecisionErrors(lTypeRedirect, leftExpressionType, rightExpressionType, rightExpression);
if (rightExpression instanceof ListExpression) {
addListAssignmentConstructorErrors(lTypeRedirect, leftExpressionType, rightExpressionType, rightExpression, assignmentExpression);
} else if (rightExpression instanceof MapExpression) {
addMapAssignmentConstructorErrors(lTypeRedirect, leftExpression, rightExpression);
}
if (!hasGStringStringError(leftExpressionType, rTypeWrapped, rightExpression) && !isConstructorAbbreviation(leftExpressionType, rightExpression)) {
checkTypeGenerics(leftExpressionType, rTypeWrapped, rightExpression);
}
}
}
Aggregations