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)); }
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)); }
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)); }
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)); }
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)); }
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)); }
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)); }