1 /* 2 * [The "BSD licence"] 3 * Copyright (c) 2011 Terence Parr 4 * All rights reserved. 5 * 6 * Conversion to C#: 7 * Copyright (c) 2011 Sam Harwell, Pixel Mine, Inc. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 namespace Antlr.Runtime.Debug 34 { 35 using ITreeAdaptor = Antlr.Runtime.Tree.ITreeAdaptor; 36 37 /** <summary> 38 * A TreeAdaptor proxy that fires debugging events to a DebugEventListener 39 * delegate and uses the TreeAdaptor delegate to do the actual work. All 40 * AST events are triggered by this adaptor; no code gen changes are needed 41 * in generated rules. Debugging events are triggered *after* invoking 42 * tree adaptor routines. 43 * </summary> 44 * 45 * <remarks> 46 * Trees created with actions in rewrite actions like "-> ^(ADD {foo} {bar})" 47 * cannot be tracked as they might not use the adaptor to create foo, bar. 48 * The debug listener has to deal with tree node IDs for which it did 49 * not see a createNode event. A single <unknown> node is sufficient even 50 * if it represents a whole tree. 51 * </remarks> 52 */ 53 public class DebugTreeAdaptor : ITreeAdaptor 54 { 55 protected IDebugEventListener dbg; 56 protected ITreeAdaptor adaptor; 57 DebugTreeAdaptor( IDebugEventListener dbg, ITreeAdaptor adaptor )58 public DebugTreeAdaptor( IDebugEventListener dbg, ITreeAdaptor adaptor ) 59 { 60 this.dbg = dbg; 61 this.adaptor = adaptor; 62 } 63 Create( IToken payload )64 public virtual object Create( IToken payload ) 65 { 66 if ( payload.TokenIndex < 0 ) 67 { 68 // could be token conjured up during error recovery 69 return Create( payload.Type, payload.Text ); 70 } 71 object node = adaptor.Create( payload ); 72 dbg.CreateNode( node, payload ); 73 return node; 74 } 75 ErrorNode( ITokenStream input, IToken start, IToken stop, RecognitionException e )76 public virtual object ErrorNode( ITokenStream input, IToken start, IToken stop, 77 RecognitionException e ) 78 { 79 object node = adaptor.ErrorNode( input, start, stop, e ); 80 if ( node != null ) 81 { 82 dbg.ErrorNode( node ); 83 } 84 return node; 85 } 86 DupTree( object tree )87 public virtual object DupTree( object tree ) 88 { 89 object t = adaptor.DupTree( tree ); 90 // walk the tree and emit create and add child events 91 // to simulate what dupTree has done. dupTree does not call this debug 92 // adapter so I must simulate. 93 SimulateTreeConstruction( t ); 94 return t; 95 } 96 97 /** <summary>^(A B C): emit create A, create B, add child, ...</summary> */ SimulateTreeConstruction( object t )98 protected virtual void SimulateTreeConstruction( object t ) 99 { 100 dbg.CreateNode( t ); 101 int n = adaptor.GetChildCount( t ); 102 for ( int i = 0; i < n; i++ ) 103 { 104 object child = adaptor.GetChild( t, i ); 105 SimulateTreeConstruction( child ); 106 dbg.AddChild( t, child ); 107 } 108 } 109 DupNode( object treeNode )110 public virtual object DupNode( object treeNode ) 111 { 112 object d = adaptor.DupNode( treeNode ); 113 dbg.CreateNode( d ); 114 return d; 115 } 116 DupNode(int type, object treeNode)117 public object DupNode(int type, object treeNode) 118 { 119 object d = adaptor.DupNode(type, treeNode); 120 dbg.CreateNode(d); 121 return d; 122 } 123 DupNode(object treeNode, string text)124 public object DupNode(object treeNode, string text) 125 { 126 object d = adaptor.DupNode(treeNode, text); 127 dbg.CreateNode(d); 128 return d; 129 } 130 DupNode(int type, object treeNode, string text)131 public object DupNode(int type, object treeNode, string text) 132 { 133 object d = adaptor.DupNode(type, treeNode, text); 134 dbg.CreateNode(d); 135 return d; 136 } 137 Nil()138 public virtual object Nil() 139 { 140 object node = adaptor.Nil(); 141 dbg.NilNode( node ); 142 return node; 143 } 144 IsNil( object tree )145 public virtual bool IsNil( object tree ) 146 { 147 return adaptor.IsNil( tree ); 148 } 149 AddChild( object t, object child )150 public virtual void AddChild( object t, object child ) 151 { 152 if ( t == null || child == null ) 153 { 154 return; 155 } 156 adaptor.AddChild( t, child ); 157 dbg.AddChild( t, child ); 158 } 159 BecomeRoot( object newRoot, object oldRoot )160 public virtual object BecomeRoot( object newRoot, object oldRoot ) 161 { 162 object n = adaptor.BecomeRoot( newRoot, oldRoot ); 163 dbg.BecomeRoot( newRoot, oldRoot ); 164 return n; 165 } 166 RulePostProcessing( object root )167 public virtual object RulePostProcessing( object root ) 168 { 169 return adaptor.RulePostProcessing( root ); 170 } 171 AddChild( object t, IToken child )172 public virtual void AddChild( object t, IToken child ) 173 { 174 object n = this.Create( child ); 175 this.AddChild( t, n ); 176 } 177 BecomeRoot( IToken newRoot, object oldRoot )178 public virtual object BecomeRoot( IToken newRoot, object oldRoot ) 179 { 180 object n = this.Create( newRoot ); 181 adaptor.BecomeRoot( n, oldRoot ); 182 dbg.BecomeRoot( newRoot, oldRoot ); 183 return n; 184 } 185 Create( int tokenType, IToken fromToken )186 public virtual object Create( int tokenType, IToken fromToken ) 187 { 188 object node = adaptor.Create( tokenType, fromToken ); 189 dbg.CreateNode( node ); 190 return node; 191 } 192 Create( int tokenType, IToken fromToken, string text )193 public virtual object Create( int tokenType, IToken fromToken, string text ) 194 { 195 object node = adaptor.Create( tokenType, fromToken, text ); 196 dbg.CreateNode( node ); 197 return node; 198 } 199 Create( int tokenType, string text )200 public virtual object Create( int tokenType, string text ) 201 { 202 object node = adaptor.Create( tokenType, text ); 203 dbg.CreateNode( node ); 204 return node; 205 } 206 Create(IToken fromToken, string text)207 public object Create(IToken fromToken, string text) 208 { 209 object node = adaptor.Create(fromToken, text); 210 dbg.CreateNode(node); 211 return node; 212 } 213 GetType( object t )214 public virtual int GetType( object t ) 215 { 216 return adaptor.GetType( t ); 217 } 218 SetType( object t, int type )219 public virtual void SetType( object t, int type ) 220 { 221 adaptor.SetType( t, type ); 222 } 223 GetText( object t )224 public virtual string GetText( object t ) 225 { 226 return adaptor.GetText( t ); 227 } 228 SetText( object t, string text )229 public virtual void SetText( object t, string text ) 230 { 231 adaptor.SetText( t, text ); 232 } 233 GetToken( object t )234 public virtual IToken GetToken( object t ) 235 { 236 return adaptor.GetToken( t ); 237 } 238 SetTokenBoundaries( object t, IToken startToken, IToken stopToken )239 public virtual void SetTokenBoundaries( object t, IToken startToken, IToken stopToken ) 240 { 241 adaptor.SetTokenBoundaries( t, startToken, stopToken ); 242 if ( t != null && startToken != null && stopToken != null ) 243 { 244 dbg.SetTokenBoundaries( 245 t, startToken.TokenIndex, 246 stopToken.TokenIndex ); 247 } 248 } 249 GetTokenStartIndex( object t )250 public virtual int GetTokenStartIndex( object t ) 251 { 252 return adaptor.GetTokenStartIndex( t ); 253 } 254 GetTokenStopIndex( object t )255 public virtual int GetTokenStopIndex( object t ) 256 { 257 return adaptor.GetTokenStopIndex( t ); 258 } 259 GetChild( object t, int i )260 public virtual object GetChild( object t, int i ) 261 { 262 return adaptor.GetChild( t, i ); 263 } 264 SetChild( object t, int i, object child )265 public virtual void SetChild( object t, int i, object child ) 266 { 267 adaptor.SetChild( t, i, child ); 268 } 269 DeleteChild( object t, int i )270 public virtual object DeleteChild( object t, int i ) 271 { 272 return DeleteChild( t, i ); 273 } 274 GetChildCount( object t )275 public virtual int GetChildCount( object t ) 276 { 277 return adaptor.GetChildCount( t ); 278 } 279 GetUniqueID( object node )280 public virtual int GetUniqueID( object node ) 281 { 282 return adaptor.GetUniqueID( node ); 283 } 284 GetParent( object t )285 public virtual object GetParent( object t ) 286 { 287 return adaptor.GetParent( t ); 288 } 289 GetChildIndex( object t )290 public virtual int GetChildIndex( object t ) 291 { 292 return adaptor.GetChildIndex( t ); 293 } 294 SetParent( object t, object parent )295 public virtual void SetParent( object t, object parent ) 296 { 297 adaptor.SetParent( t, parent ); 298 } 299 SetChildIndex( object t, int index )300 public virtual void SetChildIndex( object t, int index ) 301 { 302 adaptor.SetChildIndex( t, index ); 303 } 304 ReplaceChildren( object parent, int startChildIndex, int stopChildIndex, object t )305 public virtual void ReplaceChildren( object parent, int startChildIndex, int stopChildIndex, object t ) 306 { 307 adaptor.ReplaceChildren( parent, startChildIndex, stopChildIndex, t ); 308 } 309 310 #region support 311 GetDebugListener()312 public virtual IDebugEventListener GetDebugListener() 313 { 314 return dbg; 315 } 316 SetDebugListener( IDebugEventListener dbg )317 public virtual void SetDebugListener( IDebugEventListener dbg ) 318 { 319 this.dbg = dbg; 320 } 321 GetTreeAdaptor()322 public virtual ITreeAdaptor GetTreeAdaptor() 323 { 324 return adaptor; 325 } 326 327 #endregion 328 } 329 } 330