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 }