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