1 /*
2  * Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
3  * Use of this file is governed by the BSD 3-clause license that
4  * can be found in the LICENSE.txt file in the project root.
5  */
6 
7 module antlr.v4.runtime.atn.SingletonPredictionContext;
8 
9 import std.conv;
10 import antlr.v4.runtime.atn;
11 
12 // Class SingletonPredictionContext
13 /**
14  * TODO add class description
15  */
16 class SingletonPredictionContext : PredictionContext
17 {
18 
19     public PredictionContext parent;
20 
21     public int returnState;
22 
23     public this(PredictionContext parent, int returnState)
24     {
25         super(parent !is null ? calculateHashCode(parent, returnState) : calculateEmptyHashCode);
26         assert(returnState != ATNState.INVALID_STATE_NUMBER);
27         this.parent = parent;
28         this.returnState = returnState;
29         //this.id = new ContextID().instance.getNextId;
30     }
31 
32     public static SingletonPredictionContext create(PredictionContext parent, int returnState)
33     {
34         if (returnState == EMPTY_RETURN_STATE && parent is null ) {
35             // someone can pass in the bits of an array ctx that mean $
36             return cast(SingletonPredictionContext)EMPTY;
37         }
38         if (parent is null)
39             parent = cast(PredictionContext)PredictionContext.EMPTY;
40         return new SingletonPredictionContext(parent, returnState);
41     }
42 
43     /**
44      * @uml
45      * @override
46      */
47     public override size_t size()
48     {
49         return 1;
50     }
51 
52     /**
53      * @uml
54      * @override
55      */
56     public override PredictionContext getParent(int index)
57     {
58         assert(index == 0);
59         return parent;
60     }
61 
62     /**
63      * @uml
64      * @override
65      */
66     public override int getReturnState(int index)
67     {
68         assert(index == 0);
69         return returnState;
70     }
71 
72     /**
73      * @uml
74      * @override
75      */
76     public override bool opEquals(Object o)
77     {
78         if (!cast(SingletonPredictionContext)o) {
79             return false;
80         }
81 
82         if (this.toHash != (cast(PredictionContext)o).toHash) {
83             return false; // can't be same if hash is different
84         }
85 
86         SingletonPredictionContext s = cast(SingletonPredictionContext)o;
87         return returnState == s.returnState &&
88             (parent !is null && parent.opEquals(s.parent));
89     }
90 
91     /**
92      * @uml
93      * @override
94      */
95     public override string toString()
96     {
97         string up = parent !is null ? parent.toString : "";
98         if (up.length == 0) {
99             if (returnState == EMPTY_RETURN_STATE ) {
100                 return "$";
101             }
102             return to!string(returnState);
103         }
104         return to!string(returnState) ~ " " ~ up;
105     }
106 
107 }
108 
109 version(unittest) {
110     import dshould : be, equal, not, should;
111     import unit_threaded;
112 
113     class Test {
114 
115         @Tags("SingletonPredictionContext")
116         @("Construction")
117         unittest {
118             PredictionContext spc = SingletonPredictionContext.create(null, 12);
119             spc.should.not.be(null);
120             spc.toString.should.equal("12 $");
121             spc.getReturnState(0).should.equal(12);
122             (cast(PredictionContext)spc.getParent(0)).should.not.be(null);
123             auto emptyPC = SingletonPredictionContext.create(null,
124                                                              PredictionContext.EMPTY_RETURN_STATE);
125             (cast(SingletonPredictionContext)emptyPC).should.not.be(null);
126             spc = SingletonPredictionContext.create(emptyPC, 11);
127             spc.toString.should.equal("11 $");
128             auto spc1 = SingletonPredictionContext.create(spc, 10);
129             spc1.toString.should.equal("10 11 $");
130         }
131 
132         @Tags("SingletonPredictionContext")
133         @("Compare")
134         unittest {
135             auto spc11 = SingletonPredictionContext.create(null, 11);
136             auto spc12 = SingletonPredictionContext.create(null, 12);
137             auto spc = SingletonPredictionContext.create(null, 12);
138             spc.should.equal(spc12);
139             spc11.should.not.equal(spc12);
140             spc12.should.equal(spc12);
141             class A {}
142             auto a = new A;
143             spc11.should.not.equal(a);
144         }
145     }
146 }