static private DuplicateVariable ( object p0, string paramName ) : |
||
p0 | object | |
paramName | string | |
return |
// Checks that all variables are non-null, not byref, and unique. internal static void ValidateVariables(ReadOnlyCollection <ParameterExpression> varList, string collectionName) { if (varList.Count == 0) { return; } int count = varList.Count; var set = new Set <ParameterExpression>(count); for (int i = 0; i < count; i++) { ParameterExpression v = varList[i]; if (v == null) { throw new ArgumentNullException(string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0}[{1}]", collectionName, set.Count)); } if (v.IsByRef) { throw Error.VariableMustNotBeByRef(v, v.Type); } if (set.Contains(v)) { throw Error.DuplicateVariable(v); } set.Add(v); } }
/// <summary> /// Creates a <see cref="ForCSharpStatement"/> that represents a for loop. /// </summary> /// <param name="variables">The variables in scope of the loop.</param> /// <param name="initializers">The loop initializers.</param> /// <param name="test">The condition of the loop.</param> /// <param name="iterators">The loop iterators.</param> /// <param name="body">The body of the loop.</param> /// <param name="break">The break target used by the loop body.</param> /// <param name="continue">The continue target used by the loop body.</param> /// <returns>The created <see cref="ForCSharpStatement"/>.</returns> public static ForCSharpStatement For(IEnumerable <ParameterExpression> variables, IEnumerable <Expression> initializers, Expression test, IEnumerable <Expression> iterators, Expression body, LabelTarget @break, LabelTarget @continue) { ValidateLoop(test, body, @break, @continue, optionalTest: true); // NB: While C# requires all initializers to be of the same type, we don't quite need that restriction here. // This can be revisited. We will check whether all initializers are simple assignments though. var variableList = variables.ToReadOnly(); var initializerList = initializers.ToReadOnly <Expression>(); RequiresNotNullItems(initializerList, nameof(initializers)); var uniqueVariables = new HashSet <ParameterExpression>(); foreach (var variable in variableList) { if (!uniqueVariables.Add(variable)) { throw LinqError.DuplicateVariable(variable); } } var iteratorList = iterators.ToReadOnly(); RequiresNotNullItems(iteratorList, nameof(iterators)); return(ForCSharpStatement.Make(variableList, initializerList, test, iteratorList, body, @break, @continue)); }
/// <summary> /// Creates a <see cref="ForCSharpStatement"/> that represents a for loop. /// </summary> /// <param name="initializers">The loop initializers.</param> /// <param name="test">The condition of the loop.</param> /// <param name="iterators">The loop iterators.</param> /// <param name="body">The body of the loop.</param> /// <param name="break">The break target used by the loop body.</param> /// <param name="continue">The continue target used by the loop body.</param> /// <returns>The created <see cref="ForCSharpStatement"/>.</returns> public static ForCSharpStatement For(IEnumerable <BinaryExpression> initializers, Expression test, IEnumerable <Expression> iterators, Expression body, LabelTarget @break, LabelTarget @continue) { ValidateLoop(test, body, @break, @continue, optionalTest: true); // NB: While C# requires all initializers to be of the same type, we don't quite need that restriction here. // This can be revisited. We will check whether all initializers are simple assignments though. var initializerList = initializers.ToReadOnly <Expression>(); var uniqueVariables = new HashSet <ParameterExpression>(); var variables = new List <ParameterExpression>(); foreach (BinaryExpression initializer in initializerList) { if (initializer.NodeType != ExpressionType.Assign || initializer.Left.NodeType != ExpressionType.Parameter) { throw Error.InvalidInitializer(); } var variable = (ParameterExpression)initializer.Left; if (!uniqueVariables.Add(variable)) { throw LinqError.DuplicateVariable(variable); } // NB: We keep them in the order specified and don't rely on the hash set. variables.Add(variable); } var variableList = variables.ToReadOnly(); var iteratorList = iterators.ToReadOnly(); return(ForCSharpStatement.Make(variableList, initializerList, test, iteratorList, body, @break, @continue)); }
/// <summary> /// Creates a <see cref="BlockCSharpExpression"/> that represents a block. /// </summary> /// <param name="variables">The variables declared in the block.</param> /// <param name="statements">The statements in the block.</param> /// <param name="returnLabel">The return label used to exist the block.</param> /// <returns>The created <see cref="BlockCSharpExpression"/>.</returns> public static BlockCSharpExpression Block(IEnumerable <ParameterExpression> variables, IEnumerable <Expression> statements, LabelTarget returnLabel) { var variablesList = variables.ToReadOnly(); var uniqueVariables = new HashSet <ParameterExpression>(); foreach (var variable in variablesList) { if (!uniqueVariables.Add(variable)) { throw LinqError.DuplicateVariable(variable); } } var statementsList = statements.ToReadOnly(); RequiresNotNullItems(statementsList, nameof(statements)); return(new BlockCSharpExpression(variablesList, statementsList, returnLabel)); }
public static AsyncLambdaCSharpExpression AsyncLambda(Expression body, IEnumerable <ParameterExpression> parameters) { ContractUtils.RequiresNotNull(body, nameof(body)); var parameterList = parameters.ToReadOnly(); var count = parameterList.Count; var types = new Type[count + 1]; if (count > 0) { var set = new Set <ParameterExpression>(count); for (var i = 0; i < count; i++) { var parameter = parameterList[i]; ValidateAsyncParameter(parameter); types[i] = parameter.Type; if (set.Contains(parameter)) { throw LinqError.DuplicateVariable(parameter); } set.Add(parameter); } } if (body.Type == typeof(void)) { types[count] = typeof(Task); // REVIEW: OK to default to Task? } else { types[count] = typeof(Task <>).MakeGenericType(body.Type); } return(CreateAsyncLambda(DelegateHelpers.MakeDelegateType(types), body, parameterList)); }
internal static ReadOnlyCollection <ParameterExpression> CheckUniqueVariables(IEnumerable <ParameterExpression> variables, string paramName) { var variablesList = variables.ToReadOnly(); if (variablesList.Count > 0) { RequiresNotNullItems(variablesList, paramName); var uniqueVariables = new HashSet <ParameterExpression>(variablesList.Count); foreach (var variable in variablesList) { if (!uniqueVariables.Add(variable)) { throw LinqError.DuplicateVariable(variable); } } } return(variablesList); }
// Checks that all variables are non-null, not byref, and unique. internal static void ValidateVariables(ReadOnlyCollection <ParameterExpression> varList, string collectionName) { int count = varList.Count; if (count != 0) { var set = new HashSet <ParameterExpression>(); for (int i = 0; i < count; i++) { ParameterExpression v = varList[i]; ContractUtils.RequiresNotNull(v, collectionName, i); if (v.IsByRef) { throw Error.VariableMustNotBeByRef(v, v.Type, collectionName, i); } if (!set.Add(v)) { throw Error.DuplicateVariable(v, collectionName, i); } } } }
private static void ValidateAsyncLambdaArgs(Type delegateType, ref Expression body, ReadOnlyCollection <ParameterExpression> parameters) { //ContractUtils.RequiresNotNull(delegateType, nameof(delegateType)); //TODO: Verify //RequiresCanRead(body, nameof(body)); if (!typeof(MulticastDelegate).IsAssignableFrom(delegateType) || delegateType == typeof(MulticastDelegate)) { throw LinqError.LambdaTypeMustBeDerivedFromSystemDelegate(); } var count = parameters.Count; var method = delegateType.GetMethod("Invoke"); // TODO: use cache from LINQ var parametersCached = method.GetParametersCached(); if (parametersCached.Length != 0) { if (parametersCached.Length != count) { throw LinqError.IncorrectNumberOfLambdaDeclarationParameters(); } var set = new Set <ParameterExpression>(count); for (var i = 0; i < count; i++) { var parameter = parameters[i]; ValidateAsyncParameter(parameter); var parameterType = parametersCached[i].ParameterType; if (!TypeUtils1.AreReferenceAssignable(parameter.Type, parameterType)) { throw LinqError.ParameterExpressionNotValidAsDelegate(parameter.Type, parameterType); } if (set.Contains(parameter)) { throw LinqError.DuplicateVariable(parameter); } set.Add(parameter); } } else if (count > 0) { throw LinqError.IncorrectNumberOfLambdaDeclarationParameters(); } var returnType = method.ReturnType; if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task <>)) { var resultType = returnType.GetGenericArguments()[0]; if (!TypeUtils1.AreReferenceAssignable(resultType, body.Type) && !TryQuote(resultType, ref body)) { throw LinqError.ExpressionTypeDoesNotMatchReturn(body.Type, method.ReturnType); } } else if (returnType != typeof(void) && returnType != typeof(Task)) { throw Error.AsyncLambdaInvalidReturnType(returnType); } }