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 void Initialization() { var declaringType = MutableTypeObjectMother.Create(); var name = "abc"; var attributes = (MethodAttributes)7 | MethodAttributes.Virtual; var returnType = ReflectionObjectMother.GetSomeType(); var parameters = ParameterDeclarationObjectMother.CreateMultiple(2); var baseMethod = ReflectionObjectMother.GetSomeVirtualMethod(); var body = ExpressionTreeObjectMother.GetSomeExpression(returnType); var method = new MutableMethodInfo( declaringType, name, attributes, new MutableGenericParameter[0], returnType, parameters.AsOneTime(), baseMethod, body); Assert.That(method.DeclaringType, Is.SameAs(declaringType)); Assert.That(method.MutableDeclaringType, Is.SameAs(declaringType)); Assert.That(method.Name, Is.EqualTo(name)); Assert.That(method.Attributes, Is.EqualTo(attributes)); Assert.That(method.IsGenericMethod, Is.False); CustomParameterInfoTest.CheckParameter(method.ReturnParameter, method, -1, null, returnType, ParameterAttributes.None); Assert.That(method.MutableReturnParameter, Is.SameAs(method.ReturnParameter)); var actualParameters = method.GetParameters(); Assert.That(actualParameters, Has.Length.EqualTo(2)); CustomParameterInfoTest.CheckParameter(actualParameters[0], method, 0, parameters[0].Name, parameters[0].Type, parameters[0].Attributes); CustomParameterInfoTest.CheckParameter(actualParameters[1], method, 1, parameters[1].Name, parameters[1].Type, parameters[1].Attributes); Assert.That(method.MutableParameters, Is.EqualTo(actualParameters)); var paramExpressions = method.ParameterExpressions; Assert.That(paramExpressions, Has.Count.EqualTo(2)); Assert.That(paramExpressions[0], Has.Property("Name").EqualTo(parameters[0].Name).And.Property("Type").SameAs(parameters[0].Type)); Assert.That(paramExpressions[1], Has.Property("Name").EqualTo(parameters[1].Name).And.Property("Type").SameAs(parameters[1].Type)); Assert.That(method.BaseMethod, Is.SameAs(baseMethod)); Assert.That(method.Body, Is.SameAs(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)); }