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(unittest) {
109     import dshould : be, equal, not, should;
110     import std.typecons : tuple;
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 }