1/** A tree node that is wrapper for a Token object.  After 3.0 release
2 *  while building tree rewrite stuff, it became clear that computing
3 *  parent and child index is very difficult and cumbersome.  Better to
4 *  spend the space in every tree node.  If you don't want these extra
5 *  fields, it's easy to cut them out in your own BaseTree subclass.
6 */
7org.antlr.runtime.tree.CommonTree = function(node) {
8    /** What token indexes bracket all tokens associated with this node
9     *  and below?
10     */
11    this.startIndex = -1;
12    this.stopIndex = -1;
13
14    /** What index is this node in the child list? Range: 0..n-1 */
15    this.childIndex = -1;
16
17    /** Who is the parent node of this node; if null, implies node is root */
18    this.parent = null;
19
20    /** A single token is the payload */
21    this.token = null;
22
23    if (node instanceof org.antlr.runtime.tree.CommonTree) {
24        org.antlr.runtime.tree.CommonTree.superclass.constructor.call(this, node);
25        this.token = node.token;
26        this.startIndex = node.startIndex;
27        this.stopIndex = node.stopIndex;
28    } else if (node instanceof org.antlr.runtime.CommonToken) {
29        this.token = node;
30    }
31};
32
33/** A tree node that is wrapper for a Token object. */
34org.antlr.lang.extend(org.antlr.runtime.tree.CommonTree, org.antlr.runtime.tree.BaseTree, {
35    getToken: function() {
36        return this.token;
37    },
38
39    dupNode: function() {
40        return new org.antlr.runtime.tree.CommonTree(this);
41    },
42
43    isNil: function() {
44        return !this.token;
45    },
46
47    getType: function() {
48        if ( !this.token ) {
49            return org.antlr.runtime.Token.INVALID_TOKEN_TYPE;
50        }
51        return this.token.getType();
52    },
53
54    getText: function() {
55        if ( !this.token ) {
56            return null;
57        }
58        return this.token.getText();
59    },
60
61    getLine: function() {
62        if ( !this.token || this.token.getLine()===0 ) {
63            if ( this.getChildCount()>0 ) {
64                return this.getChild(0).getLine();
65            }
66            return 0;
67        }
68        return this.token.getLine();
69    },
70
71    getCharPositionInLine: function() {
72        if ( !this.token || this.token.getCharPositionInLine()===-1 ) {
73            if ( this.getChildCount()>0 ) {
74                return this.getChild(0).getCharPositionInLine();
75            }
76            return 0;
77        }
78        return this.token.getCharPositionInLine();
79    },
80
81    getTokenStartIndex: function() {
82        if ( this.token ) {
83            return this.token.getTokenIndex();
84        }
85        return this.startIndex;
86    },
87
88    setTokenStartIndex: function(index) {
89        this.startIndex = index;
90    },
91
92    getTokenStopIndex: function() {
93        if ( this.token ) {
94            return this.token.getTokenIndex();
95        }
96        return this.stopIndex;
97    },
98
99    setTokenStopIndex: function(index) {
100        this.stopIndex = index;
101    },
102
103    getChildIndex: function() {
104        return this.childIndex;
105    },
106
107    getParent: function() {
108        return this.parent;
109    },
110
111    setParent: function(t) {
112        this.parent = t;
113    },
114
115    setChildIndex: function(index) {
116        this.childIndex = index;
117    },
118
119    toString: function() {
120        if ( this.isNil() ) {
121            return "nil";
122        }
123        if ( this.getType()===org.antlr.runtime.Token.INVALID_TOKEN_TYPE ) {
124            return "<errornode>";
125        }
126        if ( !this.token ) {
127            return null;
128        }
129        return this.token.getText();
130    }
131});
132
133/* Monkey patch Tree static property with CommonToken value. */
134org.antlr.runtime.tree.Tree.INVALID_NODE =
135  new org.antlr.runtime.tree.CommonTree(org.antlr.runtime.Token.INVALID_TOKEN);
136