DefineMethod() public method

public DefineMethod ( string name, MethodAttributes attribs ) : MethodBuilder
name string
attribs MethodAttributes
return MethodBuilder
Esempio n. 1
0
 protected override void EmitMapXmlMetadata(TypeBuilder typeBuilder, ClassFile classFile, FieldWrapper[] fields, MethodWrapper[] methods)
 {
     Dictionary<string, IKVM.Internal.MapXml.Class> mapxml = classLoader.GetMapXmlClasses();
     if(mapxml != null)
     {
         IKVM.Internal.MapXml.Class clazz;
         if(mapxml.TryGetValue(classFile.Name, out clazz))
         {
             if(clazz.Attributes != null)
             {
                 PublishAttributes(typeBuilder, clazz);
             }
             if(clazz.Properties != null)
             {
                 PublishProperties(typeBuilder, clazz);
             }
             if(clazz.Fields != null)
             {
                 foreach(IKVM.Internal.MapXml.Field field in clazz.Fields)
                 {
                     if(field.Attributes != null)
                     {
                         foreach(FieldWrapper fw in fields)
                         {
                             if(fw.Name == field.Name && fw.Signature == field.Sig)
                             {
                                 FieldBuilder fb = fw.GetField() as FieldBuilder;
                                 if(fb != null)
                                 {
                                     foreach(IKVM.Internal.MapXml.Attribute attr in field.Attributes)
                                     {
                                         AttributeHelper.SetCustomAttribute(classLoader, fb, attr);
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
             if(clazz.Constructors != null)
             {
                 // HACK this isn't the right place to do this, but for now it suffices
                 foreach(IKVM.Internal.MapXml.Constructor constructor in clazz.Constructors)
                 {
                     // are we adding a new constructor?
                     if(GetMethodWrapper(StringConstants.INIT, constructor.Sig, false) == null)
                     {
                         if(constructor.body == null)
                         {
                             Console.Error.WriteLine("Error: Constructor {0}.<init>{1} in xml remap file doesn't have a body.", clazz.Name, constructor.Sig);
                             continue;
                         }
                         bool setmodifiers = false;
                         MethodAttributes attribs = 0;
                         MapModifiers(constructor.Modifiers, true, out setmodifiers, ref attribs);
                         Type returnType;
                         Type[] parameterTypes;
                         MapSignature(constructor.Sig, out returnType, out parameterTypes);
                         MethodBuilder cb = ReflectUtil.DefineConstructor(typeBuilder, attribs, parameterTypes);
                         if(setmodifiers)
                         {
                             AttributeHelper.SetModifiers(cb, (Modifiers)constructor.Modifiers, false);
                         }
                         CompilerClassLoader.AddDeclaredExceptions(cb, constructor.throws);
                         CodeEmitter ilgen = CodeEmitter.Create(cb);
                         constructor.Emit(classLoader, ilgen);
                         ilgen.DoEmit();
                         if(constructor.Attributes != null)
                         {
                             foreach(IKVM.Internal.MapXml.Attribute attr in constructor.Attributes)
                             {
                                 AttributeHelper.SetCustomAttribute(classLoader, cb, attr);
                             }
                         }
                     }
                 }
                 foreach(IKVM.Internal.MapXml.Constructor constructor in clazz.Constructors)
                 {
                     if(constructor.Attributes != null)
                     {
                         foreach(MethodWrapper mw in methods)
                         {
                             if(mw.Name == "<init>" && mw.Signature == constructor.Sig)
                             {
                                 MethodBuilder mb = mw.GetMethod() as MethodBuilder;
                                 if(mb != null)
                                 {
                                     foreach(IKVM.Internal.MapXml.Attribute attr in constructor.Attributes)
                                     {
                                         AttributeHelper.SetCustomAttribute(classLoader, mb, attr);
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
             if(clazz.Methods != null)
             {
                 // HACK this isn't the right place to do this, but for now it suffices
                 foreach(IKVM.Internal.MapXml.Method method in clazz.Methods)
                 {
                     // are we adding a new method?
                     if(GetMethodWrapper(method.Name, method.Sig, false) == null)
                     {
                         if(method.body == null)
                         {
                             Console.Error.WriteLine("Error: Method {0}.{1}{2} in xml remap file doesn't have a body.", clazz.Name, method.Name, method.Sig);
                             continue;
                         }
                         bool setmodifiers = false;
                         MethodAttributes attribs = method.MethodAttributes;
                         MapModifiers(method.Modifiers, false, out setmodifiers, ref attribs);
                         Type returnType;
                         Type[] parameterTypes;
                         MapSignature(method.Sig, out returnType, out parameterTypes);
                         MethodBuilder mb = typeBuilder.DefineMethod(method.Name, attribs, returnType, parameterTypes);
                         if(setmodifiers)
                         {
                             AttributeHelper.SetModifiers(mb, (Modifiers)method.Modifiers, false);
                         }
                         if(method.@override != null)
                         {
                             MethodWrapper mw = GetClassLoader().LoadClassByDottedName([email protected]).GetMethodWrapper([email protected], method.Sig, true);
                             mw.Link();
                             typeBuilder.DefineMethodOverride(mb, (MethodInfo)mw.GetMethod());
                         }
                         CompilerClassLoader.AddDeclaredExceptions(mb, method.throws);
                         CodeEmitter ilgen = CodeEmitter.Create(mb);
                         method.Emit(classLoader, ilgen);
                         ilgen.DoEmit();
                         if(method.Attributes != null)
                         {
                             foreach(IKVM.Internal.MapXml.Attribute attr in method.Attributes)
                             {
                                 AttributeHelper.SetCustomAttribute(classLoader, mb, attr);
                             }
                         }
                     }
                 }
                 foreach(IKVM.Internal.MapXml.Method method in clazz.Methods)
                 {
                     if(method.Attributes != null)
                     {
                         foreach(MethodWrapper mw in methods)
                         {
                             if(mw.Name == method.Name && mw.Signature == method.Sig)
                             {
                                 MethodBuilder mb = mw.GetMethod() as MethodBuilder;
                                 if(mb != null)
                                 {
                                     foreach(IKVM.Internal.MapXml.Attribute attr in method.Attributes)
                                     {
                                         AttributeHelper.SetCustomAttribute(classLoader, mb, attr);
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
             if(clazz.Interfaces != null)
             {
                 foreach(IKVM.Internal.MapXml.Interface iface in clazz.Interfaces)
                 {
                     TypeWrapper tw = GetClassLoader().LoadClassByDottedName(iface.Name);
                     // NOTE since this interface won't be part of the list in the ImplementAttribute,
                     // it won't be visible from Java that the type implements this interface.
                     typeBuilder.AddInterfaceImplementation(tw.TypeAsBaseType);
                     if(iface.Methods != null)
                     {
                         foreach(IKVM.Internal.MapXml.Method m in iface.Methods)
                         {
                             MethodWrapper mw = tw.GetMethodWrapper(m.Name, m.Sig, false);
                             if(mw == null)
                             {
                                 throw new InvalidOperationException("Method " + m.Name + m.Sig + " not found in interface " + tw.Name);
                             }
                             mw.Link();
                             MethodBuilder mb = mw.GetDefineMethodHelper().DefineMethod(this, typeBuilder, tw.Name + "/" + m.Name, MethodAttributes.Private | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.CheckAccessOnOverride);
                             AttributeHelper.HideFromJava(mb);
                             typeBuilder.DefineMethodOverride(mb, (MethodInfo)mw.GetMethod());
                             CodeEmitter ilgen = CodeEmitter.Create(mb);
                             m.Emit(classLoader, ilgen);
                             ilgen.DoEmit();
                         }
                     }
                 }
             }
         }
     }
 }
Esempio n. 2
0
        protected override void FinishGhost(TypeBuilder typeBuilder, MethodWrapper[] methods)
        {
            if(typeBuilderGhostInterface != null)
            {
                // TODO consider adding methods from base interface and java.lang.Object as well
                for(int i = 0; i < methods.Length; i++)
                {
                    // skip <clinit>
                    if(!methods[i].IsStatic)
                    {
                        TypeWrapper[] args = methods[i].GetParameters();
                        MethodBuilder stub = methods[i].GetDefineMethodHelper().DefineMethod(this, typeBuilder, methods[i].Name, MethodAttributes.Public);
                        AddParameterMetadata(stub, methods[i]);
                        AttributeHelper.SetModifiers(stub, methods[i].Modifiers, methods[i].IsInternal);
                        CodeEmitter ilgen = CodeEmitter.Create(stub);
                        CodeEmitterLabel end = ilgen.DefineLabel();
                        TypeWrapper[] implementers = classLoader.GetGhostImplementers(this);
                        ilgen.Emit(OpCodes.Ldarg_0);
                        ilgen.Emit(OpCodes.Ldfld, ghostRefField);
                        ilgen.Emit(OpCodes.Dup);
                        ilgen.Emit(OpCodes.Isinst, typeBuilderGhostInterface);
                        CodeEmitterLabel label = ilgen.DefineLabel();
                        ilgen.EmitBrfalse(label);
                        ilgen.Emit(OpCodes.Castclass, typeBuilderGhostInterface);
                        for(int k = 0; k < args.Length; k++)
                        {
                            ilgen.EmitLdarg(k + 1);
                        }
                        ilgen.Emit(OpCodes.Callvirt, (MethodInfo)methods[i].GetMethod());
                        ilgen.EmitBr(end);
                        ilgen.MarkLabel(label);
                        for(int j = 0; j < implementers.Length; j++)
                        {
                            ilgen.Emit(OpCodes.Dup);
                            ilgen.Emit(OpCodes.Isinst, implementers[j].TypeAsTBD);
                            label = ilgen.DefineLabel();
                            ilgen.EmitBrfalse(label);
                            ilgen.Emit(OpCodes.Castclass, implementers[j].TypeAsTBD);
                            for(int k = 0; k < args.Length; k++)
                            {
                                ilgen.EmitLdarg(k + 1);
                            }
                            MethodWrapper mw = implementers[j].GetMethodWrapper(methods[i].Name, methods[i].Signature, true);
                            mw.EmitCallvirt(ilgen);
                            ilgen.EmitBr(end);
                            ilgen.MarkLabel(label);
                        }
                        // we need to do a null check (null fails all the isinst checks)
                        ilgen.EmitNullCheck();
                        ilgen.EmitThrow("java.lang.IncompatibleClassChangeError", Name);
                        ilgen.MarkLabel(end);
                        ilgen.Emit(OpCodes.Ret);
                        ilgen.DoEmit();
                    }
                }
                // HACK create a scope to enable reuse of "implementers" name
                if(true)
                {
                    MethodBuilder mb;
                    CodeEmitter ilgen;
                    CodeEmitterLocal local;
                    // add implicit conversions for all the ghost implementers
                    TypeWrapper[] implementers = classLoader.GetGhostImplementers(this);
                    for(int i = 0; i < implementers.Length; i++)
                    {
                        mb = typeBuilder.DefineMethod("op_Implicit", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, TypeAsSignatureType, new Type[] { implementers[i].TypeAsSignatureType });
                        AttributeHelper.HideFromJava(mb);
                        ilgen = CodeEmitter.Create(mb);
                        local = ilgen.DeclareLocal(TypeAsSignatureType);
                        ilgen.Emit(OpCodes.Ldloca, local);
                        ilgen.Emit(OpCodes.Ldarg_0);
                        ilgen.Emit(OpCodes.Stfld, ghostRefField);
                        ilgen.Emit(OpCodes.Ldloca, local);
                        ilgen.Emit(OpCodes.Ldobj, TypeAsSignatureType);
                        ilgen.Emit(OpCodes.Ret);
                        ilgen.DoEmit();
                    }
                    // Implement the "IsInstance" method
                    mb = ghostIsInstanceMethod;
                    AttributeHelper.HideFromJava(mb);
                    ilgen = CodeEmitter.Create(mb);
                    CodeEmitterLabel end = ilgen.DefineLabel();
                    for(int i = 0; i < implementers.Length; i++)
                    {
                        ilgen.Emit(OpCodes.Ldarg_0);
                        ilgen.Emit(OpCodes.Isinst, implementers[i].TypeAsTBD);
                        CodeEmitterLabel label = ilgen.DefineLabel();
                        ilgen.EmitBrfalse(label);
                        ilgen.Emit(OpCodes.Ldc_I4_1);
                        ilgen.EmitBr(end);
                        ilgen.MarkLabel(label);
                    }
                    ilgen.Emit(OpCodes.Ldarg_0);
                    ilgen.Emit(OpCodes.Isinst, typeBuilderGhostInterface);
                    ilgen.Emit(OpCodes.Ldnull);
                    ilgen.Emit(OpCodes.Cgt_Un);
                    ilgen.MarkLabel(end);
                    ilgen.Emit(OpCodes.Ret);
                    ilgen.DoEmit();
                    // Implement the "IsInstanceArray" method
                    mb = ghostIsInstanceArrayMethod;
                    AttributeHelper.HideFromJava(mb);
                    ilgen = CodeEmitter.Create(mb);
                    CodeEmitterLocal localType = ilgen.DeclareLocal(Types.Type);
                    CodeEmitterLocal localRank = ilgen.DeclareLocal(Types.Int32);
                    ilgen.Emit(OpCodes.Ldarg_0);
                    CodeEmitterLabel skip = ilgen.DefineLabel();
                    ilgen.EmitBrtrue(skip);
                    ilgen.Emit(OpCodes.Ldc_I4_0);
                    ilgen.Emit(OpCodes.Ret);
                    ilgen.MarkLabel(skip);
                    ilgen.Emit(OpCodes.Ldarg_0);
                    ilgen.Emit(OpCodes.Call, Compiler.getTypeMethod);
                    ilgen.Emit(OpCodes.Stloc, localType);
                    ilgen.Emit(OpCodes.Ldarg_1);
                    ilgen.Emit(OpCodes.Stloc, localRank);
                    skip = ilgen.DefineLabel();
                    ilgen.EmitBr(skip);
                    CodeEmitterLabel iter = ilgen.DefineLabel();
                    ilgen.MarkLabel(iter);
                    ilgen.Emit(OpCodes.Ldloc, localType);
                    ilgen.Emit(OpCodes.Callvirt, Types.Type.GetMethod("GetElementType"));
                    ilgen.Emit(OpCodes.Stloc, localType);
                    ilgen.Emit(OpCodes.Ldloc, localRank);
                    ilgen.Emit(OpCodes.Ldc_I4_1);
                    ilgen.Emit(OpCodes.Sub);
                    ilgen.Emit(OpCodes.Stloc, localRank);
                    ilgen.Emit(OpCodes.Ldloc, localRank);
                    CodeEmitterLabel typecheck = ilgen.DefineLabel();
                    ilgen.EmitBrfalse(typecheck);
                    ilgen.MarkLabel(skip);
                    ilgen.Emit(OpCodes.Ldloc, localType);
                    ilgen.Emit(OpCodes.Callvirt, Types.Type.GetMethod("get_IsArray"));
                    ilgen.EmitBrtrue(iter);
                    ilgen.Emit(OpCodes.Ldc_I4_0);
                    ilgen.Emit(OpCodes.Ret);
                    ilgen.MarkLabel(typecheck);
                    for(int i = 0; i < implementers.Length; i++)
                    {
                        ilgen.Emit(OpCodes.Ldtoken, implementers[i].TypeAsTBD);
                        ilgen.Emit(OpCodes.Call, Types.Type.GetMethod("GetTypeFromHandle"));
                        ilgen.Emit(OpCodes.Ldloc, localType);
                        ilgen.Emit(OpCodes.Callvirt, Types.Type.GetMethod("IsAssignableFrom"));
                        CodeEmitterLabel label = ilgen.DefineLabel();
                        ilgen.EmitBrfalse(label);
                        ilgen.Emit(OpCodes.Ldc_I4_1);
                        ilgen.Emit(OpCodes.Ret);
                        ilgen.MarkLabel(label);
                    }
                    ilgen.Emit(OpCodes.Ldtoken, typeBuilderGhostInterface);
                    ilgen.Emit(OpCodes.Call, Types.Type.GetMethod("GetTypeFromHandle"));
                    ilgen.Emit(OpCodes.Ldloc, localType);
                    ilgen.Emit(OpCodes.Callvirt, Types.Type.GetMethod("IsAssignableFrom"));
                    skip = ilgen.DefineLabel();
                    ilgen.EmitBrfalse(skip);
                    ilgen.Emit(OpCodes.Ldc_I4_1);
                    ilgen.Emit(OpCodes.Ret);
                    ilgen.MarkLabel(skip);
                    ilgen.Emit(OpCodes.Ldarg_0);
                    ilgen.Emit(OpCodes.Ldtoken, typeBuilder);
                    ilgen.Emit(OpCodes.Ldarg_1);
                    ilgen.Emit(OpCodes.Call, StaticCompiler.GetRuntimeType("IKVM.Runtime.GhostTag").GetMethod("IsGhostArrayInstance", BindingFlags.NonPublic | BindingFlags.Static));
                    ilgen.Emit(OpCodes.Ret);
                    ilgen.DoEmit();

                    // Implement the "Cast" method
                    mb = ghostCastMethod;
                    AttributeHelper.HideFromJava(mb);
                    ilgen = CodeEmitter.Create(mb);
                    end = ilgen.DefineLabel();
                    for(int i = 0; i < implementers.Length; i++)
                    {
                        ilgen.Emit(OpCodes.Ldarg_0);
                        ilgen.Emit(OpCodes.Isinst, implementers[i].TypeAsTBD);
                        ilgen.EmitBrtrue(end);
                    }
                    ilgen.Emit(OpCodes.Ldarg_0);
                    ilgen.Emit(OpCodes.Castclass, typeBuilderGhostInterface);
                    ilgen.Emit(OpCodes.Pop);
                    ilgen.MarkLabel(end);
                    local = ilgen.DeclareLocal(TypeAsSignatureType);
                    ilgen.Emit(OpCodes.Ldloca, local);
                    ilgen.Emit(OpCodes.Ldarg_0);
                    ilgen.Emit(OpCodes.Stfld, ghostRefField);
                    ilgen.Emit(OpCodes.Ldloca, local);
                    ilgen.Emit(OpCodes.Ldobj, TypeAsSignatureType);
                    ilgen.Emit(OpCodes.Ret);
                    ilgen.DoEmit();
                    // Add "ToObject" methods
                    mb = typeBuilder.DefineMethod("ToObject", MethodAttributes.HideBySig | MethodAttributes.Public, Types.Object, Type.EmptyTypes);
                    AttributeHelper.HideFromJava(mb);
                    ilgen = CodeEmitter.Create(mb);
                    ilgen.Emit(OpCodes.Ldarg_0);
                    ilgen.Emit(OpCodes.Ldfld, ghostRefField);
                    ilgen.Emit(OpCodes.Ret);
                    ilgen.DoEmit();

                    // Implement the "CastArray" method
                    // NOTE unlike "Cast" this doesn't return anything, it just throws a ClassCastException if the
                    // cast is unsuccessful. Also, because of the complexity of this test, we call IsInstanceArray
                    // instead of reimplementing the check here.
                    mb = ghostCastArrayMethod;
                    AttributeHelper.HideFromJava(mb);
                    ilgen = CodeEmitter.Create(mb);
                    end = ilgen.DefineLabel();
                    ilgen.Emit(OpCodes.Ldarg_0);
                    ilgen.EmitBrfalse(end);
                    ilgen.Emit(OpCodes.Ldarg_0);
                    ilgen.Emit(OpCodes.Ldarg_1);
                    ilgen.Emit(OpCodes.Call, ghostIsInstanceArrayMethod);
                    ilgen.EmitBrtrue(end);
                    ilgen.Emit(OpCodes.Ldarg_0);
                    ilgen.Emit(OpCodes.Ldtoken, typeBuilder);
                    ilgen.Emit(OpCodes.Ldarg_1);
                    ilgen.Emit(OpCodes.Call, StaticCompiler.GetRuntimeType("IKVM.Runtime.GhostTag").GetMethod("ThrowClassCastException", BindingFlags.NonPublic | BindingFlags.Static));
                    ilgen.MarkLabel(end);
                    ilgen.Emit(OpCodes.Ret);
                    ilgen.DoEmit();

                    // Implement the "Equals" method
                    mb = typeBuilder.DefineMethod("Equals", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual, Types.Boolean, new Type[] { Types.Object });
                    AttributeHelper.HideFromJava(mb);
                    ilgen = CodeEmitter.Create(mb);
                    ilgen.Emit(OpCodes.Ldarg_0);
                    ilgen.Emit(OpCodes.Ldfld, ghostRefField);
                    ilgen.Emit(OpCodes.Ldarg_1);
                    ilgen.Emit(OpCodes.Ceq);
                    ilgen.Emit(OpCodes.Ret);
                    ilgen.DoEmit();

                    // Implement the "GetHashCode" method
                    mb = typeBuilder.DefineMethod("GetHashCode", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Virtual, Types.Int32, Type.EmptyTypes);
                    AttributeHelper.HideFromJava(mb);
                    ilgen = CodeEmitter.Create(mb);
                    ilgen.Emit(OpCodes.Ldarg_0);
                    ilgen.Emit(OpCodes.Ldfld, ghostRefField);
                    ilgen.Emit(OpCodes.Callvirt, Types.Object.GetMethod("GetHashCode"));
                    ilgen.Emit(OpCodes.Ret);
                    ilgen.DoEmit();

                    // Implement the "op_Equality" method
                    mb = typeBuilder.DefineMethod("op_Equality", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, Types.Boolean, new Type[] { typeBuilder, typeBuilder });
                    AttributeHelper.HideFromJava(mb);
                    ilgen = CodeEmitter.Create(mb);
                    ilgen.EmitLdarga(0);
                    ilgen.Emit(OpCodes.Ldfld, ghostRefField);
                    ilgen.EmitLdarga(1);
                    ilgen.Emit(OpCodes.Ldfld, ghostRefField);
                    ilgen.Emit(OpCodes.Ceq);
                    ilgen.Emit(OpCodes.Ret);
                    ilgen.DoEmit();

                    // Implement the "op_Inequality" method
                    mb = typeBuilder.DefineMethod("op_Inequality", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, Types.Boolean, new Type[] { typeBuilder, typeBuilder });
                    AttributeHelper.HideFromJava(mb);
                    ilgen = CodeEmitter.Create(mb);
                    ilgen.EmitLdarga(0);
                    ilgen.Emit(OpCodes.Ldfld, ghostRefField);
                    ilgen.EmitLdarga(1);
                    ilgen.Emit(OpCodes.Ldfld, ghostRefField);
                    ilgen.Emit(OpCodes.Ceq);
                    ilgen.Emit(OpCodes.Ldc_I4_0);
                    ilgen.Emit(OpCodes.Ceq);
                    ilgen.Emit(OpCodes.Ret);
                    ilgen.DoEmit();
                }
            }
        }
Esempio n. 3
0
 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);
             }
         }
     }
 }