public CSharpSetMemberBinder (CSharpBinderFlags flags, string name, Type callingContext, IEnumerable<CSharpArgumentInfo> argumentInfo)
			: base (name, false)
		{
			this.flags = flags;
			this.callingContext = callingContext;
			this.argumentInfo = argumentInfo.ToReadOnly ();
		}
Exemple #2
0
 public void LoadProvinces(IEnumerable<Province> provinces)
 {
     Provinces = provinces.ToReadOnly();
     SeaProvinces = Provinces.OfType<SeaProvince>().ToReadOnly();
     LandProvinces = Provinces.OfType<LandProvince>().ToReadOnly();
     ProvincePicker.Initialize(Provinces.First().Zones.First());
 }
 public ClientJoinExpression(ProjectionExpression projection, IEnumerable<Expression> outerKey, IEnumerable<Expression> innerKey)
     : base(DbExpressionType.ClientJoin, projection.Type)
 {
     this.outerKey = outerKey.ToReadOnly();
     this.innerKey = innerKey.ToReadOnly();
     this.projection = projection;
 }
		public CSharpInvokeBinder (CSharpBinderFlags flags, Type callingContext, IEnumerable<CSharpArgumentInfo> argumentInfo)
			: base (CSharpArgumentInfo.CreateCallInfo (argumentInfo, 1))
		{
			this.flags = flags;
			this.callingContext = callingContext;
			this.argumentInfo = argumentInfo.ToReadOnly ();
		}
 public UpdateCommandExpression(IdentifiableExpression identifiable, Expression where, IEnumerable<FieldAssignment> assignments)
     : base(DbExpressionType.Update, typeof(int))
 {
     this.identifiable = identifiable;
     this.where = where;
     this.assignments = assignments.ToReadOnly();
 }
        public static SwitchExpression Switch(Expression value, LabelTarget label, IEnumerable<SwitchCase> cases) {
            RequiresCanRead(value, "value");
            ContractUtils.Requires(value.Type == typeof(int), "value", Strings.ValueMustBeInt);
            ContractUtils.RequiresNotNull(cases, "cases");
            var caseList = cases.ToReadOnly();
            ContractUtils.RequiresNotEmpty(caseList, "cases");
            ContractUtils.RequiresNotNullItems(caseList, "cases");
            // TODO: does it make sense for switch to have non-void type?
            ContractUtils.Requires(label == null || label.Type == typeof(void), "label", Strings.LabelTypeMustBeVoid);

            bool @default = false;
            int max = Int32.MinValue;
            int min = Int32.MaxValue;
            foreach (SwitchCase sc in caseList) {
                if (sc.IsDefault) {
                    ContractUtils.Requires(@default == false, "cases", Strings.OnlyDefaultIsAllowed);
                    @default = true;
                } else {
                    int val = sc.Value;
                    if (val > max) max = val;
                    if (val < min) min = val;
                }
            }

            ContractUtils.Requires(UniqueCaseValues(caseList, min, max), "cases", Strings.CaseValuesMustBeUnique);

            return new SwitchExpression(value, label, caseList);
        }
 public static Expression VariableDictionary(IEnumerable<ParameterExpression> variables) {
     var vars = variables.ToReadOnly();
     return Expression.New(
         typeof(LocalsDictionary).GetConstructor(new[] { typeof(IRuntimeVariables), typeof(SymbolId[]) }),
         Expression.RuntimeVariables(vars),
         AstUtils.Constant(vars.Map(v => SymbolTable.StringToIdOrEmpty(v.Name)))
     );
 }
		public CSharpInvokeMemberBinder (CSharpBinderFlags flags, string name, Type callingContext, IEnumerable<Type> typeArguments, IEnumerable<CSharpArgumentInfo> argumentInfo)
			: base (name, false, CSharpArgumentInfo.CreateCallInfo (argumentInfo, 1))
		{
			this.flags = flags;
			this.callingContext = callingContext;
			this.argumentInfo = argumentInfo.ToReadOnly ();
			this.typeArguments = typeArguments.ToReadOnly ();
		}
 /// <summary>
 /// Creates a <see cref="MemberMemberBinding"/> that represents the recursive initialization of members of a field or property. 
 /// </summary>
 /// <param name="member">The <see cref="MemberInfo"/> to set the <see cref="P:MemberBinding.Member"/> property equal to.</param>
 /// <param name="bindings">An <see cref="IEnumerable{T}"/> that contains <see cref="MemberBinding"/> objects to use to populate the <see cref="P:MemberMemberBindings.Bindings"/> collection.</param>
 /// <returns>A <see cref="MemberMemberBinding"/> that has the <see cref="P:MemberBinding.BindingType"/> property equal to <see cref="MemberBinding"/> and the <see cref="P:MemberBinding.Member"/> and <see cref="P:MemberMemberBindings.Bindings"/> properties set to the specified values.</returns>
 public static MemberMemberBinding MemberBind(MemberInfo member, IEnumerable<MemberBinding> bindings) {
     ContractUtils.RequiresNotNull(member, "member");
     ContractUtils.RequiresNotNull(bindings, "bindings");
     ReadOnlyCollection<MemberBinding> roBindings = bindings.ToReadOnly();
     Type memberType;
     ValidateGettableFieldOrPropertyMember(member, out memberType);
     ValidateMemberInitArgs(memberType, roBindings);
     return new MemberMemberBinding(member, roBindings);
 }
 //CONFORMING
 ///<summary>Creates a <see cref="T:System.Linq.Expressions.MemberListBinding" /> where the member is a field or property.</summary>
 ///<returns>A <see cref="T:System.Linq.Expressions.MemberListBinding" /> that has the <see cref="P:System.Linq.Expressions.MemberBinding.BindingType" /> property equal to <see cref="F:System.Linq.Expressions.MemberBindingType.ListBinding" /> and the <see cref="P:System.Linq.Expressions.MemberBinding.Member" /> and <see cref="P:System.Linq.Expressions.MemberListBinding.Initializers" /> properties set to the specified values.</returns>
 ///<param name="member">A <see cref="T:System.Reflection.MemberInfo" /> that represents a field or property to set the <see cref="P:System.Linq.Expressions.MemberBinding.Member" /> property equal to.</param>
 ///<param name="initializers">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> that contains <see cref="T:System.Linq.Expressions.ElementInit" /> objects to use to populate the <see cref="P:System.Linq.Expressions.MemberListBinding.Initializers" /> collection.</param>
 ///<exception cref="T:System.ArgumentNullException">
 ///<paramref name="member" /> is null. -or-One or more elements of <paramref name="initializers" /> is null.</exception>
 ///<exception cref="T:System.ArgumentException">
 ///<paramref name="member" /> does not represent a field or property.-or-The <see cref="P:System.Reflection.FieldInfo.FieldType" /> or <see cref="P:System.Reflection.PropertyInfo.PropertyType" /> of the field or property that <paramref name="member" /> represents does not implement <see cref="T:System.Collections.IEnumerable" />.</exception>
 public static MemberListBinding ListBind(MemberInfo member, IEnumerable<ElementInit> initializers) {
     ContractUtils.RequiresNotNull(member, "member");
     ContractUtils.RequiresNotNull(initializers, "initializers");
     Type memberType;
     ValidateGettableFieldOrPropertyMember(member, out memberType);
     ReadOnlyCollection<ElementInit> initList = initializers.ToReadOnly();
     ValidateListInitArgs(memberType, initList);
     return new MemberListBinding(member, initList);
 }
Exemple #11
0
 //CONFORMING
 public static ElementInit ElementInit(MethodInfo addMethod, IEnumerable<Expression> arguments) {
     ContractUtils.RequiresNotNull(addMethod, "addMethod");
     ContractUtils.RequiresNotNull(arguments, "arguments");
     RequiresCanRead(arguments, "arguments");
     ValidateElementInitAddMethodInfo(addMethod);
     ReadOnlyCollection<Expression> argumentsRO = arguments.ToReadOnly();
     ValidateArgumentTypes(addMethod, ExpressionType.Call, ref argumentsRO);
     return new ElementInit(addMethod, argumentsRO);
 }
        /// <summary>
        /// Creates a <see cref="DynamicExpression" /> that represents a dynamic operation bound by the provided <see cref="CallSiteBinder" />.
        /// </summary>
        /// <param name="binder">The runtime binder for the dynamic operation.</param>
        /// <param name="returnType">The result type of the dynamic expression.</param>
        /// <param name="arguments">The arguments to the dynamic operation.</param>
        /// <returns>
        /// A <see cref="DynamicExpression" /> that has <see cref="NodeType" /> equal to
        /// <see cref="ExpressionType.Dynamic">Dynamic</see> and has the
        /// <see cref="DynamicExpression.Binder">Binder</see> and
        /// <see cref="DynamicExpression.Arguments">Arguments</see> set to the specified values.
        /// </returns>
        /// <remarks>
        /// The <see cref="DynamicExpression.DelegateType">DelegateType</see> property of the
        /// result will be inferred from the types of the arguments and the specified return type.
        /// </remarks>
        public static DynamicExpression Dynamic(CallSiteBinder binder, Type returnType, IEnumerable<Expression> arguments)
        {
            ContractUtils.RequiresNotNull(arguments, nameof(arguments));
            ContractUtils.RequiresNotNull(returnType, nameof(returnType));

            var args = arguments.ToReadOnly();
            ContractUtils.RequiresNotEmpty(args, nameof(args));
            return MakeDynamic(binder, returnType, args);
        }
Exemple #13
0
        /// <summary>
        /// Creates a <see cref="System.Linq.Expressions.SwitchCase">SwitchCase</see> for use in a <see cref="SwitchExpression"/>.
        /// </summary>
        /// <param name="body">The body of the case.</param>
        /// <param name="testValues">The test values of the case.</param>
        /// <returns>The created <see cref="System.Linq.Expressions.SwitchCase">SwitchCase</see>.</returns>
        public static SwitchCase SwitchCase(Expression body, IEnumerable<Expression> testValues) {
            RequiresCanRead(body, "body");
            
            var values = testValues.ToReadOnly();
            RequiresCanRead(values, "testValues");
            ContractUtils.RequiresNotEmpty(values, "testValues");

            return new SwitchCase(body, values);
        }
        /// <summary>
        /// Creates a <see cref="Expressions.SwitchCase"/> for use in a <see cref="SwitchExpression"/>.
        /// </summary>
        /// <param name="body">The body of the case.</param>
        /// <param name="testValues">The test values of the case.</param>
        /// <returns>The created <see cref="Expressions.SwitchCase"/>.</returns>
        public static SwitchCase SwitchCase(Expression body, IEnumerable<Expression> testValues)
        {
            RequiresCanRead(body, nameof(body));

            ReadOnlyCollection<Expression> values = testValues.ToReadOnly();
            ContractUtils.RequiresNotEmpty(values, nameof(testValues));
            RequiresCanRead(values, nameof(testValues));

            return new SwitchCase(body, values);
        }
 //CONFORMING
 public static ListInitExpression ListInit(NewExpression newExpression, IEnumerable<Expression> initializers) {
     ContractUtils.RequiresNotNull(newExpression, "newExpression");
     ContractUtils.RequiresNotNull(initializers, "initializers");
     ReadOnlyCollection<Expression> initializerlist = initializers.ToReadOnly();
     if (initializerlist.Count == 0) {
         throw Error.ListInitializerWithZeroMembers();
     }
     MethodInfo addMethod = FindMethod(newExpression.Type, "Add", null, new Expression[] { initializerlist[0] }, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
     return ListInit(newExpression, addMethod, initializers);
 }
		public CSharpUnaryOperationBinder (ExpressionType operation, CSharpBinderFlags flags, Type context, IEnumerable<CSharpArgumentInfo> argumentInfo)
			: base (operation)
		{
			this.argumentInfo = argumentInfo.ToReadOnly ();
			if (this.argumentInfo.Count != 1)
				throw new ArgumentException ("Unary operation requires 1 argument");

			this.flags = flags;
			this.context = context;
		}
        /// <summary>
        /// Creates a new CallInfo that represents arguments in the dynamic binding process.
        /// </summary>
        /// <param name="argCount">The number of arguments.</param>
        /// <param name="argNames">The argument names.</param>
        /// <returns>The new CallInfo</returns>
        public CallInfo(int argCount, IEnumerable<string> argNames) {
            ContractUtils.RequiresNotNull(argNames, "argNames");

            var argNameCol = argNames.ToReadOnly();

            if (argCount < argNameCol.Count) throw Error.ArgCntMustBeGreaterThanNameCnt();
            ContractUtils.RequiresNotNullItems(argNameCol, "argNames");

            _argCount = argCount;
            _argNames = argNameCol;
        }
Exemple #18
0
        /// <summary>
        /// Creates a new CallInfo that represents arguments in the dynamic binding process.
        /// </summary>
        /// <param name="argCount">The number of arguments.</param>
        /// <param name="argNames">The argument names.</param>
        /// <returns>The new CallInfo</returns>
        public CallInfo(int argCount, IEnumerable<string> argNames)
        {
            ContractUtils.RequiresNotNull(argNames, nameof(argNames));

            var argNameCol = argNames.ToReadOnly();

            if (argCount < argNameCol.Count) throw System.Linq.Expressions.Error.ArgCntMustBeGreaterThanNameCnt();
            ContractUtils.RequiresNotNullItems(argNameCol, nameof(argNames));

            ArgumentCount = argCount;
            ArgumentNames = argNameCol;
        }
        /// <summary>
        /// Creates an instance of <see cref="T:System.Linq.Expressions.RuntimeVariablesExpression" />.
        /// </summary>
        /// <param name="variables">A collection of <see cref="T:System.Linq.Expressions.ParameterExpression" /> objects to use to populate the <see cref="P:System.Linq.Expressions.RuntimeVariablesExpression.Variables" /> collection.</param>
        /// <returns>An instance of <see cref="T:System.Linq.Expressions.RuntimeVariablesExpression" /> that has the <see cref="P:System.Linq.Expressions.Expression.NodeType" /> property equal to <see cref="F:System.Linq.Expressions.ExpressionType.RuntimeVariables" /> and the <see cref="P:System.Linq.Expressions.RuntimeVariablesExpression.Variables" /> property set to the specified value.</returns>
        public static RuntimeVariablesExpression RuntimeVariables(IEnumerable<ParameterExpression> variables) {
            ContractUtils.RequiresNotNull(variables, "variables");

            var vars = variables.ToReadOnly();
            for (int i = 0; i < vars.Count; i++) {
                Expression v = vars[i];
                if (v == null) {
                    throw new ArgumentNullException("variables[" + i + "]");
                }
            }

            return new RuntimeVariablesExpression(vars);
        }
Exemple #20
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SelectExpression"/> class.
 /// </summary>
 /// <param name="alias">The alias.</param>
 /// <param name="columns">The columns.</param>
 /// <param name="from">From.</param>
 /// <param name="where">The where.</param>
 /// <param name="orderBy">The order by.</param>
 /// <param name="groupBy">The group by.</param>
 /// <param name="isDistinct">if set to <c>true</c> [is distinct].</param>
 /// <param name="skip">The skip.</param>
 /// <param name="take">The take.</param>
 /// <param name="reverse">if set to <c>true</c> [reverse].</param>
 public SelectExpression(TableAlias alias, IEnumerable <ColumnDeclaration> columns, Expression from, Expression where, IEnumerable <OrderExpression> orderBy, IEnumerable <Expression> groupBy,
                         bool isDistinct, Expression skip, Expression take, bool reverse)
     : base(DbExpressionType.Select, typeof(void), alias)
 {
     this.Columns    = columns.ToReadOnly();
     this.IsDistinct = isDistinct;
     this.From       = from;
     this.Where      = where;
     this.OrderBy    = orderBy.ToReadOnly();
     this.GroupBy    = groupBy.ToReadOnly();
     this.Take       = take;
     this.Skip       = skip;
     this.IsReverse  = reverse;
 }
Exemple #21
0
        public static NewArrayExpression NewArrayHelper(Type type, IEnumerable <Expression> initializers)
        {
            ContractUtils.RequiresNotNull(type, "type");
            ContractUtils.RequiresNotNull(initializers, "initializers");

            if (type.Equals(typeof(void)))
            {
                throw new ArgumentException("Argument type cannot be System.Void.");
            }

            ReadOnlyCollection <Expression> initializerList = initializers.ToReadOnly();

            Expression[] clone = null;
            for (int i = 0; i < initializerList.Count; i++)
            {
                Expression initializer = initializerList[i];
                ContractUtils.RequiresNotNull(initializer, "initializers");

                if (!TypeUtils.AreReferenceAssignable(type, initializer.Type))
                {
                    if (clone == null)
                    {
                        clone = new Expression[initializerList.Count];
                        for (int j = 0; j < i; j++)
                        {
                            clone[j] = initializerList[j];
                        }
                    }
                    if (type.IsSubclassOf(typeof(Expression)) && TypeUtils.AreAssignable(type, initializer.GetType()))
                    {
                        initializer = Expression.Quote(initializer);
                    }
                    else
                    {
                        initializer = Expression.Convert(initializer, type);
                    }
                }
                if (clone != null)
                {
                    clone[i] = initializer;
                }
            }

            if (clone != null)
            {
                initializerList = new ReadOnlyCollection <Expression>(clone);
            }

            return(Expression.NewArrayInit(type, initializerList));
        }
Exemple #22
0
        /// <summary>
        /// Creates a <see cref="DynamicExpression" /> that represents a dynamic operation bound by the provided <see cref="CallSiteBinder" />.
        /// </summary>
        /// <param name="delegateType">The type of the delegate used by the <see cref="CallSite" />.</param>
        /// <param name="binder">The runtime binder for the dynamic operation.</param>
        /// <param name="arguments">The arguments to the dynamic operation.</param>
        /// <returns>
        /// A <see cref="DynamicExpression" /> that has <see cref="NodeType" /> equal to
        /// <see cref="ExpressionType.Dynamic">Dynamic</see> and has the
        /// <see cref="DynamicExpression.DelegateType">DelegateType</see>,
        /// <see cref="DynamicExpression.Binder">Binder</see>, and
        /// <see cref="DynamicExpression.Arguments">Arguments</see> set to the specified values.
        /// </returns>
        public static DynamicExpression MakeDynamic(Type delegateType, CallSiteBinder binder, IEnumerable <Expression> arguments)
        {
            ContractUtils.RequiresNotNull(delegateType, "delegateType");
            ContractUtils.RequiresNotNull(binder, "binder");
            ContractUtils.Requires(delegateType.IsSubclassOf(typeof(Delegate)), "delegateType", Strings.TypeMustBeDerivedFromSystemDelegate);

            var method = GetValidMethodForDynamic(delegateType);

            var args = arguments.ToReadOnly();

            ValidateArgumentTypes(method, ExpressionType.Dynamic, ref args);

            return(DynamicExpression.Make(method.GetReturnType(), delegateType, binder, args));
        }
        public MixinEntityExpression(Type type, IEnumerable <FieldBinding> bindings, Alias mainEntityAlias, FieldMixin fieldMixin)
            : base(DbExpressionType.MixinInit, type)
        {
            if (bindings == null)
            {
                throw new ArgumentNullException("bindings");
            }

            Bindings = bindings.ToReadOnly();

            FieldMixin = fieldMixin;

            MainEntityAlias = mainEntityAlias;
        }
Exemple #24
0
        /// <summary>
        /// Creates a <see cref="BlockExpression"/> that contains the given variables and expressions.
        /// </summary>
        /// <param name="variables">The variables in the block.</param>
        /// <param name="expressions">The expressions in the block.</param>
        /// <returns>The created <see cref="BlockExpression"/>.</returns>
        public static BlockExpression Block(IEnumerable <ParameterExpression> variables, IEnumerable <Expression> expressions)
        {
            ContractUtils.RequiresNotNull(expressions, nameof(expressions));
            var variableList = variables.ToReadOnly();

            if (variableList.Count == 0)
            {
                return(GetOptimizedBlockExpression(expressions as IReadOnlyList <Expression> ?? expressions.ToReadOnly()));
            }

            var expressionList = expressions.ToReadOnly();

            return(BlockCore(null, variableList, expressionList));
        }
 public SwitchStatement(Expression expression, IEnumerable <SwitchCase> cases)
 {
     Expression = expression;
     Cases      = cases.ToReadOnly();
     if (Cases.Count(x => x.ContainsDefault) > 1)
     {
         throw new ArgumentException("default ラベルは switch ステートメント内に複数存在できません。");
     }
     Expression.Parent = this;
     foreach (var cs in Cases)
     {
         cs.Parent = this;
     }
 }
Exemple #26
0
        /// <summary>
        /// Creates a new CallInfo that represents arguments in the dynamic binding process.
        /// </summary>
        /// <param name="argCount">The number of arguments.</param>
        /// <param name="argNames">The argument names.</param>
        /// <returns>The new CallInfo</returns>
        public CallInfo(int argCount, IEnumerable <string> argNames)
        {
            ContractUtils.RequiresNotNull(argNames, nameof(argNames));

            var argNameCol = argNames.ToReadOnly();

            if (argCount < argNameCol.Count)
            {
                throw System.Linq.Expressions.Error.ArgCntMustBeGreaterThanNameCnt();
            }
            ContractUtils.RequiresNotNullItems(argNameCol, nameof(argNames));

            _argCount = argCount;
            _argNames = argNameCol;
        }
Exemple #27
0
 public FunctionDefinition(string name, IEnumerable <ParameterDefinition> parameters, IEnumerable <Statement> body)
 {
     Name       = name;
     Parameters = parameters.ToReadOnly();
     foreach (var param in Parameters)
     {
         param.Parent = this;
     }
     Body = body.ToReadOnly();
     foreach (var statement in Body)
     {
         statement.Parent = this;
     }
     ReturnLabel = Ast.Label(typeof(object));
 }
Exemple #28
0
        private FunctionSymbol(string name, IEnumerable <Signature> signatures, bool hidden, bool constantFoldable, ResultNameKind resultNameKind, string resultNamePrefix)
            : base(name)
        {
            this.Signatures = signatures.ToReadOnly();

            foreach (var signature in this.Signatures)
            {
                signature.Symbol = this;
            }

            this.hidden           = hidden;
            this.constantFoldable = constantFoldable;
            this.resultNameKind   = resultNameKind;
            this.resultNamePrefix = resultNamePrefix;
        }
Exemple #29
0
        /// <summary>
        /// Creates a new array expression of the specified type from the provided initializers.
        /// </summary>
        /// <param name="type">A Type that represents the element type of the array.</param>
        /// <param name="initializers">The expressions used to create the array elements.</param>
        /// <returns>An instance of the <see cref="NewArrayExpression"/>.</returns>
        public static NewArrayExpression NewArrayInit(Type type, IEnumerable <Expression> initializers)
        {
            ContractUtils.RequiresNotNull(type, "type");
            ContractUtils.RequiresNotNull(initializers, "initializers");
            if (type.Equals(typeof(void)))
            {
                throw Error.ArgumentCannotBeOfTypeVoid();
            }

            ReadOnlyCollection <Expression> initializerList = initializers.ToReadOnly();

            Expression[] newList = null;
            for (int i = 0, n = initializerList.Count; i < n; i++)
            {
                Expression expr = initializerList[i];
                RequiresCanRead(expr, "initializers");

                if (!TypeUtils.AreReferenceAssignable(type, expr.Type))
                {
                    if (TypeUtils.IsSameOrSubclass(typeof(LambdaExpression), type) && type.IsAssignableFrom(expr.GetType()))
                    {
                        expr = Expression.Quote(expr);
                    }
                    else
                    {
                        throw Error.ExpressionTypeCannotInitializeArrayType(expr.Type, type);
                    }
                    if (newList == null)
                    {
                        newList = new Expression[initializerList.Count];
                        for (int j = 0; j < i; j++)
                        {
                            newList[j] = initializerList[j];
                        }
                    }
                }
                if (newList != null)
                {
                    newList[i] = expr;
                }
            }
            if (newList != null)
            {
                initializerList = new TrueReadOnlyCollection <Expression>(newList);
            }

            return(NewArrayExpression.Make(ExpressionType.NewArrayInit, type.MakeArrayType(), initializerList));
        }
Exemple #30
0
        public void ToReadOnly_Passing_Valid_Collection_Returns_Readonly_Collection()
        {
            var collectionExpected = new List <string>()
            {
                "a", "e", "i", "o", "u",
            };

            Collection = new List <string>()
            {
                "a", "e", "i", "o", "u",
            };

            var collectionActual = Collection.ToReadOnly();

            CollectionAssert.AreEqual(collectionExpected, collectionActual);
        }
        /// <summary>
        /// Creates a <see cref="Optimizers.LambdaAbstraction" /> that abstracts over unknown query nodes and non-query nodes.
        /// </summary>
        /// <param name="body">The <see cref="LambdaExpression" /> which represents the unknown parts of a query with holes for known sub-parts.</param>
        /// <param name="parameters">The known sub-parts of a query.</param>
        /// <returns>A <see cref="Optimizers.LambdaAbstraction" /> with holes and parameters to fill the holes.</returns>
        public LambdaAbstraction LambdaAbstraction(LambdaExpression body, IEnumerable <QueryTree> parameters)
        {
            RequireNotNull(body, nameof(body));
            RequireNotNull(body.Parameters, nameof(body));

            RequireNotNull(parameters, nameof(parameters));

            var p = parameters.ToReadOnly();

            if (p.Count != body.Parameters.Count)
            {
                throw new ArgumentException("Number of parameters in body and parameter list is not consistent.");
            }

            return(new LambdaAbstraction(body, p));
        }
Exemple #32
0
        /// <summary>
        /// Creates a <see cref="InterpolatedStringCSharpExpression"/> that represents an interpolated string expression.
        /// </summary>
        /// <param name="type">The type of the interpolated string. This can be any of <see cref="string"/>, <see cref="FormattableString"/>, or <see cref="IFormattable"/>.</param>
        /// <param name="interpolations">The interpolations that make up the interpolated string.</param>
        /// <returns>An instance of the <see cref="InterpolatedStringCSharpExpression"/>.</returns>
        public static InterpolatedStringCSharpExpression InterpolatedString(Type type, IEnumerable <Interpolation> interpolations)
        {
            ContractUtils.RequiresNotNull(type, nameof(type));

            if (type == typeof(string))
            {
                return(InterpolatedString(interpolations));
            }

            if (type != typeof(FormattableString) && type != typeof(IFormattable))
            {
                throw Error.InvalidInterpolatedStringType(type);
            }

            return(new FormattableInterpolatedStringCSharpExpression(type, interpolations.ToReadOnly()));
        }
        /// <summary>
        /// Creates a new expression representing a dynamically bound (possibly generic) member invocation with the specified binder flags and the specified type context.
        /// </summary>
        /// <param name="object">The expression representing the object to invoke the member on.</param>
        /// <param name="name">The name of the member to invoke.</param>
        /// <param name="typeArguments">An enumerable sequence of type arguments to pass to the generic member. (Specify null for non-generic members.)</param>
        /// <param name="arguments">An enumerable sequence of dynamic arguments representing the arguments passed to the member upon invocation.</param>
        /// <param name="binderFlags">The binder flags to use for the dynamic operation.</param>
        /// <param name="context">The type representing the context in which the dynamic operation is bound.</param>
        /// <returns>A new expression representing a dynamically bound member invocation.</returns>
        public static InvokeMemberDynamicCSharpExpression DynamicInvokeMember(Expression @object, string name, IEnumerable<Type> typeArguments, IEnumerable<DynamicCSharpArgument> arguments, CSharpBinderFlags binderFlags, Type context)
        {
            RequiresCanRead(@object, nameof(@object));
            RequiresNotNull(name, nameof(name));

            var typeArgList = typeArguments.ToReadOnly();

            foreach (var type in typeArgList)
            {
                ValidateType(type);
            }

            var argList = arguments.ToReadOnly();

            return new InvokeInstanceMemberDynamicCSharpExpression(context, binderFlags, @object, name, typeArgList, argList);
        }
Exemple #34
0
        public MixinEntityExpression(Type type, IEnumerable <FieldBinding> bindings, Alias?mainEntityAlias, FieldMixin?fieldMixin, EntityContextInfo?info)
            : base(DbExpressionType.MixinInit, type)
        {
            if (bindings == null)
            {
                throw new ArgumentNullException(nameof(bindings));
            }

            Bindings = bindings.ToReadOnly();

            FieldMixin = fieldMixin;

            EntityContext = info;

            MainEntityAlias = mainEntityAlias;
        }
Exemple #35
0
        /// <summary>
        /// Creates a <see cref="ListInitExpression"/> that uses a method named "Add" to add elements to a collection.
        /// </summary>
        /// <param name="newExpression">A <see cref="NewExpression"/> to set the <see cref="P:ListInitExpression.NewExpression"/> property equal to.</param>
        /// <param name="initializers">An <see cref="IEnumerable{T}"/> that contains <see cref="M:ElementInit"/> objects to use to populate the <see cref="ListInitExpression.Initializers"/> collection.</param>
        /// <returns>A <see cref="ListInitExpression"/> that has the <see cref="P:ListInitExpression.NodeType"/> property equal to ListInit and the <see cref="P:ListInitExpression.NewExpression"/> property set to the specified value.</returns>
        public static ListInitExpression ListInit(NewExpression newExpression, IEnumerable <Expression> initializers)
        {
            ContractUtils.RequiresNotNull(newExpression, nameof(newExpression));
            ContractUtils.RequiresNotNull(initializers, nameof(initializers));

            ReadOnlyCollection <Expression> initializerlist = initializers.ToReadOnly();

            if (initializerlist.Count == 0)
            {
                return(new ListInitExpression(newExpression, EmptyReadOnlyCollection <ElementInit> .Instance));
            }

            MethodInfo addMethod = FindMethod(newExpression.Type, "Add", null, new Expression[] { initializerlist[0] }, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

            return(ListInit(newExpression, addMethod, initializers));
        }
Exemple #36
0
        public static ListInitExpression ListInit(NewExpression newExpression, IEnumerable <Expression> initializers)
        {
            ArgumentNullException.ThrowIfNull(newExpression);
            ArgumentNullException.ThrowIfNull(initializers);

            ReadOnlyCollection <Expression> initializerlist = initializers.ToReadOnly();

            if (initializerlist.Count == 0)
            {
                return(new ListInitExpression(newExpression, EmptyReadOnlyCollection <ElementInit> .Instance));
            }

            MethodInfo?addMethod = FindMethod(newExpression.Type, "Add", null, new Expression[] { initializerlist[0] }, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

            return(ListInit(newExpression, addMethod, initializerlist));
        }
        /// <summary>
        /// Creates a <see cref="ListInitExpression"/> that uses a method named "Add" to add elements to a collection.
        /// </summary>
        /// <param name="newExpression">A <see cref="NewExpression"/> to set the <see cref="P:ListInitExpression.NewExpression"/> property equal to.</param>
        /// <param name="initializers">An <see cref="IEnumerable{T}"/> that contains <see cref="M:ElementInit"/> objects to use to populate the <see cref="ListInitExpression.Initializers"/> collection.</param>
        /// <returns>A <see cref="ListInitExpression"/> that has the <see cref="P:ListInitExpression.NodeType"/> property equal to ListInit and the <see cref="P:ListInitExpression.NewExpression"/> property set to the specified value.</returns>
        public static ListInitExpression ListInit(NewExpression newExpression, IEnumerable <Expression> initializers)
        {
            ContractUtils.RequiresNotNull(newExpression, "newExpression");
            ContractUtils.RequiresNotNull(initializers, "initializers");

            var initializerlist = initializers.ToReadOnly();

            if (initializerlist.Count == 0)
            {
                throw Error.ListInitializerWithZeroMembers();
            }

            MethodInfo addMethod = FindMethod(newExpression.Type, "Add", null, new Expression[] { initializerlist[0] }, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

            return(ListInit(newExpression, addMethod, initializers));
        }
Exemple #38
0
        public static NewExpression New(ConstructorInfo constructor, IEnumerable <Expression>?arguments, IEnumerable <MemberInfo>?members)
        {
            ArgumentNullException.ThrowIfNull(constructor);
            if (constructor.DeclaringType is null)
            {
#pragma warning disable CA2208
                throw new ArgumentNullException($"{nameof(constructor)}.{nameof(constructor.DeclaringType)}");
#pragma warning restore CA2208
            }
            TypeUtils.ValidateType(constructor.DeclaringType !, nameof(constructor), allowByRef: true, allowPointer: true);
            ValidateConstructor(constructor, nameof(constructor));
            ReadOnlyCollection <MemberInfo> memberList = members.ToReadOnly();
            ReadOnlyCollection <Expression> argList    = arguments.ToReadOnly();
            ValidateNewArgs(constructor, ref argList, ref memberList);
            return(new NewExpression(constructor, argList, memberList));
        }
Exemple #39
0
        /// <summary>
        /// Creates a new array expression of the specified type from the provided initializers.
        /// </summary>
        /// <param name="type">A Type that represents the element type of the array.</param>
        /// <param name="initializers">The expressions used to create the array elements.</param>
        /// <returns>An instance of the <see cref="NewArrayExpression"/>.</returns>
        public static NewArrayExpression NewArrayInit(Type type, IEnumerable <Expression> initializers)
        {
            ContractUtils.RequiresNotNull(type, "type");
            ContractUtils.RequiresNotNull(initializers, "initializers");
            if (type == typeof(void))
            {
                throw Error.ArgumentCannotBeOfTypeVoid();
            }

            var initializerList = initializers.ToReadOnly();

            Expression[] newList = null;
            var          n       = initializerList.Count;

            for (var i = 0; i < n; i++)
            {
                var expr = initializerList[i];
                RequiresCanRead(expr, "initializers");

                if (!TypeHelper.AreReferenceAssignable(type, expr.Type))
                {
                    if (!TryQuote(type, ref expr))
                    {
                        throw Error.ExpressionTypeCannotInitializeArrayType(expr.Type, type);
                    }
                    if (newList == null)
                    {
                        newList = new Expression[n];
                        for (var j = 0; j < i; j++)
                        {
                            newList[j] = initializerList[j];
                        }
                    }
                }
                if (newList != null)
                {
                    newList[i] = expr;
                }
            }
            if (newList != null)
            {
                initializerList = new TrueReadOnlyCollection <Expression>(newList);
            }

            return(NewArrayExpression.Make(ExpressionType.NewArrayInit, type.MakeArrayType(), initializerList));
        }
Exemple #40
0
 private QueryOperatorParameter(
     string name,
     QueryOperatorParameterKind kind,
     bool isCaseSensitive,
     IEnumerable <string> values,
     bool isRepeatable,
     bool isHidden,
     IReadOnlyList <string> aliases)
 {
     this.Name            = name;
     this.Kind            = kind;
     this.Values          = values.ToReadOnly();
     this.IsCaseSensitive = isCaseSensitive;
     this.IsRepeatable    = isRepeatable;
     this.IsHidden        = isHidden;
     this.Aliases         = aliases.ToReadOnly();
 }
        /// <summary>
        /// Creates an instance of <see cref="T:System.Linq.Expressions.RuntimeVariablesExpression" />.
        /// </summary>
        /// <param name="variables">A collection of <see cref="T:System.Linq.Expressions.ParameterExpression" /> objects to use to populate the <see cref="P:System.Linq.Expressions.RuntimeVariablesExpression.Variables" /> collection.</param>
        /// <returns>An instance of <see cref="T:System.Linq.Expressions.RuntimeVariablesExpression" /> that has the <see cref="P:System.Linq.Expressions.Expression.NodeType" /> property equal to <see cref="F:System.Linq.Expressions.ExpressionType.RuntimeVariables" /> and the <see cref="P:System.Linq.Expressions.RuntimeVariablesExpression.Variables" /> property set to the specified value.</returns>
        public static RuntimeVariablesExpression RuntimeVariables(IEnumerable <ParameterExpression> variables)
        {
            ContractUtils.RequiresNotNull(variables, "variables");

            var vars = variables.ToReadOnly();

            for (int i = 0; i < vars.Count; i++)
            {
                Expression v = vars[i];
                if (v == null)
                {
                    throw new ArgumentNullException("variables[" + i + "]");
                }
            }

            return(new RuntimeVariablesExpression(vars));
        }
        /// <summary>
        /// Creates a <see cref="NewArrayExpression"/> that represents creating an array that has a specified rank.
        /// </summary>
        /// <param name="type">A <see cref="System.Type"/> that represents the element type of the array.</param>
        /// <param name="bounds">An <see cref="IEnumerable{T}"/> that contains <see cref="Expression"/> objects to use to populate the <see cref="NewArrayExpression.Expressions"/> collection.</param>
        /// <returns>A <see cref="NewArrayExpression"/> that has the <see cref="NodeType"/> property equal to <see cref="ExpressionType.NewArrayBounds"/> and the <see cref="NewArrayExpression.Expressions"/> property set to the specified value.</returns>
        public static NewArrayExpression NewArrayBounds(Type type, IEnumerable <Expression> bounds)
        {
            ContractUtils.RequiresNotNull(type, nameof(type));
            ContractUtils.RequiresNotNull(bounds, nameof(bounds));

            if (type == typeof(void))
            {
                throw Error.ArgumentCannotBeOfTypeVoid(nameof(type));
            }

            TypeUtils.ValidateType(type, nameof(type));

            ReadOnlyCollection <Expression> boundsList = bounds.ToReadOnly();

            int dimensions = boundsList.Count;

            if (dimensions <= 0)
            {
                throw Error.BoundsCannotBeLessThanOne(nameof(bounds));
            }

            for (int i = 0; i < dimensions; i++)
            {
                Expression expr = boundsList[i];
                ExpressionUtils.RequiresCanRead(expr, nameof(bounds), i);
                if (!expr.Type.IsInteger())
                {
                    throw Error.ArgumentMustBeInteger(nameof(bounds), i);
                }
            }

            Type arrayType;

            if (dimensions == 1)
            {
                //To get a vector, need call Type.MakeArrayType().
                //Type.MakeArrayType(1) gives a non-vector array, which will cause type check error.
                arrayType = type.MakeArrayType();
            }
            else
            {
                arrayType = type.MakeArrayType(dimensions);
            }

            return(NewArrayExpression.Make(ExpressionType.NewArrayBounds, arrayType, boundsList));
        }
Exemple #43
0
        private static IndexCSharpExpression MakeIndex(Expression instance, PropertyInfo indexer, MethodInfo method, ParameterInfo[] parameters, IEnumerable <ParameterAssignment> arguments)
        {
            RequiresCanRead(instance, nameof(instance));

            var argList = arguments.ToReadOnly();

            ValidateIndexer(instance.Type, indexer, parameters, argList);

            if (method != null)
            {
                return(new IndexCSharpExpression.MethodBased(instance, method, argList));
            }
            else
            {
                return(new IndexCSharpExpression.PropertyBased(instance, indexer, argList));
            }
        }
Exemple #44
0
        public static CSharpSwitchCase SwitchCase(IEnumerable <object> testValues, IEnumerable <Expression> statements)
        {
            RequiresNotNull(testValues, nameof(testValues));
            RequiresNotNull(statements, nameof(statements));

            // NB: We don't check the body for Break statements; worst case we'll insert one at the end during Reduce.
            //     Note that the semantics are nonetheless consistent with C#, i.e. no implicit fall-through.

            var testValuesList = testValues.ToReadOnly();

            RequiresNotEmpty(testValuesList, nameof(testValues));

            var testType = default(Type);

            var uniqueTestValues = new HashSet <object>();

            foreach (var testValue in testValuesList)
            {
                if (!uniqueTestValues.Add(testValue))
                {
                    throw Error.DuplicateTestValue(testValue);
                }

                // NB: Null is fine; every valid governing type in C# has a nullable variant (trivial for string).

                if (testValue != null && testValue != SwitchCaseDefaultValue)
                {
                    var testValueType = testValue.GetType();
                    if (testType == null)
                    {
                        testType = testValueType;
                    }
                    else
                    {
                        if (testType != testValueType)
                        {
                            throw Error.TestValuesShouldHaveConsistentType();
                        }
                    }
                }
            }

            var statementsList = GetStatements(statements);

            return(new CSharpSwitchCase(testValuesList, statementsList));
        }
Exemple #45
0
        /// <summary>
        /// Creates a copy of this <see cref="Parser{TInput}"/> with the annotations specified.
        /// </summary>
        public Parser <TInput> WithAnnotations(IEnumerable <object> annotations)
        {
            var list = annotations.ToReadOnly();

            if (this.Annotations != list)
            {
                var clone = this.Clone();
                clone.Annotations = list;
                clone.Tag         = this.Tag;
                clone.IsHidden    = this.IsHidden;
                return(clone);
            }
            else
            {
                return(this);
            }
        }
        /// <summary>
        /// Creates a <see cref="NewArrayExpression"/> of the specified type from the provided initializers.
        /// </summary>
        /// <param name="type">A Type that represents the element type of the array.</param>
        /// <param name="initializers">The expressions used to create the array elements.</param>
        /// <returns>A <see cref="NewArrayExpression"/> that has the <see cref="NodeType"/> property equal to <see cref="ExpressionType.NewArrayInit"/> and the <see cref="NewArrayExpression.Expressions"/> property set to the specified value.</returns>
        public static NewArrayExpression NewArrayInit(Type type, IEnumerable <Expression> initializers)
        {
            ContractUtils.RequiresNotNull(type, nameof(type));
            ContractUtils.RequiresNotNull(initializers, nameof(initializers));
            if (type == typeof(void))
            {
                throw Error.ArgumentCannotBeOfTypeVoid(nameof(type));
            }

            TypeUtils.ValidateType(type, nameof(type));
            ReadOnlyCollection <Expression> initializerList = initializers.ToReadOnly();

            Expression[]? newList = null;
            for (int i = 0, n = initializerList.Count; i < n; i++)
            {
                Expression expr = initializerList[i];
                ExpressionUtils.RequiresCanRead(expr, nameof(initializers), i);

                if (!TypeUtils.AreReferenceAssignable(type, expr.Type))
                {
                    if (!TryQuote(type, ref expr))
                    {
                        throw Error.ExpressionTypeCannotInitializeArrayType(expr.Type, type);
                    }
                    if (newList == null)
                    {
                        newList = new Expression[initializerList.Count];
                        for (int j = 0; j < i; j++)
                        {
                            newList[j] = initializerList[j];
                        }
                    }
                }
                if (newList != null)
                {
                    newList[i] = expr;
                }
            }
            if (newList != null)
            {
                initializerList = new TrueReadOnlyCollection <Expression>(newList);
            }

            return(NewArrayExpression.Make(ExpressionType.NewArrayInit, type.MakeArrayType(), initializerList));
        }
Exemple #47
0
        public CaseExpression(IEnumerable <When> whens, Expression?defaultValue)
            : base(DbExpressionType.Case, GetType(whens, defaultValue))
        {
            if (whens.IsEmpty())
            {
                throw new ArgumentNullException(nameof(whens));
            }

            Type refType = this.Type.UnNullify();

            if (whens.Any(w => w.Value.Type.UnNullify() != refType))
            {
                throw new ArgumentException("whens");
            }

            this.Whens        = whens.ToReadOnly();
            this.DefaultValue = defaultValue;
        }
        /// <summary>
        /// Creates a new expression representing a dynamically bound (possibly generic) member invocation with the specified binder flags and the specified type context.
        /// </summary>
        /// <param name="type">The type containing the static member to invoke.</param>
        /// <param name="name">The name of the member to invoke.</param>
        /// <param name="typeArguments">An enumerable sequence of type arguments to pass to the generic member. (Specify null for non-generic members.)</param>
        /// <param name="arguments">An enumerable sequence of dynamic arguments representing the arguments passed to the member upon invocation.</param>
        /// <param name="binderFlags">The binder flags to use for the dynamic operation.</param>
        /// <param name="context">The type representing the context in which the dynamic operation is bound.</param>
        /// <returns>A new expression representing a dynamically bound member invocation.</returns>
        public static InvokeMemberDynamicCSharpExpression DynamicInvokeMember(Type type, string name, IEnumerable <Type> typeArguments, IEnumerable <DynamicCSharpArgument> arguments, CSharpBinderFlags binderFlags, Type context)
        {
            ContractUtils.RequiresNotNull(type, nameof(type));
            ContractUtils.RequiresNotNull(name, nameof(name));

            ValidateType(type);

            var typeArgList = typeArguments.ToReadOnly();

            foreach (var typeArg in typeArgList)
            {
                ValidateType(typeArg);
            }

            var argList = arguments.ToReadOnly();

            return(new InvokeStaticMemberDynamicCSharpExpression(context, binderFlags, type, name, typeArgList, argList));
        }
Exemple #49
0
        /// <summary>
        /// Creates a <see cref="ListInitExpression"/> that uses a specified method to add elements to a collection.
        /// </summary>
        /// <param name="newExpression">A <see cref="NewExpression"/> to set the <see cref="P:ListInitExpression.NewExpression"/> property equal to.</param>
        /// <param name="addMethod">A <see cref="MethodInfo"/> that represents an instance method named "Add" (case insensitive), that adds an element to a collection. </param>
        /// <param name="initializers">An <see cref="IEnumerable{T}"/> that contains <see cref="Expression"/> objects to use to populate the Initializers collection.</param>
        /// <returns>A <see cref="ListInitExpression"/> that has the <see cref="P:ListInitExpression.NodeType"/> property equal to ListInit and the <see cref="P:ListInitExpression.NewExpression"/> property set to the specified value.</returns>
        public static ListInitExpression ListInit(NewExpression newExpression, MethodInfo addMethod, IEnumerable <Expression> initializers)
        {
            if (addMethod == null)
            {
                return(ListInit(newExpression, initializers));
            }
            ContractUtils.RequiresNotNull(newExpression, nameof(newExpression));
            ContractUtils.RequiresNotNull(initializers, nameof(initializers));

            ReadOnlyCollection <Expression> initializerlist = initializers.ToReadOnly();

            ElementInit[] initList = new ElementInit[initializerlist.Count];
            for (int i = 0; i < initializerlist.Count; i++)
            {
                initList[i] = ElementInit(addMethod, initializerlist[i]);
            }
            return(ListInit(newExpression, new TrueReadOnlyCollection <ElementInit>(initList)));
        }
Exemple #50
0
        public static NewArrayExpression NewArrayHelper(Type type, IEnumerable<Expression> initializers)
        {
            ContractUtils.RequiresNotNull(type, "type");
            ContractUtils.RequiresNotNull(initializers, "initializers");

            if (type.Equals(typeof(void))) {
                throw new ArgumentException("Argument type cannot be System.Void.");
            }

            ReadOnlyCollection<Expression> initializerList = initializers.ToReadOnly();

            Expression[] clone = null;
            for (int i = 0; i < initializerList.Count; i++) {
                Expression initializer = initializerList[i];
                ContractUtils.RequiresNotNull(initializer, "initializers");

                if (!TypeUtils.AreReferenceAssignable(type, initializer.Type)) {
                    if (clone == null) {
                        clone = new Expression[initializerList.Count];
                        for (int j = 0; j < i; j++) {
                            clone[j] = initializerList[j];
                        }
                    }
                    if (type.IsSubclassOf(typeof(Expression)) && TypeUtils.AreAssignable(type, initializer.GetType())) {
                        initializer = Expression.Quote(initializer);
                    } else {
                        initializer = Convert(initializer, type);
                    }

                }
                if (clone != null) {
                    clone[i] = initializer;
                }
            }

            if (clone != null) {
                initializerList = new ReadOnlyCollection<Expression>(clone);
            }

            return Expression.NewArrayInit(type, initializerList);
        }
        public EntityExpression(Type type, Expression externalId, Alias tableAlias, IEnumerable<FieldBinding> bindings, IEnumerable<MixinEntityExpression> mixins, bool avoidExpandOnRetrieving)
            : base(DbExpressionType.Entity, type)
        {
            if (type == null) 
                throw new ArgumentNullException("type");

            if (!type.IsIdentifiableEntity())
                throw new ArgumentException("type");
            
            if (externalId == null) 
                throw new ArgumentNullException("externalId");
            
            this.Table = Schema.Current.Table(type);
            this.ExternalId = externalId;

            this.TableAlias = tableAlias;
            this.Bindings = bindings.ToReadOnly();
            this.Mixins = mixins.ToReadOnly();

            this.AvoidExpandOnRetrieving = avoidExpandOnRetrieving;
        }
Exemple #52
0
 public SelectExpression(
     IdentifiableAlias alias,
     IEnumerable<FieldDeclaration> fields,
     Expression from,
     Expression where,
     IEnumerable<OrderExpression> orderBy,
     IEnumerable<Expression> groupBy,
     bool isDistinct,
     Expression skip,
     Expression take,
     bool reverse
     )
     : base(DbExpressionType.Select, typeof(void), alias)
 {
     this.fields = fields.ToReadOnly();
     this.isDistinct = isDistinct;
     this.from = from;
     this.where = where;
     this.orderBy = orderBy.ToReadOnly();
     this.groupBy = groupBy.ToReadOnly();
     this.take = take;
     this.skip = skip;
     this.reverse = reverse;
 }
        ///<summary>Creates a <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that represents applying an array index operator to an array of rank more than one.</summary>
        ///<returns>A <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that has the <see cref="P:System.Linq.Expressions.Expression.NodeType" /> property equal to <see cref="F:System.Linq.Expressions.ExpressionType.Call" /> and the <see cref="P:System.Linq.Expressions.MethodCallExpression.Object" /> and <see cref="P:System.Linq.Expressions.MethodCallExpression.Arguments" /> properties set to the specified values.</returns>
        ///<param name="array">An <see cref="T:System.Linq.Expressions.Expression" /> to set the <see cref="P:System.Linq.Expressions.MethodCallExpression.Object" /> property equal to.</param>
        ///<param name="indexes">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> that contains <see cref="T:System.Linq.Expressions.Expression" /> objects to use to populate the <see cref="P:System.Linq.Expressions.MethodCallExpression.Arguments" /> collection.</param>
        ///<exception cref="T:System.ArgumentNullException">
        ///<paramref name="array" /> or <paramref name="indexes" /> is null.</exception>
        ///<exception cref="T:System.ArgumentException">
        ///<paramref name="array" />.Type does not represent an array type.-or-The rank of <paramref name="array" />.Type does not match the number of elements in <paramref name="indexes" />.-or-The <see cref="P:System.Linq.Expressions.Expression.Type" /> property of one or more elements of <paramref name="indexes" /> does not represent the <see cref="T:System.Int32" /> type.</exception>
        public static MethodCallExpression ArrayIndex(Expression array, IEnumerable<Expression> indexes)
        {
            RequiresCanRead(array, "array");
            ContractUtils.RequiresNotNull(indexes, "indexes");

            Type arrayType = array.Type;
            if (!arrayType.IsArray)
            {
                throw Error.ArgumentMustBeArray();
            }

            ReadOnlyCollection<Expression> indexList = indexes.ToReadOnly();
            if (arrayType.GetArrayRank() != indexList.Count)
            {
                throw Error.IncorrectNumberOfIndexes();
            }

            foreach (Expression e in indexList)
            {
                RequiresCanRead(e, "indexes");
                if (e.Type != typeof(int))
                {
                    throw Error.ArgumentMustBeArrayIndexType();
                }
            }

            MethodInfo mi = array.Type.GetMethod("Get", BindingFlags.Public | BindingFlags.Instance);
            return Call(array, mi, indexList);
        }
        ///<summary>Creates a <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that represents a method call.</summary>
        ///<returns>A <see cref="T:System.Linq.Expressions.MethodCallExpression" /> that has the <see cref="P:System.Linq.Expressions.Expression.NodeType" /> property equal to <see cref="F:System.Linq.Expressions.ExpressionType.Call" /> and the <see cref="P:System.Linq.Expressions.MethodCallExpression.Object" />, <see cref="P:System.Linq.Expressions.MethodCallExpression.Method" />, and <see cref="P:System.Linq.Expressions.MethodCallExpression.Arguments" /> properties set to the specified values.</returns>
        ///<param name="instance">An <see cref="T:System.Linq.Expressions.Expression" /> to set the <see cref="P:System.Linq.Expressions.MethodCallExpression.Object" /> property equal to (pass null for a static (Shared in Visual Basic) method).</param>
        ///<param name="method">A <see cref="T:System.Reflection.MethodInfo" /> to set the <see cref="P:System.Linq.Expressions.MethodCallExpression.Method" /> property equal to.</param>
        ///<param name="arguments">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> that contains <see cref="T:System.Linq.Expressions.Expression" /> objects to use to populate the <see cref="P:System.Linq.Expressions.MethodCallExpression.Arguments" /> collection.</param>
        ///<exception cref="T:System.ArgumentNullException">
        ///<paramref name="method" /> is null.-or-<paramref name="instance" /> is null and <paramref name="method" /> represents an instance method.</exception>
        ///<exception cref="T:System.ArgumentException">
        ///<paramref name="instance" />.Type is not assignable to the declaring type of the method represented by <paramref name="method" />.-or-The number of elements in <paramref name="arguments" /> does not equal the number of parameters for the method represented by <paramref name="method" />.-or-One or more of the elements of <paramref name="arguments" /> is not assignable to the corresponding parameter for the method represented by <paramref name="method" />.</exception>
        public static MethodCallExpression Call(Expression instance, MethodInfo method, IEnumerable<Expression> arguments)
        {
            IReadOnlyList<Expression> argumentList = arguments as IReadOnlyList<Expression>;

            if (argumentList != null)
            {
                int argCount = argumentList.Count;

                switch (argCount)
                {
                    case 0:
                        return Call(instance, method);
                    case 1:
                        return Call(instance, method, argumentList[0]);
                    case 2:
                        return Call(instance, method, argumentList[0], argumentList[1]);
                    case 3:
                        return Call(instance, method, argumentList[0], argumentList[1], argumentList[2]);
                }

                if (instance == null)
                {
                    switch (argCount)
                    {
                        case 4:
                            return Call(method, argumentList[0], argumentList[1], argumentList[2], argumentList[3]);
                        case 5:
                            return Call(method, argumentList[0], argumentList[1], argumentList[2], argumentList[3], argumentList[4]);
                    }
                }
            }

            ContractUtils.RequiresNotNull(method, "method");

            ReadOnlyCollection<Expression> argList = arguments.ToReadOnly();

            ValidateMethodInfo(method);
            ValidateStaticOrInstanceMethod(instance, method);
            ValidateArgumentTypes(method, ExpressionType.Call, ref argList);

            if (instance == null)
            {
                return new MethodCallExpressionN(method, argList);
            }
            else
            {
                return new InstanceMethodCallExpressionN(method, instance, argList);
            }
        }
        /// <summary>
        /// Creates an instance of <see cref="RuntimeVariablesExpression"/>.
        /// </summary>
        /// <param name="variables">A collection of <see cref="ParameterExpression"/> objects to use to populate the <see cref="RuntimeVariablesExpression.Variables"/> collection.</param>
        /// <returns>An instance of <see cref="RuntimeVariablesExpression"/> that has the <see cref="NodeType"/> property equal to <see cref="ExpressionType.RuntimeVariables"/> and the <see cref="RuntimeVariablesExpression.Variables"/> property set to the specified value.</returns>
        public static RuntimeVariablesExpression RuntimeVariables(IEnumerable<ParameterExpression> variables)
        {
            ContractUtils.RequiresNotNull(variables, nameof(variables));

            ReadOnlyCollection<ParameterExpression> vars = variables.ToReadOnly();
            for (int i = 0; i < vars.Count; i++)
            {
                ContractUtils.RequiresNotNull(vars[i], nameof(variables), i);
            }

            return new RuntimeVariablesExpression(vars);
        }
        /// <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>();
            RequiresNotNullItems(initializerList, nameof(initializers));

            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();
            RequiresNotNullItems(iteratorList, nameof(iterators));

            return ForCSharpStatement.Make(variableList, initializerList, test, iteratorList, body, @break, @continue);
        }
        ///<summary>
        ///Creates an <see cref="T:System.Linq.Expressions.InvocationExpression" /> that 
        ///applies a delegate or lambda expression to a list of argument expressions.
        ///</summary>
        ///<returns>
        ///An <see cref="T:System.Linq.Expressions.InvocationExpression" /> that 
        ///applies the specified delegate or lambda expression to the provided arguments.
        ///</returns>
        ///<param name="expression">
        ///An <see cref="T:System.Linq.Expressions.Expression" /> that represents the delegate
        ///or lambda expression to be applied.
        ///</param>
        ///<param name="arguments">
        ///An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Linq.Expressions.Expression" /> objects
        ///that represent the arguments that the delegate or lambda expression is applied to.
        ///</param>
        ///<exception cref="T:System.ArgumentNullException">
        ///<paramref name="expression" /> is null.</exception>
        ///<exception cref="T:System.ArgumentException">
        ///<paramref name="expression" />.Type does not represent a delegate type or an <see cref="T:System.Linq.Expressions.Expression`1" />.-or-The <see cref="P:System.Linq.Expressions.Expression.Type" /> property of an element of <paramref name="arguments" /> is not assignable to the type of the corresponding parameter of the delegate represented by <paramref name="expression" />.</exception>
        ///<exception cref="T:System.InvalidOperationException">
        ///<paramref name="arguments" /> does not contain the same number of elements as the list of parameters for the delegate represented by <paramref name="expression" />.</exception>
        public static InvocationExpression Invoke(Expression expression, IEnumerable<Expression> arguments) {
            RequiresCanRead(expression, "expression");

            var args = arguments.ToReadOnly();
            var mi = GetInvokeMethod(expression);
            ValidateArgumentTypes(mi, ExpressionType.Invoke, ref args);
            return new InvocationExpression(expression, args, mi.ReturnType);
        }
Exemple #58
0
        /// <summary>
        /// Creates a <see cref="TryExpression"/> representing a try block with the specified elements.
        /// </summary>
        /// <param name="type">The result type of the try expression. If null, bodh and all handlers must have identical type.</param>
        /// <param name="body">The body of the try block.</param>
        /// <param name="finally">The body of the finally block. Pass null if the try block has no finally block associated with it.</param>
        /// <param name="fault">The body of the t block. Pass null if the try block has no fault block associated with it.</param>
        /// <param name="handlers">A collection of <see cref="CatchBlock"/>s representing the catch statements to be associated with the try block.</param>
        /// <returns>The created <see cref="TryExpression"/>.</returns>
        public static TryExpression MakeTry(Type type, Expression body, Expression @finally, Expression fault, IEnumerable<CatchBlock> handlers) {
            RequiresCanRead(body, "body");

            var @catch = handlers.ToReadOnly();
            ContractUtils.RequiresNotNullItems(@catch, "handlers");
            ValidateTryAndCatchHaveSameType(type, body, @catch);

            if (fault != null) {
                if (@finally != null || @catch.Count > 0) {
                    throw Error.FaultCannotHaveCatchOrFinally();
                }
                RequiresCanRead(fault, "fault");
            } else if (@finally != null) {
                RequiresCanRead(@finally, "finally");
            } else if (@catch.Count == 0) {
                throw Error.TryMustHaveCatchFinallyOrFault();
            }

            return new TryExpression(type ?? body.Type, body, @finally, fault, @catch);
        }
Exemple #59
0
        /// <summary>
        /// Creates a <see cref="SwitchExpression"/>.
        /// </summary>
        /// <param name="type">The result type of the switch.</param>
        /// <param name="switchValue">The value to be tested against each case.</param>
        /// <param name="defaultBody">The result of the switch if no cases are matched.</param>
        /// <param name="comparison">The equality comparison method to use.</param>
        /// <param name="cases">The valid cases for this switch.</param>
        /// <returns>The created <see cref="SwitchExpression"/>.</returns>
        public static SwitchExpression Switch(Type type, Expression switchValue, Expression defaultBody, MethodInfo comparison, IEnumerable<SwitchCase> cases)
        {
            RequiresCanRead(switchValue, nameof(switchValue));
            if (switchValue.Type == typeof(void)) throw Error.ArgumentCannotBeOfTypeVoid(nameof(switchValue));

            ReadOnlyCollection<SwitchCase> caseList = cases.ToReadOnly();
            ContractUtils.RequiresNotNullItems(caseList, nameof(cases));

            // Type of the result. Either provided, or it is type of the branches.
            Type resultType;
            if (type != null)
                resultType = type;
            else if (caseList.Count != 0)
                resultType = caseList[0].Body.Type;
            else if (defaultBody != null)
                resultType = defaultBody.Type;
            else
                resultType = typeof(void);
            bool customType = type != null;

            if (comparison != null)
            {
                ParameterInfo[] pms = comparison.GetParametersCached();
                if (pms.Length != 2)
                {
                    throw Error.IncorrectNumberOfMethodCallArguments(comparison, nameof(comparison));
                }
                // Validate that the switch value's type matches the comparison method's
                // left hand side parameter type.
                ParameterInfo leftParam = pms[0];
                bool liftedCall = false;
                if (!ParameterIsAssignable(leftParam, switchValue.Type))
                {
                    liftedCall = ParameterIsAssignable(leftParam, switchValue.Type.GetNonNullableType());
                    if (!liftedCall)
                    {
                        throw Error.SwitchValueTypeDoesNotMatchComparisonMethodParameter(switchValue.Type, leftParam.ParameterType);
                    }
                }

                ParameterInfo rightParam = pms[1];
                foreach (SwitchCase c in caseList)
                {
                    ContractUtils.RequiresNotNull(c, nameof(cases));
                    ValidateSwitchCaseType(c.Body, customType, resultType, nameof(cases));
                    for (int i = 0; i < c.TestValues.Count; i++)
                    {
                        // When a comparison method is provided, test values can have different type but have to
                        // be reference assignable to the right hand side parameter of the method.
                        Type rightOperandType = c.TestValues[i].Type;
                        if (liftedCall)
                        {
                            if (!rightOperandType.IsNullableType())
                            {
                                throw Error.TestValueTypeDoesNotMatchComparisonMethodParameter(rightOperandType, rightParam.ParameterType);
                            }
                            rightOperandType = rightOperandType.GetNonNullableType();
                        }
                        if (!ParameterIsAssignable(rightParam, rightOperandType))
                        {
                            throw Error.TestValueTypeDoesNotMatchComparisonMethodParameter(rightOperandType, rightParam.ParameterType);
                        }
                    }
                }

                // if we have a non-boolean user-defined equals, we don't want it.
                if (comparison.ReturnType != typeof(bool))
                {
                    throw Error.EqualityMustReturnBoolean(comparison, nameof(comparison));
                }
            }
            else if (caseList.Count != 0)
            {
                // When comparison method is not present, all the test values must have
                // the same type. Use the first test value's type as the baseline.
                Expression firstTestValue = caseList[0].TestValues[0];
                foreach (SwitchCase c in caseList)
                {
                    ContractUtils.RequiresNotNull(c, nameof(cases));
                    ValidateSwitchCaseType(c.Body, customType, resultType, nameof(cases));
                    // When no comparison method is provided, require all test values to have the same type.
                    for (int i = 0; i < c.TestValues.Count; i++)
                    {
                        if (!TypeUtils.AreEquivalent(firstTestValue.Type, c.TestValues[i].Type))
                        {
                            throw Error.AllTestValuesMustHaveSameType(nameof(cases));
                        }
                    }
                }

                // Now we need to validate that switchValue.Type and testValueType
                // make sense in an Equal node. Fortunately, Equal throws a
                // reasonable error, so just call it.
                BinaryExpression equal = Equal(switchValue, firstTestValue, false, comparison);

                // Get the comparison function from equals node.
                comparison = equal.Method;
            }

            if (defaultBody == null)
            {
                if (resultType != typeof(void)) throw Error.DefaultBodyMustBeSupplied(nameof(defaultBody));
            }
            else
            {
                ValidateSwitchCaseType(defaultBody, customType, resultType, nameof(defaultBody));
            }

            return new SwitchExpression(resultType, switchValue, defaultBody, comparison, caseList);
        }
        /// <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);
        }