public virtual void InvokeInterface(MethodInstance method) { if (method.Access.HasFlag(MethodAttributes.Static)) { throw new ArgumentException("Given method is not virtual: " + method); } NewType owner = method.Owner; if (owner == null) { InvokeVirtual(method.DeriveOwner()); } else { InvokeVirtual(method); } }
public virtual IMethodVisitor VisitMethod(MethodInstance method) { NewType owner = State.NewType; method = method.DeriveOwner(); if (Log.DebugEnabled && !State.OriginalType.Name.Contains("Member")) { Log.Debug("Implement method: " + method.ToString()); } Type[] parameters = new Type[method.Parameters.Length]; for (int a = parameters.Length; a-- > 0;) { parameters[a] = method.Parameters[a].Type; } MethodAttributes access = method.Access; if (ConstructorInstance.CONSTRUCTOR_NAME.Equals(method.Name)) { ConstructorBuilder mb = tb.DefineConstructor(access, access.HasFlag(MethodAttributes.Static) ? CallingConventions.Standard : CallingConventions.HasThis, parameters); ((BytecodeBehaviorState)State).MethodImplemented(new ConstructorInstance(newType, mb, method.Parameters)); sb.Append("\r\n" + method.ToString()); return(new MethodWriter(mb, new ConstructorInstance(owner, mb, method.Parameters), sb)); } else { PropertyInstance propertyInfo = null; Object eventInfo = null; if (!access.HasFlag(MethodAttributes.Static)) { access |= MethodAttributes.Virtual; } access |= MethodAttributes.HideBySig; access |= MethodAttributes.ReuseSlot; access &= ~MethodAttributes.VtableLayoutMask; String propertyName = null, eventName = null; Type propertyType = null; if (method.Name.StartsWith("get_") && method.Parameters.Length == 0) { propertyName = method.Name.Substring(4); propertyType = method.ReturnType.Type; } else if (method.Name.StartsWith("set_") && method.Parameters.Length == 1) { propertyName = method.Name.Substring(4); propertyType = method.Parameters[0].Type; } else if (method.Name.StartsWith("add_") && method.Parameters.Length == 1) { eventName = method.Name.Substring(4); propertyType = method.Parameters[0].Type; } else if (method.Name.StartsWith("remove_") && method.Parameters.Length == 1) { eventName = method.Name.Substring(7); propertyType = method.Parameters[0].Type; } if (propertyName != null) { propertyInfo = State.GetProperty(propertyName, NewType.GetType(propertyType)); if (propertyInfo == null) { #if SILVERLIGHT PropertyInfo pi = tb.DefineProperty(propertyName, PropertyAttributes.None, propertyType, null); #else CallingConventions cc = access.HasFlag(MethodAttributes.Static) ? CallingConventions.Standard : CallingConventions.HasThis; PropertyInfo pi = tb.DefineProperty(propertyName, PropertyAttributes.None, cc, propertyType, null); #endif propertyInfo = new PropertyInstance(pi); ((BytecodeBehaviorState)State).PropertyImplemented(propertyInfo); } } else if (eventName != null) { eventInfo = ((BytecodeBehaviorState)State).GetAlreadyImplementedEvent(eventName); if (eventInfo == null) { CallingConventions cc = access.HasFlag(MethodAttributes.Static) ? CallingConventions.Standard : CallingConventions.HasThis; EventBuilder eb = tb.DefineEvent(eventName, EventAttributes.None, propertyType); ((BytecodeBehaviorState)State).EventImplemented(eventName, eb); eventInfo = eb; } } MethodBuilder mb = tb.DefineMethod(method.Name, access, access.HasFlag(MethodAttributes.Static) ? CallingConventions.Standard : CallingConventions.HasThis, method.ReturnType.Type, parameters); //MethodInfo parentMI = State.CurrentType.GetMethod(method.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.FlattenHierarchy); //if (parentMI != null) //{ // tb.DefineMethodOverride(mb, parentMI); //} method = new MethodInstance(newType, mb, method.Parameters); ((BytecodeBehaviorState)State).MethodImplemented(method); if (propertyInfo != null && propertyInfo.Configurable) { if (method.Name.StartsWith("get_")) { propertyInfo.Getter = method; } else if (method.Name.StartsWith("set_")) { propertyInfo.Setter = method; } else { throw new ArgumentException(); } } if (eventInfo != null && eventInfo is EventBuilder) { EventBuilder eb = (EventBuilder)eventInfo; if (method.Name.StartsWith("add_")) { eb.SetAddOnMethod(mb); } else if (method.Name.StartsWith("remove_")) { eb.SetRemoveOnMethod(mb); } else { throw new ArgumentException(); } } sb.Append("\r\n" + method.ToString()); return(new MethodWriter(mb, method, sb)); } }