use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy by apache.
the class StaticTypeCheckingVisitor method typeCheckMapConstructor.
protected MethodNode typeCheckMapConstructor(final ConstructorCallExpression call, final ClassNode receiver, final Expression arguments) {
MethodNode node = null;
if (arguments instanceof TupleExpression) {
TupleExpression texp = (TupleExpression) arguments;
List<Expression> expressions = texp.getExpressions();
// should only get here with size = 2 when inner class constructor
if (expressions.size() == 1 || expressions.size() == 2) {
Expression expression = expressions.get(expressions.size() - 1);
if (expression instanceof MapExpression) {
MapExpression argList = (MapExpression) expression;
checkGroovyConstructorMap(call, receiver, argList);
Parameter[] params = expressions.size() == 1 ? new Parameter[] { new Parameter(MAP_TYPE, "map") } : new Parameter[] { new Parameter(receiver.redirect().getOuterClass(), "$p$"), new Parameter(MAP_TYPE, "map") };
node = new ConstructorNode(Opcodes.ACC_PUBLIC, params, ClassNode.EMPTY_ARRAY, GENERATED_EMPTY_STATEMENT);
node.setDeclaringClass(receiver);
}
}
}
return node;
}
use of org.codehaus.groovy.ast.expr.TupleExpression in project groovy by apache.
the class StaticTypeCheckingVisitor method typeCheckMultipleAssignmentAndContinue.
private boolean typeCheckMultipleAssignmentAndContinue(final Expression leftExpression, Expression rightExpression) {
if (rightExpression instanceof VariableExpression || rightExpression instanceof PropertyExpression || rightExpression instanceof MethodCall) {
ClassNode inferredType = Optional.ofNullable(getType(rightExpression)).orElseGet(rightExpression::getType);
GenericsType[] genericsTypes = inferredType.getGenericsTypes();
ListExpression listExpression = new ListExpression();
listExpression.setSourcePosition(rightExpression);
// convert Tuple[1-16] bearing expressions to mock list for checking
for (int n = TUPLE_TYPES.indexOf(inferredType), i = 0; i < n; i += 1) {
ClassNode type = (genericsTypes != null ? genericsTypes[i].getType() : OBJECT_TYPE);
listExpression.addExpression(varX("v" + (i + 1), type));
}
if (!listExpression.getExpressions().isEmpty()) {
rightExpression = listExpression;
}
}
if (!(rightExpression instanceof ListExpression)) {
addStaticTypeError("Multiple assignments without list or tuple on the right-hand side are unsupported in static type checking mode", rightExpression);
return false;
}
TupleExpression tuple = (TupleExpression) leftExpression;
ListExpression values = (ListExpression) rightExpression;
List<Expression> tupleExpressions = tuple.getExpressions();
List<Expression> valueExpressions = values.getExpressions();
if (tupleExpressions.size() > valueExpressions.size()) {
addStaticTypeError("Incorrect number of values. Expected:" + tupleExpressions.size() + " Was:" + valueExpressions.size(), values);
return false;
}
for (int i = 0, n = tupleExpressions.size(); i < n; i += 1) {
ClassNode valueType = getType(valueExpressions.get(i));
ClassNode targetType = getType(tupleExpressions.get(i));
if (!isAssignableTo(valueType, targetType)) {
addStaticTypeError("Cannot assign value of type " + prettyPrintType(valueType) + " to variable of type " + prettyPrintType(targetType), rightExpression);
return false;
}
storeType(tupleExpressions.get(i), valueType);
}
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 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;
}
Aggregations