+ protected DynamicMemberAssignable (Arguments args, Location loc)
+ : base (null, args, loc)
+ {
+ base.binder = this;
+ }
+
+ public Expression CreateCallSiteBinder (ResolveContext ec, Arguments args)
+ {
+ //
+ // DoResolve always uses getter
+ //
+ return CreateCallSiteBinder (ec, args, false);
+ }
+
+ protected abstract Expression CreateCallSiteBinder (ResolveContext ec, Arguments args, bool isSet);
+
+ 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;
+ }
+
+ 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 = CreateSetterArguments (rc, right_side);
+ setter = CreateCallSiteBinder (rc, setter_args, true);
+ }
+
+ eclass = ExprClass.Variable;
+ return this;
+ }
+
+ public override void Emit (EmitContext ec)
+ {
+ // It's null for ResolveLValue used without assignment
+ if (binder_expr == null)
+ EmitCall (ec, setter, Arguments, false);
+ else
+ base.Emit (ec);
+ }
+
+ public override void EmitStatement (EmitContext ec)
+ {
+ // It's null for ResolveLValue used without assignment
+ if (binder_expr == null)
+ EmitCall (ec, setter, Arguments, true);
+ else
+ base.EmitStatement (ec);