Exemple #1
0
        public AST <Node> Substitute(
            ASTQueries.NodePredAtom filter,
            Func <IEnumerable <ChildInfo>, NodeKind> subKind,
            Func <IEnumerable <ChildInfo>, Node> sub,
            CancellationToken cancel = default(CancellationToken))
        {
            var query = new ASTQueries.NodePred[]
            {
                ASTQueries.NodePredFactory.Instance.Star,
                ASTQueries.NodePredFactory.Instance.MkPredicate(NodeKind.Id) & filter
            };

            if (Root.NodeKind == NodeKind.Id)
            {
                if (Root.Eval(query[1], ChildContextKind.AnyChildContext, 0, 0))
                {
                    var rootPath = new ChildInfo[] { new ChildInfo(Root, ChildContextKind.AnyChildContext, -1, -1) };
                    var kind     = subKind(rootPath);
                    var m        = sub(rootPath);
                    return(m.NodeKind != kind ? this : Factory.Instance.ToAST(m));
                }
                else
                {
                    return(this);
                }
            }

            AST <Node> crntAst = Factory.Instance.ToAST(Root);

            this.FindAll(
                query,
                (pt, x) =>
            {
                var list  = (LinkedList <ChildInfo>)pt;
                var prev  = list.Last.Previous;
                var rkind = subKind(pt);
                if (!ASTQueries.ASTSchema.Instance.CanReplace(
                        prev.Value.Node,
                        list.Last.Value.Node,
                        list.Last.Value.Context,
                        rkind))
                {
                    return;
                }

                var rep = sub(pt);
                if (rep.NodeKind != rkind)
                {
                    return;
                }

                var newAST  = crntAst == this ? this : Factory.Instance.FromAbsPositions(crntAst.Root, pt);
                var crnt    = ((LinkedList <ChildInfo>)newAST.Path).Last;
                var subPath = new LinkedList <ChildInfo>();
                Node n      = null, p = null;
                int pos     = -1;
                while (crnt != null)
                {
                    n   = pos == -1 ? rep : crnt.Value.Node.ShallowClone(p, pos);
                    pos = crnt.Value.AbsolutePos;
                    p   = n;

                    subPath.AddFirst(new ChildInfo(n, crnt.Value.Context, pos, crnt.Value.RelativePos));
                    crnt = crnt.Previous;
                }

                crntAst = Factory.Instance.ToAST(n);
            },
                cancel);

            crntAst.GetHashCode();
            return(crntAst);
        }