public static Node SafeExpandOpAssign(this Node root, out Dictionary <Operator, Assign> out_roots)
        {
            var roots  = new Dictionary <Operator, Assign>();
            var x_root = root.Transform((Operator op) =>
            {
                var opt = op.OperatorType;
                if (!opt.IsAssign())
                {
                    return((Expression)op.DefaultTransform());
                }

                Func <Expression, Expression> mk_safe_lhs = lhs =>
                {
                    var @ref = lhs as Ref;
                    if (@ref != null)
                    {
                        return(lhs);
                    }

                    var slot = lhs as Slot;
                    if (slot != null)
                    {
                        var @this = slot.This;
                        if (@this == null || @this is Ref)
                        {
                            return(lhs);
                        }
                        else
                        {
                            var ass_root = @this.DeepClone();
                            var ref_root = new Ref(new Local(null, ass_root.Type()));
                            var ass      = new Assign(ref_root, ass_root);
                            roots.Add(op, ass);

                            var fld = slot as Fld;
                            if (fld != null)
                            {
                                return(new Fld(fld.Field, ref_root));
                            }

                            var prop = slot as Prop;
                            if (prop != null)
                            {
                                return(new Prop(prop.Property, ref_root, prop.InvokedAsVirtual));
                            }

                            throw AssertionHelper.Fail();
                        }
                    }

                    var eval = lhs as Eval;
                    var m    = eval == null ? null : eval.InvokedMethod();
                    if (m != null && m.IsArrayGetter())
                    {
                        var app   = eval.Callee;
                        var @this = eval.Callee.Args.First();

                        if (@this == null || @this is Ref)
                        {
                            return(lhs);
                        }
                        else
                        {
                            var ass_root = @this.DeepClone();
                            var ref_root = new Ref(new Local(null, ass_root.Type()));
                            var ass      = new Assign(ref_root, ass_root);
                            roots.Add(op, ass);

                            return(new Eval(new Apply(new Lambda(m), ref_root.Concat(app.Args.Skip(1)))));
                        }
                    }

                    throw AssertionHelper.Fail();
                };

                var safe_lhs = mk_safe_lhs(op.Args.FirstOrDefault());
                var rhs      = op.Args.SecondOrDefault() ?? new Const(1); // hack for inc/decrements
                return(new Assign(safe_lhs, Operator.Create(opt.Unassign(), safe_lhs, rhs)));
            }).AssertCast <Node>();

            out_roots = roots;
            return(x_root);
        }
Esempio n. 2
0
 public AssignDebugView(Assign node, Object parentProxy, String name)
 {
     _node = node; _parentProxy = parentProxy; _name = name;
 }
Esempio n. 3
0
 public AssignDebugView(Assign node) : this(node, null)
 {
 }
Esempio n. 4
0
 public AssignDebugView(Assign node, Object parentProxy) : this(node, parentProxy, NodeDebuggabilityHelper.InferDebugProxyNameFromStackTrace())
 {
 }
Esempio n. 5
0
 public AssignDebugView_NoParent(Assign node) : this(node, null)
 {
 }