1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/* 2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * [The "BSD licence"] 3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Copyright (c) 2011 Terence Parr 4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * All rights reserved. 5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Conversion to C#: 7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Copyright (c) 2011 Sam Harwell, Pixel Mine, Inc. 8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * All rights reserved. 9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Redistribution and use in source and binary forms, with or without 11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * modification, are permitted provided that the following conditions 12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * are met: 13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 1. Redistributions of source code must retain the above copyright 14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * notice, this list of conditions and the following disclaimer. 15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 2. Redistributions in binary form must reproduce the above copyright 16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * notice, this list of conditions and the following disclaimer in the 17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * documentation and/or other materials provided with the distribution. 18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 3. The name of the author may not be used to endorse or promote products 19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * derived from this software without specific prior written permission. 20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvernamespace Antlr.Runtime.Tree 34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver using System.Collections.Generic; 36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver using ArgumentNullException = System.ArgumentNullException; 38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver using Exception = System.Exception; 39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver using IDictionary = System.Collections.IDictionary; 40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver using NotSupportedException = System.NotSupportedException; 41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary>A TreeAdaptor that works with any Tree implementation.</summary> */ 43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public abstract class BaseTreeAdaptor : ITreeAdaptor 44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary> 46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * System.identityHashCode() is not always unique; we have to 47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * track ourselves. That's ok, it's only for debugging, though it's 48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * expensive: we have to create a hashtable with all tree nodes in it. 49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </summary> 50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected IDictionary<object, int> treeToUniqueIDMap; 52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected int uniqueNodeID = 1; 53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual object Nil() 55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return Create( null ); 57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary> 60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Create tree node that holds the start and stop tokens associated 61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * with an error. 62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </summary> 63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * <remarks> 65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * If you specify your own kind of tree nodes, you will likely have to 66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * override this method. CommonTree returns Token.INVALID_TOKEN_TYPE 67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * if no token payload but you might have to set token type for diff 68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * node type. 69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * You don't have to subclass CommonErrorNode; you will likely need to 71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * subclass your own tree node class to avoid class cast exception. 72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </remarks> 73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual object ErrorNode( ITokenStream input, IToken start, IToken stop, 75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver RecognitionException e ) 76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver CommonErrorNode t = new CommonErrorNode( input, start, stop, e ); 78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //System.out.println("returning error node '"+t+"' @index="+input.index()); 79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return t; 80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual bool IsNil( object tree ) 83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ( (ITree)tree ).IsNil; 85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual object DupNode(int type, object treeNode) 88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver object t = DupNode(treeNode); 90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver SetType(t, type); 91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return t; 92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual object DupNode(object treeNode, string text) 95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver object t = DupNode(treeNode); 97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver SetText(t, text); 98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return t; 99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual object DupNode(int type, object treeNode, string text) 102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver object t = DupNode(treeNode); 104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver SetType(t, type); 105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver SetText(t, text); 106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return t; 107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual object DupTree( object tree ) 110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return DupTree( tree, null ); 112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary> 115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * This is generic in the sense that it will work with any kind of 116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * tree (not just ITree interface). It invokes the adaptor routines 117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * not the tree node routines to do the construction. 118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </summary> 119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual object DupTree( object t, object parent ) 121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( t == null ) 123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return null; 125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver object newTree = DupNode( t ); 127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // ensure new subtree root has parent/child index set 128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver SetChildIndex( newTree, GetChildIndex( t ) ); // same index in new tree 129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver SetParent( newTree, parent ); 130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver int n = GetChildCount( t ); 131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for ( int i = 0; i < n; i++ ) 132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver object child = GetChild( t, i ); 134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver object newSubTree = DupTree( child, t ); 135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver AddChild( newTree, newSubTree ); 136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return newTree; 138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary> 141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Add a child to the tree t. If child is a flat tree (a list), make all 142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * in list children of t. Warning: if t has no children, but child does 143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * and child isNil then you can decide it is ok to move children to t via 144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * t.children = child.children; i.e., without copying the array. Just 145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * make sure that this is consistent with have the user will build 146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * ASTs. 147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </summary> 148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual void AddChild( object t, object child ) 150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( t != null && child != null ) 152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ( (ITree)t ).AddChild( (ITree)child ); 154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary> 158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * If oldRoot is a nil root, just copy or move the children to newRoot. 159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * If not a nil root, make oldRoot a child of newRoot. 160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </summary> 161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * <remarks> 163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * old=^(nil a b c), new=r yields ^(r a b c) 164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * old=^(a b c), new=r yields ^(r ^(a b c)) 165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * If newRoot is a nil-rooted single child tree, use the single 167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * child as the new root node. 168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * old=^(nil a b c), new=^(nil r) yields ^(r a b c) 170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * old=^(a b c), new=^(nil r) yields ^(r ^(a b c)) 171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * If oldRoot was null, it's ok, just return newRoot (even if isNil). 173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * old=null, new=r yields r 175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * old=null, new=^(nil r) yields ^(nil r) 176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Return newRoot. Throw an exception if newRoot is not a 178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * simple node or nil root with a single child node--it must be a root 179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * node. If newRoot is ^(nil x) return x as newRoot. 180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Be advised that it's ok for newRoot to point at oldRoot's 182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * children; i.e., you don't have to copy the list. We are 183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * constructing these nodes so we should have this control for 184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * efficiency. 185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </remarks> 186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual object BecomeRoot( object newRoot, object oldRoot ) 188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //System.out.println("becomeroot new "+newRoot.toString()+" old "+oldRoot); 190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ITree newRootTree = (ITree)newRoot; 191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ITree oldRootTree = (ITree)oldRoot; 192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( oldRoot == null ) 193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return newRoot; 195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // handle ^(nil real-node) 197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( newRootTree.IsNil ) 198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver int nc = newRootTree.ChildCount; 200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( nc == 1 ) 201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver newRootTree = (ITree)newRootTree.GetChild( 0 ); 202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else if ( nc > 1 ) 203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // TODO: make tree run time exceptions hierarchy 205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver throw new Exception( "more than one node as root (TODO: make exception hierarchy)" ); 206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // add oldRoot to newRoot; addChild takes care of case where oldRoot 209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // is a flat list (i.e., nil-rooted tree). All children of oldRoot 210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // are added to newRoot. 211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver newRootTree.AddChild( oldRootTree ); 212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return newRootTree; 213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary>Transform ^(nil x) to x and nil to null</summary> */ 216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual object RulePostProcessing( object root ) 217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //System.out.println("rulePostProcessing: "+((Tree)root).toStringTree()); 219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ITree r = (ITree)root; 220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( r != null && r.IsNil ) 221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( r.ChildCount == 0 ) 223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver r = null; 225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else if ( r.ChildCount == 1 ) 227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver r = (ITree)r.GetChild( 0 ); 229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // whoever invokes rule will set parent and child index 230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver r.Parent = null; 231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver r.ChildIndex = -1; 232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return r; 235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual object BecomeRoot( IToken newRoot, object oldRoot ) 238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return BecomeRoot( Create( newRoot ), oldRoot ); 240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual object Create( int tokenType, IToken fromToken ) 243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver fromToken = CreateToken( fromToken ); 245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver fromToken.Type = tokenType; 246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver object t = Create( fromToken ); 247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return t; 248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual object Create( int tokenType, IToken fromToken, string text ) 251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( fromToken == null ) 253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return Create( tokenType, text ); 254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver fromToken = CreateToken( fromToken ); 256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver fromToken.Type = tokenType; 257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver fromToken.Text = text; 258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver object result = Create(fromToken); 259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return result; 260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual object Create(IToken fromToken, string text) 263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (fromToken == null) 265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver throw new ArgumentNullException("fromToken"); 266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver fromToken = CreateToken(fromToken); 268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver fromToken.Text = text; 269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver object result = Create(fromToken); 270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return result; 271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual object Create( int tokenType, string text ) 274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver IToken fromToken = CreateToken( tokenType, text ); 276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver object t = Create( fromToken ); 277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return t; 278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual int GetType( object t ) 281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ITree tree = GetTree(t); 283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (tree == null) 284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return TokenTypes.Invalid; 285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return tree.Type; 287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual void SetType( object t, int type ) 290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver throw new NotSupportedException( "don't know enough about Tree node" ); 292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual string GetText( object t ) 295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ITree tree = GetTree(t); 297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (tree == null) 298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return null; 299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return tree.Text; 301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual void SetText( object t, string text ) 304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver throw new NotSupportedException( "don't know enough about Tree node" ); 306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual object GetChild( object t, int i ) 309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ITree tree = GetTree(t); 311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (tree == null) 312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return null; 313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return tree.GetChild(i); 315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual void SetChild( object t, int i, object child ) 318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ITree tree = GetTree(t); 320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (tree == null) 321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ITree childTree = GetTree(child); 324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.SetChild(i, childTree); 325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual object DeleteChild( object t, int i ) 328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ( (ITree)t ).DeleteChild( i ); 330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual int GetChildCount( object t ) 333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ITree tree = GetTree(t); 335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (tree == null) 336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return 0; 337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return tree.ChildCount; 339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual int GetUniqueID( object node ) 342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( treeToUniqueIDMap == null ) 344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver treeToUniqueIDMap = new Dictionary<object, int>(); 346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver int id; 348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( treeToUniqueIDMap.TryGetValue( node, out id ) ) 349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return id; 350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver id = uniqueNodeID; 352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver treeToUniqueIDMap[node] = id; 353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver uniqueNodeID++; 354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return id; 355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // GC makes these nonunique: 356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // return System.identityHashCode(node); 357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary> 360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Tell me how to create a token for use with imaginary token nodes. 361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * For example, there is probably no input symbol associated with imaginary 362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * token DECL, but you need to create it as a payload or whatever for 363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * the DECL node as in ^(DECL type ID). 364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </summary> 365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * <remarks> 367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * If you care what the token payload objects' type is, you should 368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * override this method and any other createToken variant. 369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </remarks> 370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public abstract IToken CreateToken( int tokenType, string text ); 372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary> 374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Tell me how to create a token for use with imaginary token nodes. 375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * For example, there is probably no input symbol associated with imaginary 376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * token DECL, but you need to create it as a payload or whatever for 377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * the DECL node as in ^(DECL type ID). 378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </summary> 379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * <remarks> 381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * This is a variant of createToken where the new token is derived from 382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * an actual real input token. Typically this is for converting '{' 383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * tokens to BLOCK etc... You'll see 384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * r : lc='{' ID+ '}' -> ^(BLOCK[$lc] ID+) ; 386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * If you care what the token payload objects' type is, you should 388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * override this method and any other createToken variant. 389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </remarks> 390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public abstract IToken CreateToken( IToken fromToken ); 392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public abstract object Create( IToken payload ); 394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary> 396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Duplicate a node. This is part of the factory; 397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * override if you want another kind of node to be built. 398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </summary> 399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * <remarks> 401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * I could use reflection to prevent having to override this 402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * but reflection is slow. 403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </remarks> 404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual object DupNode(object treeNode) 406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ITree tree = GetTree(treeNode); 408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (tree == null) 409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return null; 410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return tree.DupNode(); 412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public abstract IToken GetToken( object t ); 415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** <summary> 417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Track start/stop token for subtree root created for a rule. 418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Only works with Tree nodes. For rules that match nothing, 419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * seems like this will yield start=i and stop=i-1 in a nil node. 420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Might be useful info so I'll not force to be i..i. 421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * </summary> 422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual void SetTokenBoundaries(object t, IToken startToken, IToken stopToken) 424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ITree tree = GetTree(t); 426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (tree == null) 427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver int start = 0; 430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver int stop = 0; 431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (startToken != null) 433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver start = startToken.TokenIndex; 434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (stopToken != null) 435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stop = stopToken.TokenIndex; 436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.TokenStartIndex = start; 438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.TokenStopIndex = stop; 439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual int GetTokenStartIndex(object t) 442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ITree tree = GetTree(t); 444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (tree == null) 445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return -1; 446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return tree.TokenStartIndex; 448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual int GetTokenStopIndex(object t) 451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ITree tree = GetTree(t); 453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (tree == null) 454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return -1; 455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return tree.TokenStopIndex; 457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual object GetParent(object t) 460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ITree tree = GetTree(t); 462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (tree == null) 463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return null; 464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return tree.Parent; 466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual void SetParent(object t, object parent) 469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ITree tree = GetTree(t); 471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (tree == null) 472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ITree parentTree = GetTree(parent); 475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.Parent = parentTree; 476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual int GetChildIndex(object t) 479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ITree tree = GetTree(t); 481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (tree == null) 482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return 0; 483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return tree.ChildIndex; 485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual void SetChildIndex(object t, int index) 488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ITree tree = GetTree(t); 490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (tree == null) 491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.ChildIndex = index; 494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public virtual void ReplaceChildren(object parent, int startChildIndex, int stopChildIndex, object t) 497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ITree tree = GetTree(parent); 499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (tree == null) 500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree.ReplaceChildren(startChildIndex, stopChildIndex, t); 503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected virtual ITree GetTree(object t) 506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (t == null) 508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return null; 509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ITree tree = t as ITree; 511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (tree == null) 512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver throw new NotSupportedException(); 513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return tree; 515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 518