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); }
/// <inheritdoc /> public override bool IsApplicable(IntrospectiveMethodInfo method) { var hasAnyByValueNullableParameters = method.ReturnType.IsNonRefNullable() || method.ParameterTypes.Any(p => p.IsNonRefNullable()); return(hasAnyByValueNullableParameters); }
/// <inheritdoc /> public override bool IsApplicable(IntrospectiveMethodInfo method) { var hasAnyStringParameters = method.ReturnType == typeof(string) || method.ParameterTypes.Any(t => t == typeof(string)); return(hasAnyStringParameters); }
/// <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())); }
/// <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 <>)); }
/// <inheritdoc /> public override bool IsApplicable(IntrospectiveMethodInfo member) { return(Options.HasFlagFast(GenerateDisposalChecks)); }
public static bool ReturnValueRequiresLowering([NotNull] this IntrospectiveMethodInfo @this) { return(@this.ReturnType.RequiresLowering()); }
/// <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)); }