call.setMethodTarget((MethodNode) bin.getNodeMetaData(StaticTypesMarker.DIRECT_METHOD_CALL_TARGET));
call.setSourcePosition(bin);
call.copyNodeMetaData(bin);
TernaryExpression tExp = new TernaryExpression(
new BooleanExpression(
new BinaryExpression(rightExpression, Token.newSymbol("==",-1,-1), new ConstantExpression(null))
),
new BinaryExpression(leftExpression, Token.newSymbol("==", -1, -1), new ConstantExpression(null)),
call
);
return staticCompilationTransformer.transform(tExp);
}
if (list != null) {
if (operationType == Types.COMPARE_TO) {
StaticTypesTypeChooser typeChooser = staticCompilationTransformer.getTypeChooser();
ClassNode classNode = staticCompilationTransformer.getClassNode();
ClassNode leftType = typeChooser.resolveType(leftExpression, classNode);
if (leftType.implementsInterface(ClassHelper.COMPARABLE_TYPE)) {
ClassNode rightType = typeChooser.resolveType(rightExpression, classNode);
if (rightType.implementsInterface(ClassHelper.COMPARABLE_TYPE)) {
Expression left = staticCompilationTransformer.transform(leftExpression);
Expression right = staticCompilationTransformer.transform(rightExpression);
MethodCallExpression call = new MethodCallExpression(left, "compareTo", new ArgumentListExpression(right));
call.setImplicitThis(false);
call.setMethodTarget(COMPARE_TO_METHOD);
CompareIdentityExpression compareIdentity = new CompareIdentityExpression(
left, right
);
compareIdentity.putNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE, ClassHelper.boolean_TYPE);
TernaryExpression result = new TernaryExpression(
new BooleanExpression(compareIdentity), // a==b
CONSTANT_ZERO,
new TernaryExpression(
new BooleanExpression(new CompareToNullExpression(left, true)), // a==null
CONSTANT_MINUS_ONE,
new TernaryExpression(
new BooleanExpression(new CompareToNullExpression(right, true)), // b==null
CONSTANT_ONE,
call
)
)
);
compareIdentity.putNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE, ClassHelper.int_TYPE);
result.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, ClassHelper.int_TYPE);
TernaryExpression expr = (TernaryExpression) result.getFalseExpression();
expr.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, ClassHelper.int_TYPE);
expr.getFalseExpression().putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, ClassHelper.int_TYPE);
return result;
}
}
}
boolean isAssignment = StaticTypeCheckingSupport.isAssignment(operationType);
MethodCallExpression call;
MethodNode node = (MethodNode) list[0];
String name = (String) list[1];
Expression left = staticCompilationTransformer.transform(leftExpression);
Expression right = staticCompilationTransformer.transform(rightExpression);
call = new MethodCallExpression(
left,
name,
new ArgumentListExpression(right)
);
call.setImplicitThis(false);
call.setMethodTarget(node);
MethodNode adapter = StaticCompilationTransformer.BYTECODE_BINARY_ADAPTERS.get(operationType);
if (adapter != null) {
ClassExpression sba = new ClassExpression(StaticCompilationTransformer.BYTECODE_ADAPTER_CLASS);
// replace with compareEquals
call = new MethodCallExpression(sba,
"compareEquals",
new ArgumentListExpression(left, right));
call.setMethodTarget(adapter);
call.setImplicitThis(false);
}
if (!isAssignment) return call;
// case of +=, -=, /=, ...
// the method represents the operation type only, and we must add an assignment
return new BinaryExpression(left, Token.newSymbol("=", operation.getStartLine(), operation.getStartColumn()), call);
}
if (bin.getOperation().getType() == Types.EQUAL && leftExpression instanceof TupleExpression && rightExpression instanceof ListExpression) {
// multiple assignment
ListOfExpressionsExpression cle = new ListOfExpressionsExpression();
boolean isDeclaration = bin instanceof DeclarationExpression;
List<Expression> leftExpressions = ((TupleExpression) leftExpression).getExpressions();
List<Expression> rightExpressions = ((ListExpression) rightExpression).getExpressions();
Iterator<Expression> leftIt = leftExpressions.iterator();
Iterator<Expression> rightIt = rightExpressions.iterator();
if (isDeclaration) {
while (leftIt.hasNext()) {
Expression left = leftIt.next();
if (rightIt.hasNext()) {
Expression right = rightIt.next();
BinaryExpression bexp = new DeclarationExpression(left, bin.getOperation(), right);
bexp.setSourcePosition(right);
cle.addExpression(bexp);
}
}
} else {
// (next, result) = [ result, next+result ]
// -->
// def tmp1 = result
// def tmp2 = next+result
// next = tmp1
// result = tmp2
int size = rightExpressions.size();
List<Expression> tmpAssignments = new ArrayList<Expression>(size);
List<Expression> finalAssignments = new ArrayList<Expression>(size);
for (int i=0; i<Math.min(size, leftExpressions.size());i++ ) {
Expression left = leftIt.next();
Expression right = rightIt.next();
VariableExpression tmpVar = new VariableExpression("$tmpVar$"+tmpVarCounter++);
BinaryExpression bexp = new DeclarationExpression(tmpVar, bin.getOperation(), right);
bexp.setSourcePosition(right);
tmpAssignments.add(bexp);
bexp = new BinaryExpression(left, bin.getOperation(), new VariableExpression(tmpVar));
bexp.setSourcePosition(left);
finalAssignments.add(bexp);
}
for (Expression tmpAssignment : tmpAssignments) {
cle.addExpression(tmpAssignment);
}