1 19 20 package jode.expr; 21 import jode.type.Type; 22 import jode.GlobalOptions; 23 import jode.decompiler.TabbedPrintWriter; 24 25 import java.util.Collection ; 26 import java.util.Set ; 27 28 public abstract class Expression { 29 protected Type type; 30 31 Operator parent = null; 32 33 public Expression(Type type) { 34 this.type = type; 35 } 36 37 public void setType(Type otherType) { 38 Type newType = otherType.intersection(type); 39 if (type.equals(newType)) 40 return; 41 if (newType == Type.tError && otherType != Type.tError) { 42 GlobalOptions.err.println("setType: Type error in "+this 43 +": merging "+type+" and "+otherType); 44 if (parent != null) 45 GlobalOptions.err.println("\tparent is "+parent); 46 if ((GlobalOptions.debuggingFlags 47 & GlobalOptions.DEBUG_TYPES) != 0) 48 Thread.dumpStack(); 49 } 50 type = newType; 51 if (type != Type.tError) 52 updateSubTypes(); 53 } 54 55 public void updateParentType(Type otherType) { 56 setType(otherType); 57 if (parent != null) 58 parent.updateType(); 59 } 60 61 67 public abstract void updateType(); 68 69 73 public abstract void updateSubTypes(); 74 75 public Type getType() { 76 return type; 77 } 78 79 public Operator getParent() { 80 return parent; 81 } 82 83 105 public abstract int getPriority(); 106 107 110 public int getBreakPenalty() { 111 return 0; 112 } 113 114 118 public abstract int getFreeOperandCount(); 119 120 public abstract Expression addOperand(Expression op); 121 122 public Expression negate() { 123 Operator negop = 124 new UnaryOperator(Type.tBoolean, Operator.LOG_NOT_OP); 125 negop.addOperand(this); 126 return negop; 127 } 128 129 135 public boolean hasSideEffects(Expression expr) { 136 return false; 137 } 138 139 146 public int canCombine(CombineableOperator combOp) { 147 return 0; 148 } 149 150 158 public boolean containsMatchingLoad(CombineableOperator e) { 159 return false; 160 } 161 162 168 public boolean containsConflictingLoad(MatchableOperator op) { 169 return false; 170 } 171 172 182 public Expression combine(CombineableOperator comb) { 183 return null; 184 } 185 186 194 public Expression removeOnetimeLocals() { 195 return this; 196 } 197 198 public Expression simplify() { 199 return this; 200 } 201 public Expression simplifyString() { 202 return this; 203 } 204 205 public static Expression EMPTYSTRING = new ConstOperator(""); 206 207 public Expression simplifyStringBuffer() { 208 return null; 209 } 210 211 public void makeInitializer(Type type) { 212 } 213 214 public boolean isConstant() { 215 return true; 216 } 217 218 public void fillInGenSet(Collection in, Collection gen) { 219 } 220 221 public void fillDeclarables(Collection used) { 222 } 223 224 public void makeDeclaration(Set done) { 225 } 226 227 public abstract void dumpExpression(TabbedPrintWriter writer) 228 throws java.io.IOException ; 229 230 public void dumpExpression(int options, TabbedPrintWriter writer) 231 throws java.io.IOException 232 { 233 writer.startOp(options, getBreakPenalty()); 234 dumpExpression(writer); 235 writer.endOp(); 236 } 237 238 public void dumpExpression(TabbedPrintWriter writer, int minPriority) 239 throws java.io.IOException { 240 int options; 241 boolean needParen1 = false, needParen2 = false; 242 boolean needEndOp1 = false, needEndOp2 = false; 243 244 String typecast = ""; 245 246 if (type == Type.tError) 247 typecast = "/*TYPE_ERROR*/"; 248 else if ((GlobalOptions.debuggingFlags 249 & GlobalOptions.DEBUG_TYPES) != 0) 250 typecast = "(TYPE "+type+")"; 251 252 if (typecast != "") { 253 if (minPriority > 700) { 254 needParen1 = true; 255 needEndOp1 = true; 256 writer.print("("); 257 writer.startOp(writer.EXPL_PAREN, 0); 258 } else if (minPriority < 700) { 259 needEndOp1 = true; 260 writer.startOp(writer.IMPL_PAREN, 1); 261 } 262 writer.print(typecast); 263 writer.breakOp(); 264 writer.print(" "); 265 minPriority = 700; 266 } 267 268 int priority = getPriority(); 269 if (priority < minPriority) { 270 needParen2 = true; 271 needEndOp2 = true; 272 writer.print("("); 273 writer.startOp(writer.EXPL_PAREN, getBreakPenalty()); 274 } else if (priority != minPriority) { 275 needEndOp2 = true; 276 if (getType() == Type.tVoid) 277 writer.startOp(writer.NO_PAREN, getBreakPenalty()); 278 else 279 writer.startOp(writer.IMPL_PAREN, 1 + getBreakPenalty()); 280 } 281 282 try { 283 dumpExpression(writer); 284 } catch (RuntimeException ex) { 285 writer.print("(RUNTIME ERROR IN EXPRESSION)"); 286 ex.printStackTrace(GlobalOptions.err); 287 } 288 289 if (needEndOp2) { 290 writer.endOp(); 291 if (needParen2) 292 writer.print(")"); 293 } 294 if (needEndOp1) { 295 writer.endOp(); 296 if (needParen1) 297 writer.print(")"); 298 } 299 } 300 301 public String toString() { 302 try { 303 java.io.StringWriter strw = new java.io.StringWriter (); 304 TabbedPrintWriter writer = new TabbedPrintWriter(strw); 305 dumpExpression(writer); 306 return strw.toString(); 307 } catch (java.io.IOException ex) { 308 return "/*IOException*/"+super.toString(); 309 } catch (RuntimeException ex) { 310 return "/*RuntimeException*/"+super.toString(); 311 } 312 } 313 314 public boolean isVoid() { 315 return getType() == Type.tVoid; 316 } 317 } 318 | Popular Tags |