示例#1
0
        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);
            }
示例#4
0
        // 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);
        }
示例#5
0
 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;
 }
示例#6
0
        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);
        }
示例#7
0
        /// <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);
        }
示例#8
0
        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);
                }
            }
        }
示例#10
0
        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));
        }
示例#11
0
        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);
        }
示例#12
0
        /// <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));
        }
示例#13
0
        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);
        }
示例#14
0
 public static MethodDefinition CreateMethod(this TypeDefinition type, SystemTypeOrTypeReference returnType, MethodAttributes?attributes = null)
 {
     return(CreateMethod(type, null, returnType.GetTypeReference(type.GetModule()), attributes));
 }
示例#15
0
 public static MethodDefinition CreateMethod <T>(this TypeDefinition type, string name = null, MethodAttributes?attributes = null)
 {
     return(CreateMethod(type, name, typeof(T), attributes));
 }