Example #1
0
        public MutableConstructorInfo CreateConstructor(
            MutableType declaringType,
            MethodAttributes attributes,
            IEnumerable <ParameterDeclaration> parameters,
            Func <ConstructorBodyCreationContext, Expression> bodyProvider)
        {
            ArgumentUtility.CheckNotNull("declaringType", declaringType);
            ArgumentUtility.CheckNotNull("parameters", parameters);
            ArgumentUtility.CheckNotNull("bodyProvider", bodyProvider);

            MemberAttributesUtility.ValidateAttributes("constructors", MemberAttributesUtility.InvalidConstructorAttributes, attributes, "attributes");

            var isStatic = attributes.IsSet(MethodAttributes.Static);
            var paras    = parameters.ToList();

            if (isStatic && paras.Count != 0)
            {
                throw new ArgumentException("A type initializer (static constructor) cannot have parameters.", "parameters");
            }

            var signature = new MethodSignature(typeof(void), paras.Select(p => p.Type), 0);

            if (declaringType.AddedConstructors.Any(ctor => ctor.IsStatic == isStatic && MethodSignature.Create(ctor).Equals(signature)))
            {
                throw new InvalidOperationException("Constructor with equal signature already exists.");
            }

            var parameterExpressions = paras.Select(p => p.Expression);
            var context = new ConstructorBodyCreationContext(declaringType, isStatic, parameterExpressions);
            var body    = BodyProviderUtility.GetTypedBody(typeof(void), bodyProvider, context);

            var attr = attributes.Set(MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);

            return(new MutableConstructorInfo(declaringType, attr, paras, body));
        }
Example #2
0
        public MutablePropertyInfo CreateProperty(
            MutableType declaringType, string name, PropertyAttributes attributes, MutableMethodInfo getMethod, MutableMethodInfo setMethod)
        {
            ArgumentUtility.CheckNotNull("declaringType", declaringType);
            ArgumentUtility.CheckNotNullOrEmpty("name", name);
            // Get method may be null.
            // Set method may be null.

            MemberAttributesUtility.ValidateAttributes("properties", MemberAttributesUtility.InvalidPropertyAttributes, attributes, "attributes");

            if (getMethod == null && setMethod == null)
            {
                throw new ArgumentException("Property must have at least one accessor.", "getMethod");
            }

            var readWriteProperty = getMethod != null && setMethod != null;

            if (readWriteProperty && getMethod.IsStatic != setMethod.IsStatic)
            {
                throw new ArgumentException("Accessor methods must be both either static or non-static.", "getMethod");
            }

            if (getMethod != null && !ReferenceEquals(getMethod.DeclaringType, declaringType))
            {
                throw new ArgumentException("Get method is not declared on the current type.", "getMethod");
            }
            if (setMethod != null && !ReferenceEquals(setMethod.DeclaringType, declaringType))
            {
                throw new ArgumentException("Set method is not declared on the current type.", "setMethod");
            }

            if (getMethod != null && getMethod.ReturnType == typeof(void))
            {
                throw new ArgumentException("Get accessor must be a non-void method.", "getMethod");
            }
            if (setMethod != null && setMethod.ReturnType != typeof(void))
            {
                throw new ArgumentException("Set accessor must have return type void.", "setMethod");
            }

            var getSignature  = getMethod != null ? new PropertySignature(getMethod.ReturnType, getMethod.GetParameters().Select(p => p.ParameterType)) : null;
            var setParameters = setMethod != null?setMethod.GetParameters().Select(p => p.ParameterType).ToList() : null;

            var setSignature = setMethod != null ? new PropertySignature(setParameters.Last(), setParameters.Take(setParameters.Count - 1)) : null;

            if (readWriteProperty && !getSignature.Equals(setSignature))
            {
                throw new ArgumentException("Get and set accessor methods must have a matching signature.", "setMethod");
            }

            var signature = getSignature ?? setSignature;

            if (declaringType.AddedProperties.Any(p => p.Name == name && PropertySignature.Create(p).Equals(signature)))
            {
                throw new InvalidOperationException("Property with equal name and signature already exists.");
            }

            return(new MutablePropertyInfo(declaringType, name, attributes, getMethod, setMethod));
        }
Example #3
0
        public MutablePropertyInfo CreateProperty(
            MutableType declaringType,
            string name,
            Type type,
            IEnumerable <ParameterDeclaration> indexParameters,
            MethodAttributes accessorAttributes,
            Func <MethodBodyCreationContext, Expression> getBodyProvider,
            Func <MethodBodyCreationContext, Expression> setBodyProvider)
        {
            ArgumentUtility.CheckNotNull("declaringType", declaringType);
            ArgumentUtility.CheckNotNullOrEmpty("name", name);
            ArgumentUtility.CheckNotNull("type", type);
            ArgumentUtility.CheckNotNull("indexParameters", indexParameters);
            // Get body provider may be null.
            // Set body provider may be null.

            MemberAttributesUtility.ValidateAttributes(
                "property accessor methods", MemberAttributesUtility.InvalidMethodAttributes, accessorAttributes, "accessorAttributes");

            if (getBodyProvider == null && setBodyProvider == null)
            {
                throw new ArgumentException("At least one accessor body provider must be specified.", "getBodyProvider");
            }

            var indexParams = indexParameters.ToList();
            var signature   = new PropertySignature(type, indexParams.Select(pd => pd.Type));

            if (declaringType.AddedProperties.Any(p => p.Name == name && PropertySignature.Create(p).Equals(signature)))
            {
                throw new InvalidOperationException("Property with equal name and signature already exists.");
            }

            var attributes = accessorAttributes | MethodAttributes.SpecialName;
            MutableMethodInfo getMethod = null, setMethod = null;

            if (getBodyProvider != null)
            {
                getMethod = CreateAccessor(declaringType, "get_" + name, attributes, type, indexParams, getBodyProvider);
            }
            if (setBodyProvider != null)
            {
                var setterParams = indexParams.Concat(new[] { new ParameterDeclaration(type, "value") });
                setMethod = CreateAccessor(declaringType, "set_" + name, attributes, typeof(void), setterParams, setBodyProvider);
            }

            return(new MutablePropertyInfo(declaringType, name, PropertyAttributes.None, getMethod, setMethod));
        }
Example #4
0
        public MutableEventInfo CreateEvent(
            MutableType declaringType,
            string name,
            Type handlerType,
            MethodAttributes accessorAttributes,
            Func <MethodBodyCreationContext, Expression> addBodyProvider,
            Func <MethodBodyCreationContext, Expression> removeBodyProvider,
            Func <MethodBodyCreationContext, Expression> raiseBodyProvider)
        {
            ArgumentUtility.CheckNotNull("declaringType", declaringType);
            ArgumentUtility.CheckNotNullOrEmpty("name", name);
            ArgumentUtility.CheckNotNullAndTypeIsAssignableFrom("handlerType", handlerType, typeof(Delegate));
            ArgumentUtility.CheckNotNull("addBodyProvider", addBodyProvider);
            ArgumentUtility.CheckNotNull("removeBodyProvider", removeBodyProvider);
            // Raise body provider may be null.

            MemberAttributesUtility.ValidateAttributes(
                "event accessor methods", MemberAttributesUtility.InvalidMethodAttributes, accessorAttributes, "accessorAttributes");

            var signature = new EventSignature(handlerType);

            if (declaringType.AddedEvents.Any(e => e.Name == name && EventSignature.Create(e).Equals(signature)))
            {
                throw new InvalidOperationException("Event with equal name and signature already exists.");
            }

            var attributes          = accessorAttributes | MethodAttributes.SpecialName;
            var addRemoveParameters = new[] { new ParameterDeclaration(handlerType, "handler") };

            var addMethod    = CreateAccessor(declaringType, "add_" + name, attributes, typeof(void), addRemoveParameters, addBodyProvider);
            var removeMethod = CreateAccessor(declaringType, "remove_" + name, attributes, typeof(void), addRemoveParameters, removeBodyProvider);

            MutableMethodInfo raiseMethod = null;

            if (raiseBodyProvider != null)
            {
                var invokeMethod    = GetInvokeMethod(handlerType);
                var raiseParameters = invokeMethod.GetParameters().Select(p => new ParameterDeclaration(p.ParameterType, p.Name, p.Attributes));
                raiseMethod = CreateAccessor(declaringType, "raise_" + name, attributes, invokeMethod.ReturnType, raiseParameters, raiseBodyProvider);
            }

            return(new MutableEventInfo(declaringType, name, EventAttributes.None, addMethod, removeMethod, raiseMethod));
        }
Example #5
0
        public MutableFieldInfo CreateField(MutableType declaringType, string name, Type type, FieldAttributes attributes)
        {
            ArgumentUtility.CheckNotNull("declaringType", declaringType);
            ArgumentUtility.CheckNotNullOrEmpty("name", name);
            ArgumentUtility.CheckNotNull("type", type);

            if (type == typeof(void))
            {
                throw new ArgumentException("Field cannot be of type void.", "type");
            }

            MemberAttributesUtility.ValidateAttributes("fields", MemberAttributesUtility.InvalidFieldAttributes, attributes, "attributes");

            var signature = new FieldSignature(type);

            if (declaringType.AddedFields.Any(f => f.Name == name && FieldSignature.Create(f).Equals(signature)))
            {
                throw new InvalidOperationException("Field with equal name and signature already exists.");
            }

            return(new MutableFieldInfo(declaringType, name, type, attributes));
        }
Example #6
0
        public MutableMethodInfo CreateMethod(
            MutableType declaringType,
            string name,
            MethodAttributes attributes,
            IEnumerable <GenericParameterDeclaration> genericParameters,
            Func <GenericParameterContext, Type> returnTypeProvider,
            Func <GenericParameterContext, IEnumerable <ParameterDeclaration> > parameterProvider,
            Func <MethodBodyCreationContext, Expression> bodyProvider)
        {
            ArgumentUtility.CheckNotNull("declaringType", declaringType);
            ArgumentUtility.CheckNotNullOrEmpty("name", name);
            ArgumentUtility.CheckNotNull("genericParameters", genericParameters);
            ArgumentUtility.CheckNotNull("returnTypeProvider", returnTypeProvider);
            ArgumentUtility.CheckNotNull("parameterProvider", parameterProvider);
            // Body provider may be null (for abstract methods).

            // TODO 5478: virtual and static is an invalid combination

            var isAbstract = attributes.IsSet(MethodAttributes.Abstract);

            if (!isAbstract && bodyProvider == null)
            {
                throw new ArgumentNullException("bodyProvider", "Non-abstract methods must have a body.");
            }
            if (isAbstract && bodyProvider != null)
            {
                throw new ArgumentException("Abstract methods cannot have a body.", "bodyProvider");
            }

            MemberAttributesUtility.ValidateAttributes("methods", MemberAttributesUtility.InvalidMethodAttributes, attributes, "attributes");

            var isVirtual = attributes.IsSet(MethodAttributes.Virtual);
            var isNewSlot = attributes.IsSet(MethodAttributes.NewSlot);

            if (isAbstract && !isVirtual)
            {
                throw new ArgumentException("Abstract methods must also be virtual.", "attributes");
            }
            if (!isVirtual && isNewSlot)
            {
                throw new ArgumentException("NewSlot methods must also be virtual.", "attributes");
            }

            var methodItems = GetMethodSignatureItems(declaringType, genericParameters, returnTypeProvider, parameterProvider);

            var signature = new MethodSignature(
                methodItems.ReturnType,
                methodItems.ParameterDeclarations.Select(pd => pd.Type),
                methodItems.GenericParameters.Count,
                s_methodSignatureStringBuilderHelper);

            if (declaringType.AddedMethods.Any(m => m.Name == name && MethodSignature.Create(m).Equals(signature)))
            {
                throw new InvalidOperationException("Method with equal name and signature already exists.");
            }

            var baseMethod = GetBaseMethod(declaringType, name, signature, isVirtual, isNewSlot);
            // TODO 5478: if it is an implicit overriddenMethod override, it needs at least the same ore more public visibility

            var body = GetMethodBody(declaringType, attributes, bodyProvider, methodItems, baseMethod);

            return(new MutableMethodInfo(
                       declaringType, name, attributes, methodItems.GenericParameters, methodItems.ReturnType, methodItems.ParameterDeclarations, baseMethod, body));
        }
Example #7
0
        public MutableEventInfo CreateEvent(
            MutableType declaringType,
            string name,
            EventAttributes attributes,
            MutableMethodInfo addMethod,
            MutableMethodInfo removeMethod,
            MutableMethodInfo raiseMethod)
        {
            ArgumentUtility.CheckNotNull("declaringType", declaringType);
            ArgumentUtility.CheckNotNullOrEmpty("name", name);
            ArgumentUtility.CheckNotNull("addMethod", addMethod);
            ArgumentUtility.CheckNotNull("removeMethod", removeMethod);
            // Raise method may be null.

            MemberAttributesUtility.ValidateAttributes("events", MemberAttributesUtility.InvalidEventAttributes, attributes, "attributes");

            if (addMethod.IsStatic != removeMethod.IsStatic || (raiseMethod != null && raiseMethod.IsStatic != addMethod.IsStatic))
            {
                throw new ArgumentException("Accessor methods must be all either static or non-static.", "addMethod");
            }

            if (!ReferenceEquals(addMethod.DeclaringType, declaringType))
            {
                throw new ArgumentException("Add method is not declared on the current type.", "addMethod");
            }
            if (!ReferenceEquals(removeMethod.DeclaringType, declaringType))
            {
                throw new ArgumentException("Remove method is not declared on the current type.", "removeMethod");
            }
            if (raiseMethod != null && !ReferenceEquals(raiseMethod.DeclaringType, declaringType))
            {
                throw new ArgumentException("Raise method is not declared on the current type.", "raiseMethod");
            }

            if (addMethod.ReturnType != typeof(void))
            {
                throw new ArgumentException("Add method must have return type void.", "addMethod");
            }
            if (removeMethod.ReturnType != typeof(void))
            {
                throw new ArgumentException("Remove method must have return type void.", "removeMethod");
            }

            var addMethodParameterTypes    = addMethod.GetParameters().Select(p => p.ParameterType).ToList();
            var removeMethodParameterTypes = removeMethod.GetParameters().Select(p => p.ParameterType).ToList();

            if (addMethodParameterTypes.Count != 1 || !addMethodParameterTypes[0].IsSubclassOf(typeof(Delegate)))
            {
                throw new ArgumentException("Add method must have a single parameter that is assignable to 'System.Delegate'.", "addMethod");
            }
            if (removeMethodParameterTypes.Count != 1 || !removeMethodParameterTypes[0].IsSubclassOf(typeof(Delegate)))
            {
                throw new ArgumentException("Remove method must have a single parameter that is assignable to 'System.Delegate'.", "removeMethod");
            }

            if (addMethodParameterTypes.Single() != removeMethodParameterTypes.Single())
            {
                throw new ArgumentException("The type of the handler parameter is different for the add and remove method.", "removeMethod");
            }

            var handlerType  = addMethodParameterTypes.Single();
            var invokeMethod = GetInvokeMethod(handlerType);

            if (raiseMethod != null && !MethodSignature.AreEqual(raiseMethod, invokeMethod))
            {
                throw new ArgumentException("The signature of the raise method does not match the handler type.", "raiseMethod");
            }

            var signature = new EventSignature(handlerType);

            if (declaringType.AddedEvents.Any(e => e.Name == name && EventSignature.Create(e).Equals(signature)))
            {
                throw new InvalidOperationException("Event with equal name and signature already exists.");
            }

            return(new MutableEventInfo(declaringType, name, attributes, addMethod, removeMethod, raiseMethod));
        }