e.printStackTrace();
}
ClassWriter cw = createClassWriter( classLoader,
ACC_PUBLIC + ACC_SUPER,
internalProxy,
null,
Type.getInternalName( proxyBaseClass ),
new String[]{ internalTrait, Type.getInternalName( Serializable.class ) } );
{
fv = cw.visitField( ACC_PRIVATE + ACC_FINAL + ACC_STATIC,
TraitType.traitNameField, Type.getDescriptor( String.class ),
null, null );
fv.visitEnd();
}
{
fv = cw.visitField( ACC_PUBLIC + ACC_FINAL, "object", descrCore, null, null );
fv.visitEnd();
}
{
fv = cw.visitField( ACC_PUBLIC + ACC_FINAL, "map", Type.getDescriptor( Map.class ), "Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;", null );
fv.visitEnd();
}
if ( mixinClass != null ) {
{
fv = cw.visitField( ACC_PRIVATE,
mixin,
BuildUtils.getTypeDescriptor( mixinClass.getName() ),
null, null );
fv.visitEnd();
}
}
{
mv = cw.visitMethod( ACC_STATIC, "<clinit>", "()V", null, null );
mv.visitCode();
mv.visitLdcInsn( Type.getType( Type.getDescriptor( trait.getDefinedClass() ) ) );
mv.visitMethodInsn( INVOKEVIRTUAL,
Type.getInternalName( Class.class ), "getName", "()" + Type.getDescriptor( String.class ) );
mv.visitFieldInsn( PUTSTATIC,
internalProxy,
TraitType.traitNameField,
Type.getDescriptor( String.class ) );
mv.visitInsn( RETURN );
mv.visitMaxs( 0, 0 );
mv.visitEnd();
}
{
mv = cw.visitMethod( ACC_PUBLIC, "<init>", "()V", null, null );
mv.visitCode();
mv.visitVarInsn( ALOAD, 0 );
mv.visitMethodInsn( INVOKESPECIAL, Type.getInternalName( proxyBaseClass ), "<init>", "()V" );
mv.visitInsn( RETURN );
// mv.visitMaxs( 1, 1 );
mv.visitMaxs( 0, 0 );
mv.visitEnd();
}
{
mv = cw.visitMethod( ACC_PUBLIC, "<init>",
"(" + descrCore + Type.getDescriptor( Map.class ) + Type.getDescriptor( BitSet.class ) + Type.getDescriptor( BitSet.class ) + Type.getDescriptor( boolean.class ) + ")V",
"(" + descrCore + "Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;" + Type.getDescriptor( BitSet.class ) + Type.getDescriptor( BitSet.class ) + Type.getDescriptor( boolean.class ) + ")V", null);
mv.visitCode();
mv.visitVarInsn( ALOAD, 0 );
mv.visitMethodInsn( INVOKESPECIAL, Type.getInternalName( proxyBaseClass ), "<init>", "()V" );
mv.visitVarInsn( ALOAD, 2 );
Label l0 = new Label();
mv.visitJumpInsn( IFNONNULL, l0 );
mv.visitTypeInsn( NEW, Type.getInternalName( ExternalizableLinkedHashMap.class ) );
mv.visitInsn( DUP );
mv.visitMethodInsn( INVOKESPECIAL, Type.getInternalName( ExternalizableLinkedHashMap.class ), "<init>", "()V" );
mv.visitVarInsn( ASTORE, 2 );
mv.visitLabel( l0 );
if ( mixinClass != null ) {
try {
Class actualArg = getPossibleConstructor( mixinClass, trait.getDefinedClass() );
mv.visitVarInsn( ALOAD, 0 );
mv.visitTypeInsn( NEW, Type.getInternalName( mixinClass ) );
mv.visitInsn( DUP );
mv.visitVarInsn( ALOAD, 0 );
mv.visitMethodInsn( INVOKESPECIAL,
Type.getInternalName( mixinClass ),
"<init>",
"("+ Type.getDescriptor( actualArg ) + ")V");
mv.visitFieldInsn( PUTFIELD,
internalProxy,
mixin,
Type.getDescriptor( mixinClass ) );
} catch ( NoSuchMethodException nsme ) {
mv.visitVarInsn( ALOAD, 0 );
mv.visitTypeInsn( NEW, Type.getInternalName( mixinClass ) );
mv.visitInsn( DUP );
mv.visitMethodInsn( INVOKESPECIAL, Type.getInternalName( mixinClass ), "<init>", "()V" );
mv.visitFieldInsn( PUTFIELD,
internalProxy,
mixin,
Type.getDescriptor( mixinClass ) );
}
}
mv.visitVarInsn( ALOAD, 0 );
mv.visitVarInsn( ALOAD, 1 );
mv.visitFieldInsn( PUTFIELD, internalProxy, "object", descrCore );
mv.visitVarInsn( ALOAD, 0 );
mv.visitVarInsn( ALOAD, 2 );
mv.visitFieldInsn( PUTFIELD, internalProxy, "map", Type.getDescriptor( Map.class ) );
mv.visitVarInsn( ALOAD, 0 );
mv.visitVarInsn( ALOAD, 3 );
mv.visitMethodInsn( INVOKEVIRTUAL, internalProxy, "setTypeCode", Type.getMethodDescriptor( Type.VOID_TYPE, new Type[] { Type.getType( BitSet.class ) } ) );
mv.visitVarInsn( ALOAD, 0 );
mv.visitTypeInsn( NEW, internalWrapper );
mv.visitInsn( DUP );
mv.visitVarInsn( ALOAD, 1 );
mv.visitVarInsn( ALOAD, 2 );
mv.visitMethodInsn( INVOKESPECIAL, internalWrapper, "<init>", "(" + descrCore + Type.getDescriptor( Map.class ) + ")V" );
mv.visitFieldInsn( PUTFIELD, internalProxy, "fields", Type.getDescriptor( Map.class ) );
mv.visitVarInsn( ALOAD, 1 );
mv.visitMethodInsn( INVOKEVIRTUAL, internalCore, "_getDynamicProperties", "()" + Type.getDescriptor( Map.class ) );
Label l1 = new Label();
mv.visitJumpInsn( IFNONNULL, l1 );
mv.visitVarInsn( ALOAD, 1 );
mv.visitVarInsn( ALOAD, 2 );
mv.visitMethodInsn( INVOKEVIRTUAL, internalCore, "_setDynamicProperties", "(" + Type.getDescriptor( Map.class ) + ")V" );
mv.visitLabel( l1 );
mv.visitVarInsn( ALOAD, 1 );
mv.visitMethodInsn( INVOKEVIRTUAL, internalCore, "_getTraitMap", "()" + Type.getDescriptor( Map.class ) );
Label l2 = new Label();
mv.visitJumpInsn( IFNONNULL, l2 );
mv.visitVarInsn( ALOAD, 1 );
mv.visitTypeInsn( NEW, Type.getInternalName( TraitTypeMap.class ) );
mv.visitInsn( DUP );
mv.visitTypeInsn( NEW, Type.getInternalName( ExternalizableLinkedHashMap.class ) );
mv.visitInsn( DUP );
mv.visitMethodInsn( INVOKESPECIAL, Type.getInternalName( ExternalizableLinkedHashMap.class ), "<init>", "()V" );
mv.visitMethodInsn( INVOKESPECIAL, Type.getInternalName( TraitTypeMap.class ), "<init>", "(" + Type.getDescriptor( Map.class ) + ")V" );
mv.visitMethodInsn( INVOKEVIRTUAL, internalCore, "_setTraitMap", "(" + Type.getDescriptor( Map.class ) + ")V" );
mv.visitLabel( l2 );
// core._setBottomTypeCode()
mv.visitVarInsn( ALOAD, 1 );
mv.visitVarInsn( ALOAD, 4 );
mv.visitMethodInsn( INVOKEVIRTUAL, internalCore, "_setBottomTypeCode", Type.getMethodDescriptor( Type.VOID_TYPE, new Type[] { Type.getType( BitSet.class ) } ) );
// core.addTrait
mv.visitVarInsn( ALOAD, 1 );
mv.visitLdcInsn( trait.getName().endsWith( TraitFactory.SUFFIX ) ? trait.getName().replace( TraitFactory.SUFFIX , "" ) : trait.getName() );
mv.visitVarInsn( ALOAD, 0 );
mv.visitMethodInsn( INVOKEVIRTUAL, internalCore, "addTrait", Type.getMethodDescriptor( Type.VOID_TYPE, new Type[] { Type.getType( String.class ), Type.getType( Thing.class ) } ) );
mv.visitVarInsn( ALOAD, 0 );
mv.visitVarInsn( ILOAD, 5 );
mv.visitMethodInsn( INVOKESPECIAL, internalProxy, "synchFields", Type.getMethodDescriptor( Type.VOID_TYPE, new Type[] { Type.BOOLEAN_TYPE } ) );
mv.visitInsn( RETURN );
// mv.visitMaxs( 5, 3 );
mv.visitMaxs( 0, 0 );
mv.visitEnd();
}
{
mv = cw.visitMethod( ACC_PUBLIC, "getTraitName", "()" + Type.getDescriptor( String.class ), null, null);
mv.visitCode();
mv.visitFieldInsn( GETSTATIC, internalProxy, TraitType.traitNameField, Type.getDescriptor( String.class ) );
mv.visitInsn( ARETURN );
mv.visitMaxs( 0, 0 );
mv.visitEnd();
}
{
mv = cw.visitMethod( ACC_PUBLIC, "getCore", "()" + descrCore + "", null, null );
mv.visitCode();
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD, internalProxy, "object", descrCore );
mv.visitInsn( ARETURN );
// mv.visitMaxs( 1, 1 );
mv.visitMaxs( 0, 0 );
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "getObject", "()" + Type.getDescriptor( TraitableBean.class ), null, null);
mv.visitCode();
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD, internalProxy, "object", descrCore );
mv.visitTypeInsn( CHECKCAST, Type.getInternalName( TraitableBean.class ) );
mv.visitInsn( ARETURN );
// mv.visitMaxs( 1, 1 );
mv.visitMaxs( 0, 0 );
mv.visitEnd();
}
{
mv = cw.visitMethod( ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC, "getCore", "()" + Type.getDescriptor( Object.class ), null, null );
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, internalProxy, "getCore", "()" + descrCore);
mv.visitInsn(ARETURN);
// mv.visitMaxs( 1, 1 );
mv.visitMaxs( 0, 0 );
mv.visitEnd();
}
{
mv = cw.visitMethod( ACC_PUBLIC, "isTop", "()Z", null, null );
mv.visitCode();
mv.visitInsn( Thing.class.equals( trait.getDefinedClass() ) ? ICONST_1 : ICONST_0 );
mv.visitInsn( IRETURN );
mv.visitMaxs( 0, 0 );
mv.visitEnd();
}
{
mv = cw.visitMethod( ACC_PUBLIC, "shed", Type.getMethodDescriptor( Type.VOID_TYPE, new Type[] {} ), null, null );
mv.visitCode();
if ( core.isFullTraiting() ) {
Iterator<FieldDefinition> iter = trait.getFieldsDefinitions().iterator();
for ( int j = 0; j < trait.getFieldsDefinitions().size(); j++ ) {
FieldDefinition fld = iter.next();
boolean hardField = ! TraitRegistry.isSoftField( fld, j, mask );
shedField( mv, fld, internalProxy, trait, core, hardField, j + 2 );
}
}
mv.visitInsn( RETURN );
mv.visitMaxs( 0, 0 );
mv.visitEnd();
}
{
mv = cw.visitMethod( ACC_PUBLIC, "writeExternal", "(" + Type.getDescriptor( ObjectOutput.class ) + ")V", null, new String[] { Type.getInternalName( IOException.class ) } );
mv.visitCode();
mv.visitVarInsn( ALOAD, 1 );
mv.visitVarInsn( ALOAD, 0 );
mv.visitMethodInsn( INVOKEVIRTUAL, internalProxy, "getObject", "()" + Type.getDescriptor( TraitableBean.class ) );
mv.visitMethodInsn( INVOKEINTERFACE, Type.getInternalName( ObjectOutput.class ), "writeObject", "(" + Type.getDescriptor( Object.class ) + ")V" );
mv.visitVarInsn( ALOAD, 1 );
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD, internalProxy, "map", Type.getDescriptor( Map.class ) );
mv.visitMethodInsn( INVOKEINTERFACE, Type.getInternalName( ObjectOutput.class ), "writeObject", "(" + Type.getDescriptor( Object.class ) + ")V" );
mv.visitVarInsn( ALOAD, 0 );
mv.visitVarInsn( ALOAD, 1 );
mv.visitMethodInsn( INVOKESPECIAL, Type.getInternalName( proxyBaseClass ), "writeExternal", "(" + Type.getDescriptor( ObjectOutput.class ) + ")V" );
mv.visitInsn( RETURN );
// mv.visitMaxs( 2, 2 );
mv.visitMaxs( 0, 0 );
mv.visitEnd();
}
{
mv = cw.visitMethod( ACC_PUBLIC, "readExternal", "(" + Type.getDescriptor( ObjectInput.class )+ ")V",
null, new String[] { Type.getInternalName( IOException.class ), Type.getInternalName( ClassNotFoundException.class ) } );
mv.visitCode();
mv.visitVarInsn( ALOAD, 0 );
mv.visitVarInsn( ALOAD, 1 );
mv.visitMethodInsn( INVOKEINTERFACE, Type.getInternalName( ObjectInput.class ), "readObject", "()" + Type.getDescriptor( Object.class ) );
mv.visitTypeInsn( CHECKCAST, internalCore );
mv.visitFieldInsn( PUTFIELD, internalProxy, "object", descrCore );
mv.visitVarInsn( ALOAD, 0 );
mv.visitVarInsn( ALOAD, 1 );
mv.visitMethodInsn( INVOKEINTERFACE, Type.getInternalName( ObjectInput.class ), "readObject", "()" + Type.getDescriptor( Object.class ) );
mv.visitTypeInsn( CHECKCAST, Type.getInternalName( Map.class ) );
mv.visitFieldInsn( PUTFIELD, internalProxy, "map", Type.getDescriptor( Map.class ) );
mv.visitVarInsn( ALOAD, 0 );
mv.visitVarInsn( ALOAD, 1 );
mv.visitMethodInsn( INVOKESPECIAL, Type.getInternalName( proxyBaseClass ), "readExternal", "(" + Type.getDescriptor( ObjectInput.class ) + ")V" );
mv.visitInsn( RETURN );
// mv.visitMaxs( 3, 2 );
mv.visitMaxs( 0, 0 );
mv.visitEnd();
}
int j = 0;
for ( FieldDefinition field : trait.getFieldsDefinitions() ) {
boolean hardField = ! TraitRegistry.isSoftField( field, j++, mask );
if ( core.isFullTraiting() ) {
buildLogicalGetter( cw, field, masterName, trait, core );
if ( hardField ) {
buildHardSetter( cw, field, masterName, trait, core );
} else {
buildSoftSetter( cw, field, masterName, trait, core );
}
} else {
if ( ! hardField ) {
if ( ! mixinGetSet.containsKey( BuildUtils.getterName( field.getName(), field.getTypeName() ) ) ) {
buildSoftGetter( cw, field, masterName, trait, core );
buildSoftSetter( cw, field, masterName, trait, core );
} else {
//
}
} else {
buildHardGetter( cw, field, masterName, trait, core );
buildHardSetter( cw, field, masterName, trait, core );
}
}
}
boolean hasKeys = false;
for ( FactField ff : trait.getFields() ) {
if ( ff.isKey() ) {
hasKeys = true;
break;
}
}
if ( ! hasKeys ) {
buildEqualityMethods( cw, masterName, core.getClassName() );
} else {
buildKeyedEqualityMethods( cw, trait, masterName, core.getClassName() );
}
if ( mixinClass != null ) {
buildMixinMethods( cw, masterName, mixin, mixinClass, mixinMethods );
buildMixinMethods( cw, masterName, mixin, mixinClass, mixinGetSet.values() );
}
buildCommonMethods( cw, masterName, core.getClassName() );
buildExtendedMethods( cw, trait, core, mask );
buildShadowMethods( cw, trait, core, mask );
cw.visitEnd();
return cw.toByteArray();
}