DuplicateVariable() static private method

ArgumentException with message like "Found duplicate parameter '{0}'. Each ParameterExpression in the list must be a unique object."
static private DuplicateVariable ( object p0, string paramName ) : Exception
p0 object
paramName string
return System.Exception
        // 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));
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        // 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);
                    }
                }
            }
        }
Beispiel #8
0
        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);
            }
        }