private void PublishProperties(TypeBuilder typeBuilder, IKVM.Internal.MapXml.Class clazz) { foreach(IKVM.Internal.MapXml.Property prop in clazz.Properties) { TypeWrapper typeWrapper = GetClassLoader().RetTypeWrapperFromSigNoThrow(prop.Sig); TypeWrapper[] propargs = GetClassLoader().ArgTypeWrapperListFromSigNoThrow(prop.Sig); Type[] indexer = new Type[propargs.Length]; for(int i = 0; i < propargs.Length; i++) { indexer[i] = propargs[i].TypeAsSignatureType; } PropertyBuilder propbuilder = typeBuilder.DefineProperty(prop.Name, PropertyAttributes.None, typeWrapper.TypeAsSignatureType, indexer); AttributeHelper.HideFromJava(propbuilder); if(prop.Attributes != null) { foreach(IKVM.Internal.MapXml.Attribute attr in prop.Attributes) { AttributeHelper.SetCustomAttribute(classLoader, propbuilder, attr); } } MethodWrapper getter = null; MethodWrapper setter = null; if(prop.getter != null) { getter = GetMethodWrapper(prop.getter.Name, prop.getter.Sig, true); if(getter == null) { Console.Error.WriteLine("Warning: getter not found for {0}::{1}", clazz.Name, prop.Name); } } if(prop.setter != null) { setter = GetMethodWrapper(prop.setter.Name, prop.setter.Sig, true); if(setter == null) { Console.Error.WriteLine("Warning: setter not found for {0}::{1}", clazz.Name, prop.Name); } } bool final = (getter != null && getter.IsFinal) || (setter != null && setter.IsFinal); if(getter != null) { MethodWrapper mw = getter; if(!CheckPropertyArgs(mw.GetParametersForDefineMethod(), indexer) || mw.ReturnType != typeWrapper) { Console.Error.WriteLine("Warning: ignoring invalid property getter for {0}::{1}", clazz.Name, prop.Name); } else { MethodBuilder mb = mw.GetMethod() as MethodBuilder; if(mb == null || mb.DeclaringType != typeBuilder || (!mb.IsFinal && final)) { mb = typeBuilder.DefineMethod("get_" + prop.Name, GetPropertyMethodAttributes(mw, final), typeWrapper.TypeAsSignatureType, indexer); AttributeHelper.HideFromJava(mb); CodeEmitter ilgen = CodeEmitter.Create(mb); if(mw.IsStatic) { for(int i = 0; i < indexer.Length; i++) { ilgen.EmitLdarg(i); } mw.EmitCall(ilgen); } else { ilgen.Emit(OpCodes.Ldarg_0); for(int i = 0; i < indexer.Length; i++) { ilgen.EmitLdarg(i + 1); } mw.EmitCallvirt(ilgen); } ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); } propbuilder.SetGetMethod(mb); } } if(setter != null) { MethodWrapper mw = setter; Type[] args = new Type[indexer.Length + 1]; indexer.CopyTo(args, 0); args[args.Length - 1] = typeWrapper.TypeAsSignatureType; if(!CheckPropertyArgs(args, mw.GetParametersForDefineMethod())) { Console.Error.WriteLine("Warning: ignoring invalid property setter for {0}::{1}", clazz.Name, prop.Name); } else { MethodBuilder mb = mw.GetMethod() as MethodBuilder; if(mb == null || mb.DeclaringType != typeBuilder || (!mb.IsFinal && final)) { mb = typeBuilder.DefineMethod("set_" + prop.Name, GetPropertyMethodAttributes(mw, final), mw.ReturnTypeForDefineMethod, args); AttributeHelper.HideFromJava(mb); CodeEmitter ilgen = CodeEmitter.Create(mb); if(mw.IsStatic) { for(int i = 0; i <= indexer.Length; i++) { ilgen.EmitLdarg(i); } mw.EmitCall(ilgen); } else { ilgen.Emit(OpCodes.Ldarg_0); for(int i = 0; i <= indexer.Length; i++) { ilgen.EmitLdarg(i + 1); } mw.EmitCallvirt(ilgen); } ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); } propbuilder.SetSetMethod(mb); } } } }