protected void shedField( MethodVisitor mv, FieldDefinition fld, String proxyName, ClassDefinition trait, ClassDefinition core, boolean hardField, int j ) {
FieldDefinition coreField = core.getFieldByAlias( fld.resolveAlias() );
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD, BuildUtils.getInternalType( proxyName ), "object", Type.getDescriptor( core.getDefinedClass() ) );
mv.visitTypeInsn( CHECKCAST, Type.getInternalName( TraitableBean.class ) );
mv.visitMethodInsn( INVOKEINTERFACE, Type.getInternalName( TraitableBean.class ), "_getFieldTMS", Type.getMethodDescriptor( Type.getType( TraitFieldTMS.class ), new Type[] {} ) );
mv.visitVarInsn( ASTORE, 1 );
mv.visitVarInsn( ALOAD, 1 );
// fld Name
mv.visitLdcInsn( fld.resolveAlias() );
// this
mv.visitVarInsn( ALOAD, 0 );
// fld type
if ( BuildUtils.isPrimitive( fld.getTypeName() ) ) {
mv.visitLdcInsn( Type.getType( BuildUtils.getTypeDescriptor( BuildUtils.box( fld.getTypeName() ) ) ) );
} else {
mv.visitLdcInsn( Type.getType( Type.getDescriptor( fld.getType() ) ) );
}
if ( hardField ) {
if ( BuildUtils.isPrimitive( coreField.getTypeName() ) ) {
mv.visitLdcInsn( Type.getType( BuildUtils.getTypeDescriptor( BuildUtils.box( coreField.getTypeName() ) ) ) );
} else {
mv.visitLdcInsn( Type.getType( Type.getDescriptor( coreField.getType() ) ) );
}
} else {
mv.visitLdcInsn( Type.getType( Type.getDescriptor( Object.class ) ) );
}
mv.visitMethodInsn( INVOKEINTERFACE,
Type.getInternalName( TraitFieldTMS.class ),
"shedField",
Type.getMethodDescriptor( Type.getType( Object.class ), new Type[] {
Type.getType( String.class ), Type.getType( TraitType.class ), Type.getType( Class.class ), Type.getType( Class.class )
} ) );
mv.visitVarInsn( ASTORE, j );
if ( hardField ) {
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD, BuildUtils.getInternalType( proxyName ), "object", Type.getDescriptor( core.getDefinedClass() ) );
mv.visitVarInsn( ALOAD, j );
if ( BuildUtils.isPrimitive( coreField.getTypeName() ) ) {
Label l0 = new Label();
mv.visitJumpInsn( IFNULL, l0 );
mv.visitVarInsn( ALOAD, j );
mv.visitTypeInsn( CHECKCAST, BuildUtils.getInternalType( BuildUtils.box( coreField.getTypeName() ) ) );
mv.visitMethodInsn( INVOKEVIRTUAL,
BuildUtils.getInternalType( BuildUtils.box( coreField.getTypeName() ) ),
BuildUtils.numericMorph( BuildUtils.box( coreField.getTypeName() ) ),
Type.getMethodDescriptor( Type.getType( coreField.getType() ), new Type[] {} ) );
Label l1 = new Label();
mv.visitJumpInsn( GOTO, l1 );
mv.visitLabel( l0 );
mv.visitInsn( BuildUtils.zero( coreField.getTypeName() ) );
mv.visitLabel( l1 );
} else {
mv.visitTypeInsn( CHECKCAST, Type.getInternalName( coreField.getType() ) );
}
mv.visitMethodInsn( INVOKEVIRTUAL,
Type.getInternalName( core.getDefinedClass() ),
BuildUtils.setterName( coreField.getName(), coreField.getTypeName() ),
"(" + BuildUtils.getTypeDescriptor( coreField.getTypeName() ) + ")" + Type.getDescriptor( void.class ) );
} else {
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD, BuildUtils.getInternalType( proxyName ), "map", Type.getDescriptor( Map.class ) );
mv.visitLdcInsn( fld.resolveAlias() );