"equals",
"(Ljava/lang/Object;)Z",
null,
null );
mv.visitCode();
Label l0 = null;
if ( this.debug ) {
l0 = new Label();
mv.visitLabel( l0 );
}
// if ( this == obj ) return true;
mv.visitVarInsn( Opcodes.ALOAD,
0 );
mv.visitVarInsn( Opcodes.ALOAD,
1 );
Label l1 = new Label();
mv.visitJumpInsn( Opcodes.IF_ACMPNE,
l1 );
mv.visitInsn( Opcodes.ICONST_1 );
mv.visitInsn( Opcodes.IRETURN );
// if ( obj == null ) return false;
mv.visitLabel( l1 );
mv.visitVarInsn( Opcodes.ALOAD,
1 );
Label l2 = new Label();
mv.visitJumpInsn( Opcodes.IFNONNULL,
l2 );
mv.visitInsn( Opcodes.ICONST_0 );
mv.visitInsn( Opcodes.IRETURN );
// if ( getClass() != obj.getClass() ) return false;
mv.visitLabel( l2 );
mv.visitVarInsn( Opcodes.ALOAD,
0 );
mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
Type.getInternalName( Object.class ),
"getClass",
Type.getMethodDescriptor( Type.getType( Class.class ),
new Type[]{} ) );
mv.visitVarInsn( Opcodes.ALOAD,
1 );
mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
Type.getInternalName( Object.class ),
"getClass",
Type.getMethodDescriptor( Type.getType( Class.class ),
new Type[]{} ) );
Label l3 = new Label();
mv.visitJumpInsn( Opcodes.IF_ACMPEQ,
l3 );
mv.visitInsn( Opcodes.ICONST_0 );
mv.visitInsn( Opcodes.IRETURN );
// final <classname> other = (<classname>) obj;
mv.visitLabel( l3 );
mv.visitVarInsn( Opcodes.ALOAD,
1 );
mv.visitTypeInsn( Opcodes.CHECKCAST,
getInternalType( classDef.getClassName() ) );
mv.visitVarInsn( Opcodes.ASTORE,
2 );
// for each key field
int count = 0;
for ( FieldDefinition field : classDef.getFieldsDefinitions() ) {
if ( field.isKey() ) {
count++;
Label goNext = new Label();
if ( isPrimitive( field.getTypeName() ) ) {
// if attr is primitive
// if ( this.<attr> != other.<booleanAttr> ) return false;
mv.visitVarInsn( Opcodes.ALOAD,
0 );
mv.visitFieldInsn( Opcodes.GETFIELD,
getInternalType( classDef.getClassName() ),
field.getName(),
getTypeDescriptor( field.getTypeName() ) );
mv.visitVarInsn( Opcodes.ALOAD,
2 );
mv.visitFieldInsn( Opcodes.GETFIELD,
getInternalType( classDef.getClassName() ),
field.getName(),
getTypeDescriptor( field.getTypeName() ) );
if ( field.getTypeName().equals( "long" ) ) {
mv.visitInsn( Opcodes.LCMP );
mv.visitJumpInsn( Opcodes.IFEQ,
goNext );
} else if ( field.getTypeName().equals( "double" ) ) {
mv.visitInsn( Opcodes.DCMPL );
mv.visitJumpInsn( Opcodes.IFEQ,
goNext );
} else if ( field.getTypeName().equals( "float" ) ) {
mv.visitInsn( Opcodes.FCMPL );
mv.visitJumpInsn( Opcodes.IFEQ,
goNext );
} else {
// boolean, byte, char, short, int
mv.visitJumpInsn( Opcodes.IF_ICMPEQ,
goNext );
}
mv.visitInsn( Opcodes.ICONST_0 );
mv.visitInsn( Opcodes.IRETURN );
} else {
// if attr is not a primitive
// if ( this.<attr> == null && other.<attr> != null ||
// this.<attr> != null && ! this.<attr>.equals( other.<attr> ) ) return false;
mv.visitVarInsn( Opcodes.ALOAD,
0 );
mv.visitFieldInsn( Opcodes.GETFIELD,
getInternalType( classDef.getClassName() ),
field.getName(),
getTypeDescriptor( field.getTypeName() ) );
Label secondIfPart = new Label();
mv.visitJumpInsn( Opcodes.IFNONNULL,
secondIfPart );
// if ( other.objAttr != null ) return false;
mv.visitVarInsn( Opcodes.ALOAD,
2 );
mv.visitFieldInsn( Opcodes.GETFIELD,
getInternalType( classDef.getClassName() ),
field.getName(),
getTypeDescriptor( field.getTypeName() ) );
Label returnFalse = new Label();
mv.visitJumpInsn( Opcodes.IFNONNULL,
returnFalse );
mv.visitLabel( secondIfPart );
mv.visitVarInsn( Opcodes.ALOAD,
0 );
mv.visitFieldInsn( Opcodes.GETFIELD,
getInternalType( classDef.getClassName() ),
field.getName(),
getTypeDescriptor( field.getTypeName() ) );
mv.visitJumpInsn( Opcodes.IFNULL,
goNext );
mv.visitVarInsn( Opcodes.ALOAD,
0 );
mv.visitFieldInsn( Opcodes.GETFIELD,
getInternalType( classDef.getClassName() ),
field.getName(),
getTypeDescriptor( field.getTypeName() ) );
mv.visitVarInsn( Opcodes.ALOAD,
2 );
mv.visitFieldInsn( Opcodes.GETFIELD,
getInternalType( classDef.getClassName() ),
field.getName(),
getTypeDescriptor( field.getTypeName() ) );
mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL,
getInternalType( field.getTypeName() ),
"equals",
"(Ljava/lang/Object;)Z" );
mv.visitJumpInsn( Opcodes.IFNE,
goNext );
mv.visitLabel( returnFalse );
mv.visitInsn( Opcodes.ICONST_0 );
mv.visitInsn( Opcodes.IRETURN );
}
mv.visitLabel( goNext );
}
}
if ( count > 0 ) {
mv.visitInsn( Opcodes.ICONST_1 );
} else {
mv.visitInsn( Opcodes.ICONST_0 );
}
mv.visitInsn( Opcodes.IRETURN );
Label lastLabel = null;
if ( this.debug ) {
lastLabel = new Label();
mv.visitLabel( lastLabel );
mv.visitLocalVariable( "this",
getTypeDescriptor( classDef.getClassName() ),
null,
l0,