public SetCustomAttribute ( ConstructorInfo con, byte binaryAttribute ) : void | ||
con | ConstructorInfo | |
binaryAttribute | byte | |
Результат | void |
internal override MethodBase DoLink() { RemapperTypeWrapper typeWrapper = (RemapperTypeWrapper)DeclaringType; if(typeWrapper.IsInterface) { if(m.@override == null) { throw new InvalidOperationException(typeWrapper.Name + "." + m.Name + m.Sig); } MethodInfo interfaceMethod = typeWrapper.shadowType.GetMethod([email protected], typeWrapper.GetClassLoader().ArgTypeListFromSig(m.Sig)); if(interfaceMethod == null) { throw new InvalidOperationException(typeWrapper.Name + "." + m.Name + m.Sig); } // if any of the remapped types has a body for this interface method, we need a helper method // to special invocation through this interface for that type List<IKVM.Internal.MapXml.Class> specialCases = null; foreach(IKVM.Internal.MapXml.Class c in map.assembly.Classes) { if(c.Methods != null) { foreach(IKVM.Internal.MapXml.Method mm in c.Methods) { if(mm.Name == m.Name && mm.Sig == m.Sig && mm.body != null) { if(specialCases == null) { specialCases = new List<IKVM.Internal.MapXml.Class>(); } specialCases.Add(c); break; } } } } string[] throws; if (m.throws == null) { throws = new string[0]; } else { throws = new string[m.throws.Length]; for (int i = 0; i < throws.Length; i++) { throws[i] = m.throws[i].Class; } } AttributeHelper.SetRemappedInterfaceMethod(typeWrapper.typeBuilder, m.Name, [email protected], throws); MethodBuilder helper = null; if(specialCases != null) { CodeEmitter ilgen; Type[] temp = typeWrapper.GetClassLoader().ArgTypeListFromSig(m.Sig); Type[] argTypes = new Type[temp.Length + 1]; temp.CopyTo(argTypes, 1); argTypes[0] = typeWrapper.shadowType; if(typeWrapper.helperTypeBuilder == null) { // FXBUG we use a nested helper class, because Reflection.Emit won't allow us to add a static method to the interface // TODO now that we're on Whidbey we can remove this workaround typeWrapper.helperTypeBuilder = typeWrapper.typeBuilder.DefineNestedType("__Helper", TypeAttributes.NestedPublic | TypeAttributes.Class | TypeAttributes.Sealed); ilgen = CodeEmitter.Create(typeWrapper.helperTypeBuilder.DefineConstructor(MethodAttributes.Private, CallingConventions.Standard, Type.EmptyTypes)); ilgen.Emit(OpCodes.Ldnull); ilgen.Emit(OpCodes.Throw); ilgen.DoEmit(); AttributeHelper.HideFromJava(typeWrapper.helperTypeBuilder); } helper = typeWrapper.helperTypeBuilder.DefineMethod(m.Name, MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static, typeWrapper.GetClassLoader().RetTypeWrapperFromSig(m.Sig).TypeAsSignatureType, argTypes); if(m.Attributes != null) { foreach(IKVM.Internal.MapXml.Attribute custattr in m.Attributes) { AttributeHelper.SetCustomAttribute(DeclaringType.GetClassLoader(), helper, custattr); } } SetParameters(DeclaringType.GetClassLoader(), helper, m.Params); ilgen = CodeEmitter.Create(helper); foreach(IKVM.Internal.MapXml.Class c in specialCases) { TypeWrapper tw = typeWrapper.GetClassLoader().LoadClassByDottedName(c.Name); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Isinst, tw.TypeAsTBD); ilgen.Emit(OpCodes.Dup); CodeEmitterLabel label = ilgen.DefineLabel(); ilgen.Emit(OpCodes.Brfalse_S, label); for(int i = 1; i < argTypes.Length; i++) { ilgen.Emit(OpCodes.Ldarg, (short)i); } MethodWrapper mw = tw.GetMethodWrapper(m.Name, m.Sig, false); mw.Link(); mw.EmitCallvirt(ilgen); ilgen.Emit(OpCodes.Ret); ilgen.MarkLabel(label); ilgen.Emit(OpCodes.Pop); } for(int i = 0; i < argTypes.Length; i++) { ilgen.Emit(OpCodes.Ldarg, (short)i); } ilgen.Emit(OpCodes.Callvirt, interfaceMethod); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); } mbHelper = helper; return interfaceMethod; } else { MethodBuilder mbCore = null; Type[] paramTypes = typeWrapper.GetClassLoader().ArgTypeListFromSig(m.Sig); Type retType = typeWrapper.GetClassLoader().RetTypeWrapperFromSig(m.Sig).TypeAsSignatureType; if(typeWrapper.shadowType.IsSealed && (m.Modifiers & IKVM.Internal.MapXml.MapModifiers.Static) == 0) { // skip instance methods in sealed types, but we do need to add them to the overriders if(typeWrapper.BaseTypeWrapper != null && (m.Modifiers & IKVM.Internal.MapXml.MapModifiers.Private) == 0) { RemappedMethodWrapper baseMethod = typeWrapper.BaseTypeWrapper.GetMethodWrapper(m.Name, m.Sig, true) as RemappedMethodWrapper; if(baseMethod != null && !baseMethod.IsFinal && !baseMethod.IsPrivate && (baseMethod.m.@override != null || baseMethod.m.redirect != null || baseMethod.m.body != null || baseMethod.m.alternateBody != null)) { baseMethod.overriders.Add(typeWrapper); } } } else { MethodInfo overrideMethod = null; MethodAttributes attr = MapMethodAccessModifiers(m.Modifiers) | MethodAttributes.HideBySig; if((m.Modifiers & IKVM.Internal.MapXml.MapModifiers.Static) != 0) { attr |= MethodAttributes.Static; } else if((m.Modifiers & IKVM.Internal.MapXml.MapModifiers.Private) == 0 && (m.Modifiers & IKVM.Internal.MapXml.MapModifiers.Final) == 0) { attr |= MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.CheckAccessOnOverride; if(!typeWrapper.shadowType.IsSealed) { MethodInfo autoOverride = typeWrapper.shadowType.GetMethod(m.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, paramTypes, null); if(autoOverride != null && autoOverride.ReturnType == retType && !autoOverride.IsFinal) { // the method we're processing is overriding a method in its shadowType (which is the actual base type) attr &= ~MethodAttributes.NewSlot; } } if(typeWrapper.BaseTypeWrapper != null) { RemappedMethodWrapper baseMethod = typeWrapper.BaseTypeWrapper.GetMethodWrapper(m.Name, m.Sig, true) as RemappedMethodWrapper; if(baseMethod != null) { baseMethod.overriders.Add(typeWrapper); if(baseMethod.m.@override != null) { overrideMethod = typeWrapper.BaseTypeWrapper.TypeAsTBD.GetMethod([email protected], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, paramTypes, null); if(overrideMethod == null) { throw new InvalidOperationException(); } } } } } mbCore = typeWrapper.typeBuilder.DefineMethod(m.Name, attr, CallingConventions.Standard, retType, paramTypes); if(m.Attributes != null) { foreach(IKVM.Internal.MapXml.Attribute custattr in m.Attributes) { AttributeHelper.SetCustomAttribute(DeclaringType.GetClassLoader(), mbCore, custattr); } } SetParameters(DeclaringType.GetClassLoader(), mbCore, m.Params); if(overrideMethod != null && !inherited) { typeWrapper.typeBuilder.DefineMethodOverride(mbCore, overrideMethod); } if(inherited) { AttributeHelper.HideFromReflection(mbCore); } AddDeclaredExceptions(mbCore, m.throws); } if((m.Modifiers & IKVM.Internal.MapXml.MapModifiers.Static) == 0 && !IsHideFromJava(m)) { // instance methods must have an instancehelper method MethodAttributes attr = MapMethodAccessModifiers(m.Modifiers) | MethodAttributes.HideBySig | MethodAttributes.Static; // NOTE instancehelpers for protected methods are made internal // and special cased in DotNetTypeWrapper.LazyPublishMembers if((m.Modifiers & IKVM.Internal.MapXml.MapModifiers.Protected) != 0) { attr &= ~MethodAttributes.MemberAccessMask; attr |= MethodAttributes.Assembly; } Type[] exParamTypes = new Type[paramTypes.Length + 1]; Array.Copy(paramTypes, 0, exParamTypes, 1, paramTypes.Length); exParamTypes[0] = typeWrapper.shadowType; mbHelper = typeWrapper.typeBuilder.DefineMethod("instancehelper_" + m.Name, attr, CallingConventions.Standard, retType, exParamTypes); if(m.Attributes != null) { foreach(IKVM.Internal.MapXml.Attribute custattr in m.Attributes) { AttributeHelper.SetCustomAttribute(DeclaringType.GetClassLoader(), mbHelper, custattr); } } IKVM.Internal.MapXml.Param[] parameters; if(m.Params == null) { parameters = new IKVM.Internal.MapXml.Param[1]; } else { parameters = new IKVM.Internal.MapXml.Param[m.Params.Length + 1]; m.Params.CopyTo(parameters, 1); } parameters[0] = new IKVM.Internal.MapXml.Param(); parameters[0].Name = "this"; SetParameters(DeclaringType.GetClassLoader(), mbHelper, parameters); if(!typeWrapper.IsFinal) { AttributeHelper.SetEditorBrowsableNever(mbHelper); } AttributeHelper.SetModifiers(mbHelper, (Modifiers)m.Modifiers, false); AttributeHelper.SetNameSig(mbHelper, m.Name, m.Sig); AddDeclaredExceptions(mbHelper, m.throws); mbHelper.SetCustomAttribute(new CustomAttributeBuilder(JVM.Import(typeof(ObsoleteAttribute)).GetConstructor(new Type[] { Types.String }), new object[] { "This function will be removed from future versions. Please use extension methods from ikvm.extensions namespace instead." })); } return mbCore; } }
public void SetCustomAttribute(CustomAttributeBuilder customBuilder) { methodBuilder.SetCustomAttribute(customBuilder); }