Home | History | Annotate | Download | only in Antlr.Runtime.Debug
      1 /*
      2  * [The "BSD licence"]
      3  * Copyright (c) 2005-2008 Terence Parr
      4  * All rights reserved.
      5  *
      6  * Conversion to C#:
      7  * Copyright (c) 2008-2009 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     using ITreeAdaptor = Antlr.Runtime.Tree.ITreeAdaptor;
     35 
     36     /** <summary>
     37      *  A TreeAdaptor proxy that fires debugging events to a DebugEventListener
     38      *  delegate and uses the TreeAdaptor delegate to do the actual work.  All
     39      *  AST events are triggered by this adaptor; no code gen changes are needed
     40      *  in generated rules.  Debugging events are triggered *after* invoking
     41      *  tree adaptor routines.
     42      *  </summary>
     43      *
     44      *  <remarks>
     45      *  Trees created with actions in rewrite actions like "-&gt; ^(ADD {foo} {bar})"
     46      *  cannot be tracked as they might not use the adaptor to create foo, bar.
     47      *  The debug listener has to deal with tree node IDs for which it did
     48      *  not see a createNode event.  A single &lt;unknown&gt; node is sufficient even
     49      *  if it represents a whole tree.
     50      *  </remarks>
     51      */
     52     public class DebugTreeAdaptor : ITreeAdaptor {
     53         protected IDebugEventListener dbg;
     54         protected ITreeAdaptor adaptor;
     55 
     56         public DebugTreeAdaptor(IDebugEventListener dbg, ITreeAdaptor adaptor) {
     57             this.dbg = dbg;
     58             this.adaptor = adaptor;
     59         }
     60 
     61         public virtual object Create(IToken payload) {
     62             if (payload.TokenIndex < 0) {
     63                 // could be token conjured up during error recovery
     64                 return Create(payload.Type, payload.Text);
     65             }
     66             object node = adaptor.Create(payload);
     67             dbg.CreateNode(node, payload);
     68             return node;
     69         }
     70 
     71         public virtual object ErrorNode(ITokenStream input, IToken start, IToken stop,
     72                                 RecognitionException e) {
     73             object node = adaptor.ErrorNode(input, start, stop, e);
     74             if (node != null) {
     75                 dbg.ErrorNode(node);
     76             }
     77             return node;
     78         }
     79 
     80         public virtual object DupTree(object tree) {
     81             object t = adaptor.DupTree(tree);
     82             // walk the tree and emit create and add child events
     83             // to simulate what dupTree has done. dupTree does not call this debug
     84             // adapter so I must simulate.
     85             SimulateTreeConstruction(t);
     86             return t;
     87         }
     88 
     89         /** <summary>^(A B C): emit create A, create B, add child, ...</summary> */
     90         protected virtual void SimulateTreeConstruction(object t) {
     91             dbg.CreateNode(t);
     92             int n = adaptor.GetChildCount(t);
     93             for (int i = 0; i < n; i++) {
     94                 object child = adaptor.GetChild(t, i);
     95                 SimulateTreeConstruction(child);
     96                 dbg.AddChild(t, child);
     97             }
     98         }
     99 
    100         public virtual object DupNode(object treeNode) {
    101             object d = adaptor.DupNode(treeNode);
    102             dbg.CreateNode(d);
    103             return d;
    104         }
    105 
    106         public virtual object Nil() {
    107             object node = adaptor.Nil();
    108             dbg.NilNode(node);
    109             return node;
    110         }
    111 
    112         public virtual bool IsNil(object tree) {
    113             return adaptor.IsNil(tree);
    114         }
    115 
    116         public virtual void AddChild(object t, object child) {
    117             if (t == null || child == null) {
    118                 return;
    119             }
    120             adaptor.AddChild(t, child);
    121             dbg.AddChild(t, child);
    122         }
    123 
    124         public virtual object BecomeRoot(object newRoot, object oldRoot) {
    125             object n = adaptor.BecomeRoot(newRoot, oldRoot);
    126             dbg.BecomeRoot(newRoot, oldRoot);
    127             return n;
    128         }
    129 
    130         public virtual object RulePostProcessing(object root) {
    131             return adaptor.RulePostProcessing(root);
    132         }
    133 
    134         public virtual void AddChild(object t, IToken child) {
    135             object n = this.Create(child);
    136             this.AddChild(t, n);
    137         }
    138 
    139         public virtual object BecomeRoot(IToken newRoot, object oldRoot) {
    140             object n = this.Create(newRoot);
    141             adaptor.BecomeRoot(n, oldRoot);
    142             dbg.BecomeRoot(newRoot, oldRoot);
    143             return n;
    144         }
    145 
    146         public virtual object Create(int tokenType, IToken fromToken) {
    147             object node = adaptor.Create(tokenType, fromToken);
    148             dbg.CreateNode(node);
    149             return node;
    150         }
    151 
    152         public virtual object Create(int tokenType, IToken fromToken, string text) {
    153             object node = adaptor.Create(tokenType, fromToken, text);
    154             dbg.CreateNode(node);
    155             return node;
    156         }
    157 
    158         public virtual object Create(int tokenType, string text) {
    159             object node = adaptor.Create(tokenType, text);
    160             dbg.CreateNode(node);
    161             return node;
    162         }
    163 
    164         public virtual int GetType(object t) {
    165             return adaptor.GetType(t);
    166         }
    167 
    168         public virtual void SetType(object t, int type) {
    169             adaptor.SetType(t, type);
    170         }
    171 
    172         public virtual string GetText(object t) {
    173             return adaptor.GetText(t);
    174         }
    175 
    176         public virtual void SetText(object t, string text) {
    177             adaptor.SetText(t, text);
    178         }
    179 
    180         public virtual IToken GetToken(object t) {
    181             return adaptor.GetToken(t);
    182         }
    183 
    184         public virtual void SetTokenBoundaries(object t, IToken startToken, IToken stopToken) {
    185             adaptor.SetTokenBoundaries(t, startToken, stopToken);
    186             if (t != null && startToken != null && stopToken != null) {
    187                 dbg.SetTokenBoundaries(
    188                     t, startToken.TokenIndex,
    189                     stopToken.TokenIndex);
    190             }
    191         }
    192 
    193         public virtual int GetTokenStartIndex(object t) {
    194             return adaptor.GetTokenStartIndex(t);
    195         }
    196 
    197         public virtual int GetTokenStopIndex(object t) {
    198             return adaptor.GetTokenStopIndex(t);
    199         }
    200 
    201         public virtual object GetChild(object t, int i) {
    202             return adaptor.GetChild(t, i);
    203         }
    204 
    205         public virtual void SetChild(object t, int i, object child) {
    206             adaptor.SetChild(t, i, child);
    207         }
    208 
    209         public virtual object DeleteChild(object t, int i) {
    210             return DeleteChild(t, i);
    211         }
    212 
    213         public virtual int GetChildCount(object t) {
    214             return adaptor.GetChildCount(t);
    215         }
    216 
    217         public virtual int GetUniqueID(object node) {
    218             return adaptor.GetUniqueID(node);
    219         }
    220 
    221         public virtual object GetParent(object t) {
    222             return adaptor.GetParent(t);
    223         }
    224 
    225         public virtual int GetChildIndex(object t) {
    226             return adaptor.GetChildIndex(t);
    227         }
    228 
    229         public virtual void SetParent(object t, object parent) {
    230             adaptor.SetParent(t, parent);
    231         }
    232 
    233         public virtual void SetChildIndex(object t, int index) {
    234             adaptor.SetChildIndex(t, index);
    235         }
    236 
    237         public virtual void ReplaceChildren(object parent, int startChildIndex, int stopChildIndex, object t) {
    238             adaptor.ReplaceChildren(parent, startChildIndex, stopChildIndex, t);
    239         }
    240 
    241         #region support
    242 
    243         public virtual IDebugEventListener GetDebugListener() {
    244             return dbg;
    245         }
    246 
    247         public virtual void SetDebugListener(IDebugEventListener dbg) {
    248             this.dbg = dbg;
    249         }
    250 
    251         public virtual ITreeAdaptor GetTreeAdaptor() {
    252             return adaptor;
    253         }
    254 
    255         #endregion
    256     }
    257 }
    258