new JavaField.Instance (
null,
HASH_CODE_FIELD_NAME,
JavaTypeName.INT);
JavaExpression condition =
new OperatorExpression.Binary (
JavaOperator.EQUALS_INT,
hashCodeField,
LiteralWrapper.make(new Integer(0)));
JavaStatement.Block thenBlock = new JavaStatement.Block();
IfThenElseStatement ifThen =
new IfThenElseStatement (condition, thenBlock);
hashCode.addStatement (ifThen);
// build up the hashcode value.
JavaExpression.LocalVariable result =
new LocalVariable ("result", JavaTypeName.INT);
LocalVariableDeclaration localVarDecl =
new LocalVariableDeclaration(result, LiteralWrapper.make(new Integer(17)));
thenBlock.addStatement(localVarDecl);
LiteralWrapper thirtySeven = LiteralWrapper.make (new Integer(37));
JavaExpression thirtySevenTimesResult =
new OperatorExpression.Binary(JavaOperator.MULTIPLY_INT, thirtySeven, result);
LiteralWrapper zero = LiteralWrapper.make (new Integer (0));
LiteralWrapper one = LiteralWrapper.make (new Integer (1));
// Start by including dc name in the hashcode.
// get objects hashcode
JavaExpression nameExpression =
new MethodInvocation.Instance (
new MethodInvocation.Instance(
null,
GET_DC_NAME_METHOD_NAME,
JavaTypeName.STRING,
MethodInvocation.InvocationType.VIRTUAL),
"hashCode",
JavaTypeName.INT,
MethodInvocation.InvocationType.VIRTUAL);
JavaExpression newResult =
new OperatorExpression.Binary (JavaOperator.ADD_INT, thirtySevenTimesResult, nameExpression);
JavaExpression assignResult = new Assignment (result, newResult);
thenBlock.addStatement(new ExpressionStatement (assignResult));
// Now get the contribution from each dc field.
for (FieldName fn : fieldNames) {
String javaFieldName = typeConstructorInfo.fieldJavaNames.get (fn);
JavaTypeName fieldType = fieldNameToType.get (fn);
JavaField field = new JavaField.Instance(null, javaFieldName, fieldType);
JavaExpression fieldExpression;
if (fieldType instanceof JavaTypeName.Primitive) {
if (fieldType instanceof JavaTypeName.Primitive.Boolean) {
fieldExpression =
new OperatorExpression.Ternary (field, zero, one);
} else if (fieldType instanceof JavaTypeName.Primitive.Byte ||
fieldType instanceof JavaTypeName.Primitive.Char ||
fieldType instanceof JavaTypeName.Primitive.Short) {
fieldExpression =
new CastExpression(JavaTypeName.INT, field);
}else if (fieldType instanceof JavaTypeName.Primitive.Double) {
// long f = Double.doubleToLongBits(f);
// result = (int) (f ^ (f >>> 32));
JavaExpression.LocalVariable f =
new LocalVariable ("f", JavaTypeName.LONG);
JavaExpression initializeF =
new MethodInvocation.Static (
JavaTypeName.DOUBLE_OBJECT,
"doubleToLongBits",
field,
JavaTypeName.DOUBLE,
JavaTypeName.LONG);
LocalVariableDeclaration fVarDecl =
new LocalVariableDeclaration(f, initializeF);
thenBlock.addStatement(fVarDecl);
fieldExpression =
new OperatorExpression.Binary (
JavaOperator.SHIFTR_UNSIGNED_LONG,
f,
LiteralWrapper.make(new Integer (32)));
fieldExpression =
new OperatorExpression.Binary (
JavaOperator.BITWISE_XOR_LONG,
f,
fieldExpression);
fieldExpression =
new CastExpression (JavaTypeName.INT, fieldExpression);
} else if (fieldType instanceof JavaTypeName.Primitive.Float) {
fieldExpression =
new MethodInvocation.Static (
JavaTypeName.FLOAT_OBJECT,
"floatToIntBits",
field,
JavaTypeName.FLOAT,
JavaTypeName.INT);
} else if (fieldType instanceof JavaTypeName.Primitive.Int) {
fieldExpression = field;
} else if (fieldType instanceof JavaTypeName.Primitive.Long) {
fieldExpression =
new OperatorExpression.Binary (
JavaOperator.SHIFTR_UNSIGNED_LONG,
field,
LiteralWrapper.make(new Integer (32)));
fieldExpression =
new OperatorExpression.Binary (
JavaOperator.BITWISE_XOR_LONG,
field,
fieldExpression);
fieldExpression =
new CastExpression (JavaTypeName.INT, fieldExpression);
} else {
fieldExpression =
new MethodInvocation.Instance (field, "hashCode", JavaTypeName.INT, MethodInvocation.InvocationType.VIRTUAL);
}
} else {
// get objects hashcode
fieldExpression =
new MethodInvocation.Instance (field, "hashCode", JavaTypeName.INT, MethodInvocation.InvocationType.VIRTUAL);
}
newResult =
new OperatorExpression.Binary (JavaOperator.ADD_INT, thirtySevenTimesResult, fieldExpression);
assignResult = new Assignment (result, newResult);
thenBlock.addStatement(new ExpressionStatement (assignResult));
}
// Assign the hash code value to the hashCode field.
JavaExpression assign = new JavaExpression.Assignment(hashCodeField, result);
thenBlock.addStatement(new ExpressionStatement (assign));
// Return the initialized hashCode field.
hashCode.addStatement (new ReturnStatement (hashCodeField));