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) =>
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); }
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); }
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); }