Example #1
0
        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);
            }
        }
Example #2
0
        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));
            }
        }