00001 package edu.ksu.cis.bandera.jext;
00002
00003 import ca.mcgill.sable.soot.*;
00004 import ca.mcgill.sable.soot.grimp.*;
00005 import ca.mcgill.sable.soot.jimple.*;
00006 import ca.mcgill.sable.util.*;
00007
00008
00009
00010
00011
00012 public class HookExpr implements Expr {
00013 private ValueBox op1Box, op2Box, op3Box;
00014 private Type t;
00015 public HookExpr(Value v1, Value v2, Value v3)
00016 {
00017 this(Grimp.v().newArgBox(v1), Grimp.v().newArgBox(v2), Grimp.v().newArgBox(v3));
00018 }
00019 public HookExpr(ValueBox v1, ValueBox v2, ValueBox v3)
00020 {
00021 if (v1.getValue().getType() != BooleanType.v()) throw new RuntimeException("Test expression must be boolean!");
00022 op1Box = v1; op2Box = v2; op3Box = v3;
00023
00024 t = v2.getValue().getType();
00025 Type t2 = v3.getValue().getType();
00026
00027
00028 if (t == VoidType.v() || t2 == VoidType.v()) throw new RuntimeException("Then part or else part cannot be void!");
00029 if (t instanceof ArrayType && t2 instanceof ArrayType)
00030 {
00031 if (t.equals(t2)) return; else throw new RuntimeException("Then part or else part array are not the same!");
00032 }
00033
00034 if (t == t2) return;
00035
00036 if (t == ByteType.v())
00037 {
00038 if (t2 == IntType.v() || t2 == ShortType.v() || t2 == FloatType.v() || t2 == DoubleType.v() || t2 == LongType.v()) { t = t2; return; }
00039 } else if (t == ShortType.v())
00040 {
00041 if (t2 == ByteType.v()) return;
00042 if (t2 == IntType.v() || t2 == FloatType.v() || t2 == DoubleType.v() || t2 == LongType.v()) { t = t2; return; }
00043 } else if (t == IntType.v())
00044 {
00045 if (t2 == ByteType.v() || t2 == ShortType.v()) return;
00046 if (t2 == FloatType.v() || t2 == DoubleType.v() || t2 == LongType.v()) { t = t2; return; }
00047
00048 } else if (t == LongType.v())
00049 {
00050 if (t2 == ByteType.v() || t2 == ShortType.v() || t2 == IntType.v()) return;
00051 if (t2 == FloatType.v() || t2 == DoubleType.v()) { t = t2; return; }
00052 } else if (t == FloatType.v())
00053 {
00054 if (t2 == ByteType.v() || t2 == ShortType.v() || t2 == IntType.v() || t2 == LongType.v()) return;
00055 if (t2 == DoubleType.v()) { t = t2; return; }
00056 } else if (t == DoubleType.v())
00057 {
00058 if (t2 == ByteType.v() || t2 == IntType.v() || t2 == ShortType.v() || t2 == FloatType.v() || t2 == LongType.v()) return;
00059 } else if (t == NullType.v())
00060 {
00061 if (t2 instanceof RefType || t2 instanceof ArrayType) { t = t2; return; }
00062 } else if (t instanceof RefType || t instanceof ArrayType)
00063 {
00064 if (t2 == NullType.v()) return;
00065 }
00066
00067 throw new RuntimeException("Type mismatch on then part and else part!");
00068 }
00069
00070
00071
00072 public void apply(Switch sw)
00073 {
00074 ((PAExprSwitch) sw).caseHookExpr(this);
00075 }
00076 public Value getElseOp() { return op3Box.getValue(); }
00077 public ValueBox getElseOpBox() { return op3Box; }
00078 public Value getTestOp() { return op1Box.getValue(); }
00079 public ValueBox getTestOpBox() { return op1Box; }
00080 public Value getThenOp() { return op2Box.getValue(); }
00081 public ValueBox getThenOpBox() { return op2Box; }
00082
00083
00084
00085 public Type getType() {
00086 return t;
00087 }
00088
00089
00090
00091 public List getUseBoxes() {
00092 ca.mcgill.sable.util.List list = new ca.mcgill.sable.util.ArrayList();
00093
00094 list.addAll(op1Box.getValue().getUseBoxes());
00095 list.add(op1Box);
00096 list.addAll(op2Box.getValue().getUseBoxes());
00097 list.add(op2Box);
00098 list.addAll(op3Box.getValue().getUseBoxes());
00099 list.add(op3Box);
00100
00101 return list;
00102 }
00103
00104
00105
00106 public String toBriefString() {
00107 return ((ToBriefString) op1Box.getValue()).toBriefString() + "?" +
00108 ((ToBriefString) op2Box.getValue()).toBriefString() + ":" +
00109 ((ToBriefString) op3Box.getValue()).toBriefString();
00110 }
00111 public String toString()
00112 {
00113 return op1Box.getValue().toString() + "?" +
00114 op2Box.getValue().toString() + ":" +
00115 op3Box.getValue().toString();
00116 }
00117 }