예제 #1
0
        public AstNode ReplaceWith(Func <AstNode, AstNode> replaceFunction)
        {
            if (replaceFunction == null)
            {
                throw new ArgumentNullException("replaceFunction");
            }
            if (parent == null)
            {
                throw new InvalidOperationException(this.IsNull ? "Cannot replace the null nodes" : "Cannot replace the root node");
            }
            AstNode oldParent    = parent;
            AstNode oldSuccessor = nextSibling;
            Role    oldRole      = this.Role;

            Remove();
            AstNode replacement = replaceFunction(this);

            if (oldSuccessor != null && oldSuccessor.parent != oldParent)
            {
                throw new InvalidOperationException("replace function changed nextSibling of node being replaced?");
            }
            if (!(replacement == null || replacement.IsNull))
            {
                if (replacement.parent != null)
                {
                    throw new InvalidOperationException("replace function must return the root of a tree");
                }
                if (!oldRole.IsValid(replacement))
                {
                    throw new InvalidOperationException(string.Format("The new node '{0}' is not valid in the role {1}", replacement.GetType().Name, oldRole.ToString()));
                }

                if (oldSuccessor != null)
                {
                    oldParent.InsertChildBeforeUnsafe(oldSuccessor, replacement, oldRole);
                }
                else
                {
                    oldParent.AddChildUnsafe(replacement, oldRole);
                }
            }
            return(replacement);
        }
예제 #2
0
        /// <summary>
        /// Clones the whole subtree starting at this AST node.
        /// </summary>
        /// <remarks>Annotations are copied over to the new nodes; and any annotations implementing ICloneable will be cloned.</remarks>
        public AstNode Clone()
        {
            AstNode copy = (AstNode)MemberwiseClone();

            // First, reset the shallow pointer copies
            copy.parent      = null;
            copy.firstChild  = null;
            copy.lastChild   = null;
            copy.prevSibling = null;
            copy.nextSibling = null;
            copy.flags      &= ~frozenBit;        // unfreeze the copy

            // Then perform a deep copy:
            for (AstNode cur = firstChild; cur != null; cur = cur.nextSibling)
            {
                copy.AddChildUnsafe(cur.Clone(), cur.Role);
            }

            // Finally, clone the annotation, if necessary
            copy.CloneAnnotations();

            return(copy);
        }