// annotate with @Override
hashCodeMethod.annotate(Override.class);
equalsMethod.annotate(Override.class);
// add paramter for equals()-method
final JVar vObj = equalsMethod.param(Object.class, "obj");
// is it me? this==obj -> true
final JConditional condMe = equalsMethod.body()._if(JExpr._this().eq(vObj));
condMe._then()._return(JExpr.TRUE);
// it's null? obj==null -> false
final JConditional condNull = equalsMethod.body()._if(vObj.eq(JExpr._null()));
condNull._then()._return(JExpr.FALSE);
// paternity test (only add if equals in superclass isn't overridden)?
// !super.equals(obj) -> false --> (super.equals(obj) == false)
if (isSuperClass) {
final JConditional condSuper = equalsMethod.body()._if(JExpr._super().invoke("equals").arg(vObj).eq(JExpr.FALSE));
condSuper._then()._return(JExpr.FALSE);
}
// suit the class? !(obj instanceof TypeB) -> false --> if ((obj instanceof TypeB) == false)
final JConditional condInstance = equalsMethod.body()._if(vObj._instanceof(implClass).eq(JExpr.FALSE));
condInstance._then()._return(JExpr.FALSE);
// cast: TYPE other = (TYPE) obj;
final JVar vOther = equalsMethod.body().decl(implClass, "other", JExpr.cast(implClass, vObj));
/*
* check for each declared field distinguish between primitive types:
*
* <pre> if (field != other.field) { return false; } </pre>
*
* and reference types: <pre> if (field == null) { if (other.field != null) { return false; } } else if (!field.equals(other.field)) {
* // --> if (field.equals(other.field) == false) return false; } </code>
*/
JConditional condFieldCheck;
boolean containsDouble = false;
for (final JFieldVar jFieldVar : fields) {
if (jFieldVar.type().fullName().equals("java.lang.Double") || jFieldVar.type().fullName().equals("double")) {
jFieldVar.type(implClass.owner().DOUBLE);
containsDouble = true;
// break;
}
}
for (final JFieldVar jFieldVar : fields) {
if (jFieldVar.type().isPrimitive()) {
// LOG.info("JConditional: " + jFieldVar.name() +
// " is PRIMITIVE");
condFieldCheck = equalsMethod.body()._if(JExpr.ref(jFieldVar.name()).ne(vOther.ref(jFieldVar.name())));
condFieldCheck._then()._return(JExpr.FALSE);
} else {
// LOG.info("JConditional: " + jFieldVar.name() +
// " is REFERENCE");
condFieldCheck = equalsMethod.body()._if(JExpr.ref(jFieldVar.name()).eq(JExpr._null()));
condFieldCheck._then()._if(vOther.ref(jFieldVar.name()).ne(JExpr._null()))._then()._return(JExpr.FALSE);
condFieldCheck._elseif(JExpr.ref(jFieldVar.name()).invoke("equals").arg(vOther.ref(jFieldVar.name())).eq(JExpr.FALSE))._then()
._return(JExpr.FALSE);
}
}
// ir all works out, the objects are equal, return true
equalsMethod.body()._return(JExpr.TRUE);
// useful fields
final JFieldRef vPrime = JExpr.ref("prime");
final JFieldRef vResult = JExpr.ref("result");
// ==> final int prime = 31;
hashCodeMethod.body().assign(JExpr.ref("final int prime"), JExpr.ref("31"));
// ==> int result = 1; || int result = super.hashCode();
JExpression initializeResult = null;
if (isSuperClass) {
initializeResult = JExpr._super().invoke("hashCode");
} else {
initializeResult = JExpr.ref("1");
}
hashCodeMethod.body().assign(JExpr.ref("int result"), initializeResult);
// if class contains double
// long temp;
JVar tempVariableForDoubleChecks = null;
JType doubleClass = null;
if (containsDouble == true) {
tempVariableForDoubleChecks = hashCodeMethod.body().decl(implClass.owner().LONG, "temp");
doubleClass = implClass.owner()._ref(Double.class);
}
JExpression tenaryCond;
for (final JFieldVar jFieldVar : fields) {
if (jFieldVar.type().isPrimitive()) {
if (jFieldVar.type().fullName().equals("double")) {
// temp = Double.doubleToLongBits(altitude);
// result = prime * result + (int) (temp ^ (temp >>> 32));
// LOG.info("implClass: " + implClass.name());
// LOG.info("jFieldVar: " + jFieldVar.name());
// LOG.info(" is " + jFieldVar.type().fullName());
// LOG.info(" + " + tempVariableForDoubleChecks.name());
// LOG.info(" + " + doubleClass.boxify().fullName());
hashCodeMethod.body().assign(tempVariableForDoubleChecks, doubleClass.boxify().staticInvoke("doubleToLongBits").arg(jFieldVar));
tenaryCond = JExpr.cast(implClass.owner().INT, tempVariableForDoubleChecks.xor(tempVariableForDoubleChecks.shrz(JExpr
.direct("32"))));
} else {
// if field is primitive:
// ==> result = prime * result + field;
tenaryCond = JExpr.ref(jFieldVar.name());