public void AssertMethod(string typename, string method, MethodAttributes?attributes = null, string returnType = null, params string [] parameterTypes) { LoadAssembly(); var t = assembly.MainModule.Types.First((v) => v.FullName == typename); var m = t.Methods.FirstOrDefault((v) => { if (v.Name != method) { return(false); } if (v.Parameters.Count != parameterTypes.Length) { return(false); } for (int i = 0; i < v.Parameters.Count; i++) { if (v.Parameters [i].ParameterType.FullName != parameterTypes [i]) { return(false); } } return(true); }); if (m == null) { Assert.Fail($"No method '{method}' with signature '{string.Join ("', '", parameterTypes)}' was found."); } if (attributes.HasValue) { Assert.AreEqual(attributes.Value, m.Attributes, "Attributes for {0}", m.FullName); } }
public void ShouldNotThrowArgumentExceptionIfNullableValueIsNull() { // Arrange MethodAttributes?value = null; // Act Ensure.That(value, "").HasFlag(MethodAttributes.Abstract); }
public void ShouldThrowArgumentExceptionIfNullableValueIsNotValid() { // Arrange MethodAttributes?value = MethodAttributes.Abstract; // Act Ensure.That(value, "").HasFlag(MethodAttributes.Assembly); }
// The signature for the proxy method and the executor method - exactly same as the origianl method // Both the proxy method and the executor method have the same signature as the original method // The proxy method overrides the original method to add pre-processing and post-processing // The executor method executes the original method properly, even when the original method is virtual private static MethodBuilder DefineMethodSignature( TypeBuilder typeBuilder, MethodInfo method, string?uniqueName = default, MethodAttributes?accessFlag = default, bool newSlot = false) { var name = uniqueName ?? method.Name; var attributes = method.Attributes; if (newSlot) { if (!attributes.HasFlag(MethodAttributes.NewSlot)) { attributes |= MethodAttributes.NewSlot; } } else if (attributes.HasFlag(MethodAttributes.NewSlot)) { attributes -= attributes & MethodAttributes.NewSlot; } if (accessFlag != null) { if (!attributes.HasFlag(accessFlag)) { attributes -= attributes & MethodAttributes.MemberAccessMask; attributes |= accessFlag.Value; } } MethodBuilder methodBuilder; if (method.IsGenericMethodDefinition) { methodBuilder = typeBuilder.DefineMethod( name, attributes, method.CallingConvention); DefineGenericMethodParameters(method, methodBuilder); } else { methodBuilder = typeBuilder.DefineMethod( name, attributes, method.CallingConvention, method.ReturnType, method.GetParameters().Select(p => p.ParameterType).ToArray()); } return(methodBuilder); }
public PropertyEmitter(string name, TypeReference propertyType, TypeDefinition declaringType = null, PropertyAttributes attributes = DefaultAttributes, MethodAttributes?getterAttributes = DefaultGetterAttributes, MethodAttributes?setterAttributes = DefaultSetterAttributes) { this._name = name; this._propertyType = propertyType; this._declaringType = declaringType; this._attributes = attributes; this._getterAttributes = getterAttributes; this._setterAttributes = setterAttributes; }
public static MethodAttributes?GetMethodAttributes(string attributes) { MethodAttributes?result = null; attributes.Split(", ").ToList().ForEach(attribute => { if (result == null) { result = (MethodAttributes)Enum.Parse(typeof(MethodAttributes), attribute); } else { result |= (MethodAttributes)Enum.Parse(typeof(MethodAttributes), attribute); } }); return(result); }
/// <summary> /// Converts a MethodAttributes back into its access modifier for display /// in the Validation. /// </summary> /// <param name="attributes">Attributes to convert</param> /// <returns>Access modifier, or null if the member is hidden</returns> internal static Access?Convert(this MethodAttributes?attributes) { if (attributes == null) { return(null); } var toConvert = attributes.Value; if (toConvert.HasFlag(MethodAttributes.Public)) { return(Access.Public); } if (toConvert.HasFlag(MethodAttributes.Family)) { return(Access.Protected); } return(Access.Private); }
private string GetMoreRelaxedVisibility(MethodAttributes?attributes1, MethodAttributes?attributes2) { if (attributes1 == null) { return(this.GetVisibility(attributes2.Value)); } else if (attributes2 == null) { return(this.GetVisibility(attributes1.Value)); } if (attributes1 > attributes2) { return(this.GetVisibility(attributes1.Value)); } else if (attributes2 > attributes1) { return(this.GetVisibility(attributes2.Value)); } else { return(this.GetVisibility(attributes1.Value)); } }
/// <summary> /// Creates constructors that relay calls to public and protected constructors in the base class. /// </summary> /// <param name="this">This <see cref="TypeBuilder"/>.</param> /// <param name="baseConstructorfilter"> /// Optional predicate used to filter constructors that must be implemented and set its <see cref="MethodAttributes"/>. /// When this function returns null, the constructor is not implemented, otherwise it can return the baseConstructor's Attribute. /// When null, all public and protected constructors are replicated with the same access (public or protected). /// </param> /// <param name="constructorAttributesFilter"> /// Optional predicate used to filter constructors' attributes. /// When null, all attributes are redefined. /// </param> /// <param name="parameterAttributesFilter"> /// Optional predicate used to filter constructors' arguments' attributes. /// When null, all attributes are redefined. /// </param> public static void DefinePassThroughConstructors(this TypeBuilder @this, Func <ConstructorInfo, MethodAttributes?> baseConstructorfilter = null, Func <ConstructorInfo, CustomAttributeData, bool> constructorAttributesFilter = null, Func <ParameterInfo, CustomAttributeData, bool> parameterAttributesFilter = null) { Type baseType = @this.BaseType; foreach (var baseCtor in baseType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { if (baseCtor.IsPrivate) { continue; } MethodAttributes?newCtorAttr = baseCtor.Attributes; if (baseConstructorfilter != null && !(newCtorAttr = baseConstructorfilter(baseCtor)).HasValue) { continue; } var parameters = baseCtor.GetParameters(); if (parameters.Length == 0) { @this.DefineDefaultConstructor(newCtorAttr.Value); } else { Type[] parameterTypes = ReflectionHelper.CreateParametersType(parameters); // REVIEW: Type.EmptyTypes replaces GetRequiredCustomModifiers and GetOptionalCustomModifiers Type[][] requiredCustomModifiers = parameters.Select(p => Type.EmptyTypes).ToArray(); Type[][] optionalCustomModifiers = parameters.Select(p => Type.EmptyTypes).ToArray(); var ctor = @this.DefineConstructor(newCtorAttr.Value, baseCtor.CallingConvention, parameterTypes, requiredCustomModifiers, optionalCustomModifiers); for (var i = 0; i < parameters.Length; ++i) { ParameterInfo parameter = parameters[i]; ParameterBuilder pBuilder = ctor.DefineParameter(i + 1, parameter.Attributes, parameter.Name); if ((parameter.Attributes & ParameterAttributes.HasDefault) != 0) { pBuilder.SetConstant(parameter.DefaultValue); } if (parameterAttributesFilter != null) { ReflectionHelper.GenerateCustomAttributeBuilder(parameter.CustomAttributes, pBuilder.SetCustomAttribute, a => parameterAttributesFilter(parameter, a)); } else { ReflectionHelper.GenerateCustomAttributeBuilder(parameter.CustomAttributes, pBuilder.SetCustomAttribute); } } if (constructorAttributesFilter != null) { ReflectionHelper.GenerateCustomAttributeBuilder(baseCtor.CustomAttributes, ctor.SetCustomAttribute, a => constructorAttributesFilter(baseCtor, a)); } else { ReflectionHelper.GenerateCustomAttributeBuilder(baseCtor.CustomAttributes, ctor.SetCustomAttribute); } var g = ctor.GetILGenerator(); g.RepushActualParameters(true, parameters.Length + 1); g.Emit(OpCodes.Call, baseCtor); g.Emit(OpCodes.Ret); } } }
internal static MethodBuilder DefineParameterlessMethod(this TypeBuilder typeBuilder, MethodInfo method, MethodAttributes?attributes = null) { attributes = attributes ?? method.Attributes & ~MethodAttributes.Abstract; return(typeBuilder.DefineMethod(method.Name, attributes.Value, method.ReturnType, Type.EmptyTypes)); }
public static MethodBuilder DefineMethod(this TypeBuilder typeBuilder, MethodInfo method, MethodAttributes?attributes = null, ParameterInfo[] parameters = null) { Type[] parametersTypes = null; MethodBuilder methodBuilder = null; parameters = parameters ?? method.GetParameters(); parametersTypes = parameters.ToArray(parameter => parameter.ParameterType); attributes = attributes ?? method.Attributes & ~MethodAttributes.Abstract; methodBuilder = typeBuilder.DefineMethod(method.Name, attributes.Value, method.ReturnType, parametersTypes); parameters.ForEach(1, (parameter, i) => { var parameterBuilder = methodBuilder.DefineParameter(i, parameter.Attributes, parameter.Name); if (parameter.IsDefined <ParamArrayAttribute>()) { parameterBuilder.SetCustomAttribute <ParamArrayAttribute>(); } else if (parameter.IsOut) { parameterBuilder.SetCustomAttribute <OutAttribute>(); } else if (parameter.IsOptional) { parameterBuilder.SetCustomAttribute <OptionalAttribute>() .SetConstant(parameter.DefaultValue); } }); return(methodBuilder); }
/// <summary> /// Create a new method within the type. If a method already exists with the provided name, return type, /// and parameter information, then the existing method will be returned. /// </summary> /// <param name="name"></param> /// <param name="returnType"></param> /// <param name="parameterTypes"></param> /// <param name="genericTypes"></param> /// <returns></returns> public MethodEmitter EmitMethod(string name, TypeReference returnType, TypeReference[] parameterTypes = null, GenericParameter[] genericTypes = null, bool toStatic = false, bool toPrivate = false, MethodAttributes?toVisibility = null) { var existing = Target.Methods.Where(m => m.Name == name && m.ReturnType.FullName == returnType.FullName && m.IsStatic == toStatic); if (parameterTypes != null) { existing = existing.Where(m => m.Parameters.Count == parameterTypes.Length && m.Parameters.Select(p => p.ParameterType.FullName).SequenceEqual(parameterTypes.Select(p => p.FullName))); } if (genericTypes != null) { existing = existing.Where(m => m.GenericParameters.Count == genericTypes.Length && m.GenericParameters.Select(p => p.Name).SequenceEqual(genericTypes.Select(p => p.Name))); } if (existing.Any()) { return(new MethodEmitter(this, existing.First())); } var attributes = MethodAttributes.Final | MethodAttributes.Virtual; if (toVisibility != null) { attributes |= toVisibility.Value; } else { attributes |= toPrivate ? MethodAttributes.Private : MethodAttributes.Public; } if (toStatic) { attributes |= MethodAttributes.Static; } var method = new MethodDefinition(name, attributes, returnType); if (parameterTypes != null && parameterTypes.Length > 0) { foreach (var type in parameterTypes) { method.Parameters.Add(new ParameterDefinition(type)); } } if (genericTypes != null && genericTypes.Length > 0) { foreach (var type in genericTypes) { method.GenericParameters.Add(new GenericParameter(type.Name, method)); } } Target.Methods.Add(method); Context.AddCompilerGenerated(method); return(new MethodEmitter(this, method)); }
public static MethodDefinition CreateMethod(this TypeDefinition type, string name = null, SystemTypeOrTypeReference returnType = null, MethodAttributes?attributes = null) { var module = type.GetModule(); var t = returnType != null?returnType.GetTypeReference(type.GetModule()) : module.TypeSystem.Void; var method = new MethodDefinition(name ?? Generate.Name.ForMethod(), attributes ?? 0, t); var definition = type as TypeDefinition; if (definition != null) { definition.Resolve().Methods.Add(method); } else { type.DeclaringType.Methods.Add(method); } return(method); }
public static MethodDefinition CreateMethod(this TypeDefinition type, SystemTypeOrTypeReference returnType, MethodAttributes?attributes = null) { return(CreateMethod(type, null, returnType.GetTypeReference(type.GetModule()), attributes)); }
public static MethodDefinition CreateMethod <T>(this TypeDefinition type, string name = null, MethodAttributes?attributes = null) { return(CreateMethod(type, name, typeof(T), attributes)); }