001 /* This file was generated with JastAdd2 (http://jastadd.org) version R20130213 */ 002 package AST; 003 004 import java.util.HashSet; 005 import java.io.File; 006 import java.util.*; 007 import beaver.*; 008 import java.util.ArrayList; 009 import java.util.zip.*; 010 import java.io.*; 011 import java.io.FileNotFoundException; 012 import java.util.Collection; 013 /** 014 * @production AddExpr : {@link AdditiveExpr}; 015 * @ast node 016 * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/java.ast:158 017 */ 018 public class AddExpr extends AdditiveExpr implements Cloneable { 019 /** 020 * @apilevel low-level 021 */ 022 public void flushCache() { 023 } 024 /** 025 * @apilevel internal 026 */ 027 public void flushCollectionCache() { 028 } 029 /** 030 * @apilevel internal 031 */ 032 @SuppressWarnings({"unchecked", "cast"}) 033 public AddExpr clone() throws CloneNotSupportedException { 034 AddExpr node = (AddExpr)super.clone(); 035 node.type_computed = false; 036 node.type_value = null; 037 node.in$Circle(false); 038 node.is$Final(false); 039 return node; 040 } 041 /** 042 * @apilevel internal 043 */ 044 @SuppressWarnings({"unchecked", "cast"}) 045 public AddExpr copy() { 046 047 try { 048 AddExpr node = (AddExpr) clone(); 049 node.parent = null; 050 if(children != null) 051 node.children = (ASTNode[]) children.clone(); 052 053 return node; 054 } catch (CloneNotSupportedException e) { 055 throw new Error("Error: clone not supported for " + getClass().getName()); 056 } 057 058 }/** 059 * Create a deep copy of the AST subtree at this node. 060 * The copy is dangling, i.e. has no parent. 061 * @return dangling copy of the subtree at this node 062 * @apilevel low-level 063 */ 064 @SuppressWarnings({"unchecked", "cast"}) 065 public AddExpr fullCopy() { 066 067 AddExpr tree = (AddExpr) copy(); 068 if (children != null) { 069 for (int i = 0; i < children.length; ++i) { 070 071 ASTNode child = (ASTNode) children[i]; 072 if(child != null) { 073 child = child.fullCopy(); 074 tree.setChild(child, i); 075 } 076 } 077 } 078 return tree; 079 080 } /** 081 * @ast method 082 * @aspect TypeCheck 083 * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/TypeCheck.jrag:172 084 */ 085 public void typeCheck() { 086 TypeDecl left = getLeftOperand().type(); 087 TypeDecl right = getRightOperand().type(); 088 if(!left.isString() && !right.isString()) 089 super.typeCheck(); 090 else if(left.isVoid()) 091 error("The type void of the left hand side is not numeric"); 092 else if(right.isVoid()) 093 error("The type void of the right hand side is not numeric"); 094 } 095 /** 096 * @ast method 097 * @aspect CodeGenerationBinaryOperations 098 * @declaredat /home/jesper/svn/JastAddJ/Java1.4Backend/CodeGeneration.jrag:1024 099 */ 100 void emitOperation(CodeGeneration gen) { type().add(gen); } 101 /** 102 * @ast method 103 * @aspect CreateBCode 104 * @declaredat /home/jesper/svn/JastAddJ/Java1.4Backend/CreateBCode.jrag:900 105 */ 106 public void createBCode(CodeGeneration gen) { 107 if(!type().isString()) 108 super.createBCode(gen); 109 else if(isConstant()) { 110 StringLiteral.push(gen, constant().stringValue()); 111 } 112 else { 113 TypeDecl stringBuffer = lookupType("java.lang", "StringBuffer"); 114 String classname = stringBuffer.constantPoolName(); 115 String desc; 116 int index; 117 TypeDecl argumentType; 118 if(firstStringAddPart()) { 119 stringBuffer.emitNew(gen); // new StringBuffer 120 gen.emitDup(); // dup 121 desc = "()V"; 122 index = gen.constantPool().addMethodref(classname, "<init>", desc); 123 gen.emit(Bytecode.INVOKESPECIAL, -1).add2(index); // invokespecial StringBuffer() 124 getLeftOperand().createBCode(gen); // left 125 argumentType = getLeftOperand().type().stringPromotion(); 126 desc = "(" + argumentType.typeDescriptor() + ")" + stringBuffer.typeDescriptor(); 127 index = gen.constantPool().addMethodref(classname, "append", desc); 128 gen.emit(Bytecode.INVOKEVIRTUAL, -argumentType.variableSize()).add2(index); // StringBuffer.append 129 } 130 else { 131 getLeftOperand().createBCode(gen); 132 } 133 getRightOperand().createBCode(gen); // right 134 argumentType = getRightOperand().type().stringPromotion(); 135 desc = "(" + argumentType.typeDescriptor() + ")" + stringBuffer.typeDescriptor(); 136 index = gen.constantPool().addMethodref(classname, "append", desc); 137 gen.emit(Bytecode.INVOKEVIRTUAL, -argumentType.variableSize()).add2(index); // StringBuffer.append 138 if(lastStringAddPart()) { 139 desc = "()" + type().typeDescriptor(); 140 index = gen.constantPool().addMethodref(classname, "toString", desc); 141 gen.emit(Bytecode.INVOKEVIRTUAL, 0).add2(index); // StringBuffer.toString 142 } 143 } 144 } 145 /** 146 * @ast method 147 * 148 */ 149 public AddExpr() { 150 super(); 151 152 153 } 154 /** 155 * Initializes the child array to the correct size. 156 * Initializes List and Opt nta children. 157 * @apilevel internal 158 * @ast method 159 * @ast method 160 * 161 */ 162 public void init$Children() { 163 children = new ASTNode[2]; 164 } 165 /** 166 * @ast method 167 * 168 */ 169 public AddExpr(Expr p0, Expr p1) { 170 setChild(p0, 0); 171 setChild(p1, 1); 172 } 173 /** 174 * @apilevel low-level 175 * @ast method 176 * 177 */ 178 protected int numChildren() { 179 return 2; 180 } 181 /** 182 * @apilevel internal 183 * @ast method 184 * 185 */ 186 public boolean mayHaveRewrite() { 187 return false; 188 } 189 /** 190 * Replaces the LeftOperand child. 191 * @param node The new node to replace the LeftOperand child. 192 * @apilevel high-level 193 * @ast method 194 * 195 */ 196 public void setLeftOperand(Expr node) { 197 setChild(node, 0); 198 } 199 /** 200 * Retrieves the LeftOperand child. 201 * @return The current node used as the LeftOperand child. 202 * @apilevel high-level 203 * @ast method 204 * 205 */ 206 public Expr getLeftOperand() { 207 return (Expr)getChild(0); 208 } 209 /** 210 * Retrieves the LeftOperand child. 211 * <p><em>This method does not invoke AST transformations.</em></p> 212 * @return The current node used as the LeftOperand child. 213 * @apilevel low-level 214 * @ast method 215 * 216 */ 217 public Expr getLeftOperandNoTransform() { 218 return (Expr)getChildNoTransform(0); 219 } 220 /** 221 * Replaces the RightOperand child. 222 * @param node The new node to replace the RightOperand child. 223 * @apilevel high-level 224 * @ast method 225 * 226 */ 227 public void setRightOperand(Expr node) { 228 setChild(node, 1); 229 } 230 /** 231 * Retrieves the RightOperand child. 232 * @return The current node used as the RightOperand child. 233 * @apilevel high-level 234 * @ast method 235 * 236 */ 237 public Expr getRightOperand() { 238 return (Expr)getChild(1); 239 } 240 /** 241 * Retrieves the RightOperand child. 242 * <p><em>This method does not invoke AST transformations.</em></p> 243 * @return The current node used as the RightOperand child. 244 * @apilevel low-level 245 * @ast method 246 * 247 */ 248 public Expr getRightOperandNoTransform() { 249 return (Expr)getChildNoTransform(1); 250 } 251 /** 252 * @attribute syn 253 * @aspect ConstantExpression 254 * @declaredat /home/jesper/svn/JastAddJ/Java7Frontend/ConstantExpression.jrag:91 255 */ 256 public Constant constant() { 257 ASTNode$State state = state(); 258 try { return type().add(getLeftOperand().constant(), getRightOperand().constant()); } 259 finally { 260 } 261 } 262 /** 263 * @attribute syn 264 * @aspect PrettyPrint 265 * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/PrettyPrint.jadd:400 266 */ 267 public String printOp() { 268 ASTNode$State state = state(); 269 try { return " + "; } 270 finally { 271 } 272 } 273 /** 274 * @apilevel internal 275 */ 276 protected boolean type_computed = false; 277 /** 278 * @apilevel internal 279 */ 280 protected TypeDecl type_value; 281 /** 282 * @attribute syn 283 * @aspect TypeAnalysis 284 * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/TypeAnalysis.jrag:327 285 */ 286 @SuppressWarnings({"unchecked", "cast"}) 287 public TypeDecl type() { 288 if(type_computed) { 289 return type_value; 290 } 291 ASTNode$State state = state(); 292 int num = state.boundariesCrossed; 293 boolean isFinal = this.is$Final(); 294 type_value = type_compute(); 295 if(isFinal && num == state().boundariesCrossed){ type_computed = true; } 296 return type_value; 297 } 298 /** 299 * @apilevel internal 300 */ 301 private TypeDecl type_compute() { 302 TypeDecl left = getLeftOperand().type(); 303 TypeDecl right = getRightOperand().type(); 304 if(!left.isString() && !right.isString()) 305 return super.type(); 306 else { 307 if(left.isVoid() || right.isVoid()) 308 return unknownType(); 309 // pick the string type 310 return left.isString() ? left : right; 311 } 312 } 313 /** 314 * @attribute syn 315 * @aspect InnerClasses 316 * @declaredat /home/jesper/svn/JastAddJ/Java1.4Backend/InnerClasses.jrag:88 317 */ 318 public boolean isStringAdd() { 319 ASTNode$State state = state(); 320 try { return type().isString() && !isConstant(); } 321 finally { 322 } 323 } 324 /** 325 * @attribute syn 326 * @aspect InnerClasses 327 * @declaredat /home/jesper/svn/JastAddJ/Java1.4Backend/InnerClasses.jrag:91 328 */ 329 public boolean firstStringAddPart() { 330 ASTNode$State state = state(); 331 try { return type().isString() && !getLeftOperand().isStringAdd(); } 332 finally { 333 } 334 } 335 /** 336 * @attribute syn 337 * @aspect InnerClasses 338 * @declaredat /home/jesper/svn/JastAddJ/Java1.4Backend/InnerClasses.jrag:92 339 */ 340 public boolean lastStringAddPart() { 341 ASTNode$State state = state(); 342 try { return !getParent().isStringAdd(); } 343 finally { 344 } 345 } 346 /** 347 * @apilevel internal 348 */ 349 public ASTNode rewriteTo() { 350 return super.rewriteTo(); 351 } 352 }