Browse Source

Enable automatic removal when replacing a node with its own descendant.

newNRvisualizers
Daniel Grunwald 15 years ago
parent
commit
57522bf091
  1. 44
      ICSharpCode.NRefactory/CSharp/Ast/AstNode.cs

44
ICSharpCode.NRefactory/CSharp/Ast/AstNode.cs

@ -129,6 +129,26 @@ namespace ICSharpCode.NRefactory.CSharp @@ -129,6 +129,26 @@ namespace ICSharpCode.NRefactory.CSharp
}
}
/// <summary>
/// Gets the ancestors of this node (excluding this node itself)
/// </summary>
public IEnumerable<AstNode> Ancestors {
get {
for (AstNode cur = parent; cur != null; cur = cur.parent) {
yield return cur;
}
}
}
/// <summary>
/// Gets all descendants of this node (excluding this node itself).
/// </summary>
public IEnumerable<AstNode> Descendants {
get {
return Utils.TreeTraversal.PreOrder(this.Children, n => n.Children);
}
}
/// <summary>
/// Gets the first child with the specified role.
/// Returns the role's null object if the child is not found.
@ -291,20 +311,27 @@ namespace ICSharpCode.NRefactory.CSharp @@ -291,20 +311,27 @@ namespace ICSharpCode.NRefactory.CSharp
Remove();
return;
}
if (this.parent == null) {
if (newNode == this)
return; // nothing to do...
if (parent == null) {
throw new InvalidOperationException(this.IsNull ? "Cannot replace the null nodes" : "Cannot replace the root node");
}
if (newNode.parent != null) {
// TODO: what if newNode is used within *this* tree?
// e.g. "parenthesizedExpr.ReplaceWith(parenthesizedExpr.Expression);"
// We'll probably want to allow that.
throw new ArgumentException ("Node is already used in another tree.", "newNode");
}
// Because this method doesn't statically check the new node's type with the role,
// we perform a runtime test:
if (!role.IsValid(newNode)) {
throw new ArgumentException (string.Format("The new node '{0}' is not valid in the role {1}", newNode.GetType().Name, role.ToString()), "newNode");
}
if (newNode.parent != null) {
// newNode is used within this tree?
if (newNode.Ancestors.Contains(this)) {
// e.g. "parenthesizedExpr.ReplaceWith(parenthesizedExpr.Expression);"
// enable automatic removal
newNode.Remove();
} else {
throw new ArgumentException ("Node is already used in another tree.", "newNode");
}
}
newNode.parent = parent;
newNode.role = role;
newNode.prevSibling = prevSibling;
@ -335,6 +362,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -335,6 +362,9 @@ namespace ICSharpCode.NRefactory.CSharp
{
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 = role;

Loading…
Cancel
Save