001 /* This file was generated with JastAdd2 (http://jastadd.org) version 2.1.13-12-g880e696 */ 002 package org.extendj.ast; 003 004 import java.util.HashSet; 005 import java.io.File; 006 import java.util.Set; 007 import java.util.Collections; 008 import java.util.Collection; 009 import java.util.ArrayList; 010 import beaver.*; 011 import java.util.*; 012 import java.io.ByteArrayOutputStream; 013 import java.io.PrintStream; 014 import java.lang.reflect.InvocationTargetException; 015 import java.lang.reflect.Method; 016 import org.jastadd.util.*; 017 import java.util.zip.*; 018 import java.io.*; 019 import org.jastadd.util.PrettyPrintable; 020 import org.jastadd.util.PrettyPrinter; 021 import java.io.FileNotFoundException; 022 import java.io.BufferedInputStream; 023 import java.io.DataInputStream; 024 /** 025 * @ast node 026 * @declaredat /home/jesper/git/extendj/java4/grammar/Java.ast:113 027 * @production AssignPlusExpr : {@link AssignAdditiveExpr}; 028 029 */ 030 public class AssignPlusExpr extends AssignAdditiveExpr implements Cloneable { 031 /** 032 * @aspect TypeCheck 033 * @declaredat /home/jesper/git/extendj/java4/frontend/TypeCheck.jrag:98 034 */ 035 public void typeCheck() { 036 if (!getDest().isVariable()) { 037 error("left hand side is not a variable"); 038 } else if (getSource().type().isUnknown() || getDest().type().isUnknown()) { 039 return; 040 } else if (getDest().type().isString() && !(getSource().type().isVoid())) { 041 return; 042 } else if (getSource().type().isBoolean() || getDest().type().isBoolean()) { 043 error("Operator + does not operate on boolean types"); 044 } else if (getSource().type().isPrimitive() && getDest().type().isPrimitive()) { 045 return; 046 } else 047 errorf("can not assign %s of type %s a value of type %s", 048 getDest().prettyPrint(), getDest().type().typeName(), getSource().type().typeName()); 049 } 050 /** 051 * @aspect CreateBCode 052 * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:359 053 */ 054 public void createBCode(CodeGeneration gen) { 055 TypeDecl dest = getDest().type(); 056 TypeDecl source = getSource().type(); 057 if (dest.isString()) { 058 getDest().createAssignLoadDest(gen); 059 060 // new StringBuffer() 061 TypeDecl stringBuffer = lookupType("java.lang", "StringBuffer"); 062 String classname = stringBuffer.constantPoolName(); 063 String desc; 064 int index; 065 TypeDecl argumentType; 066 stringBuffer.emitNew(gen); // new StringBuffer 067 gen.emitDup(); // dup 068 desc = "()V"; 069 index = gen.constantPool().addMethodref(classname, "<init>", desc); 070 gen.emit(Bytecode.INVOKESPECIAL, -1).add2(index); // invokespecial StringBuffer() 071 072 gen.emitSwap(); 073 074 // append 075 argumentType = dest.stringPromotion(); 076 desc = "(" + argumentType.typeDescriptor() + ")" + stringBuffer.typeDescriptor(); 077 index = gen.constantPool().addMethodref(classname, "append", desc); 078 gen.emit(Bytecode.INVOKEVIRTUAL, -argumentType.variableSize()).add2(index); // StringBuffer.append 079 080 getSource().createBCode(gen); 081 082 // typed append 083 argumentType = source.stringPromotion(); 084 desc = "(" + argumentType.typeDescriptor() + ")" + stringBuffer.typeDescriptor(); 085 index = gen.constantPool().addMethodref(classname, "append", desc); 086 gen.emit(Bytecode.INVOKEVIRTUAL, -argumentType.variableSize()).add2(index); // StringBuffer.append 087 088 // toString 089 desc = "()" + type().typeDescriptor(); 090 index = gen.constantPool().addMethodref(classname, "toString", desc); 091 gen.emit(Bytecode.INVOKEVIRTUAL, 0).add2(index); // StringBuffer.toString 092 093 if (needsPush()) { 094 getDest().createPushAssignmentResult(gen); 095 } 096 getDest().emitStore(gen); 097 } else { 098 super.createBCode(gen); 099 } 100 } 101 /** 102 * @aspect CreateBCode 103 * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:505 104 */ 105 public void createAssignOp(CodeGeneration gen, TypeDecl type) { type.add(gen); } 106 /** 107 * @declaredat ASTNode:1 108 */ 109 public AssignPlusExpr() { 110 super(); 111 } 112 /** 113 * Initializes the child array to the correct size. 114 * Initializes List and Opt nta children. 115 * @apilevel internal 116 * @ast method 117 * @declaredat ASTNode:10 118 */ 119 public void init$Children() { 120 children = new ASTNode[2]; 121 } 122 /** 123 * @declaredat ASTNode:13 124 */ 125 public AssignPlusExpr(Expr p0, Expr p1) { 126 setChild(p0, 0); 127 setChild(p1, 1); 128 } 129 /** 130 * @apilevel low-level 131 * @declaredat ASTNode:20 132 */ 133 protected int numChildren() { 134 return 2; 135 } 136 /** 137 * @apilevel internal 138 * @declaredat ASTNode:26 139 */ 140 public boolean mayHaveRewrite() { 141 return false; 142 } 143 /** 144 * @apilevel internal 145 * @declaredat ASTNode:32 146 */ 147 public void flushAttrCache() { 148 super.flushAttrCache(); 149 } 150 /** 151 * @apilevel internal 152 * @declaredat ASTNode:38 153 */ 154 public void flushCollectionCache() { 155 super.flushCollectionCache(); 156 } 157 /** 158 * @apilevel internal 159 * @declaredat ASTNode:44 160 */ 161 public void flushRewriteCache() { 162 super.flushRewriteCache(); 163 } 164 /** 165 * @apilevel internal 166 * @declaredat ASTNode:50 167 */ 168 public AssignPlusExpr clone() throws CloneNotSupportedException { 169 AssignPlusExpr node = (AssignPlusExpr) super.clone(); 170 return node; 171 } 172 /** 173 * @apilevel internal 174 * @declaredat ASTNode:57 175 */ 176 public AssignPlusExpr copy() { 177 try { 178 AssignPlusExpr node = (AssignPlusExpr) clone(); 179 node.parent = null; 180 if (children != null) { 181 node.children = (ASTNode[]) children.clone(); 182 } 183 return node; 184 } catch (CloneNotSupportedException e) { 185 throw new Error("Error: clone not supported for " + getClass().getName()); 186 } 187 } 188 /** 189 * Create a deep copy of the AST subtree at this node. 190 * The copy is dangling, i.e. has no parent. 191 * @return dangling copy of the subtree at this node 192 * @apilevel low-level 193 * @deprecated Please use treeCopy or treeCopyNoTransform instead 194 * @declaredat ASTNode:76 195 */ 196 @Deprecated 197 public AssignPlusExpr fullCopy() { 198 return treeCopyNoTransform(); 199 } 200 /** 201 * Create a deep copy of the AST subtree at this node. 202 * The copy is dangling, i.e. has no parent. 203 * @return dangling copy of the subtree at this node 204 * @apilevel low-level 205 * @declaredat ASTNode:86 206 */ 207 public AssignPlusExpr treeCopyNoTransform() { 208 AssignPlusExpr tree = (AssignPlusExpr) copy(); 209 if (children != null) { 210 for (int i = 0; i < children.length; ++i) { 211 ASTNode child = (ASTNode) children[i]; 212 if (child != null) { 213 child = child.treeCopyNoTransform(); 214 tree.setChild(child, i); 215 } 216 } 217 } 218 return tree; 219 } 220 /** 221 * Create a deep copy of the AST subtree at this node. 222 * The subtree of this node is traversed to trigger rewrites before copy. 223 * The copy is dangling, i.e. has no parent. 224 * @return dangling copy of the subtree at this node 225 * @apilevel low-level 226 * @declaredat ASTNode:106 227 */ 228 public AssignPlusExpr treeCopy() { 229 doFullTraversal(); 230 return treeCopyNoTransform(); 231 } 232 /** 233 * @apilevel internal 234 * @declaredat ASTNode:113 235 */ 236 protected boolean is$Equal(ASTNode node) { 237 return super.is$Equal(node); 238 } 239 /** 240 * Replaces the Dest child. 241 * @param node The new node to replace the Dest child. 242 * @apilevel high-level 243 */ 244 public void setDest(Expr node) { 245 setChild(node, 0); 246 } 247 /** 248 * Retrieves the Dest child. 249 * @return The current node used as the Dest child. 250 * @apilevel high-level 251 */ 252 @ASTNodeAnnotation.Child(name="Dest") 253 public Expr getDest() { 254 return (Expr) getChild(0); 255 } 256 /** 257 * Retrieves the Dest child. 258 * <p><em>This method does not invoke AST transformations.</em></p> 259 * @return The current node used as the Dest child. 260 * @apilevel low-level 261 */ 262 public Expr getDestNoTransform() { 263 return (Expr) getChildNoTransform(0); 264 } 265 /** 266 * Replaces the Source child. 267 * @param node The new node to replace the Source child. 268 * @apilevel high-level 269 */ 270 public void setSource(Expr node) { 271 setChild(node, 1); 272 } 273 /** 274 * Retrieves the Source child. 275 * @return The current node used as the Source child. 276 * @apilevel high-level 277 */ 278 @ASTNodeAnnotation.Child(name="Source") 279 public Expr getSource() { 280 return (Expr) getChild(1); 281 } 282 /** 283 * Retrieves the Source child. 284 * <p><em>This method does not invoke AST transformations.</em></p> 285 * @return The current node used as the Source child. 286 * @apilevel low-level 287 */ 288 public Expr getSourceNoTransform() { 289 return (Expr) getChildNoTransform(1); 290 } 291 /** The operator string used for pretty printing this expression. 292 * @attribute syn 293 * @aspect PrettyPrintUtil 294 * @declaredat /home/jesper/git/extendj/java4/frontend/PrettyPrintUtil.jrag:292 295 */ 296 @ASTNodeAnnotation.Attribute 297 public String printOp() { 298 String printOp_value = "+="; 299 300 return printOp_value; 301 } 302 /** 303 * @apilevel internal 304 */ 305 public ASTNode rewriteTo() { 306 return super.rewriteTo(); 307 } 308 }