classBuilder.addField(fieldModifiers, fieldNamePrefix+i, types[i]);
// Create constructor
- MethodBuilderBase mb = classBuilder.addConstructor(
+ MethodBuilderBase mb = classBuilder.addConstructorBase(
types.length == 0 ? Opcodes.ACC_PRIVATE : Opcodes.ACC_PUBLIC,
JavaTypeTranslator.filterVoid(types));
mb.loadThis();
tsmb.finish();
}
- if(generateEqualsAndHashCode) {
- // Create equals
- {
- TypeDesc CLASS = TypeDesc.forClass(Class.class);
+ if(generateEqualsAndHashCode)
+ implementHashCodeAndEquals(classBuilder, recordName, fieldNamePrefix, types);
+ }
- MethodBuilderBase tsmb = classBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "equals", TypeDesc.BOOLEAN, Constants.OBJECTS[1]);
- LocalVariable parameter = tsmb.getParameter(0);
- Label success = tsmb.createLabel();
- Label failure = tsmb.createLabel();
+ public static void implementHashCodeAndEquals(ClassBuilder classBuilder, String recordName, String fieldNamePrefix, TypeDesc[] types) {
+ // Create equals
+ {
+ TypeDesc CLASS = TypeDesc.forClass(Class.class);
- // Check type
- tsmb.loadThis();
- tsmb.loadLocal(parameter);
- tsmb.ifComparisonBranch(success, "==", TypeDesc.OBJECT);
- tsmb.loadLocal(parameter);
- tsmb.ifNullBranch(failure, true);
- tsmb.loadLocal(parameter);
- tsmb.invokeVirtual("java/lang/Object", "getClass", CLASS, Constants.EMPTY_TYPEDESC_ARRAY);
- tsmb.loadThis();
- tsmb.invokeVirtual("java/lang/Object", "getClass", CLASS, Constants.EMPTY_TYPEDESC_ARRAY);
- tsmb.ifComparisonBranch(failure, "!=", CLASS);
- tsmb.loadLocal(parameter);
- tsmb.checkCast(classBuilder.getType());
- LocalVariable other = tsmb.createLocalVariable("other", classBuilder.getType());
- tsmb.storeLocal(other);
+ MethodBuilderBase tsmb = classBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "equals", TypeDesc.BOOLEAN, Constants.OBJECTS[1]);
+ LocalVariable parameter = tsmb.getParameter(0);
+ Label success = tsmb.createLabel();
+ Label failure = tsmb.createLabel();
- // Compare fields
- for(int i=0;i<types.length;++i) {
- TypeDesc type = types[i];
- if(type.equals(TypeDesc.VOID))
- continue;
- tsmb.loadThis();
- tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
- tsmb.loadLocal(other);
- tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
- equals(tsmb, type, failure);
- }
+ // Check type
+ tsmb.loadThis();
+ tsmb.loadLocal(parameter);
+ tsmb.ifComparisonBranch(success, "==", TypeDesc.OBJECT);
+ tsmb.loadLocal(parameter);
+ tsmb.ifNullBranch(failure, true);
+ tsmb.loadLocal(parameter);
+ tsmb.invokeVirtual("java/lang/Object", "getClass", CLASS, Constants.EMPTY_TYPEDESC_ARRAY);
+ tsmb.loadThis();
+ tsmb.invokeVirtual("java/lang/Object", "getClass", CLASS, Constants.EMPTY_TYPEDESC_ARRAY);
+ tsmb.ifComparisonBranch(failure, "!=", CLASS);
+ tsmb.loadLocal(parameter);
+ tsmb.checkCast(classBuilder.getType());
+ LocalVariable other = tsmb.createLocalVariable("other", classBuilder.getType());
+ tsmb.storeLocal(other);
- // Return
- tsmb.setLocation(success);
- tsmb.loadConstant(true);
- tsmb.returnValue(TypeDesc.BOOLEAN);
- tsmb.setLocation(failure);
- tsmb.loadConstant(false);
- tsmb.returnValue(TypeDesc.BOOLEAN);
- tsmb.finish();
+ // Compare fields
+ for(int i=0;i<types.length;++i) {
+ TypeDesc type = types[i];
+ if(type.equals(TypeDesc.VOID))
+ continue;
+ tsmb.loadThis();
+ tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
+ tsmb.loadLocal(other);
+ tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
+ equals(tsmb, type, failure);
}
- // Create hashCode
- {
- MethodBuilderBase tsmb = classBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "hashCode", TypeDesc.INT, Constants.EMPTY_TYPEDESC_ARRAY);
- tsmb.loadConstant(recordName.hashCode());
- for(int i=0;i<types.length;++i) {
- TypeDesc type = types[i];
- if(type.equals(TypeDesc.VOID))
- continue;
- tsmb.loadConstant(31);
- tsmb.math(Opcodes.IMUL);
- tsmb.loadThis();
- tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
- hashCode(tsmb, type);
- tsmb.math(Opcodes.IADD);
- }
- tsmb.returnValue(TypeDesc.INT);
- tsmb.finish();
+ // Return
+ tsmb.setLocation(success);
+ tsmb.loadConstant(true);
+ tsmb.returnValue(TypeDesc.BOOLEAN);
+ tsmb.setLocation(failure);
+ tsmb.loadConstant(false);
+ tsmb.returnValue(TypeDesc.BOOLEAN);
+ tsmb.finish();
+ }
+
+ // Create hashCode
+ {
+ MethodBuilderBase tsmb = classBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "hashCode", TypeDesc.INT, Constants.EMPTY_TYPEDESC_ARRAY);
+ tsmb.loadConstant(recordName.hashCode());
+ for(int i=0;i<types.length;++i) {
+ TypeDesc type = types[i];
+ if(type.equals(TypeDesc.VOID))
+ continue;
+ tsmb.loadConstant(31);
+ tsmb.math(Opcodes.IMUL);
+ tsmb.loadThis();
+ tsmb.loadField(classBuilder.getClassName(), fieldNamePrefix+i, type);
+ hashCode(tsmb, type);
+ tsmb.math(Opcodes.IADD);
}
+ tsmb.returnValue(TypeDesc.INT);
+ tsmb.finish();
}
}