use of org.codehaus.groovy.ast.expr.ListExpression in project groovy by apache.
the class StaticTypeCheckingVisitor method addListAssignmentConstructorErrors.
private void addListAssignmentConstructorErrors(final ClassNode leftRedirect, final ClassNode leftExpressionType, final ClassNode inferredRightExpressionType, final Expression rightExpression, final Expression assignmentExpression) {
// GROOVY-6802, GROOVY-6803
if (isWildcardLeftHandSide(leftRedirect) && !isClassType(leftRedirect))
return;
// In that case, more checks can be performed
if (!implementsInterfaceOrIsSubclassOf(LIST_TYPE, leftRedirect) && (!leftRedirect.isAbstract() || leftRedirect.isArray()) && !ArrayList_TYPE.isDerivedFrom(leftRedirect) && !LinkedHashSet_TYPE.isDerivedFrom(leftRedirect)) {
ClassNode[] types = getArgumentTypes(args(((ListExpression) rightExpression).getExpressions()));
MethodNode methodNode = checkGroovyStyleConstructor(leftRedirect, types, assignmentExpression);
if (methodNode != null) {
rightExpression.putNodeMetaData(DIRECT_METHOD_CALL_TARGET, methodNode);
}
} else if (implementsInterfaceOrIsSubclassOf(inferredRightExpressionType, LIST_TYPE) && !implementsInterfaceOrIsSubclassOf(inferredRightExpressionType, leftRedirect)) {
if (!extension.handleIncompatibleAssignment(leftExpressionType, inferredRightExpressionType, assignmentExpression)) {
addAssignmentError(leftExpressionType, inferredRightExpressionType, assignmentExpression);
}
}
}
use of org.codehaus.groovy.ast.expr.ListExpression 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.ListExpression in project groovy by apache.
the class AsmClassGenerator method containsSpreadExpression.
public static boolean containsSpreadExpression(final Expression arguments) {
List<Expression> args;
if (arguments instanceof TupleExpression) {
TupleExpression tupleExpression = (TupleExpression) arguments;
args = tupleExpression.getExpressions();
} else if (arguments instanceof ListExpression) {
ListExpression le = (ListExpression) arguments;
args = le.getExpressions();
} else {
return arguments instanceof SpreadExpression;
}
for (Expression arg : args) {
if (arg instanceof SpreadExpression)
return true;
}
return false;
}
use of org.codehaus.groovy.ast.expr.ListExpression in project groovy by apache.
the class AsmClassGenerator method visitArrayAttributes.
private void visitArrayAttributes(final AnnotationNode an, final Map<String, ListExpression> arrayAttr, final AnnotationVisitor av) {
if (arrayAttr.isEmpty())
return;
for (Map.Entry<String, ListExpression> entry : arrayAttr.entrySet()) {
AnnotationVisitor av2 = av.visitArray(entry.getKey());
List<Expression> values = entry.getValue().getExpressions();
if (!values.isEmpty()) {
int arrayElementType = determineCommonArrayType(values);
for (Expression exprChild : values) {
visitAnnotationArrayElement(exprChild, arrayElementType, av2);
}
}
av2.visitEnd();
}
}
use of org.codehaus.groovy.ast.expr.ListExpression in project groovy by apache.
the class AsmClassGenerator method visitAnnotationAttributes.
/**
* Generates the annotation attributes.
*
* @param an the node with an annotation
* @param av the visitor to use
*/
private void visitAnnotationAttributes(final AnnotationNode an, final AnnotationVisitor av) {
Map<String, Object> constantAttrs = new HashMap<>();
Map<String, PropertyExpression> enumAttrs = new HashMap<>();
Map<String, Object> atAttrs = new HashMap<>();
Map<String, ListExpression> arrayAttrs = new HashMap<>();
for (Map.Entry<String, Expression> member : an.getMembers().entrySet()) {
String name = member.getKey();
Expression expr = member.getValue();
if (expr instanceof AnnotationConstantExpression) {
atAttrs.put(name, ((AnnotationConstantExpression) expr).getValue());
} else if (expr instanceof ConstantExpression) {
constantAttrs.put(name, ((ConstantExpression) expr).getValue());
} else if (expr instanceof ClassExpression) {
constantAttrs.put(name, Type.getType(BytecodeHelper.getTypeDescription((expr.getType()))));
} else if (expr instanceof PropertyExpression) {
enumAttrs.put(name, (PropertyExpression) expr);
} else if (expr instanceof ListExpression) {
arrayAttrs.put(name, (ListExpression) expr);
} else if (expr instanceof ClosureExpression) {
ClassNode closureClass = controller.getClosureWriter().getOrAddClosureClass((ClosureExpression) expr, ACC_PUBLIC);
constantAttrs.put(name, Type.getType(BytecodeHelper.getTypeDescription(closureClass)));
}
}
for (Map.Entry<String, Object> entry : constantAttrs.entrySet()) {
av.visit(entry.getKey(), entry.getValue());
}
for (Map.Entry<String, PropertyExpression> entry : enumAttrs.entrySet()) {
PropertyExpression propExp = entry.getValue();
av.visitEnum(entry.getKey(), BytecodeHelper.getTypeDescription(propExp.getObjectExpression().getType()), String.valueOf(((ConstantExpression) propExp.getProperty()).getValue()));
}
for (Map.Entry<String, Object> entry : atAttrs.entrySet()) {
AnnotationNode atNode = (AnnotationNode) entry.getValue();
AnnotationVisitor av2 = av.visitAnnotation(entry.getKey(), BytecodeHelper.getTypeDescription(atNode.getClassNode()));
visitAnnotationAttributes(atNode, av2);
av2.visitEnd();
}
visitArrayAttributes(an, arrayAttrs, av);
}
Aggregations