Example #1
0
		protected virtual Arguments CreateSetterArguments (ResolveContext rc, Expression rhs)
		{
			var setter_args = new Arguments (Arguments.Count + 1);
			setter_args.AddRange (Arguments);
			setter_args.Add (new Argument (rhs));
			return setter_args;
		}
Example #2
0
File: assign.cs Project: dyxu/vimrc
		protected override Expression DoResolve (ResolveContext ec)
		{
			right = right.Resolve (ec);
			if (right == null)
				return null;

			MemberAccess ma = target as MemberAccess;
			using (ec.Set (ResolveContext.Options.CompoundAssignmentScope)) {
				target = target.Resolve (ec);
			}
			
			if (target == null)
				return null;

			if (target is MethodGroupExpr){
				ec.Report.Error (1656, loc,
					"Cannot assign to `{0}' because it is a `{1}'",
					((MethodGroupExpr)target).Name, target.ExprClassName);
				return null;
			}

			var event_expr = target as EventExpr;
			if (event_expr != null) {
				source = Convert.ImplicitConversionRequired (ec, right, target.Type, loc);
				if (source == null)
					return null;

				Expression rside;
				if (op == Binary.Operator.Addition)
					rside = EmptyExpression.EventAddition;
				else if (op == Binary.Operator.Subtraction)
					rside = EmptyExpression.EventSubtraction;
				else
					rside = null;

				target = target.ResolveLValue (ec, rside);
				if (target == null)
					return null;

				eclass = ExprClass.Value;
				type = event_expr.Operator.ReturnType;
				return this;
			}

			//
			// Only now we can decouple the original source/target
			// into a tree, to guarantee that we do not have side
			// effects.
			//
			if (left == null)
				left = new TargetExpression (target);

			source = new Binary (op, left, right, true);

			if (target is DynamicMemberAssignable) {
				Arguments targs = ((DynamicMemberAssignable) target).Arguments;
				source = source.Resolve (ec);

				Arguments args = new Arguments (targs.Count + 1);
				args.AddRange (targs);
				args.Add (new Argument (source));

				var binder_flags = CSharpBinderFlags.ValueFromCompoundAssignment;

				//
				// Compound assignment does target conversion using additional method
				// call, set checked context as the binary operation can overflow
				//
				if (ec.HasSet (ResolveContext.Options.CheckedScope))
					binder_flags |= CSharpBinderFlags.CheckedContext;

				if (target is DynamicMemberBinder) {
					source = new DynamicMemberBinder (ma.Name, binder_flags, args, loc).Resolve (ec);

					// Handles possible event addition/subtraction
					if (op == Binary.Operator.Addition || op == Binary.Operator.Subtraction) {
						args = new Arguments (targs.Count + 1);
						args.AddRange (targs);
						args.Add (new Argument (right));
						string method_prefix = op == Binary.Operator.Addition ?
							Event.AEventAccessor.AddPrefix : Event.AEventAccessor.RemovePrefix;

						var invoke = DynamicInvocation.CreateSpecialNameInvoke (
							new MemberAccess (right, method_prefix + ma.Name, loc), args, loc).Resolve (ec);

						args = new Arguments (targs.Count);
						args.AddRange (targs);
						source = new DynamicEventCompoundAssign (ma.Name, args,
							(ExpressionStatement) source, (ExpressionStatement) invoke, loc).Resolve (ec);
					}
				} else {
					source = new DynamicIndexBinder (binder_flags, args, loc).Resolve (ec);
				}

				return source;
			}

			return base.DoResolve (ec);
		}
Example #3
0
        public override Expression DoResolveLValue(ResolveContext rc, Expression right_side)
        {
            if (right_side == EmptyExpression.OutAccess.Instance) {
                right_side.DoResolveLValue (rc, this);
                return null;
            }

            if (DoResolveCore (rc)) {
                setter_args = new Arguments (Arguments.Count + 1);
                setter_args.AddRange (Arguments);
                setter_args.Add (new Argument (right_side));
                setter = CreateCallSiteBinder (rc, setter_args, true);
            }

            eclass = ExprClass.Variable;
            return this;
        }
Example #4
0
		protected virtual Arguments CreateSetterArguments (ResolveContext rc, Expression rhs)
		{
			var setter_args = new Arguments (Arguments.Count + 1);
			setter_args.AddRange (Arguments);
			setter_args.Add (new Argument (rhs));
			return setter_args;
		}
Example #5
0
        protected override Expression DoResolve(ResolveContext ec)
        {
            right = right.Resolve(ec);
            if (right == null)
            {
                return(null);
            }

            MemberAccess ma = target as MemberAccess;

            using (ec.Set(ResolveContext.Options.CompoundAssignmentScope)) {
                target = target.Resolve(ec);
            }

            if (target == null)
            {
                return(null);
            }

            if (target is MethodGroupExpr)
            {
                ec.Report.Error(1656, loc,
                                "Cannot assign to `{0}' because it is a `{1}'",
                                ((MethodGroupExpr)target).Name, target.ExprClassName);
                return(null);
            }

            var event_expr = target as EventExpr;

            if (event_expr != null)
            {
                source = Convert.ImplicitConversionRequired(ec, right, target.Type, loc);
                if (source == null)
                {
                    return(null);
                }

                Expression rside;
                if (op == Binary.Operator.Addition)
                {
                    rside = EmptyExpression.EventAddition;
                }
                else if (op == Binary.Operator.Subtraction)
                {
                    rside = EmptyExpression.EventSubtraction;
                }
                else
                {
                    rside = null;
                }

                target = target.ResolveLValue(ec, rside);
                if (target == null)
                {
                    return(null);
                }

                eclass = ExprClass.Value;
                type   = event_expr.Operator.ReturnType;
                return(this);
            }

            //
            // Only now we can decouple the original source/target
            // into a tree, to guarantee that we do not have side
            // effects.
            //
            if (left == null)
            {
                left = new TargetExpression(target);
            }

            source = new Binary(op, left, right, true, loc);

            if (target is DynamicMemberAssignable)
            {
                Arguments targs = ((DynamicMemberAssignable)target).Arguments;
                source = source.Resolve(ec);

                Arguments args = new Arguments(targs.Count + 1);
                args.AddRange(targs);
                args.Add(new Argument(source));

                var binder_flags = CSharpBinderFlags.ValueFromCompoundAssignment;

                //
                // Compound assignment does target conversion using additional method
                // call, set checked context as the binary operation can overflow
                //
                if (ec.HasSet(ResolveContext.Options.CheckedScope))
                {
                    binder_flags |= CSharpBinderFlags.CheckedContext;
                }

                if (target is DynamicMemberBinder)
                {
                    source = new DynamicMemberBinder(ma.Name, binder_flags, args, loc).Resolve(ec);

                    // Handles possible event addition/subtraction
                    if (op == Binary.Operator.Addition || op == Binary.Operator.Subtraction)
                    {
                        args = new Arguments(targs.Count + 1);
                        args.AddRange(targs);
                        args.Add(new Argument(right));
                        string method_prefix = op == Binary.Operator.Addition ?
                                               Event.AEventAccessor.AddPrefix : Event.AEventAccessor.RemovePrefix;

                        var invoke = DynamicInvocation.CreateSpecialNameInvoke(
                            new MemberAccess(right, method_prefix + ma.Name, loc), args, loc).Resolve(ec);

                        args = new Arguments(targs.Count);
                        args.AddRange(targs);
                        source = new DynamicEventCompoundAssign(ma.Name, args,
                                                                (ExpressionStatement)source, (ExpressionStatement)invoke, loc).Resolve(ec);
                    }
                }
                else
                {
                    source = new DynamicIndexBinder(binder_flags, args, loc).Resolve(ec);
                }

                return(source);
            }

            return(base.DoResolve(ec));
        }
Example #6
0
File: assign.cs Project: ikvm/mono
		protected override Expression DoResolve (ResolveContext ec)
		{
			right = right.Resolve (ec);
			if (right == null)
				return null;

			MemberAccess ma = target as MemberAccess;
			using (ec.Set (ResolveContext.Options.CompoundAssignmentScope)) {
				target = target.Resolve (ec);
			}
			
			if (target == null)
				return null;

			if (target is MethodGroupExpr){
				ec.Report.Error (1656, loc,
					"Cannot assign to `{0}' because it is a `{1}'",
					((MethodGroupExpr)target).Name, target.ExprClassName);
				return null;
			}

			if (target is EventExpr)
				return new EventAddOrRemove (target, op, right, loc).Resolve (ec);

			//
			// Only now we can decouple the original source/target
			// into a tree, to guarantee that we do not have side
			// effects.
			//
			if (left == null)
				left = new TargetExpression (target);

			source = new Binary (op, left, right, true, loc);

			if (target is DynamicMemberBinder) {
				Arguments targs = ((DynamicMemberBinder) target).Arguments;
				source = source.Resolve (ec);

				Arguments args = new Arguments (2);
				args.AddRange (targs);
				args.Add (new Argument (source));
				source = new DynamicMemberBinder (ma.Name, args, loc).ResolveLValue (ec, right);

				// Handles possible event addition/subtraction
				if (op == Binary.Operator.Addition || op == Binary.Operator.Subtraction) {
					args = new Arguments (2);
					args.AddRange (targs);
					args.Add (new Argument (right));
					string method_prefix = op == Binary.Operator.Addition ?
						Event.AEventAccessor.AddPrefix : Event.AEventAccessor.RemovePrefix;

					var invoke = DynamicInvocation.CreateSpecialNameInvoke (
						new MemberAccess (right, method_prefix + ma.Name, loc), args, loc).Resolve (ec);

					args = new Arguments (1);
					args.AddRange (targs);
					source = new DynamicEventCompoundAssign (ma.Name, args,
						(ExpressionStatement) source, (ExpressionStatement) invoke, loc).Resolve (ec);
				}

				return source;
			}

			return base.DoResolve (ec);
		}
Example #7
0
        ///
        /// Determines if the candidate method is applicable (section 14.4.2.1)
        /// to the given set of arguments
        /// A return value rates candidate method compatibility,
        /// 0 = the best, int.MaxValue = the worst
        ///
        public int IsApplicable(ResolveContext ec,
            ref Arguments arguments, int arg_count, ref MethodSpec method, ref bool params_expanded_form)
        {
            var candidate = method;

            AParametersCollection pd = candidate.Parameters;
            int param_count = GetApplicableParametersCount (candidate, pd);
            int optional_count = 0;

            if (arg_count != param_count) {
                for (int i = 0; i < pd.Count; ++i) {
                    if (pd.FixedParameters [i].HasDefaultValue) {
                        optional_count = pd.Count - i;
                        break;
                    }
                }

                int args_gap = System.Math.Abs (arg_count - param_count);
                if (optional_count != 0) {
                    if (args_gap > optional_count)
                        return int.MaxValue - 10000 + args_gap - optional_count;

                    // Readjust expected number when params used
                    if (pd.HasParams) {
                        optional_count--;
                        if (arg_count < param_count)
                            param_count--;
                    } else if (arg_count > param_count) {
                        return int.MaxValue - 10000 + args_gap;
                    }
                } else if (arg_count != param_count) {
                    if (!pd.HasParams)
                        return int.MaxValue - 10000 + args_gap;
                    if (arg_count < param_count - 1)
                        return int.MaxValue - 10000 + args_gap;
                }

                // Initialize expanded form of a method with 1 params parameter
                params_expanded_form = param_count == 1 && pd.HasParams;

                // Resize to fit optional arguments
                if (optional_count != 0) {
                    Arguments resized;
                    if (arguments == null) {
                        resized = new Arguments (optional_count);
                    } else {
                        resized = new Arguments (param_count);
                        resized.AddRange (arguments);
                    }

                    for (int i = arg_count; i < param_count; ++i)
                        resized.Add (null);
                    arguments = resized;
                }
            }

            if (arg_count > 0) {
                //
                // Shuffle named arguments to the right positions if there are any
                //
                if (arguments [arg_count - 1] is NamedArgument) {
                    arg_count = arguments.Count;

                    for (int i = 0; i < arg_count; ++i) {
                        bool arg_moved = false;
                        while (true) {
                            NamedArgument na = arguments[i] as NamedArgument;
                            if (na == null)
                                break;

                            int index = pd.GetParameterIndexByName (na.Name);

                            // Named parameter not found or already reordered
                            if (index <= i)
                                break;

                            // When using parameters which should not be available to the user
                            if (index >= param_count)
                                break;

                            if (!arg_moved) {
                                arguments.MarkReorderedArgument (na);
                                arg_moved = true;
                            }

                            Argument temp = arguments[index];
                            arguments[index] = arguments[i];
                            arguments[i] = temp;

                            if (temp == null)
                                break;
                        }
                    }
                } else {
                    arg_count = arguments.Count;
                }
            } else if (arguments != null) {
                arg_count = arguments.Count;
            }

            //
            // 1. Handle generic method using type arguments when specified or type inference
            //
            if (candidate.IsGeneric) {
                if (type_arguments != null) {
                    var g_args_count = candidate.Arity;
                    if (g_args_count != type_arguments.Count)
                        return int.MaxValue - 20000 + System.Math.Abs (type_arguments.Count - g_args_count);

                    method = candidate.MakeGenericMethod (type_arguments.Arguments);
                    candidate = method;
                    pd = candidate.Parameters;
                } else {
                    int score = TypeManager.InferTypeArguments (ec, arguments, ref candidate);
                    if (score != 0)
                        return score - 20000;

                    pd = candidate.Parameters;
                }
            } else {
                if (type_arguments != null)
                    return int.MaxValue - 15000;
            }

            //
            // 2. Each argument has to be implicitly convertible to method parameter
            //
            method = candidate;
            Parameter.Modifier p_mod = 0;
            TypeSpec pt = null;
            for (int i = 0; i < arg_count; i++) {
                Argument a = arguments [i];
                if (a == null) {
                    if (!pd.FixedParameters [i].HasDefaultValue)
                        throw new InternalErrorException ();

                    Expression e = pd.FixedParameters [i].DefaultValue as Constant;
                    if (e == null)
                        e = new DefaultValueExpression (new TypeExpression (pd.Types [i], loc), loc).Resolve (ec);

                    arguments [i] = new Argument (e, Argument.AType.Default);
                    continue;
                }

                if (p_mod != Parameter.Modifier.PARAMS) {
                    p_mod = pd.FixedParameters [i].ModFlags & ~(Parameter.Modifier.OUTMASK | Parameter.Modifier.REFMASK);
                    pt = pd.Types [i];
                } else {
                    params_expanded_form = true;
                }

                Parameter.Modifier a_mod = a.Modifier & ~(Parameter.Modifier.OUTMASK | Parameter.Modifier.REFMASK);
                int score = 1;
                if (!params_expanded_form)
                    score = IsArgumentCompatible (ec, a_mod, a, p_mod & ~Parameter.Modifier.PARAMS, pt);

                if (score != 0 && (p_mod & Parameter.Modifier.PARAMS) != 0 && delegate_type == null) {
                    // It can be applicable in expanded form
                    score = IsArgumentCompatible (ec, a_mod, a, 0, TypeManager.GetElementType (pt));
                    if (score == 0)
                        params_expanded_form = true;
                }

                if (score != 0) {
                    if (params_expanded_form)
                        ++score;
                    return (arg_count - i) * 2 + score;
                }
            }

            if (arg_count != param_count)
                params_expanded_form = true;

            return 0;
        }
		Expression ResolveAccessor (ResolveContext ec, Expression right_side)
		{
			CommonResolve (ec);

			bool dynamic;
			arguments.Resolve (ec, out dynamic);
			if (dynamic || TypeManager.IsDynamicType (indexer_type)) {
				int additional = right_side == null ? 1 : 2;
				Arguments args = new Arguments (arguments.Count + additional);
				if (is_base_indexer) {
					ec.Report.Error (1972, loc, "The indexer base access cannot be dynamically dispatched. Consider casting the dynamic arguments or eliminating the base access");
				} else {
					args.Add (new Argument (instance_expr));
				}
				args.AddRange (arguments);
				if (right_side != null)
					args.Add (new Argument (right_side));

				return new DynamicIndexBinder (right_side != null, args, loc).Resolve (ec);
			}

			Indexers ilist = Indexers.GetIndexersForType (current_type, indexer_type);
			if (ilist.Methods == null) {
				ec.Report.Error (21, loc, "Cannot apply indexing with [] to an expression of type `{0}'",
						  TypeManager.CSharpName (indexer_type));
				return null;
			}

			MethodGroupExpr mg = new IndexerMethodGroupExpr (ilist, loc);
			mg = mg.OverloadResolve (ec, ref arguments, false, loc);
			if (mg == null)
				return null;

			MethodInfo mi = (MethodInfo) mg;
			PropertyInfo pi = null;
			for (int i = 0; i < ilist.Methods.Count; ++i) {
				if (ilist.Methods [i] == mi) {
					pi = (PropertyInfo) ilist.Properties [i];
					break;
				}
			}

			type = TypeManager.TypeToCoreType (pi.PropertyType);
			if (type.IsPointer && !ec.IsUnsafe)
				UnsafeError (ec, loc);

			MethodInfo accessor;
			if (right_side == null) {
				accessor = get = pi.GetGetMethod (true);
			} else {
				accessor = set = pi.GetSetMethod (true);
				if (accessor == null && pi.GetGetMethod (true) != null) {
					ec.Report.SymbolRelatedToPreviousError (pi);
					ec.Report.Error (200, loc, "The read only property or indexer `{0}' cannot be assigned to",
						TypeManager.GetFullNameSignature (pi));
					return null;
				}

				set_expr = Convert.ImplicitConversion (ec, right_side, type, loc);
			}

			if (accessor == null) {
				ec.Report.SymbolRelatedToPreviousError (pi);
				ec.Report.Error (154, loc, "The property or indexer `{0}' cannot be used in this context because it lacks a `{1}' accessor",
					TypeManager.GetFullNameSignature (pi), GetAccessorName (right_side != null));
				return null;
			}

			//
			// Only base will allow this invocation to happen.
			//
			if (accessor.IsAbstract && this is BaseIndexerAccess) {
				Error_CannotCallAbstractBase (ec, TypeManager.GetFullNameSignature (pi));
			}

			bool must_do_cs1540_check;
			if (!IsAccessorAccessible (ec.CurrentType, accessor, out must_do_cs1540_check)) {
				if (set == null)
					set = pi.GetSetMethod (true);
				else
					get = pi.GetGetMethod (true);

				if (set != null && get != null &&
					(set.Attributes & MethodAttributes.MemberAccessMask) != (get.Attributes & MethodAttributes.MemberAccessMask)) {
					ec.Report.SymbolRelatedToPreviousError (accessor);
					ec.Report.Error (271, loc, "The property or indexer `{0}' cannot be used in this context because a `{1}' accessor is inaccessible",
						TypeManager.GetFullNameSignature (pi), GetAccessorName (right_side != null));
				} else {
					ec.Report.SymbolRelatedToPreviousError (pi);
					ErrorIsInaccesible (loc, TypeManager.GetFullNameSignature (pi), ec.Report);
				}
			}

			instance_expr.CheckMarshalByRefAccess (ec);
			eclass = ExprClass.IndexerAccess;
			return this;
		}
Example #9
0
        public override Expression DoResolve(ResolveContext ec)
        {
            right = right.Resolve(ec);
            if (right == null)
            {
                return(null);
            }

            MemberAccess ma = target as MemberAccess;

            using (ec.Set(ResolveContext.Options.CompoundAssignmentScope)) {
                target = target.Resolve(ec);
            }

            if (target == null)
            {
                return(null);
            }

            if (target is MethodGroupExpr)
            {
                ec.Report.Error(1656, loc,
                                "Cannot assign to `{0}' because it is a `{1}'",
                                ((MethodGroupExpr)target).Name, target.ExprClassName);
                return(null);
            }

            if (target is EventExpr)
            {
                return(new EventAddOrRemove(target, op, right, loc).DoResolve(ec));
            }

            //
            // Only now we can decouple the original source/target
            // into a tree, to guarantee that we do not have side
            // effects.
            //
            if (left == null)
            {
                left = new TargetExpression(target);
            }

            source = new Binary(op, left, right, true);

            // TODO: TargetExpression breaks MemberAccess composition
            if (target is DynamicMemberBinder)
            {
                Arguments targs = ((DynamicMemberBinder)target).Arguments;
                source = source.Resolve(ec);

                Arguments args = new Arguments(2);
                args.AddRange(targs);
                args.Add(new Argument(source));
                source = new DynamicMemberBinder(true, ma.Name, args, loc).Resolve(ec);

                // Handles possible event addition/subtraction
                if (op == Binary.Operator.Addition || op == Binary.Operator.Subtraction)
                {
                    args = new Arguments(2);
                    args.AddRange(targs);
                    args.Add(new Argument(right));
                    string method_prefix = op == Binary.Operator.Addition ?
                                           Event.AEventAccessor.AddPrefix : Event.AEventAccessor.RemovePrefix;

                    Expression invoke = new DynamicInvocation(
                        new MemberAccess(right, method_prefix + ma.Name, loc), args, loc).Resolve(ec);

                    args = new Arguments(1);
                    args.AddRange(targs);
                    source = new DynamicEventCompoundAssign(ma.Name, args,
                                                            (ExpressionStatement)source, (ExpressionStatement)invoke, loc).Resolve(ec);
                }

                return(source);
            }

            return(base.DoResolve(ec));
        }