Ejemplo n.º 1
0
        public override bool TryEvaluate(
            Type sourceType,
            string operationName,
            ParameterInfo asyncParameter,
            ParameterInfo syncParameter,
            UniqueIdentifierBuilder identifierBuilder, [NotNullWhen(true)] out ParameterPair?result)
        {
            result = null;

            var asyncParamType = asyncParameter.ParameterType;
            var syncParamType  = syncParameter.ParameterType;

            if (!TypeHelper.IsIntegratedNumericType(asyncParamType) &&
                !TypeHelper.IsNullableIntegratedNumericType(asyncParamType))
            {
                return(false);
            }

            if (!TypeHelper.IsIntegratedNumericType(syncParamType) &&
                !TypeHelper.IsNullableIntegratedNumericType(syncParamType))
            {
                return(false);
            }

            identifierBuilder.WithParameter(asyncParameter.Name !);

            var syncParamDefinition = Parameter.Default(syncParameter.Name !, async(writer, variableName) =>
            {
                await writer.WriteLineAsync($"            var {variableName} = 5;").ConfigureAwait(false);
            });

            Parameter asyncParamDefinition;

            // We only need a single variable definition
            if (asyncParamType == syncParamType)
            {
                asyncParamDefinition = syncParamDefinition;
                syncParamDefinition  = Parameter.Default(asyncParamDefinition.Name);
            }
            else
            {
                asyncParamDefinition = Parameter.Default(asyncParameter.Name !, "async", async(writer, variableName) =>
                {
                    await writer.WriteLineAsync($"            var {variableName} = 5;").ConfigureAwait(false);
                });
            }

            result = new ParameterPair(asyncParamDefinition, syncParamDefinition);
            return(true);
        }
        public ParameterListPair BuildParameters(
            Type sourceType,
            MethodInfo asyncMethod,
            MethodInfo syncMethod,
            UniqueIdentifierBuilder identifierBuilder)
        {
            Debug.Assert(sourceType is not null);
            Debug.Assert(asyncMethod is not null);
            Debug.Assert(syncMethod is not null);
            Debug.Assert(identifierBuilder is not null);

            var operationName   = OperationNameHelper.GetOperationName(asyncMethod);
            var asyncParameters = asyncMethod.GetParameters();
            var syncParameters  = syncMethod.GetParameters();

            Debug.Assert(asyncParameters.Length == syncParameters.Length ||
                         asyncParameters.Length == syncParameters.Length + 1 &&
                         asyncParameters[^ 1].ParameterType == typeof(CancellationToken));

            var asyncParametersBuilder = ImmutableList.CreateBuilder <Parameter>();
            var syncParametersBuilder  = ImmutableList.CreateBuilder <Parameter>();

            for (var i = 0; i < syncParameters.Length; i++)
            {
                var asyncParameter = asyncParameters[i];
                var syncParameter  = syncParameters[i];

                var(constructedAsyncParam, constructedSyncParam) = BuildParameter(
                    sourceType,
                    operationName,
                    asyncParameter,
                    syncParameter,
                    identifierBuilder);

                asyncParametersBuilder.Add(constructedAsyncParam);
                syncParametersBuilder.Add(constructedSyncParam);
            }

            if (asyncParameters.Length == syncParameters.Length + 1 &&
                asyncParameters[^ 1].ParameterType == typeof(CancellationToken))
            {
                asyncParametersBuilder.Add(Parameter.Default(asyncParameters[^ 1].Name !, async(writer, variableName) =>
Ejemplo n.º 3
0
 public abstract bool TryEvaluate(
     Type sourceType,
     string operationName,
     ParameterInfo asyncParameter,
     ParameterInfo syncParameter,
     UniqueIdentifierBuilder identifierBuilder, [NotNullWhen(true)] out ParameterPair?result);
        public override bool TryEvaluate(
            Type sourceType,
            string operationName,
            ParameterInfo asyncParameter,
            ParameterInfo syncParameter,
            UniqueIdentifierBuilder identifierBuilder, [NotNullWhen(true)] out ParameterPair?result)
        {
            result = null;

            var asyncParamType = asyncParameter.ParameterType;
            var syncParamType  = syncParameter.ParameterType;

            if (!TypeHelper.IsEqualityComparerType(asyncParamType, out var asyncComparisonType))
            {
                return(false);
            }

            if (!TypeHelper.IsEqualityComparerType(syncParamType, out var syncComparisonType))
            {
                return(false);
            }

            identifierBuilder.WithParameter(asyncParameter.Name !);

            Parameter asyncParamDefinition, syncParamDefinition;

            if (syncComparisonType == typeof(string))
            {
                syncParamDefinition = Parameter.Default(syncParameter.Name !, async(writer, variableName) =>
                {
                    await writer.WriteLineAsync($"            var {variableName} = StringComparer.Ordinal;").ConfigureAwait(false);
                });
            }
            else
            {
                syncParamDefinition = Parameter.Default(syncParameter.Name !, async(writer, variableName) =>
                {
                    await writer.WriteLineAsync($"            var {variableName} = EqualityComparer<{TypeHelper.FormatCSharpTypeName(syncComparisonType, KnownNamespaces.Namespaces)}>.Default;").ConfigureAwait(false);
                });
            }

            // We only need a single variable definition
            if (string.Equals(asyncParameter.Name, syncParameter.Name, StringComparison.Ordinal) &&
                asyncComparisonType == syncComparisonType)
            {
                asyncParamDefinition = syncParamDefinition;
                syncParamDefinition  = Parameter.Default(syncParamDefinition.Name);
            }
            else if (asyncComparisonType == typeof(string))
            {
                asyncParamDefinition = Parameter.Default(asyncParameter.Name !, async(writer, variableName) =>
                {
                    await writer.WriteLineAsync($"            var {variableName} = StringComparer.Ordinal;").ConfigureAwait(false);
                });
            }
            else
            {
                asyncParamDefinition = Parameter.Default(asyncParameter.Name !, async(writer, variableName) =>
                {
                    await writer.WriteLineAsync($"            var {variableName} = EqualityComparer<{TypeHelper.FormatCSharpTypeName(asyncComparisonType, KnownNamespaces.Namespaces)}>.Default;").ConfigureAwait(false);
                });
            }

            result = new ParameterPair(asyncParamDefinition, syncParamDefinition);
            return(true);
        }
Ejemplo n.º 5
0
        public override bool TryEvaluate(
            Type sourceType,
            string operationName,
            ParameterInfo asyncParameter,
            ParameterInfo syncParameter,
            UniqueIdentifierBuilder identifierBuilder, [NotNullWhen(true)] out ParameterPair?result)
        {
            result = null;

            var asyncParamType = asyncParameter.ParameterType;
            var syncParamType  = syncParameter.ParameterType;

            var  asyncParameterIsExpression = true;
            var  syncParameterIsExpression = true;
            Type?asyncDelegateType, syncDelegateType;

            if (TypeHelper.IsDelegate(asyncParamType))
            {
                asyncDelegateType          = asyncParamType;
                asyncParameterIsExpression = false;
            }
            else if (!TypeHelper.IsLambdaExpression(asyncParamType, out asyncDelegateType))
            {
                return(false);
            }

            if (TypeHelper.IsDelegate(syncParamType))
            {
                syncDelegateType          = syncParamType;
                syncParameterIsExpression = false;
            }
            else if (!TypeHelper.IsLambdaExpression(syncParamType, out syncDelegateType))
            {
                return(false);
            }

            var singleDefinition = asyncDelegateType == syncDelegateType && asyncParameterIsExpression == syncParameterIsExpression;

            if (!TryConstructDelegateOrLambdaExpression(
                    sourceType,
                    syncDelegateType,
                    prefix: null,
                    syncParameterIsExpression,
                    syncParameter.Name !,
                    operationName,
                    singleDefinition ? identifierBuilder : null,
                    out var syncParamDefinition))
            {
                return(false);
            }

            Parameter?asyncParamDefinition;

            // We only need a single variable definition
            if (singleDefinition)
            {
                asyncParamDefinition = syncParamDefinition;
                syncParamDefinition  = Parameter.Default(asyncParamDefinition.Name);
            }
            else if (!TryConstructDelegateOrLambdaExpression(
                         sourceType,
                         asyncDelegateType,
                         prefix: "async",
                         asyncParameterIsExpression,
                         asyncParameter.Name !,
                         operationName,
                         identifierBuilder,
                         out asyncParamDefinition))
            {
                return(false);
            }

            result = new ParameterPair(asyncParamDefinition, syncParamDefinition);
            return(true);
        }
Ejemplo n.º 6
0
        public override bool TryEvaluate(
            Type sourceType,
            string operationName,
            ParameterInfo asyncParameter,
            ParameterInfo syncParameter,
            UniqueIdentifierBuilder identifierBuilder, [NotNullWhen(true)] out ParameterPair?result)
        {
            result = null;

            var asyncParamType = asyncParameter.ParameterType;
            var syncParamType  = syncParameter.ParameterType;

            int?limit = null;

            // Limit the source of Single and SingleOrDefault operations, but only if there is not predicate
            if (string.Equals(operationName, "Single", StringComparison.Ordinal) ||
                string.Equals(operationName, "SingleOrDefault", StringComparison.Ordinal))
            {
                // Use the sync method, here as the async method can have a cancellation-token
                if ((syncParameter.Member as MethodInfo) !.GetParameters().Length == 1)
                {
                    limit = 1;
                }
            }

            if (TryEvaluateKnownType(
                    operationName,
                    asyncParamType,
                    syncParamType,
                    asyncParameter.Name !,
                    syncParameter.Name !,
                    identifierBuilder,
                    transform: null,
                    limit,
                    out result))
            {
                return(true);
            }

            if (typeof(IAsyncQueryable <object>).IsAssignableTo(asyncParamType) &&
                typeof(IQueryable <object>).IsAssignableTo(syncParamType))
            {
                if (string.Equals(operationName, "OfType", StringComparison.Ordinal))
                {
                    if (!string.Equals(asyncParameter.Name, "source", StringComparison.Ordinal))
                    {
                        identifierBuilder.WithParameter(asyncParameter.Name !);
                    }

                    var knownPrimitiveCollectionTypes = KnownCollectionTypes.CollectionTypes.ToArray();

                    var asyncParamDefinition = Parameter.Default(asyncParameter.Name !, "async", async(writer, variableName) =>
                    {
                        for (var i = 0; i < knownPrimitiveCollectionTypes.Length; i++)
                        {
                            await writer.WriteLineAsync($"            var {variableName}Part{i + 1} = queryAdapter.GetAsyncQueryable<{TypeHelper.FormatCSharpTypeName(knownPrimitiveCollectionTypes[i], KnownNamespaces.Namespaces)}>().Select(p => (object)p);").ConfigureAwait(false);
                        }

                        await writer.WriteAsync($"            var {variableName} = ").ConfigureAwait(false);

                        for (var i = 0; i < knownPrimitiveCollectionTypes.Length; i++)
                        {
                            if (i == 0)
                            {
                                await writer.WriteAsync($"{variableName}Part{i + 1}").ConfigureAwait(false);
                            }
                            else
                            {
                                await writer.WriteAsync($".Concat({variableName}Part{i + 1})").ConfigureAwait(false);
                            }
                        }

                        await writer.WriteLineAsync($";").ConfigureAwait(false);
                    });

                    var syncParamDefinition = Parameter.Default(syncParameter.Name !, async(writer, variableName) =>
                    {
                        for (var i = 0; i < knownPrimitiveCollectionTypes.Length; i++)
                        {
                            await writer.WriteLineAsync($"            var {variableName}Part{i + 1} = GetQueryable<{TypeHelper.FormatCSharpTypeName(knownPrimitiveCollectionTypes[i], KnownNamespaces.Namespaces)}>().Select(p => (object)p);").ConfigureAwait(false);
                        }

                        await writer.WriteAsync($"            var {variableName} = ").ConfigureAwait(false);

                        for (var i = 0; i < knownPrimitiveCollectionTypes.Length; i++)
                        {
                            if (i == 0)
                            {
                                await writer.WriteAsync($"{variableName}Part{i + 1}").ConfigureAwait(false);
                            }
                            else
                            {
                                await writer.WriteAsync($".Concat({variableName}Part{i + 1})").ConfigureAwait(false);
                            }
                        }

                        await writer.WriteLineAsync($";").ConfigureAwait(false);
                    });

                    result = new ParameterPair(asyncParamDefinition, syncParamDefinition);
                    return(true);
                }
                else if (string.Equals(operationName, "Cast", StringComparison.Ordinal))
                {
                    // Only include the type of collection that is casted to, to prevent exceptions
                    var asyncResultType = (asyncParameter.Member as MethodInfo) !.ReturnType;
                    var syncResultType  = (syncParameter.Member as MethodInfo) !.ReturnType;

                    if (TryEvaluateKnownType(
                            operationName,
                            asyncResultType,
                            syncResultType,
                            asyncParameter.Name !,
                            syncParameter.Name !,
                            identifierBuilder: null,
                            transform: "p => (object)p",
                            limit: null,
                            out result))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }