public static TypeBuilder DefineDelegate
        (
            [NotNull] this ModuleBuilder module,
            [NotNull] string name,
            [NotNull] IntrospectiveMethodInfo baseMember,
            bool suppressSecurity = false
        )
        {
            var metadataAttribute = baseMember.GetCustomAttribute <NativeSymbolAttribute>() ??
                                    new NativeSymbolAttribute(baseMember.Name);

            var delegateBuilder = DefineDelegateType
                                  (
                module,
                name,
                metadataAttribute.CallingConvention,
                suppressSecurity
                                  );

            foreach (var attribute in baseMember.CustomAttributes)
            {
                delegateBuilder.SetCustomAttribute(attribute.GetAttributeBuilder());
            }

            var delegateInvocationBuilder = DefineDelegateInvocationMethod
                                                (delegateBuilder, baseMember.ReturnType, baseMember.ParameterTypes.ToArray());

            delegateInvocationBuilder.ApplyCustomAttributesFrom(baseMember);

            return(delegateBuilder);
        }
        internal IntrospectiveMethodInfo GenerateDefinitionFromSignature
        (
            [NotNull] IntrospectiveMethodInfo interfaceDefinition,
            [CanBeNull] IntrospectiveMethodInfo abstractImplementation,
            [CanBeNull] string nameOverride = null
        )
        {
            var methodBuilder = TargetType.DefineMethod
                                (
                nameOverride ?? interfaceDefinition.Name,
                Public | Final | Virtual | HideBySig | NewSlot,
                CallingConventions.Standard,
                interfaceDefinition.ReturnType,
                interfaceDefinition.ParameterTypes.ToArray()
                                );

            // In the following blocks, which set of attributes to pass through is selected. The logic is as follows:
            // If either the interface or abstract implementation have attributes, select the one which does
            // If both have attributes, select the abstract implementation
            // If neither have attributes, select the interface definition
            if (!(abstractImplementation is null))
            {
                if (abstractImplementation.CustomAttributes.Any())
                {
                    methodBuilder.ApplyCustomAttributesFrom(abstractImplementation);
                }
                else
                {
                    methodBuilder.ApplyCustomAttributesFrom(interfaceDefinition);
                }

                TargetType.DefineMethodOverride(methodBuilder, abstractImplementation.GetWrappedMember());
            }
        public IReadOnlyList <IReadOnlyList <Type> > Generate([NotNull] IntrospectiveMethodInfo baseMethod)
        {
            var parameters = baseMethod.ParameterTypes;

            // First, we calculate the total number of possible combinations, given that we can have either a
            // concrete type or an IntPtr, and refNullableParameterCount instances thereof.
            var refNullableParameterCount = parameters.Count(p => p.IsRefNullable());
            var permutationCount          = Math.Pow
                                            (
                2,
                refNullableParameterCount
                                            );

            // Then, we take the types used in the base method and generate combinations from it.
            var permutations = new List <IReadOnlyList <Type> >();

            for (int i = 0; i < permutationCount; ++i)
            {
                // Due to the fact that we only need to flip between two states for each instance of a nullable
                // parameter, we can piggyback on the permutation count and use it as a bitmask which determines
                // what to flip each parameter to.
                var mask = new BitArray(new[] { i });
                permutations.Add(GeneratePermutation(parameters, mask));
            }

            return(permutations);
        }
示例#4
0
        /// <inheritdoc />
        public override bool IsApplicable(IntrospectiveMethodInfo method)
        {
            var hasAnyByValueNullableParameters = method.ReturnType.IsNonRefNullable() ||
                                                  method.ParameterTypes.Any(p => p.IsNonRefNullable());

            return(hasAnyByValueNullableParameters);
        }
示例#5
0
        /// <inheritdoc />
        public override bool IsApplicable(IntrospectiveMethodInfo method)
        {
            var hasAnyStringParameters = method.ReturnType == typeof(string) ||
                                         method.ParameterTypes.Any(t => t == typeof(string));

            return(hasAnyStringParameters);
        }
示例#6
0
        /// <inheritdoc/>
        public override bool IsApplicable(IntrospectiveMethodInfo member)
        {
            if (member.ReturnType.IsGenericDelegate())
            {
                return(true);
            }

            return(member.ParameterTypes.Any(t => t.IsGenericDelegate()));
        }
        public static bool ParametersRequireLowering([NotNull] this IntrospectiveMethodInfo @this)
        {
            var parameters = @this.ParameterTypes;

            return(parameters.Any
                   (
                       p =>
                       p.RequiresLowering()
                   ));
        }
        /// <summary>
        /// Copies all custom attributes from the given <see cref="IntrospectiveMethodInfo"/> instance. This method will redefine the
        /// return value and method parameters in order to apply the required custom attributes.
        /// </summary>
        /// <param name="this">The builder to copy the attributes to.</param>
        /// <param name="source">The method to copy the attributes from.</param>
        /// <param name="newReturnParameterType">The return type of the target method.</param>
        /// <param name="newParameterTypes">The parameter types of the target method.</param>
        public static void ApplyCustomAttributesFrom
        (
            [NotNull] this MethodBuilder @this,
            [NotNull] IntrospectiveMethodInfo source,
            [CanBeNull] Type newReturnParameterType = null,
            [CanBeNull, ItemNotNull] IReadOnlyList <Type> newParameterTypes = null
        )
        {
            newReturnParameterType = newReturnParameterType ?? source.ReturnType;
            newParameterTypes      = newParameterTypes ?? source.ParameterTypes;

            // Pass through all applied attributes
            var returnValueBuilder = @this.DefineParameter(0, source.ReturnParameterAttributes, null);

            foreach (var attribute in source.ReturnParameterCustomAttributes)
            {
                if (AttributeBlacklist.ContainsKey(newReturnParameterType) && AttributeBlacklist[newReturnParameterType].Contains(attribute.AttributeType))
                {
                    continue;
                }

                returnValueBuilder.SetCustomAttribute(attribute.GetAttributeBuilder());
            }

            if (source.ParameterTypes.Any())
            {
                for (var i = 0; i < source.ParameterTypes.Count; ++i)
                {
                    var targetParameterType             = newParameterTypes[i];
                    var methodParameterCustomAttributes = source.ParameterCustomAttributes[i];
                    var methodParameterAttributes       = source.ParameterAttributes[i];
                    var methodParameterName             = source.ParameterNames[i];

                    var parameterBuilder = @this.DefineParameter(i + 1, methodParameterAttributes, methodParameterName);
                    foreach (var attribute in methodParameterCustomAttributes)
                    {
                        if (AttributeBlacklist.ContainsKey(targetParameterType) && AttributeBlacklist[targetParameterType].Contains(attribute.AttributeType))
                        {
                            continue;
                        }

                        parameterBuilder.SetCustomAttribute(attribute.GetAttributeBuilder());
                    }
                }
            }

            foreach (var attribute in source.CustomAttributes)
            {
                @this.SetCustomAttribute(attribute.GetAttributeBuilder());
            }
        }
        private NativeCollectionLengthAttribute GetNativeCollectionLengthMetadata(IntrospectiveMethodInfo info)
        {
            IReadOnlyList <CustomAttributeData> attributes = info.ReturnParameterCustomAttributes;

            foreach (CustomAttributeData customAttributeData in attributes)
            {
                if (customAttributeData.AttributeType == typeof(NativeCollectionLengthAttribute))
                {
                    return(customAttributeData.ToInstance <NativeCollectionLengthAttribute>());
                }
            }

            throw new InvalidOperationException($"Method return type does not have required {nameof(NativeCollectionLengthAttribute)}");
        }
        internal IntrospectiveMethodInfo GenerateDefinitionFromSignature([NotNull] IntrospectiveMethodInfo interfaceDefinition)
        {
            var methodBuilder = _targetType.DefineMethod
                                (
                interfaceDefinition.Name,
                Public | Final | Virtual | HideBySig | NewSlot,
                CallingConventions.Standard,
                interfaceDefinition.ReturnType,
                interfaceDefinition.ParameterTypes.ToArray()
                                );

            methodBuilder.ApplyCustomAttributesFrom(interfaceDefinition);

            _targetType.DefineMethodOverride(methodBuilder, interfaceDefinition.GetWrappedMember());

            return(new IntrospectiveMethodInfo(methodBuilder, interfaceDefinition.ReturnType, interfaceDefinition.ParameterTypes, interfaceDefinition));
        }
        /// <inheritdoc />
        public override bool IsApplicable(IntrospectiveMethodInfo member)
        {
            if (member.ReturnType.IsDelegate())
            {
                return(true);
            }

            for (int i = 0; i < member.ParameterTypes.Count; i++)
            {
                var p = member.ParameterTypes[i];
                if (p.IsDelegate())
                {
                    return(true);
                }
            }

            return(false);
        }
 public static bool RequiresRefPermutations([NotNull] this IntrospectiveMethodInfo @this)
 {
     return(@this.ParameterTypes.Any(p => p.IsRefNullable()));
 }
示例#13
0
        /// <inheritdoc />
        public override bool IsApplicable(IntrospectiveMethodInfo method)
        {
            var hasAnyBooleanParameters = method.ReturnType == typeof(bool) || method.ParameterTypes.Any(t => t == typeof(bool));

            return(hasAnyBooleanParameters && Options.HasFlagFast(UseIndirectCalls));
        }
 /// <inheritdoc />
 public override bool IsApplicable(IntrospectiveMethodInfo member)
 {
     return(member.ReturnType.IsGenericType && // prevents exception on the line below
            member.ReturnType.GetGenericTypeDefinition() == typeof(Span <>));
 }
示例#15
0
 /// <inheritdoc />
 public override bool IsApplicable(IntrospectiveMethodInfo member)
 {
     return(Options.HasFlagFast(GenerateDisposalChecks));
 }
 public static bool ReturnValueRequiresLowering([NotNull] this IntrospectiveMethodInfo @this)
 {
     return(@this.ReturnType.RequiresLowering());
 }
示例#17
0
 /// <inheritdoc />
 public override bool IsApplicable(IntrospectiveMethodInfo member)
 {
     return(IsSpanType(member.ReturnType) || member.ParameterTypes.Any(IsSpanType));
 }
 public static bool RequiresLowering([NotNull] this IntrospectiveMethodInfo @this)
 {
     return(ParametersRequireLowering(@this) || ReturnValueRequiresLowering(@this));
 }