Update DuckTyping types with the latest changes (#1717)
* Change the accessibility for most types in the OpenTelemetry.AutoInstrumentation.DuckTyping namespace, except for DuckType (and inner classes) and IDuckType * Port the latest dd-trace-dotnet DuckTyping changes into this repo, after removing nullable type references
This commit is contained in:
parent
339a310e47
commit
90d7bec37e
|
|
@ -1,4 +1,3 @@
|
|||
const OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.DefaultFlags = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.FlattenHierarchy -> System.Reflection.BindingFlags
|
||||
OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetInvoker
|
||||
OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetReturn
|
||||
OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetReturn.CallTargetReturn() -> void
|
||||
|
|
@ -14,67 +13,19 @@ OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetState.CallTargetState(Sys
|
|||
OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetState.CallTargetState(System.Diagnostics.Activity activity, object state, System.DateTimeOffset? startTime) -> void
|
||||
OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetState.StartTime.get -> System.DateTimeOffset?
|
||||
OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetState.State.get -> object
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.CreateProxyInstance<T>
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.BindingFlags.get -> System.Reflection.BindingFlags
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.BindingFlags.set -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.DuckAttribute() -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.ExplicitInterfaceTypeName.get -> string
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.ExplicitInterfaceTypeName.set -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.GenericParameterTypeNames.get -> string[]
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.GenericParameterTypeNames.set -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.Kind.get -> OpenTelemetry.AutoInstrumentation.DuckTyping.DuckKind
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.Kind.set -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.Name.get -> string
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.Name.set -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.ParameterTypeNames.get -> string[]
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.ParameterTypeNames.set -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckCopyAttribute
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckCopyAttribute.DuckCopyAttribute() -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckFieldAttribute
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckFieldAttribute.DuckFieldAttribute() -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckIgnoreAttribute
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckIgnoreAttribute.DuckIgnoreAttribute() -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckIncludeAttribute
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckIncludeAttribute.DuckIncludeAttribute() -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckKind
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckKind.Field = 1 -> OpenTelemetry.AutoInstrumentation.DuckTyping.DuckKind
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckKind.Property = 0 -> OpenTelemetry.AutoInstrumentation.DuckTyping.DuckKind
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckReverseMethodAttribute
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckReverseMethodAttribute.Arguments.get -> string[]
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckReverseMethodAttribute.DuckReverseMethodAttribute() -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckReverseMethodAttribute.DuckReverseMethodAttribute(params string[] arguments) -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateCache<T>
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateTypeResult
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateTypeResult.CanCreate() -> bool
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateTypeResult.CreateInstance<T>(object instance) -> T
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateTypeResult.CreateInstance<T, TOriginal>(TOriginal instance) -> T
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateTypeResult.CreateTypeResult() -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateTypeResult.ProxyType.get -> System.Type
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.DelegateCache<TProxyDelegate>
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeExtensions
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeFieldIsReadonlyException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeInvalidTypeConversionException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypePropertyArgumentsLengthException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypePropertyCantBeReadException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypePropertyCantBeWrittenException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypePropertyOrFieldNotFoundException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeProxyAndTargetMethodParameterSignatureMismatchException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeProxyMethodParameterIsMissingException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeProxyMethodsWithGenericParametersNotSupportedInNonPublicInstancesException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeProxyTypeDefinitionIsNull
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeStructMembersCannotBeChangedException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeTargetMethodAmbiguousMatchException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeTargetMethodNotFoundException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeTargetObjectInstanceIsNull
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeTypeIsNotPublicException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.IDuckType
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.IDuckType.Instance.get -> object
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.IDuckType.ToString() -> string
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.IDuckType.Type.get -> System.Type
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.IgnoresAccessChecksToAttribute
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.IgnoresAccessChecksToAttribute.AssemblyName.get -> string
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.IgnoresAccessChecksToAttribute.IgnoresAccessChecksToAttribute(string assemblyName) -> void
|
||||
OpenTelemetry.AutoInstrumentation.Instrumentations.GraphQL.ErrorLocationStruct
|
||||
OpenTelemetry.AutoInstrumentation.Instrumentations.GraphQL.ErrorLocationStruct.Column -> int
|
||||
OpenTelemetry.AutoInstrumentation.Instrumentations.GraphQL.ErrorLocationStruct.ErrorLocationStruct() -> void
|
||||
|
|
@ -138,24 +89,20 @@ static OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetReturn<T>.GetDefau
|
|||
static OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetState.GetDefault() -> OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetState
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CanCreate(System.Type proxyType, object instance) -> bool
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CanCreate<T>(object instance) -> bool
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.Create(System.Type proxyType, object instance) -> OpenTelemetry.AutoInstrumentation.DuckTyping.IDuckType
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.Create(System.Type proxyType, object instance) -> object
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.Create<T>(object instance) -> T
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateReverse(System.Type typeToDeriveFrom, object delegationInstance) -> object
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.GetOrCreateReverseProxyType(System.Type typeToDeriveFrom, System.Type delegationType) -> OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateTypeResult
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateCache<T>.CanCreate(object instance) -> bool
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateCache<T>.Create(object instance) -> T
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateCache<T>.CreateFrom<TOriginal>(TOriginal instance) -> T
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateCache<T>.CreateReverse(object instance) -> T
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateCache<T>.GetReverseProxy(System.Type targetType) -> OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateTypeResult
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateCache<T>.GetProxy(System.Type targetType) -> OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateTypeResult
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.DelegateCache<TProxyDelegate>.GetDelegate() -> TProxyDelegate
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.GetOrCreateProxyType(System.Type proxyType, System.Type targetType) -> OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateTypeResult
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeExtensions.DuckAs(this object instance, System.Type targetType) -> object
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeExtensions.DuckAs<T>(this object instance) -> T
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeExtensions.DuckCast(this object instance, System.Type targetType) -> object
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeExtensions.DuckCast<T>(this object instance) -> T
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeExtensions.DuckIs(this object instance, System.Type targetType) -> bool
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeExtensions.DuckIs<T>(this object instance) -> bool
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeExtensions.TryDuckCast(this object instance, System.Type targetType, out object value) -> bool
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeExtensions.TryDuckCast<T>(this object instance, out T value) -> bool
|
||||
static OpenTelemetry.AutoInstrumentation.Instrumentations.GraphQL.ExecuteAsyncIntegration.OnAsyncMethodEnd<TTarget, TExecutionResult>(TTarget instance, TExecutionResult executionResult, System.Exception exception, OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetState state) -> TExecutionResult
|
||||
static OpenTelemetry.AutoInstrumentation.Instrumentations.GraphQL.ExecuteAsyncIntegration.OnMethodBegin<TTarget, TContext>(TTarget instance, TContext context) -> OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetState
|
||||
static readonly OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateCache<T>.IsVisible -> bool
|
||||
static readonly OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateCache<T>.Type -> System.Type
|
||||
static readonly OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.EnumToObjectMethodInfo -> System.Reflection.MethodInfo
|
||||
static readonly OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.GetTypeFromHandleMethodInfo -> System.Reflection.MethodInfo
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.EnumToObjectMethodInfo.get -> System.Reflection.MethodInfo
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.GetTypeFromHandleMethodInfo.get -> System.Reflection.MethodInfo
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
const OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.DefaultFlags = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.FlattenHierarchy -> System.Reflection.BindingFlags
|
||||
OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetInvoker
|
||||
OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetReturn
|
||||
OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetReturn.CallTargetReturn() -> void
|
||||
|
|
@ -14,67 +13,19 @@ OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetState.CallTargetState(Sys
|
|||
OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetState.CallTargetState(System.Diagnostics.Activity activity, object state, System.DateTimeOffset? startTime) -> void
|
||||
OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetState.StartTime.get -> System.DateTimeOffset?
|
||||
OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetState.State.get -> object
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.CreateProxyInstance<T>
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.BindingFlags.get -> System.Reflection.BindingFlags
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.BindingFlags.set -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.DuckAttribute() -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.ExplicitInterfaceTypeName.get -> string
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.ExplicitInterfaceTypeName.set -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.GenericParameterTypeNames.get -> string[]
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.GenericParameterTypeNames.set -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.Kind.get -> OpenTelemetry.AutoInstrumentation.DuckTyping.DuckKind
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.Kind.set -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.Name.get -> string
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.Name.set -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.ParameterTypeNames.get -> string[]
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckAttribute.ParameterTypeNames.set -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckCopyAttribute
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckCopyAttribute.DuckCopyAttribute() -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckFieldAttribute
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckFieldAttribute.DuckFieldAttribute() -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckIgnoreAttribute
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckIgnoreAttribute.DuckIgnoreAttribute() -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckIncludeAttribute
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckIncludeAttribute.DuckIncludeAttribute() -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckKind
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckKind.Field = 1 -> OpenTelemetry.AutoInstrumentation.DuckTyping.DuckKind
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckKind.Property = 0 -> OpenTelemetry.AutoInstrumentation.DuckTyping.DuckKind
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckReverseMethodAttribute
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckReverseMethodAttribute.Arguments.get -> string[]
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckReverseMethodAttribute.DuckReverseMethodAttribute() -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckReverseMethodAttribute.DuckReverseMethodAttribute(params string[] arguments) -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateCache<T>
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateTypeResult
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateTypeResult.CanCreate() -> bool
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateTypeResult.CreateInstance<T>(object instance) -> T
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateTypeResult.CreateInstance<T, TOriginal>(TOriginal instance) -> T
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateTypeResult.CreateTypeResult() -> void
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateTypeResult.ProxyType.get -> System.Type
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.DelegateCache<TProxyDelegate>
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeExtensions
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeFieldIsReadonlyException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeInvalidTypeConversionException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypePropertyArgumentsLengthException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypePropertyCantBeReadException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypePropertyCantBeWrittenException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypePropertyOrFieldNotFoundException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeProxyAndTargetMethodParameterSignatureMismatchException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeProxyMethodParameterIsMissingException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeProxyMethodsWithGenericParametersNotSupportedInNonPublicInstancesException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeProxyTypeDefinitionIsNull
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeStructMembersCannotBeChangedException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeTargetMethodAmbiguousMatchException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeTargetMethodNotFoundException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeTargetObjectInstanceIsNull
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeTypeIsNotPublicException
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.IDuckType
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.IDuckType.Instance.get -> object
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.IDuckType.ToString() -> string
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.IDuckType.Type.get -> System.Type
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.IgnoresAccessChecksToAttribute
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.IgnoresAccessChecksToAttribute.AssemblyName.get -> string
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.IgnoresAccessChecksToAttribute.IgnoresAccessChecksToAttribute(string assemblyName) -> void
|
||||
OpenTelemetry.AutoInstrumentation.Instrumentations.GraphQL.ErrorLocationStruct
|
||||
OpenTelemetry.AutoInstrumentation.Instrumentations.GraphQL.ErrorLocationStruct.Column -> int
|
||||
OpenTelemetry.AutoInstrumentation.Instrumentations.GraphQL.ErrorLocationStruct.ErrorLocationStruct() -> void
|
||||
|
|
@ -138,24 +89,20 @@ static OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetReturn<T>.GetDefau
|
|||
static OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetState.GetDefault() -> OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetState
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CanCreate(System.Type proxyType, object instance) -> bool
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CanCreate<T>(object instance) -> bool
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.Create(System.Type proxyType, object instance) -> OpenTelemetry.AutoInstrumentation.DuckTyping.IDuckType
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.Create(System.Type proxyType, object instance) -> object
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.Create<T>(object instance) -> T
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateReverse(System.Type typeToDeriveFrom, object delegationInstance) -> object
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.GetOrCreateReverseProxyType(System.Type typeToDeriveFrom, System.Type delegationType) -> OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateTypeResult
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateCache<T>.CanCreate(object instance) -> bool
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateCache<T>.Create(object instance) -> T
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateCache<T>.CreateFrom<TOriginal>(TOriginal instance) -> T
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateCache<T>.CreateReverse(object instance) -> T
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateCache<T>.GetReverseProxy(System.Type targetType) -> OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateTypeResult
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateCache<T>.GetProxy(System.Type targetType) -> OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateTypeResult
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.DelegateCache<TProxyDelegate>.GetDelegate() -> TProxyDelegate
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.GetOrCreateProxyType(System.Type proxyType, System.Type targetType) -> OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateTypeResult
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeExtensions.DuckAs(this object instance, System.Type targetType) -> object
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeExtensions.DuckAs<T>(this object instance) -> T
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeExtensions.DuckCast(this object instance, System.Type targetType) -> object
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeExtensions.DuckCast<T>(this object instance) -> T
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeExtensions.DuckIs(this object instance, System.Type targetType) -> bool
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeExtensions.DuckIs<T>(this object instance) -> bool
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeExtensions.TryDuckCast(this object instance, System.Type targetType, out object value) -> bool
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckTypeExtensions.TryDuckCast<T>(this object instance, out T value) -> bool
|
||||
static OpenTelemetry.AutoInstrumentation.Instrumentations.GraphQL.ExecuteAsyncIntegration.OnAsyncMethodEnd<TTarget, TExecutionResult>(TTarget instance, TExecutionResult executionResult, System.Exception exception, OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetState state) -> TExecutionResult
|
||||
static OpenTelemetry.AutoInstrumentation.Instrumentations.GraphQL.ExecuteAsyncIntegration.OnMethodBegin<TTarget, TContext>(TTarget instance, TContext context) -> OpenTelemetry.AutoInstrumentation.CallTarget.CallTargetState
|
||||
static readonly OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateCache<T>.IsVisible -> bool
|
||||
static readonly OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.CreateCache<T>.Type -> System.Type
|
||||
static readonly OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.EnumToObjectMethodInfo -> System.Reflection.MethodInfo
|
||||
static readonly OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.GetTypeFromHandleMethodInfo -> System.Reflection.MethodInfo
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.EnumToObjectMethodInfo.get -> System.Reflection.MethodInfo
|
||||
static OpenTelemetry.AutoInstrumentation.DuckTyping.DuckType.GetTypeFromHandleMethodInfo.get -> System.Reflection.MethodInfo
|
||||
|
|
@ -14,7 +14,6 @@
|
|||
// limitations under the License.
|
||||
// </copyright>
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace OpenTelemetry.AutoInstrumentation.DuckTyping;
|
||||
|
|
@ -22,7 +21,7 @@ namespace OpenTelemetry.AutoInstrumentation.DuckTyping;
|
|||
/// <summary>
|
||||
/// Duck kind
|
||||
/// </summary>
|
||||
public enum DuckKind
|
||||
internal enum DuckKind
|
||||
{
|
||||
/// <summary>
|
||||
/// Property
|
||||
|
|
@ -38,41 +37,15 @@ public enum DuckKind
|
|||
/// <summary>
|
||||
/// Duck attribute
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Field, AllowMultiple = false)]
|
||||
public class DuckAttribute : Attribute
|
||||
internal class DuckAttribute : DuckAttributeBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Default BindingFlags
|
||||
/// </summary>
|
||||
public const BindingFlags DefaultFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.FlattenHierarchy;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the underlying type member name
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets duck kind
|
||||
/// </summary>
|
||||
public DuckKind Kind { get; set; } = DuckKind.Property;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the binding flags
|
||||
/// </summary>
|
||||
public BindingFlags BindingFlags { get; set; } = DefaultFlags;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the generic parameter type names definition for a generic method call (required when calling generic methods and instance type is non public)
|
||||
/// </summary>
|
||||
public string[] GenericParameterTypeNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the parameter type names of the target method (optional / used to disambiguation)
|
||||
/// </summary>
|
||||
public string[] ParameterTypeNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the explicit interface type name
|
||||
/// </summary>
|
||||
public string ExplicitInterfaceTypeName { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
// <copyright file="DuckAttributeBase.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace OpenTelemetry.AutoInstrumentation.DuckTyping;
|
||||
|
||||
/// <summary>
|
||||
/// Duck attribute
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Field, AllowMultiple = false)]
|
||||
internal abstract class DuckAttributeBase : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the underlying type member name
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the binding flags
|
||||
/// </summary>
|
||||
public BindingFlags BindingFlags { get; set; } = DuckAttribute.DefaultFlags;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the generic parameter type names definition for a generic method call (required when calling generic methods and instance type is non public)
|
||||
/// </summary>
|
||||
public string[] GenericParameterTypeNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the parameter type names of the target method (optional / used to disambiguation)
|
||||
/// </summary>
|
||||
public string[] ParameterTypeNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the explicit interface type name
|
||||
/// </summary>
|
||||
public string ExplicitInterfaceTypeName { get; set; }
|
||||
}
|
||||
|
|
@ -22,6 +22,6 @@ namespace OpenTelemetry.AutoInstrumentation.DuckTyping;
|
|||
/// Duck copy struct attribute
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Struct, AllowMultiple = false)]
|
||||
public class DuckCopyAttribute : Attribute
|
||||
internal class DuckCopyAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace OpenTelemetry.AutoInstrumentation.DuckTyping;
|
|||
/// <summary>
|
||||
/// Duck attribute where the underlying member is a field
|
||||
/// </summary>
|
||||
public class DuckFieldAttribute : DuckAttribute
|
||||
internal class DuckFieldAttribute : DuckAttribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DuckFieldAttribute"/> class.
|
||||
|
|
|
|||
|
|
@ -22,6 +22,6 @@ namespace OpenTelemetry.AutoInstrumentation.DuckTyping;
|
|||
/// Ignores the member when DuckTyping
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Field, AllowMultiple = false)]
|
||||
public class DuckIgnoreAttribute : Attribute
|
||||
internal class DuckIgnoreAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,6 @@ namespace OpenTelemetry.AutoInstrumentation.DuckTyping;
|
|||
/// Use to include a member that would normally be ignored
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
|
||||
public class DuckIncludeAttribute : Attribute
|
||||
internal class DuckIncludeAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,34 +14,11 @@
|
|||
// limitations under the License.
|
||||
// </copyright>
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTelemetry.AutoInstrumentation.DuckTyping;
|
||||
|
||||
/// <summary>
|
||||
/// Duck reverse method attribute
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class DuckReverseMethodAttribute : Attribute
|
||||
internal class DuckReverseMethodAttribute : DuckAttributeBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DuckReverseMethodAttribute"/> class.
|
||||
/// </summary>
|
||||
public DuckReverseMethodAttribute()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DuckReverseMethodAttribute"/> class.
|
||||
/// </summary>
|
||||
/// <param name="arguments">Methods arguments</param>
|
||||
public DuckReverseMethodAttribute(params string[] arguments)
|
||||
{
|
||||
Arguments = arguments;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the methods arguments
|
||||
/// </summary>
|
||||
public string[] Arguments { get; private set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,25 +25,33 @@ namespace OpenTelemetry.AutoInstrumentation.DuckTyping;
|
|||
/// </summary>
|
||||
public static partial class DuckType
|
||||
{
|
||||
private static MethodBuilder GetFieldGetMethod(TypeBuilder proxyTypeBuilder, Type targetType, MemberInfo proxyMember, FieldInfo targetField, FieldInfo instanceField)
|
||||
private static MethodBuilder GetFieldGetMethod(
|
||||
TypeBuilder proxyTypeBuilder,
|
||||
Type targetType,
|
||||
MemberInfo proxyMember,
|
||||
FieldInfo targetField,
|
||||
FieldInfo instanceField)
|
||||
{
|
||||
string proxyMemberName = proxyMember.Name;
|
||||
Type proxyMemberReturnType = proxyMember is PropertyInfo pinfo ? pinfo.PropertyType : proxyMember is FieldInfo finfo ? finfo.FieldType : typeof(object);
|
||||
|
||||
MethodBuilder proxyMethod = proxyTypeBuilder.DefineMethod(
|
||||
MethodBuilder proxyMethod = proxyTypeBuilder?.DefineMethod(
|
||||
"get_" + proxyMemberName,
|
||||
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.Virtual,
|
||||
proxyMemberReturnType,
|
||||
Type.EmptyTypes);
|
||||
|
||||
LazyILGenerator il = new LazyILGenerator(proxyMethod.GetILGenerator());
|
||||
LazyILGenerator il = new LazyILGenerator(proxyMethod?.GetILGenerator());
|
||||
Type returnType = targetField.FieldType;
|
||||
|
||||
// Load the instance
|
||||
if (!targetField.IsStatic)
|
||||
{
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(instanceField.FieldType.IsValueType ? OpCodes.Ldflda : OpCodes.Ldfld, instanceField);
|
||||
if (instanceField is not null)
|
||||
{
|
||||
il.Emit(instanceField.FieldType.IsValueType ? OpCodes.Ldflda : OpCodes.Ldfld, instanceField);
|
||||
}
|
||||
}
|
||||
|
||||
// Load the field value to the stack
|
||||
|
|
@ -52,7 +60,7 @@ public static partial class DuckType
|
|||
// In case is public is pretty simple
|
||||
il.Emit(targetField.IsStatic ? OpCodes.Ldsfld : OpCodes.Ldfld, targetField);
|
||||
}
|
||||
else
|
||||
else if (targetField.DeclaringType is not null && proxyTypeBuilder is not null)
|
||||
{
|
||||
// If the instance or the field are non public we need to create a Dynamic method to overpass the visibility checks
|
||||
// we can't access non public types so we have to cast to object type (in the instance object and the return type if is needed).
|
||||
|
|
@ -85,20 +93,22 @@ public static partial class DuckType
|
|||
// Emit the call to the dynamic method
|
||||
il.WriteDynamicMethodCall(dynMethod, proxyTypeBuilder);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Dry run: We enable all checks done in the preview if branch
|
||||
returnType = UseDirectAccessTo(proxyTypeBuilder, targetField.FieldType) ? targetField.FieldType : typeof(object);
|
||||
ILHelpersExtensions.CheckTypeConversion(targetField.FieldType, returnType);
|
||||
}
|
||||
|
||||
// Check if the type can be converted or if we need to enable duck chaining
|
||||
if (NeedsDuckChaining(targetField.FieldType, proxyMemberReturnType))
|
||||
{
|
||||
if (UseDirectAccessTo(proxyTypeBuilder, targetField.FieldType) && targetField.FieldType.IsValueType)
|
||||
{
|
||||
il.Emit(OpCodes.Box, targetField.FieldType);
|
||||
}
|
||||
UseDirectAccessTo(proxyTypeBuilder, targetField.FieldType);
|
||||
|
||||
// WARNING: If targetField.FieldType cannot be duck cast to proxyMemberReturnType
|
||||
// this will throw an exception at runtime when accessing the member
|
||||
// We call DuckType.CreateCache<>.Create()
|
||||
MethodInfo getProxyMethodInfo = typeof(CreateCache<>)
|
||||
.MakeGenericType(proxyMemberReturnType).GetMethod("Create");
|
||||
|
||||
il.Emit(OpCodes.Call, getProxyMethodInfo);
|
||||
MethodIlHelper.AddIlToDuckChain(il, proxyMemberReturnType, targetField.FieldType);
|
||||
}
|
||||
else if (returnType != proxyMemberReturnType)
|
||||
{
|
||||
|
|
@ -108,29 +118,41 @@ public static partial class DuckType
|
|||
|
||||
il.Emit(OpCodes.Ret);
|
||||
il.Flush();
|
||||
_methodBuilderGetToken.Invoke(proxyMethod, null);
|
||||
if (proxyMethod is not null)
|
||||
{
|
||||
MethodBuilderGetToken.Invoke(proxyMethod, null);
|
||||
}
|
||||
|
||||
return proxyMethod;
|
||||
}
|
||||
|
||||
private static MethodBuilder GetFieldSetMethod(TypeBuilder proxyTypeBuilder, Type targetType, MemberInfo proxyMember, FieldInfo targetField, FieldInfo instanceField)
|
||||
private static MethodBuilder GetFieldSetMethod(
|
||||
TypeBuilder proxyTypeBuilder,
|
||||
Type targetType,
|
||||
MemberInfo proxyMember,
|
||||
FieldInfo targetField,
|
||||
FieldInfo instanceField)
|
||||
{
|
||||
string proxyMemberName = proxyMember.Name;
|
||||
Type proxyMemberReturnType = proxyMember is PropertyInfo pinfo ? pinfo.PropertyType : proxyMember is FieldInfo finfo ? finfo.FieldType : typeof(object);
|
||||
|
||||
MethodBuilder method = proxyTypeBuilder.DefineMethod(
|
||||
MethodBuilder method = proxyTypeBuilder?.DefineMethod(
|
||||
"set_" + proxyMemberName,
|
||||
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.Virtual,
|
||||
typeof(void),
|
||||
new[] { proxyMemberReturnType });
|
||||
|
||||
LazyILGenerator il = new LazyILGenerator(method.GetILGenerator());
|
||||
LazyILGenerator il = new LazyILGenerator(method?.GetILGenerator());
|
||||
Type currentValueType = proxyMemberReturnType;
|
||||
|
||||
// Load instance
|
||||
if (!targetField.IsStatic)
|
||||
{
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(instanceField.FieldType.IsValueType ? OpCodes.Ldflda : OpCodes.Ldfld, instanceField);
|
||||
if (instanceField is not null)
|
||||
{
|
||||
il.Emit(instanceField.FieldType.IsValueType ? OpCodes.Ldflda : OpCodes.Ldfld, instanceField);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the type can be converted of if we need to enable duck chaining
|
||||
|
|
@ -141,7 +163,7 @@ public static partial class DuckType
|
|||
il.WriteTypeConversion(proxyMemberReturnType, typeof(IDuckType));
|
||||
|
||||
// Call IDuckType.Instance property to get the actual value
|
||||
il.EmitCall(OpCodes.Callvirt, DuckTypeInstancePropertyInfo.GetMethod, null);
|
||||
il.EmitCall(OpCodes.Callvirt, DuckTypeInstancePropertyInfo.GetMethod!, null!);
|
||||
|
||||
currentValueType = typeof(object);
|
||||
}
|
||||
|
|
@ -159,10 +181,9 @@ public static partial class DuckType
|
|||
|
||||
il.Emit(targetField.IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, targetField);
|
||||
}
|
||||
else
|
||||
else if (targetField.DeclaringType is not null && proxyTypeBuilder is not null)
|
||||
{
|
||||
// If the instance or the field are non public we need to create a Dynamic method to overpass the visibility checks
|
||||
|
||||
string dynMethodName = $"_setField_{targetField.DeclaringType.Name}_{targetField.Name}";
|
||||
|
||||
// Convert the field type for the dynamic method
|
||||
|
|
@ -200,10 +221,21 @@ public static partial class DuckType
|
|||
// Emit the call to the dynamic method
|
||||
il.WriteDynamicMethodCall(dynMethod, proxyTypeBuilder);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Dry run: We enable all checks done in the preview if branch
|
||||
Type dynValueType = UseDirectAccessTo(proxyTypeBuilder, targetField.FieldType) ? targetField.FieldType : typeof(object);
|
||||
ILHelpersExtensions.CheckTypeConversion(currentValueType, dynValueType);
|
||||
ILHelpersExtensions.CheckTypeConversion(dynValueType, targetField.FieldType);
|
||||
}
|
||||
|
||||
il.Emit(OpCodes.Ret);
|
||||
il.Flush();
|
||||
_methodBuilderGetToken.Invoke(method, null);
|
||||
if (method is not null)
|
||||
{
|
||||
MethodBuilderGetToken.Invoke(method, null);
|
||||
}
|
||||
|
||||
return method;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -27,8 +27,21 @@ namespace OpenTelemetry.AutoInstrumentation.DuckTyping;
|
|||
/// </summary>
|
||||
public static partial class DuckType
|
||||
{
|
||||
private static MethodBuilder GetPropertyGetMethod(TypeBuilder proxyTypeBuilder, Type targetType, MemberInfo proxyMember, PropertyInfo targetProperty, FieldInfo instanceField)
|
||||
private static MethodBuilder GetPropertyGetMethod(
|
||||
TypeBuilder proxyTypeBuilder,
|
||||
Type targetType,
|
||||
MemberInfo proxyMember,
|
||||
PropertyInfo targetProperty,
|
||||
FieldInfo instanceField,
|
||||
Func<LazyILGenerator, Type, Type, Type> duckCastInnerToOuterFunc,
|
||||
Func<Type, Type, bool> needsDuckChaining)
|
||||
{
|
||||
MethodInfo targetMethod = targetProperty.GetMethod;
|
||||
if (targetMethod is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string proxyMemberName = proxyMember.Name;
|
||||
Type proxyMemberReturnType = typeof(object);
|
||||
Type[] proxyParameterTypes = Type.EmptyTypes;
|
||||
|
|
@ -53,21 +66,23 @@ public static partial class DuckType
|
|||
}
|
||||
}
|
||||
|
||||
MethodBuilder proxyMethod = proxyTypeBuilder.DefineMethod(
|
||||
MethodBuilder proxyMethod = proxyTypeBuilder?.DefineMethod(
|
||||
"get_" + proxyMemberName,
|
||||
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.Virtual,
|
||||
proxyMemberReturnType,
|
||||
proxyParameterTypes);
|
||||
|
||||
LazyILGenerator il = new LazyILGenerator(proxyMethod.GetILGenerator());
|
||||
MethodInfo targetMethod = targetProperty.GetMethod;
|
||||
LazyILGenerator il = new LazyILGenerator(proxyMethod?.GetILGenerator());
|
||||
Type returnType = targetProperty.PropertyType;
|
||||
|
||||
// Load the instance if needed
|
||||
if (!targetMethod.IsStatic)
|
||||
{
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(instanceField.FieldType.IsValueType ? OpCodes.Ldflda : OpCodes.Ldfld, instanceField);
|
||||
if (instanceField is not null)
|
||||
{
|
||||
il.Emit(instanceField.FieldType.IsValueType ? OpCodes.Ldflda : OpCodes.Ldfld, instanceField);
|
||||
}
|
||||
}
|
||||
|
||||
// Load the indexer keys to the stack
|
||||
|
|
@ -84,7 +99,7 @@ public static partial class DuckType
|
|||
il.Emit(OpCodes.Castclass, typeof(IDuckType));
|
||||
|
||||
// Call IDuckType.Instance property to get the actual value
|
||||
il.EmitCall(OpCodes.Callvirt, DuckTypeInstancePropertyInfo.GetMethod, null);
|
||||
il.EmitCall(OpCodes.Callvirt, DuckTypeInstancePropertyInfo.GetMethod!, null!);
|
||||
targetParamType = typeof(object);
|
||||
}
|
||||
else
|
||||
|
|
@ -108,7 +123,7 @@ public static partial class DuckType
|
|||
if (targetMethod.IsPublic)
|
||||
{
|
||||
// We can emit a normal call if we have a public instance with a public property method.
|
||||
il.EmitCall(targetMethod.IsStatic || instanceField.FieldType.IsValueType ? OpCodes.Call : OpCodes.Callvirt, targetMethod, null);
|
||||
il.EmitCall(targetMethod.IsStatic || (instanceField?.FieldType.IsValueType ?? false) ? OpCodes.Call : OpCodes.Callvirt, targetMethod, null!);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -116,7 +131,7 @@ public static partial class DuckType
|
|||
il.WriteMethodCalli(targetMethod);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (targetProperty.DeclaringType is not null && proxyTypeBuilder is not null && instanceField is not null)
|
||||
{
|
||||
// If the instance is not public we need to create a Dynamic method to overpass the visibility checks
|
||||
// we can't access non public types so we have to cast to object type (in the instance object and the return type).
|
||||
|
|
@ -143,7 +158,7 @@ public static partial class DuckType
|
|||
dynIL.WriteTypeConversion(dynParameters[idx], targetParameters[idx]);
|
||||
}
|
||||
|
||||
dynIL.EmitCall(targetMethod.IsStatic || instanceField.FieldType.IsValueType ? OpCodes.Call : OpCodes.Callvirt, targetMethod, null);
|
||||
dynIL.EmitCall(targetMethod.IsStatic || instanceField.FieldType.IsValueType ? OpCodes.Call : OpCodes.Callvirt, targetMethod, null!);
|
||||
dynIL.WriteTypeConversion(targetProperty.PropertyType, returnType);
|
||||
dynIL.Emit(OpCodes.Ret);
|
||||
dynIL.Flush();
|
||||
|
|
@ -151,21 +166,29 @@ public static partial class DuckType
|
|||
// Emit the call to the dynamic method
|
||||
il.WriteDynamicMethodCall(dynMethod, proxyTypeBuilder);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Dry run: We enable all checks done in the preview if branch
|
||||
returnType = UseDirectAccessTo(proxyTypeBuilder, targetProperty.PropertyType) ? targetProperty.PropertyType : typeof(object);
|
||||
Type[] targetParameters = GetPropertyGetParametersTypes(proxyTypeBuilder, targetProperty, false, !targetMethod.IsStatic).ToArray();
|
||||
Type[] dynParameters = targetMethod.IsStatic ? targetParametersTypes : (new[] { typeof(object) }).Concat(targetParametersTypes).ToArray();
|
||||
for (int idx = targetMethod.IsStatic ? 0 : 1; idx < dynParameters.Length; idx++)
|
||||
{
|
||||
ILHelpersExtensions.CheckTypeConversion(dynParameters[idx], targetParameters[idx]);
|
||||
}
|
||||
|
||||
ILHelpersExtensions.CheckTypeConversion(targetProperty.PropertyType, returnType);
|
||||
}
|
||||
|
||||
// Handle the return value
|
||||
// Check if the type can be converted or if we need to enable duck chaining
|
||||
if (NeedsDuckChaining(targetProperty.PropertyType, proxyMemberReturnType))
|
||||
if (needsDuckChaining(targetProperty.PropertyType, proxyMemberReturnType))
|
||||
{
|
||||
if (UseDirectAccessTo(proxyTypeBuilder, targetProperty.PropertyType) && targetProperty.PropertyType.IsValueType)
|
||||
{
|
||||
il.Emit(OpCodes.Box, targetProperty.PropertyType);
|
||||
}
|
||||
UseDirectAccessTo(proxyTypeBuilder, targetProperty.PropertyType);
|
||||
|
||||
// We call DuckType.CreateCache<>.Create()
|
||||
MethodInfo getProxyMethodInfo = typeof(CreateCache<>)
|
||||
.MakeGenericType(proxyMemberReturnType).GetMethod("Create");
|
||||
|
||||
il.Emit(OpCodes.Call, getProxyMethodInfo);
|
||||
// If this is a forward duck type, we need to create a duck type from the original instance
|
||||
// If this is a reverse duck type, we need to cast to IDuckType and extract the original instance
|
||||
duckCastInnerToOuterFunc(il, proxyMemberReturnType, targetProperty.PropertyType);
|
||||
}
|
||||
else if (returnType != proxyMemberReturnType)
|
||||
{
|
||||
|
|
@ -175,12 +198,29 @@ public static partial class DuckType
|
|||
|
||||
il.Emit(OpCodes.Ret);
|
||||
il.Flush();
|
||||
_methodBuilderGetToken.Invoke(proxyMethod, null);
|
||||
if (proxyMethod is not null)
|
||||
{
|
||||
MethodBuilderGetToken.Invoke(proxyMethod, null);
|
||||
}
|
||||
|
||||
return proxyMethod;
|
||||
}
|
||||
|
||||
private static MethodBuilder GetPropertySetMethod(TypeBuilder proxyTypeBuilder, Type targetType, MemberInfo proxyMember, PropertyInfo targetProperty, FieldInfo instanceField)
|
||||
private static MethodBuilder GetPropertySetMethod(
|
||||
TypeBuilder proxyTypeBuilder,
|
||||
Type targetType,
|
||||
MemberInfo proxyMember,
|
||||
PropertyInfo targetProperty,
|
||||
FieldInfo instanceField,
|
||||
Func<LazyILGenerator, Type, Type, Type> duckCastOuterToInner,
|
||||
Func<Type, Type, bool> needsDuckChaining)
|
||||
{
|
||||
MethodInfo targetMethod = targetProperty.SetMethod;
|
||||
if (targetMethod is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string proxyMemberName = null;
|
||||
Type[] proxyParameterTypes = Type.EmptyTypes;
|
||||
Type[] targetParametersTypes = GetPropertySetParametersTypes(proxyTypeBuilder, targetProperty, true).ToArray();
|
||||
|
|
@ -197,27 +237,29 @@ public static partial class DuckType
|
|||
else if (proxyMember is FieldInfo proxyField)
|
||||
{
|
||||
proxyMemberName = proxyField.Name;
|
||||
proxyParameterTypes = new Type[] { proxyField.FieldType };
|
||||
proxyParameterTypes = new[] { proxyField.FieldType };
|
||||
if (proxyParameterTypes.Length != targetParametersTypes.Length)
|
||||
{
|
||||
DuckTypePropertyArgumentsLengthException.Throw(targetProperty);
|
||||
}
|
||||
}
|
||||
|
||||
MethodBuilder proxyMethod = proxyTypeBuilder.DefineMethod(
|
||||
MethodBuilder proxyMethod = proxyTypeBuilder?.DefineMethod(
|
||||
"set_" + proxyMemberName,
|
||||
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.Virtual,
|
||||
typeof(void),
|
||||
proxyParameterTypes);
|
||||
|
||||
LazyILGenerator il = new LazyILGenerator(proxyMethod.GetILGenerator());
|
||||
MethodInfo targetMethod = targetProperty.SetMethod;
|
||||
LazyILGenerator il = new LazyILGenerator(proxyMethod?.GetILGenerator());
|
||||
|
||||
// Load the instance if needed
|
||||
if (!targetMethod.IsStatic)
|
||||
{
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(instanceField.FieldType.IsValueType ? OpCodes.Ldflda : OpCodes.Ldfld, instanceField);
|
||||
if (instanceField is not null)
|
||||
{
|
||||
il.Emit(instanceField.FieldType.IsValueType ? OpCodes.Ldflda : OpCodes.Ldfld, instanceField);
|
||||
}
|
||||
}
|
||||
|
||||
// Load the indexer keys and set value to the stack
|
||||
|
|
@ -227,16 +269,15 @@ public static partial class DuckType
|
|||
Type targetParamType = targetParametersTypes[pIndex];
|
||||
|
||||
// Check if the type can be converted of if we need to enable duck chaining
|
||||
if (NeedsDuckChaining(targetParamType, proxyParamType))
|
||||
if (needsDuckChaining(targetParamType, proxyParamType))
|
||||
{
|
||||
// Load the argument and cast it as Duck type
|
||||
il.WriteLoadArgument(pIndex, false);
|
||||
il.Emit(OpCodes.Castclass, typeof(IDuckType));
|
||||
|
||||
// Call IDuckType.Instance property to get the actual value
|
||||
il.EmitCall(OpCodes.Callvirt, DuckTypeInstancePropertyInfo.GetMethod, null);
|
||||
|
||||
targetParamType = typeof(object);
|
||||
// If this is a forward duck type, we need to cast to IDuckType and extract the original instance
|
||||
// and set the targetParamType to object
|
||||
// If this is a reverse duck type, we need to create a duck type from the original instance
|
||||
targetParamType = duckCastOuterToInner(il, targetParamType, proxyParamType);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -258,7 +299,7 @@ public static partial class DuckType
|
|||
if (targetMethod.IsPublic)
|
||||
{
|
||||
// We can emit a normal call if we have a public instance with a public property method.
|
||||
il.EmitCall(targetMethod.IsStatic ? OpCodes.Call : OpCodes.Callvirt, targetMethod, null);
|
||||
il.EmitCall(targetMethod.IsStatic ? OpCodes.Call : OpCodes.Callvirt, targetMethod, null!);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -266,7 +307,7 @@ public static partial class DuckType
|
|||
il.WriteMethodCalli(targetMethod);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (targetProperty.DeclaringType is not null && proxyTypeBuilder is not null && instanceField is not null)
|
||||
{
|
||||
// If the instance is not public we need to create a Dynamic method to overpass the visibility checks
|
||||
// we can't access non public types so we have to cast to object type (in the instance object and the return type).
|
||||
|
|
@ -292,17 +333,30 @@ public static partial class DuckType
|
|||
dynIL.WriteTypeConversion(dynParameters[idx], targetParameters[idx]);
|
||||
}
|
||||
|
||||
dynIL.EmitCall(targetMethod.IsStatic ? OpCodes.Call : OpCodes.Callvirt, targetMethod, null);
|
||||
dynIL.EmitCall(targetMethod.IsStatic ? OpCodes.Call : OpCodes.Callvirt, targetMethod, null!);
|
||||
dynIL.Emit(OpCodes.Ret);
|
||||
dynIL.Flush();
|
||||
|
||||
// Create and load delegate for the DynamicMethod
|
||||
il.WriteDynamicMethodCall(dynMethod, proxyTypeBuilder);
|
||||
}
|
||||
else
|
||||
{
|
||||
Type[] targetParameters = GetPropertySetParametersTypes(proxyTypeBuilder, targetProperty, false, !targetMethod.IsStatic).ToArray();
|
||||
Type[] dynParameters = targetMethod.IsStatic ? targetParametersTypes : (new[] { typeof(object) }).Concat(targetParametersTypes).ToArray();
|
||||
for (int idx = targetMethod.IsStatic ? 0 : 1; idx < dynParameters.Length; idx++)
|
||||
{
|
||||
ILHelpersExtensions.CheckTypeConversion(dynParameters[idx], targetParameters[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
il.Emit(OpCodes.Ret);
|
||||
il.Flush();
|
||||
_methodBuilderGetToken.Invoke(proxyMethod, null);
|
||||
if (proxyMethod is not null)
|
||||
{
|
||||
MethodBuilderGetToken.Invoke(proxyMethod, null);
|
||||
}
|
||||
|
||||
return proxyMethod;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ using System.Collections.Generic;
|
|||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.Runtime.CompilerServices;
|
||||
// ReSharper disable InconsistentNaming
|
||||
|
||||
namespace OpenTelemetry.AutoInstrumentation.DuckTyping;
|
||||
|
||||
|
|
@ -28,43 +30,123 @@ namespace OpenTelemetry.AutoInstrumentation.DuckTyping;
|
|||
/// </summary>
|
||||
public static partial class DuckType
|
||||
{
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private static readonly object Locker;
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private static readonly ConcurrentDictionary<TypesTuple, Lazy<CreateTypeResult>> DuckTypeCache;
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private static readonly Dictionary<Assembly, ModuleBuilder> ActiveBuilders;
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private static readonly Dictionary<ModuleBuilder, HashSet<string>> IgnoresAccessChecksToAssembliesSetDictionary;
|
||||
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private static readonly MethodInfo _getTypeFromHandleMethodInfo;
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private static readonly MethodInfo _enumToObjectMethodInfo;
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private static readonly PropertyInfo _duckTypeInstancePropertyInfo;
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private static readonly MethodInfo _methodBuilderGetToken;
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private static readonly ConstructorInfo _ignoresAccessChecksToAttributeCtor;
|
||||
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private static long _assemblyCount;
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private static long _typeCount;
|
||||
|
||||
static DuckType()
|
||||
{
|
||||
Locker = new();
|
||||
DuckTypeCache = new();
|
||||
ActiveBuilders = new();
|
||||
IgnoresAccessChecksToAssembliesSetDictionary = new();
|
||||
|
||||
_getTypeFromHandleMethodInfo = typeof(Type).GetMethod(nameof(Type.GetTypeFromHandle));
|
||||
_enumToObjectMethodInfo = typeof(Enum).GetMethod(nameof(Enum.ToObject), new[] { typeof(Type), typeof(object) });
|
||||
_duckTypeInstancePropertyInfo = typeof(IDuckType).GetProperty(nameof(IDuckType.Instance));
|
||||
_methodBuilderGetToken = typeof(MethodBuilder).GetMethod("GetToken", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
_ignoresAccessChecksToAttributeCtor = typeof(IgnoresAccessChecksToAttribute).GetConstructor(new[] { typeof(string) });
|
||||
|
||||
_assemblyCount = 0;
|
||||
_typeCount = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Type.GetTypeFromHandle method info
|
||||
/// </summary>
|
||||
public static readonly MethodInfo GetTypeFromHandleMethodInfo = typeof(Type).GetMethod(nameof(Type.GetTypeFromHandle));
|
||||
public static MethodInfo GetTypeFromHandleMethodInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_getTypeFromHandleMethodInfo is null)
|
||||
{
|
||||
DuckTypeException.Throw($"{nameof(Type)}.{nameof(Type.GetTypeFromHandle)}() cannot be found.");
|
||||
}
|
||||
|
||||
return _getTypeFromHandleMethodInfo;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Enum.ToObject method info
|
||||
/// </summary>
|
||||
public static readonly MethodInfo EnumToObjectMethodInfo = typeof(Enum).GetMethod(nameof(Enum.ToObject), new[] { typeof(Type), typeof(object) });
|
||||
public static MethodInfo EnumToObjectMethodInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_enumToObjectMethodInfo is null)
|
||||
{
|
||||
DuckTypeException.Throw($"{nameof(Enum)}.{nameof(Enum.ToObject)}() cannot be found.");
|
||||
}
|
||||
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private static readonly object _locker = new object();
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private static readonly ConcurrentDictionary<TypesTuple, Lazy<CreateTypeResult>> DuckTypeCache = new ConcurrentDictionary<TypesTuple, Lazy<CreateTypeResult>>();
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private static readonly PropertyInfo DuckTypeInstancePropertyInfo = typeof(IDuckType).GetProperty(nameof(IDuckType.Instance));
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private static readonly MethodInfo _methodBuilderGetToken = typeof(MethodBuilder).GetMethod("GetToken", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private static readonly Dictionary<Assembly, ModuleBuilder> ActiveBuilders = new Dictionary<Assembly, ModuleBuilder>();
|
||||
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private static long _assemblyCount = 0;
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private static long _typeCount = 0;
|
||||
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private static ConstructorInfo _ignoresAccessChecksToAttributeCtor = typeof(IgnoresAccessChecksToAttribute).GetConstructor(new Type[] { typeof(string) });
|
||||
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
|
||||
private static Dictionary<ModuleBuilder, HashSet<string>> _ignoresAccessChecksToAssembliesSetDictionary = new Dictionary<ModuleBuilder, HashSet<string>>();
|
||||
return _enumToObjectMethodInfo;
|
||||
}
|
||||
}
|
||||
|
||||
internal static long AssemblyCount => _assemblyCount;
|
||||
|
||||
internal static long TypeCount => _typeCount;
|
||||
|
||||
private static PropertyInfo DuckTypeInstancePropertyInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_duckTypeInstancePropertyInfo is null)
|
||||
{
|
||||
DuckTypeException.Throw($"{nameof(IDuckType)}.{nameof(IDuckType.Instance)} cannot be found.");
|
||||
}
|
||||
|
||||
return _duckTypeInstancePropertyInfo;
|
||||
}
|
||||
}
|
||||
|
||||
private static MethodInfo MethodBuilderGetToken
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_methodBuilderGetToken is null)
|
||||
{
|
||||
DuckTypeException.Throw($"{nameof(MethodBuilder)}.GetToken() cannot be found.");
|
||||
}
|
||||
|
||||
return _methodBuilderGetToken;
|
||||
}
|
||||
}
|
||||
|
||||
private static ConstructorInfo IgnoresAccessChecksToAttributeCtor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_ignoresAccessChecksToAttributeCtor is null)
|
||||
{
|
||||
DuckTypeException.Throw($"{nameof(IgnoresAccessChecksToAttribute)}.ctor() cannot be found.");
|
||||
}
|
||||
|
||||
return _ignoresAccessChecksToAttributeCtor;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ModuleBuilder instance from a target type. (.NET Framework / Non AssemblyLoadContext version)
|
||||
/// </summary>
|
||||
|
|
@ -73,14 +155,14 @@ public static partial class DuckType
|
|||
/// <returns>ModuleBuilder instance</returns>
|
||||
private static ModuleBuilder GetModuleBuilder(Type targetType, bool isVisible)
|
||||
{
|
||||
Assembly targetAssembly = targetType.Assembly ?? typeof(DuckType).Assembly;
|
||||
Assembly targetAssembly = targetType.Assembly;
|
||||
|
||||
if (!isVisible)
|
||||
{
|
||||
// If the target type is not visible then we create a new module builder.
|
||||
// This is the only way to IgnoresAccessChecksToAttribute to work.
|
||||
// We can't reuse the module builder if the attributes collection changes.
|
||||
return CreateModuleBuilder($"DuckTypeNotVisibleAssembly.{targetType.Name}", targetAssembly);
|
||||
return CreateModuleBuilder(DuckTypeConstants.DuckTypeNotVisibleAssemblyPrefix + targetType.Name, targetAssembly);
|
||||
}
|
||||
|
||||
if (targetType.IsGenericType)
|
||||
|
|
@ -89,14 +171,14 @@ public static partial class DuckType
|
|||
{
|
||||
if (type.Assembly != targetAssembly)
|
||||
{
|
||||
return CreateModuleBuilder($"DuckTypeGenericTypeAssembly.{targetType.Name}", targetAssembly);
|
||||
return CreateModuleBuilder(DuckTypeConstants.DuckTypeGenericTypeAssemblyPrefix + targetType.Name, targetAssembly);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ActiveBuilders.TryGetValue(targetAssembly, out var moduleBuilder))
|
||||
{
|
||||
moduleBuilder = CreateModuleBuilder($"DuckTypeAssembly.{targetType.Assembly?.GetName().Name}", targetAssembly);
|
||||
moduleBuilder = CreateModuleBuilder(DuckTypeConstants.DuckTypeAssemblyPrefix + targetType.Assembly.GetName().Name, targetAssembly);
|
||||
ActiveBuilders.Add(targetAssembly, moduleBuilder);
|
||||
}
|
||||
|
||||
|
|
@ -126,6 +208,11 @@ public static partial class DuckType
|
|||
/// <returns>TProxyDelegate instance</returns>
|
||||
public static TProxyDelegate GetDelegate()
|
||||
{
|
||||
if (_delegate is null)
|
||||
{
|
||||
DuckTypeException.Throw("Delegate instance in DelegateCache is null, please ensure that FillDelegate is called before this call.");
|
||||
}
|
||||
|
||||
return _delegate;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ public static partial class DuckType
|
|||
/// <param name="type">Type to gain internals visibility</param>
|
||||
private static void EnsureTypeVisibility(ModuleBuilder builder, Type type)
|
||||
{
|
||||
EnsureAssemblyNameVisibility(builder, type.Assembly.GetName().Name);
|
||||
EnsureAssemblyNameVisibility(builder, type.Assembly.GetName().Name ?? string.Empty);
|
||||
|
||||
if (type.IsGenericType && !type.IsGenericTypeDefinition)
|
||||
{
|
||||
|
|
@ -60,7 +60,7 @@ public static partial class DuckType
|
|||
{
|
||||
if (!t.IsVisible)
|
||||
{
|
||||
EnsureAssemblyNameVisibility(builder, t.Assembly.GetName().Name);
|
||||
EnsureAssemblyNameVisibility(builder, t.Assembly.GetName().Name ?? string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -69,26 +69,33 @@ public static partial class DuckType
|
|||
{
|
||||
if (!type.IsNestedPublic)
|
||||
{
|
||||
EnsureAssemblyNameVisibility(builder, type.Assembly.GetName().Name);
|
||||
EnsureAssemblyNameVisibility(builder, type.Assembly.GetName().Name ?? string.Empty);
|
||||
}
|
||||
|
||||
// this should be null for non-nested types.
|
||||
type = type.DeclaringType;
|
||||
if (type.DeclaringType is { } declaringType)
|
||||
{
|
||||
type = declaringType;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void EnsureAssemblyNameVisibility(ModuleBuilder builder, string assemblyName)
|
||||
{
|
||||
lock (_ignoresAccessChecksToAssembliesSetDictionary)
|
||||
lock (IgnoresAccessChecksToAssembliesSetDictionary)
|
||||
{
|
||||
if (!_ignoresAccessChecksToAssembliesSetDictionary.TryGetValue(builder, out var hashSet))
|
||||
if (!IgnoresAccessChecksToAssembliesSetDictionary.TryGetValue(builder, out var hashSet))
|
||||
{
|
||||
hashSet = new HashSet<string>();
|
||||
_ignoresAccessChecksToAssembliesSetDictionary[builder] = hashSet;
|
||||
IgnoresAccessChecksToAssembliesSetDictionary[builder] = hashSet;
|
||||
}
|
||||
|
||||
if (hashSet.Add(assemblyName))
|
||||
{
|
||||
((AssemblyBuilder)builder.Assembly).SetCustomAttribute(new CustomAttributeBuilder(_ignoresAccessChecksToAttributeCtor, new object[] { assemblyName }));
|
||||
((AssemblyBuilder)builder.Assembly).SetCustomAttribute(new CustomAttributeBuilder(IgnoresAccessChecksToAttributeCtor, new object[] { assemblyName }));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -98,10 +105,10 @@ public static partial class DuckType
|
|||
{
|
||||
// The condition to apply duck chaining is:
|
||||
// 1. Is a struct with the DuckCopy attribute
|
||||
// 2. Both types must be differents.
|
||||
// 2. Both types must be different.
|
||||
// 3. The proxy type (duck chaining proxy definition type) can't be a struct
|
||||
// 4. The proxy type can't be a generic parameter (should be a well known type)
|
||||
// 5. Can't be a base type or an iterface implemented by the targetType type.
|
||||
// 5. Can't be a base type or an interface implemented by the targetType type.
|
||||
// 6. The proxy type can't be a CLR type
|
||||
return proxyType.GetCustomAttribute<DuckCopyAttribute>() != null ||
|
||||
(proxyType != targetType &&
|
||||
|
|
@ -112,14 +119,14 @@ public static partial class DuckType
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets if the direct access method should be used or the inderect method (dynamic method)
|
||||
/// Gets if the direct access method should be used or the indirect method (dynamic method)
|
||||
/// </summary>
|
||||
/// <param name="builder">Module builder</param>
|
||||
/// <param name="targetType">Target type</param>
|
||||
/// <returns>true for direct method; otherwise, false.</returns>
|
||||
private static bool UseDirectAccessTo(ModuleBuilder builder, Type targetType)
|
||||
{
|
||||
if (builder == null)
|
||||
if (builder is null)
|
||||
{
|
||||
return targetType.IsPublic || targetType.IsNestedPublic;
|
||||
}
|
||||
|
|
@ -129,23 +136,18 @@ public static partial class DuckType
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets if the direct access method should be used or the inderect method (dynamic method)
|
||||
/// Gets if the direct access method should be used or the indirect method (dynamic method)
|
||||
/// </summary>
|
||||
/// <param name="builder">Type builder</param>
|
||||
/// <param name="targetType">Target type</param>
|
||||
/// <returns>true for direct method; otherwise, false.</returns>
|
||||
private static bool UseDirectAccessTo(TypeBuilder builder, Type targetType)
|
||||
{
|
||||
return UseDirectAccessTo((ModuleBuilder)builder?.Module, targetType);
|
||||
}
|
||||
if (builder is null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets if the direct access method should be used or the inderect method (dynamic method)
|
||||
/// </summary>
|
||||
/// <param name="targetType">Target type</param>
|
||||
/// <returns>true for direct method; otherwise, false.</returns>
|
||||
private static bool UseDirectAccessTo(Type targetType)
|
||||
{
|
||||
return UseDirectAccessTo((ModuleBuilder)null, targetType);
|
||||
return UseDirectAccessTo((ModuleBuilder)builder.Module, targetType);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,24 @@
|
|||
// <copyright file="DuckTypeConstants.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
|
||||
namespace OpenTelemetry.AutoInstrumentation.DuckTyping;
|
||||
|
||||
internal static class DuckTypeConstants
|
||||
{
|
||||
internal const string DuckTypeAssemblyPrefix = "DuckTypeAssembly.";
|
||||
internal const string DuckTypeNotVisibleAssemblyPrefix = "DuckTypeNotVisibleAssembly.";
|
||||
internal const string DuckTypeGenericTypeAssemblyPrefix = "DuckTypeGenericTypeAssembly.";
|
||||
}
|
||||
|
|
@ -15,9 +15,11 @@
|
|||
// </copyright>
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
#pragma warning disable SA1649 // File name must match first type name
|
||||
#pragma warning disable SA1402 // File may only contain a single class
|
||||
|
||||
|
|
@ -26,18 +28,37 @@ namespace OpenTelemetry.AutoInstrumentation.DuckTyping;
|
|||
/// <summary>
|
||||
/// DuckType Exception
|
||||
/// </summary>
|
||||
public class DuckTypeException : Exception
|
||||
internal class DuckTypeException : Exception
|
||||
{
|
||||
internal DuckTypeException(string message)
|
||||
protected DuckTypeException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
protected DuckTypeException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(string message)
|
||||
{
|
||||
throw new DuckTypeException(message);
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(string message, Exception innerException)
|
||||
{
|
||||
throw new DuckTypeException(message, innerException);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DuckType proxy type definition is null
|
||||
/// </summary>
|
||||
public class DuckTypeProxyTypeDefinitionIsNull : DuckTypeException
|
||||
internal class DuckTypeProxyTypeDefinitionIsNull : DuckTypeException
|
||||
{
|
||||
private DuckTypeProxyTypeDefinitionIsNull()
|
||||
: base($"The proxy type definition is null.")
|
||||
|
|
@ -45,6 +66,7 @@ public class DuckTypeProxyTypeDefinitionIsNull : DuckTypeException
|
|||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw()
|
||||
{
|
||||
throw new DuckTypeProxyTypeDefinitionIsNull();
|
||||
|
|
@ -54,7 +76,7 @@ public class DuckTypeProxyTypeDefinitionIsNull : DuckTypeException
|
|||
/// <summary>
|
||||
/// DuckType target object instance is null
|
||||
/// </summary>
|
||||
public class DuckTypeTargetObjectInstanceIsNull : DuckTypeException
|
||||
internal class DuckTypeTargetObjectInstanceIsNull : DuckTypeException
|
||||
{
|
||||
private DuckTypeTargetObjectInstanceIsNull()
|
||||
: base($"The target object instance is null.")
|
||||
|
|
@ -62,6 +84,7 @@ public class DuckTypeTargetObjectInstanceIsNull : DuckTypeException
|
|||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw()
|
||||
{
|
||||
throw new DuckTypeTargetObjectInstanceIsNull();
|
||||
|
|
@ -71,7 +94,7 @@ public class DuckTypeTargetObjectInstanceIsNull : DuckTypeException
|
|||
/// <summary>
|
||||
/// DuckType invalid type conversion exception
|
||||
/// </summary>
|
||||
public class DuckTypeInvalidTypeConversionException : DuckTypeException
|
||||
internal class DuckTypeInvalidTypeConversionException : DuckTypeException
|
||||
{
|
||||
private DuckTypeInvalidTypeConversionException(Type actualType, Type expectedType)
|
||||
: base($"Invalid type conversion from {actualType.FullName} to {expectedType.FullName}")
|
||||
|
|
@ -79,6 +102,7 @@ public class DuckTypeInvalidTypeConversionException : DuckTypeException
|
|||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(Type actualType, Type expectedType)
|
||||
{
|
||||
throw new DuckTypeInvalidTypeConversionException(actualType, expectedType);
|
||||
|
|
@ -88,7 +112,7 @@ public class DuckTypeInvalidTypeConversionException : DuckTypeException
|
|||
/// <summary>
|
||||
/// DuckType property can't be read
|
||||
/// </summary>
|
||||
public class DuckTypePropertyCantBeReadException : DuckTypeException
|
||||
internal class DuckTypePropertyCantBeReadException : DuckTypeException
|
||||
{
|
||||
private DuckTypePropertyCantBeReadException(PropertyInfo property)
|
||||
: base($"The property '{property.Name}' can't be read, you should remove the getter from the proxy definition base type class or interface.")
|
||||
|
|
@ -96,6 +120,7 @@ public class DuckTypePropertyCantBeReadException : DuckTypeException
|
|||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(PropertyInfo property)
|
||||
{
|
||||
throw new DuckTypePropertyCantBeReadException(property);
|
||||
|
|
@ -105,7 +130,7 @@ public class DuckTypePropertyCantBeReadException : DuckTypeException
|
|||
/// <summary>
|
||||
/// DuckType property can't be written
|
||||
/// </summary>
|
||||
public class DuckTypePropertyCantBeWrittenException : DuckTypeException
|
||||
internal class DuckTypePropertyCantBeWrittenException : DuckTypeException
|
||||
{
|
||||
private DuckTypePropertyCantBeWrittenException(PropertyInfo property)
|
||||
: base($"The property '{property.Name}' can't be written, you should remove the setter from the proxy definition base type class or interface.")
|
||||
|
|
@ -113,6 +138,7 @@ public class DuckTypePropertyCantBeWrittenException : DuckTypeException
|
|||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(PropertyInfo property)
|
||||
{
|
||||
throw new DuckTypePropertyCantBeWrittenException(property);
|
||||
|
|
@ -122,7 +148,7 @@ public class DuckTypePropertyCantBeWrittenException : DuckTypeException
|
|||
/// <summary>
|
||||
/// DuckType property argument doesn't have the same argument length
|
||||
/// </summary>
|
||||
public class DuckTypePropertyArgumentsLengthException : DuckTypeException
|
||||
internal class DuckTypePropertyArgumentsLengthException : DuckTypeException
|
||||
{
|
||||
private DuckTypePropertyArgumentsLengthException(PropertyInfo property)
|
||||
: base($"The property '{property.Name}' doesn't have the same number of arguments as the original property.")
|
||||
|
|
@ -130,6 +156,7 @@ public class DuckTypePropertyArgumentsLengthException : DuckTypeException
|
|||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(PropertyInfo property)
|
||||
{
|
||||
throw new DuckTypePropertyArgumentsLengthException(property);
|
||||
|
|
@ -139,7 +166,7 @@ public class DuckTypePropertyArgumentsLengthException : DuckTypeException
|
|||
/// <summary>
|
||||
/// DuckType field is readonly
|
||||
/// </summary>
|
||||
public class DuckTypeFieldIsReadonlyException : DuckTypeException
|
||||
internal class DuckTypeFieldIsReadonlyException : DuckTypeException
|
||||
{
|
||||
private DuckTypeFieldIsReadonlyException(FieldInfo field)
|
||||
: base($"The field '{field.Name}' is marked as readonly, you should remove the setter from the base type class or interface.")
|
||||
|
|
@ -147,6 +174,7 @@ public class DuckTypeFieldIsReadonlyException : DuckTypeException
|
|||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(FieldInfo field)
|
||||
{
|
||||
throw new DuckTypeFieldIsReadonlyException(field);
|
||||
|
|
@ -156,41 +184,25 @@ public class DuckTypeFieldIsReadonlyException : DuckTypeException
|
|||
/// <summary>
|
||||
/// DuckType property or field not found
|
||||
/// </summary>
|
||||
public class DuckTypePropertyOrFieldNotFoundException : DuckTypeException
|
||||
internal class DuckTypePropertyOrFieldNotFoundException : DuckTypeException
|
||||
{
|
||||
private DuckTypePropertyOrFieldNotFoundException(string name, string duckAttributeName)
|
||||
: base($"The property or field '{duckAttributeName}' for the proxy property '{name}' was not found in the instance.")
|
||||
private DuckTypePropertyOrFieldNotFoundException(string name, string duckAttributeName, string type)
|
||||
: base($"The property or field '{duckAttributeName}' for the proxy property '{name}' was not found in the instance of type '{type}'.")
|
||||
{
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
internal static void Throw(string name, string duckAttributeName)
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(string name, string duckAttributeName, Type type)
|
||||
{
|
||||
throw new DuckTypePropertyOrFieldNotFoundException(name, duckAttributeName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DuckType type is not public exception
|
||||
/// </summary>
|
||||
public class DuckTypeTypeIsNotPublicException : DuckTypeException
|
||||
{
|
||||
private DuckTypeTypeIsNotPublicException(Type type, string argumentName)
|
||||
: base($"The type '{type.FullName}' must be public, argument: '{argumentName}'")
|
||||
{
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
internal static void Throw(Type type, string argumentName)
|
||||
{
|
||||
throw new DuckTypeTypeIsNotPublicException(type, argumentName);
|
||||
throw new DuckTypePropertyOrFieldNotFoundException(name, duckAttributeName, type?.FullName ?? type?.Name ?? "NULL");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DuckType struct members cannot be changed exception
|
||||
/// </summary>
|
||||
public class DuckTypeStructMembersCannotBeChangedException : DuckTypeException
|
||||
internal class DuckTypeStructMembersCannotBeChangedException : DuckTypeException
|
||||
{
|
||||
private DuckTypeStructMembersCannotBeChangedException(Type type)
|
||||
: base($"Modifying struct members is not supported. [{type.FullName}]")
|
||||
|
|
@ -198,6 +210,7 @@ public class DuckTypeStructMembersCannotBeChangedException : DuckTypeException
|
|||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(Type type)
|
||||
{
|
||||
throw new DuckTypeStructMembersCannotBeChangedException(type);
|
||||
|
|
@ -207,7 +220,7 @@ public class DuckTypeStructMembersCannotBeChangedException : DuckTypeException
|
|||
/// <summary>
|
||||
/// DuckType target method can not be found exception
|
||||
/// </summary>
|
||||
public class DuckTypeTargetMethodNotFoundException : DuckTypeException
|
||||
internal class DuckTypeTargetMethodNotFoundException : DuckTypeException
|
||||
{
|
||||
private DuckTypeTargetMethodNotFoundException(MethodInfo method)
|
||||
: base($"The target method for the proxy method '{method}' was not found.")
|
||||
|
|
@ -215,6 +228,7 @@ public class DuckTypeTargetMethodNotFoundException : DuckTypeException
|
|||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(MethodInfo method)
|
||||
{
|
||||
throw new DuckTypeTargetMethodNotFoundException(method);
|
||||
|
|
@ -224,7 +238,7 @@ public class DuckTypeTargetMethodNotFoundException : DuckTypeException
|
|||
/// <summary>
|
||||
/// DuckType proxy method parameter is missing exception
|
||||
/// </summary>
|
||||
public class DuckTypeProxyMethodParameterIsMissingException : DuckTypeException
|
||||
internal class DuckTypeProxyMethodParameterIsMissingException : DuckTypeException
|
||||
{
|
||||
private DuckTypeProxyMethodParameterIsMissingException(MethodInfo proxyMethod, ParameterInfo targetParameterInfo)
|
||||
: base($"The proxy method '{proxyMethod.Name}' is missing parameter '{targetParameterInfo.Name}' declared in the target method.")
|
||||
|
|
@ -232,6 +246,7 @@ public class DuckTypeProxyMethodParameterIsMissingException : DuckTypeException
|
|||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(MethodInfo proxyMethod, ParameterInfo targetParameterInfo)
|
||||
{
|
||||
throw new DuckTypeProxyMethodParameterIsMissingException(proxyMethod, targetParameterInfo);
|
||||
|
|
@ -241,7 +256,7 @@ public class DuckTypeProxyMethodParameterIsMissingException : DuckTypeException
|
|||
/// <summary>
|
||||
/// DuckType parameter signature mismatch between proxy and target method
|
||||
/// </summary>
|
||||
public class DuckTypeProxyAndTargetMethodParameterSignatureMismatchException : DuckTypeException
|
||||
internal class DuckTypeProxyAndTargetMethodParameterSignatureMismatchException : DuckTypeException
|
||||
{
|
||||
private DuckTypeProxyAndTargetMethodParameterSignatureMismatchException(MethodInfo proxyMethod, MethodInfo targetMethod)
|
||||
: base($"Parameter signature mismatch between proxy '{proxyMethod}' and target method '{targetMethod}'")
|
||||
|
|
@ -249,16 +264,35 @@ public class DuckTypeProxyAndTargetMethodParameterSignatureMismatchException : D
|
|||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(MethodInfo proxyMethod, MethodInfo targetMethod)
|
||||
{
|
||||
throw new DuckTypeProxyAndTargetMethodParameterSignatureMismatchException(proxyMethod, targetMethod);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DuckType parameter signature mismatch between proxy and target method
|
||||
/// </summary>
|
||||
internal class DuckTypeProxyAndTargetMethodReturnTypeMismatchException : DuckTypeException
|
||||
{
|
||||
private DuckTypeProxyAndTargetMethodReturnTypeMismatchException(MethodInfo proxyMethod, MethodInfo targetMethod)
|
||||
: base($"Return type mismatch between proxy '{proxyMethod}' and target method '{targetMethod}'.")
|
||||
{
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(MethodInfo proxyMethod, MethodInfo targetMethod)
|
||||
{
|
||||
throw new DuckTypeProxyAndTargetMethodReturnTypeMismatchException(proxyMethod, targetMethod);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DuckType proxy methods with generic parameters are not supported in non public instances exception
|
||||
/// </summary>
|
||||
public class DuckTypeProxyMethodsWithGenericParametersNotSupportedInNonPublicInstancesException : DuckTypeException
|
||||
internal class DuckTypeProxyMethodsWithGenericParametersNotSupportedInNonPublicInstancesException : DuckTypeException
|
||||
{
|
||||
private DuckTypeProxyMethodsWithGenericParametersNotSupportedInNonPublicInstancesException(MethodInfo proxyMethod)
|
||||
: base($"The proxy method with generic parameters '{proxyMethod}' are not supported on non public instances")
|
||||
|
|
@ -266,6 +300,7 @@ public class DuckTypeProxyMethodsWithGenericParametersNotSupportedInNonPublicIns
|
|||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(MethodInfo proxyMethod)
|
||||
{
|
||||
throw new DuckTypeProxyMethodsWithGenericParametersNotSupportedInNonPublicInstancesException(proxyMethod);
|
||||
|
|
@ -275,7 +310,7 @@ public class DuckTypeProxyMethodsWithGenericParametersNotSupportedInNonPublicIns
|
|||
/// <summary>
|
||||
/// DuckType proxy method has an ambiguous match in the target type exception
|
||||
/// </summary>
|
||||
public class DuckTypeTargetMethodAmbiguousMatchException : DuckTypeException
|
||||
internal class DuckTypeTargetMethodAmbiguousMatchException : DuckTypeException
|
||||
{
|
||||
private DuckTypeTargetMethodAmbiguousMatchException(MethodInfo proxyMethod, MethodInfo targetMethod, MethodInfo targetMethod2)
|
||||
: base($"The proxy method '{proxyMethod}' matches at least two methods in the target type. Method1 = '{targetMethod}' and Method2 = '{targetMethod2}'")
|
||||
|
|
@ -283,8 +318,172 @@ public class DuckTypeTargetMethodAmbiguousMatchException : DuckTypeException
|
|||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(MethodInfo proxyMethod, MethodInfo targetMethod, MethodInfo targetMethod2)
|
||||
{
|
||||
throw new DuckTypeTargetMethodAmbiguousMatchException(proxyMethod, targetMethod, targetMethod2);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DuckType reverse proxy type to derive from is a struct exception
|
||||
/// </summary>
|
||||
internal class DuckTypeReverseProxyBaseIsStructException : DuckTypeException
|
||||
{
|
||||
private DuckTypeReverseProxyBaseIsStructException(Type type)
|
||||
: base($"Cannot derive from struct type '{type.FullName}' for reverse proxy")
|
||||
{
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(Type type)
|
||||
{
|
||||
throw new DuckTypeReverseProxyBaseIsStructException(type);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DuckType proxy method is abstract
|
||||
/// </summary>
|
||||
internal class DuckTypeReverseProxyImplementorIsAbstractOrInterfaceException : DuckTypeException
|
||||
{
|
||||
private DuckTypeReverseProxyImplementorIsAbstractOrInterfaceException(Type type)
|
||||
: base($"The implementation type '{type.FullName}' must not be an interface or abstract type for reverse proxy")
|
||||
{
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(Type type)
|
||||
{
|
||||
throw new DuckTypeReverseProxyImplementorIsAbstractOrInterfaceException(type);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DuckType property can't be read
|
||||
/// </summary>
|
||||
internal class DuckTypeReverseProxyPropertyCannotBeAbstractException : DuckTypeException
|
||||
{
|
||||
private DuckTypeReverseProxyPropertyCannotBeAbstractException(PropertyInfo property)
|
||||
: base($"The property '{property.Name}' cannot be abstract for reverse proxy")
|
||||
{
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(PropertyInfo property)
|
||||
{
|
||||
throw new DuckTypeReverseProxyPropertyCannotBeAbstractException(property);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DuckType method was [DuckReverseMethod] in non-reverse proxy
|
||||
/// </summary>
|
||||
internal class DuckTypeIncorrectReverseMethodUsageException : DuckTypeException
|
||||
{
|
||||
private DuckTypeIncorrectReverseMethodUsageException(MethodInfo method)
|
||||
: base($"The method '{method.Name}' was marked as a [DuckReverseMethod] but not doing reverse duck typing.")
|
||||
{
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(MethodInfo method)
|
||||
{
|
||||
throw new DuckTypeIncorrectReverseMethodUsageException(method);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DuckType property was [DuckReverseMethod] in non-reverse proxy
|
||||
/// </summary>
|
||||
internal class DuckTypeIncorrectReversePropertyUsageException : DuckTypeException
|
||||
{
|
||||
private DuckTypeIncorrectReversePropertyUsageException(PropertyInfo property)
|
||||
: base($"The property '{property.Name}' was marked as a [DuckReverseMethod] but not doing reverse duck typing.")
|
||||
{
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(PropertyInfo property)
|
||||
{
|
||||
throw new DuckTypeIncorrectReversePropertyUsageException(property);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DuckType proxy was missing an implementation
|
||||
/// </summary>
|
||||
internal class DuckTypeReverseProxyMissingPropertyImplementationException : DuckTypeException
|
||||
{
|
||||
private DuckTypeReverseProxyMissingPropertyImplementationException(IEnumerable<PropertyInfo> properties)
|
||||
: base($"The duck reverse proxy was missing implementations for properties: {string.Join(", ", properties.Select(x => x.Name))}")
|
||||
{
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(IEnumerable<PropertyInfo> properties)
|
||||
{
|
||||
throw new DuckTypeReverseProxyMissingPropertyImplementationException(properties);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DuckType proxy was missing an implementation
|
||||
/// </summary>
|
||||
internal class DuckTypeReverseProxyMissingMethodImplementationException : DuckTypeException
|
||||
{
|
||||
private DuckTypeReverseProxyMissingMethodImplementationException(IEnumerable<MethodInfo> methods)
|
||||
: base($"The duck reverse proxy was missing implementations for methods: {string.Join(", ", methods.Select(x => x.Name))}")
|
||||
{
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(IEnumerable<MethodInfo> methods)
|
||||
{
|
||||
throw new DuckTypeReverseProxyMissingMethodImplementationException(methods);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DuckType proxy tried to implement a generic method in a non-generic way
|
||||
/// </summary>
|
||||
internal class DuckTypeReverseAttributeParameterNamesMismatchException : DuckTypeException
|
||||
{
|
||||
private DuckTypeReverseAttributeParameterNamesMismatchException(MethodInfo method)
|
||||
: base($"The reverse duck attribute parameter names for method '{method.Name}' did not match the method's parameters ")
|
||||
{
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(MethodInfo method)
|
||||
{
|
||||
throw new DuckTypeReverseAttributeParameterNamesMismatchException(method);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DuckType proxy tried to implement a generic method in a non-generic way
|
||||
/// </summary>
|
||||
internal class DuckTypeReverseProxyMustImplementGenericMethodAsGenericException : DuckTypeException
|
||||
{
|
||||
private DuckTypeReverseProxyMustImplementGenericMethodAsGenericException(MethodInfo implementationMethod, MethodInfo targetMethod)
|
||||
: base($"The duck reverse proxy implementation '{implementationMethod.Name}' for generic target method '{targetMethod.Name}' " +
|
||||
$"must have same number of generic parameters - had {implementationMethod.GetGenericArguments().Length}, expected {targetMethod.GetGenericArguments().Length}")
|
||||
{
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void Throw(MethodInfo implementationMethod, MethodInfo targetMethod)
|
||||
{
|
||||
throw new DuckTypeReverseProxyMustImplementGenericMethodAsGenericException(implementationMethod, targetMethod);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
// </copyright>
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace OpenTelemetry.AutoInstrumentation.DuckTyping;
|
||||
|
|
@ -22,7 +23,7 @@ namespace OpenTelemetry.AutoInstrumentation.DuckTyping;
|
|||
/// <summary>
|
||||
/// Duck type extensions
|
||||
/// </summary>
|
||||
public static class DuckTypeExtensions
|
||||
internal static class DuckTypeExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the duck type instance for the object implementing a base class or interface T
|
||||
|
|
@ -59,14 +60,11 @@ public static class DuckTypeExtensions
|
|||
DuckTypeTargetObjectInstanceIsNull.Throw();
|
||||
}
|
||||
|
||||
if (DuckType.CreateCache<T>.IsVisible)
|
||||
DuckType.CreateTypeResult proxyResult = DuckType.CreateCache<T>.GetProxy(instance.GetType());
|
||||
if (proxyResult.Success)
|
||||
{
|
||||
DuckType.CreateTypeResult proxyResult = DuckType.CreateCache<T>.GetProxy(instance.GetType());
|
||||
if (proxyResult.Success)
|
||||
{
|
||||
value = proxyResult.CreateInstance<T>(instance);
|
||||
return true;
|
||||
}
|
||||
value = proxyResult.CreateInstance<T>(instance)!;
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
|
|
@ -88,7 +86,7 @@ public static class DuckTypeExtensions
|
|||
DuckTypeTargetObjectInstanceIsNull.Throw();
|
||||
}
|
||||
|
||||
if (targetType != null && (targetType.IsPublic || targetType.IsNestedPublic))
|
||||
if (targetType != null)
|
||||
{
|
||||
DuckType.CreateTypeResult proxyResult = DuckType.GetOrCreateProxyType(targetType, instance.GetType());
|
||||
if (proxyResult.Success)
|
||||
|
|
@ -117,13 +115,10 @@ public static class DuckTypeExtensions
|
|||
DuckTypeTargetObjectInstanceIsNull.Throw();
|
||||
}
|
||||
|
||||
if (DuckType.CreateCache<T>.IsVisible)
|
||||
DuckType.CreateTypeResult proxyResult = DuckType.CreateCache<T>.GetProxy(instance.GetType());
|
||||
if (proxyResult.Success)
|
||||
{
|
||||
DuckType.CreateTypeResult proxyResult = DuckType.CreateCache<T>.GetProxy(instance.GetType());
|
||||
if (proxyResult.Success)
|
||||
{
|
||||
return proxyResult.CreateInstance<T>(instance);
|
||||
}
|
||||
return proxyResult.CreateInstance<T>(instance);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
@ -143,7 +138,7 @@ public static class DuckTypeExtensions
|
|||
DuckTypeTargetObjectInstanceIsNull.Throw();
|
||||
}
|
||||
|
||||
if (targetType != null && (targetType.IsPublic || targetType.IsNestedPublic))
|
||||
if (targetType != null)
|
||||
{
|
||||
DuckType.CreateTypeResult proxyResult = DuckType.GetOrCreateProxyType(targetType, instance.GetType());
|
||||
if (proxyResult.Success)
|
||||
|
|
@ -169,12 +164,7 @@ public static class DuckTypeExtensions
|
|||
DuckTypeTargetObjectInstanceIsNull.Throw();
|
||||
}
|
||||
|
||||
if (DuckType.CreateCache<T>.IsVisible)
|
||||
{
|
||||
return DuckType.CanCreate<T>(instance);
|
||||
}
|
||||
|
||||
return false;
|
||||
return DuckType.CanCreate<T>(instance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -191,11 +181,53 @@ public static class DuckTypeExtensions
|
|||
DuckTypeTargetObjectInstanceIsNull.Throw();
|
||||
}
|
||||
|
||||
if (targetType != null && (targetType.IsPublic || targetType.IsNestedPublic))
|
||||
if (targetType != null)
|
||||
{
|
||||
return DuckType.CanCreate(targetType, instance);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or creates a proxy that implements/derives from <paramref name="typeToDeriveFrom"/>,
|
||||
/// and delegates implementations/overrides to <paramref name="instance"/>
|
||||
/// </summary>
|
||||
/// <param name="instance">The instance containing additional overrides/implementations</param>
|
||||
/// <param name="typeToDeriveFrom">The type to derive from</param>
|
||||
/// <returns>DuckType instance</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static object DuckImplement(this object instance, Type typeToDeriveFrom)
|
||||
=> DuckType.CreateReverse(typeToDeriveFrom, instance);
|
||||
|
||||
/// <summary>
|
||||
/// Tries to create a proxy that implements/derives from <paramref name="typeToDeriveFrom"/>,
|
||||
/// and delegates implementations/overrides to <paramref name="instance"/>
|
||||
/// ducktype the object implementing a base class or interface T
|
||||
/// </summary>
|
||||
/// <param name="instance">The instance containing additional overrides/implementations</param>
|
||||
/// <param name="typeToDeriveFrom">The type to derive from</param>
|
||||
/// <param name="value">The Ducktype instance</param>
|
||||
/// <returns>true if the object instance was ducktyped; otherwise, false.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool TryDuckImplement(this object instance, Type typeToDeriveFrom, out object value)
|
||||
{
|
||||
if (instance is null)
|
||||
{
|
||||
DuckTypeTargetObjectInstanceIsNull.Throw();
|
||||
}
|
||||
|
||||
if (typeToDeriveFrom != null)
|
||||
{
|
||||
DuckType.CreateTypeResult proxyResult = DuckType.GetOrCreateReverseProxyType(typeToDeriveFrom, instance.GetType());
|
||||
if (proxyResult.Success)
|
||||
{
|
||||
value = proxyResult.CreateInstance(instance);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,12 +15,15 @@
|
|||
// </copyright>
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace OpenTelemetry.AutoInstrumentation.DuckTyping;
|
||||
|
||||
/// <summary>
|
||||
/// Duck type interface
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public interface IDuckType
|
||||
{
|
||||
/// <summary>
|
||||
|
|
@ -32,4 +35,10 @@ public interface IDuckType
|
|||
/// Gets instance Type
|
||||
/// </summary>
|
||||
Type Type { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Calls ToString() on the instance
|
||||
/// </summary>
|
||||
/// <returns>ToString result</returns>
|
||||
string ToString();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,15 +25,16 @@ namespace OpenTelemetry.AutoInstrumentation.DuckTyping;
|
|||
/// <summary>
|
||||
/// Internal IL Helpers
|
||||
/// </summary>
|
||||
// ReSharper disable once InconsistentNaming
|
||||
internal static class ILHelpersExtensions
|
||||
{
|
||||
private static List<DynamicMethod> _dynamicMethods = new List<DynamicMethod>();
|
||||
private static readonly List<DynamicMethod> DynamicMethods = new();
|
||||
|
||||
internal static DynamicMethod GetDynamicMethodForIndex(int index)
|
||||
{
|
||||
lock (_dynamicMethods)
|
||||
lock (DynamicMethods)
|
||||
{
|
||||
return _dynamicMethods[index];
|
||||
return DynamicMethods[index];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -62,8 +63,14 @@ internal static class ILHelpersExtensions
|
|||
|
||||
methodBuilder.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed);
|
||||
|
||||
delType = delegateType.CreateTypeInfo().AsType();
|
||||
invokeMethod = delType.GetMethod("Invoke");
|
||||
var delegateTypeInfo = delegateType.CreateTypeInfo();
|
||||
if (delegateTypeInfo is null)
|
||||
{
|
||||
DuckTypeException.Throw($"Error creating the delegate type info for {delegateType.FullName}");
|
||||
}
|
||||
|
||||
delType = delegateTypeInfo.AsType();
|
||||
invokeMethod = delType.GetMethod("Invoke")!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -345,11 +352,49 @@ internal static class ILHelpersExtensions
|
|||
}
|
||||
else if (expectedUnderlyingType != typeof(object))
|
||||
{
|
||||
// WARNING: If the actual type cannot be cast to expectedUnderlyingType,
|
||||
// this will throw an exception at runtime when accessing the member
|
||||
il.Emit(OpCodes.Castclass, expectedUnderlyingType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WARNING: This method is a slim version of the WriteTypeConversion method without IL
|
||||
// Checks in both method must match! if you change either, you need to change both
|
||||
internal static void CheckTypeConversion(Type actualType, Type expectedType)
|
||||
{
|
||||
var actualUnderlyingType = actualType.IsEnum ? Enum.GetUnderlyingType(actualType) : actualType;
|
||||
var expectedUnderlyingType = expectedType.IsEnum ? Enum.GetUnderlyingType(expectedType) : expectedType;
|
||||
|
||||
if (actualUnderlyingType == expectedUnderlyingType)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (actualUnderlyingType.IsValueType)
|
||||
{
|
||||
if (expectedUnderlyingType.IsValueType)
|
||||
{
|
||||
// If both underlying types are value types then both must be of the same type.
|
||||
DuckTypeInvalidTypeConversionException.Throw(actualType, expectedType);
|
||||
}
|
||||
else if (expectedUnderlyingType != typeof(object) && !expectedUnderlyingType.IsAssignableFrom(actualUnderlyingType))
|
||||
{
|
||||
// If the expected type can't be assigned from the actual value type.
|
||||
// Means if the expected type is an interface the actual type doesn't implement it.
|
||||
// So no possible conversion or casting can be made here.
|
||||
DuckTypeInvalidTypeConversionException.Throw(actualType, expectedType);
|
||||
}
|
||||
}
|
||||
else if (expectedUnderlyingType.IsValueType)
|
||||
{
|
||||
if (actualUnderlyingType != typeof(object) && !actualUnderlyingType.IsAssignableFrom(expectedUnderlyingType))
|
||||
{
|
||||
DuckTypeInvalidTypeConversionException.Throw(actualType, expectedType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write a Call to a method using Calli
|
||||
/// </summary>
|
||||
|
|
@ -364,7 +409,7 @@ internal static class ILHelpersExtensions
|
|||
method.CallingConvention,
|
||||
method.ReturnType,
|
||||
method.GetParameters().Select(p => p.ParameterType).ToArray(),
|
||||
null);
|
||||
null!);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -375,25 +420,31 @@ internal static class ILHelpersExtensions
|
|||
/// <param name="proxyType">ProxyType builder</param>
|
||||
internal static void WriteDynamicMethodCall(this LazyILGenerator il, DynamicMethod dynamicMethod, TypeBuilder proxyType)
|
||||
{
|
||||
if (proxyType is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// We create a custom delegate inside the module builder
|
||||
CreateDelegateTypeFor(proxyType, dynamicMethod, out Type delegateType, out MethodInfo invokeMethod);
|
||||
int index;
|
||||
lock (_dynamicMethods)
|
||||
lock (DynamicMethods)
|
||||
{
|
||||
_dynamicMethods.Add(dynamicMethod);
|
||||
index = _dynamicMethods.Count - 1;
|
||||
DynamicMethods.Add(dynamicMethod);
|
||||
index = DynamicMethods.Count - 1;
|
||||
}
|
||||
|
||||
// We fill the DelegateCache<> for that custom type with the delegate instance
|
||||
MethodInfo fillDelegateMethodInfo = typeof(DuckType.DelegateCache<>).MakeGenericType(delegateType).GetMethod("FillDelegate", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
fillDelegateMethodInfo.Invoke(null, new object[] { index });
|
||||
var delegateCacheType = typeof(DuckType.DelegateCache<>).MakeGenericType(delegateType);
|
||||
MethodInfo fillDelegateMethodInfo = delegateCacheType.GetMethod("FillDelegate", BindingFlags.NonPublic | BindingFlags.Static)!;
|
||||
fillDelegateMethodInfo?.Invoke(null, new object[] { index });
|
||||
|
||||
// We get the delegate instance and load it in to the stack before the parameters (at the begining of the IL body)
|
||||
il.SetOffset(0);
|
||||
il.EmitCall(OpCodes.Call, typeof(DuckType.DelegateCache<>).MakeGenericType(delegateType).GetMethod("GetDelegate"), null);
|
||||
il.EmitCall(OpCodes.Call, delegateCacheType.GetMethod("GetDelegate")!, null!);
|
||||
il.ResetOffset();
|
||||
|
||||
// We emit the call to the delegate invoke method.
|
||||
il.EmitCall(OpCodes.Callvirt, invokeMethod, null);
|
||||
il.EmitCall(OpCodes.Callvirt, invokeMethod, null!);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,15 +14,14 @@
|
|||
// limitations under the License.
|
||||
// </copyright>
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTelemetry.AutoInstrumentation.DuckTyping;
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace System.Runtime.CompilerServices;
|
||||
|
||||
/// <summary>
|
||||
/// This attribute is recognized by the CLR and allow us to disable visibility checks for certain assemblies (only from 4.6+)
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
|
||||
public class IgnoresAccessChecksToAttribute : Attribute
|
||||
internal class IgnoresAccessChecksToAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IgnoresAccessChecksToAttribute"/> class.
|
||||
|
|
|
|||
|
|
@ -21,10 +21,11 @@ using System.Reflection.Emit;
|
|||
|
||||
namespace OpenTelemetry.AutoInstrumentation.DuckTyping;
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
internal class LazyILGenerator
|
||||
{
|
||||
private ILGenerator _generator;
|
||||
private List<Action<ILGenerator>> _instructions;
|
||||
private readonly ILGenerator _generator;
|
||||
private readonly List<Action<ILGenerator>> _instructions;
|
||||
private int _offset;
|
||||
|
||||
public LazyILGenerator(ILGenerator generator)
|
||||
|
|
@ -70,17 +71,17 @@ internal class LazyILGenerator
|
|||
|
||||
public LocalBuilder DeclareLocal(Type localType, bool pinned)
|
||||
{
|
||||
return _generator.DeclareLocal(localType, pinned);
|
||||
return _generator?.DeclareLocal(localType, pinned);
|
||||
}
|
||||
|
||||
public LocalBuilder DeclareLocal(Type localType)
|
||||
{
|
||||
return _generator.DeclareLocal(localType);
|
||||
return _generator?.DeclareLocal(localType);
|
||||
}
|
||||
|
||||
public Label DefineLabel()
|
||||
{
|
||||
return _generator.DefineLabel();
|
||||
return _generator?.DefineLabel() ?? default;
|
||||
}
|
||||
|
||||
public void Emit(OpCode opcode, string str)
|
||||
|
|
@ -449,9 +450,12 @@ internal class LazyILGenerator
|
|||
|
||||
public void Flush()
|
||||
{
|
||||
foreach (Action<ILGenerator> instr in _instructions)
|
||||
if (_generator is not null)
|
||||
{
|
||||
instr(_generator);
|
||||
foreach (Action<ILGenerator> instruction in _instructions)
|
||||
{
|
||||
instruction(_generator);
|
||||
}
|
||||
}
|
||||
|
||||
_instructions.Clear();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,182 @@
|
|||
// <copyright file="System.Diagnostics.CodeAnalysis.Attributes.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// https://github.com/dotnet/runtime/blob/bffa7cf52b3982597adc5447c25e7aaa3b063c1c/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/NullableAttributes.cs
|
||||
|
||||
// This file contains attributes from the System.Diagnostics.CodeAnalysis namespace
|
||||
// used by the compiler for null-state static analysis.
|
||||
// This is a C# feature, but requires these attributes to be defined,
|
||||
// so we define them here for older .NET runtimes.
|
||||
// https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/attributes/nullable-analysis
|
||||
|
||||
#pragma warning disable SA1649 // file name should match first type name
|
||||
#pragma warning disable SA1402 // file may only contain a single type
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace System.Diagnostics.CodeAnalysis;
|
||||
|
||||
#if !NETCOREAPP3_0_OR_GREATER
|
||||
/// <summary>Specifies that null is allowed as an input even if the corresponding type disallows it.</summary>
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property)]
|
||||
internal sealed class AllowNullAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Specifies that null is disallowed as an input even if the corresponding type allows it.</summary>
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property)]
|
||||
internal sealed class DisallowNullAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Specifies that an output may be null even if the corresponding type disallows it.</summary>
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue)]
|
||||
internal sealed class MaybeNullAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Specifies that an output will not be null even if the corresponding type allows it. Specifies that an input argument was not null when the call returns.</summary>
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue)]
|
||||
internal sealed class NotNullAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Specifies that when a method returns <see cref="ReturnValue"/>, the parameter may be null even if the corresponding type disallows it.</summary>
|
||||
[AttributeUsage(AttributeTargets.Parameter)]
|
||||
internal sealed class MaybeNullWhenAttribute : Attribute
|
||||
{
|
||||
/// <summary>Initializes a new instance of the <see cref="MaybeNullWhenAttribute"/> class with the specified return value condition.</summary>
|
||||
/// <param name="returnValue">
|
||||
/// The return value condition. If the method returns this value, the associated parameter may be null.
|
||||
/// </param>
|
||||
public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
|
||||
|
||||
/// <summary>Gets a value indicating whether the associated parameter may be null.</summary>
|
||||
public bool ReturnValue { get; }
|
||||
}
|
||||
|
||||
/// <summary>Specifies that when a method returns <see cref="ReturnValue"/>, the parameter will not be null even if the corresponding type allows it.</summary>
|
||||
[AttributeUsage(AttributeTargets.Parameter)]
|
||||
internal sealed class NotNullWhenAttribute : Attribute
|
||||
{
|
||||
/// <summary>Initializes a new instance of the <see cref="NotNullWhenAttribute"/> class with the specified return value condition.</summary>
|
||||
/// <param name="returnValue">
|
||||
/// The return value condition. If the method returns this value, the associated parameter will not be null.
|
||||
/// </param>
|
||||
public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
|
||||
|
||||
/// <summary>Gets a value indicating whether the associated parameter will not be null.</summary>
|
||||
public bool ReturnValue { get; }
|
||||
}
|
||||
|
||||
/// <summary>Specifies that the output will be non-null if the named parameter is non-null.</summary>
|
||||
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true)]
|
||||
internal sealed class NotNullIfNotNullAttribute : Attribute
|
||||
{
|
||||
/// <summary>Initializes a new instance of the <see cref="NotNullIfNotNullAttribute"/> class with the associated parameter name.</summary>
|
||||
/// <param name="parameterName">
|
||||
/// The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null.
|
||||
/// </param>
|
||||
public NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName;
|
||||
|
||||
/// <summary>Gets the associated parameter name.</summary>
|
||||
public string ParameterName { get; }
|
||||
}
|
||||
|
||||
/// <summary>Applied to a method that will never return under any circumstance.</summary>
|
||||
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
|
||||
internal sealed class DoesNotReturnAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Specifies that the method will not return if the associated Boolean parameter is passed the specified value.</summary>
|
||||
[AttributeUsage(AttributeTargets.Parameter)]
|
||||
internal sealed class DoesNotReturnIfAttribute : Attribute
|
||||
{
|
||||
/// <summary>Initializes a new instance of the <see cref="DoesNotReturnIfAttribute"/> class with the specified parameter value.</summary>
|
||||
/// <param name="parameterValue">
|
||||
/// The condition parameter value. Code after the method will be considered unreachable by diagnostics if the argument to
|
||||
/// the associated parameter matches this value.
|
||||
/// </param>
|
||||
public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue;
|
||||
|
||||
/// <summary>Gets a value indicating whether the method will not return if the associated Boolean parameter is passed the specified value.</summary>
|
||||
public bool ParameterValue { get; }
|
||||
}
|
||||
|
||||
/// <summary>Specifies that the method or property will ensure that the listed field and property members have not-null values.</summary>
|
||||
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
|
||||
internal sealed class MemberNotNullAttribute : Attribute
|
||||
{
|
||||
/// <summary>Initializes a new instance of the <see cref="MemberNotNullAttribute"/> class with a field or property member.</summary>
|
||||
/// <param name="member">
|
||||
/// The field or property member that is promised to be not-null.
|
||||
/// </param>
|
||||
public MemberNotNullAttribute(string member) => Members = new[] { member };
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="MemberNotNullAttribute"/> class with the list of field and property members.</summary>
|
||||
/// <param name="members">
|
||||
/// The list of field and property members that are promised to be not-null.
|
||||
/// </param>
|
||||
public MemberNotNullAttribute(params string[] members) => Members = members;
|
||||
|
||||
/// <summary>Gets field or property member names.</summary>
|
||||
public string[] Members { get; }
|
||||
}
|
||||
#endif
|
||||
#if !NET5_0_OR_GREATER
|
||||
|
||||
/// <summary>Specifies that the method or property will ensure that the listed field and property members have not-null values when returning with the specified return value condition.</summary>
|
||||
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
|
||||
internal sealed class MemberNotNullWhenAttribute : Attribute
|
||||
{
|
||||
/// <summary>Initializes a new instance of the <see cref="MemberNotNullWhenAttribute"/> class with the specified return value condition and a field or property member.</summary>
|
||||
/// <param name="returnValue">
|
||||
/// The return value condition. If the method returns this value, the associated parameter will not be null.
|
||||
/// </param>
|
||||
/// <param name="member">
|
||||
/// The field or property member that is promised to be not-null.
|
||||
/// </param>
|
||||
public MemberNotNullWhenAttribute(bool returnValue, string member)
|
||||
{
|
||||
ReturnValue = returnValue;
|
||||
Members = new[] { member };
|
||||
}
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="MemberNotNullWhenAttribute"/> class with the specified return value condition and list of field and property members.</summary>
|
||||
/// <param name="returnValue">
|
||||
/// The return value condition. If the method returns this value, the associated parameter will not be null.
|
||||
/// </param>
|
||||
/// <param name="members">
|
||||
/// The list of field and property members that are promised to be not-null.
|
||||
/// </param>
|
||||
public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
|
||||
{
|
||||
ReturnValue = returnValue;
|
||||
Members = members;
|
||||
}
|
||||
|
||||
/// <summary>Gets a value indicating whether the return value will be null or not.</summary>
|
||||
public bool ReturnValue { get; }
|
||||
|
||||
/// <summary>Gets field or property member names.</summary>
|
||||
public string[] Members { get; }
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma warning restore SA1402
|
||||
#pragma warning restore SA1649
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
// <copyright file="ThrowHelper.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace OpenTelemetry.AutoInstrumentation.Util;
|
||||
|
||||
internal class ThrowHelper
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void ThrowArgumentNullException(string paramName) => throw new ArgumentNullException(paramName);
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void ThrowArgumentOutOfRangeException(string paramName) => throw new ArgumentOutOfRangeException(paramName);
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void ThrowArgumentOutOfRangeException(string paramName, string message) => throw new ArgumentOutOfRangeException(paramName, message);
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void ThrowArgumentOutOfRangeException(string paramName, object actualValue, string message) => throw new ArgumentOutOfRangeException(paramName, actualValue, message);
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void ThrowArgumentException(string message) => throw new ArgumentException(message);
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void ThrowArgumentException(string message, string paramName) => throw new ArgumentException(message, paramName);
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void ThrowInvalidOperationException(string message) => throw new InvalidOperationException(message);
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void ThrowException(string message) => throw new Exception(message);
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void ThrowInvalidCastException(string message) => throw new InvalidCastException(message);
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void ThrowNotSupportedException(string message) => throw new NotSupportedException(message);
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void ThrowKeyNotFoundException(string message) => throw new KeyNotFoundException(message);
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
[DebuggerHidden]
|
||||
[DoesNotReturn]
|
||||
internal static void ThrowNullReferenceException(string message) => throw new NullReferenceException(message);
|
||||
}
|
||||
Loading…
Reference in New Issue