- public sealed class Reachability
- {
- TriState returns, throws, barrier;
-
- public TriState Returns {
- get { return returns; }
- }
- public TriState Throws {
- get { return throws; }
- }
- public TriState Barrier {
- get { return barrier; }
- }
-
- Reachability (TriState returns, TriState throws, TriState barrier)
- {
- this.returns = returns;
- this.throws = throws;
- this.barrier = barrier;
- }
-
- public Reachability Clone ()
- {
- return new Reachability (returns, throws, barrier);
- }
-
- public static TriState TriState_Meet (TriState a, TriState b)
- {
- // (1) if both are Never, return Never
- // (2) if both are Always, return Always
- // (3) otherwise, return Sometimes
- // note that (3) => (3') if both are Sometimes, return Sometimes
- return a == b ? a : TriState.Sometimes;
- }
-
- public static TriState TriState_Max (TriState a, TriState b)
- {
- return ((byte) a > (byte) b) ? a : b;
- }
-
- public void Meet (Reachability b)
- {
- if ((AlwaysReturns && b.AlwaysHasBarrier) || (AlwaysHasBarrier && b.AlwaysReturns))
- returns = TriState.Always;
- else
- returns = TriState_Meet (returns, b.returns);
-
- throws = TriState_Meet (throws, b.throws);
- barrier = TriState_Meet (barrier, b.barrier);
- }
-
- public void Or (Reachability b)
- {
- returns = TriState_Max (returns, b.returns);
- throws = TriState_Max (throws, b.throws);
- barrier = TriState_Max (barrier, b.barrier);
- }
-
- public static Reachability Always ()
- {
- return new Reachability (TriState.Never, TriState.Never, TriState.Never);
- }
-
- TriState Unreachable {
- get { return TriState_Max (returns, TriState_Max (throws, barrier)); }
- }
-
- TriState Reachable {
- get {
- TriState unreachable = Unreachable;
- if (unreachable == TriState.Sometimes)
- return TriState.Sometimes;
- return unreachable == TriState.Always ? TriState.Never : TriState.Always;
- }
- }
-
- public bool AlwaysReturns {
- get { return returns == TriState.Always; }
- }
-
- public bool AlwaysThrows {
- get { return throws == TriState.Always; }
- }
-
- public bool AlwaysHasBarrier {
- get { return barrier == TriState.Always; }
- }
-
- public bool IsUnreachable {
- get { return Unreachable == TriState.Always; }
- }
-
- public void SetReturns ()
- {
- returns = TriState.Always;
- }
-
- public void SetThrows ()
- {
- throws = TriState.Always;
- }
-
- public void SetBarrier ()
- {
- barrier = TriState.Always;
- }
-
- static string ShortName (TriState returns)
- {
- switch (returns) {
- case TriState.Never:
- return "N";
- case TriState.Sometimes:
- return "S";
- default:
- return "A";
- }
- }
-
- public override string ToString ()
- {
- return String.Format ("[{0}:{1}:{2}:{3}]",
- ShortName (returns), ShortName (throws), ShortName (barrier),
- ShortName (Reachable));
- }
- }
-