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 AssignPlusExpr : {@link AssignAdditiveExpr};
015     * @ast node
016     * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/java.ast:116
017     */
018    public class AssignPlusExpr extends AssignAdditiveExpr 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 AssignPlusExpr clone() throws CloneNotSupportedException {
034        AssignPlusExpr node = (AssignPlusExpr)super.clone();
035        node.in$Circle(false);
036        node.is$Final(false);
037        return node;
038      }
039    /**
040     * @apilevel internal
041     */
042      @SuppressWarnings({"unchecked", "cast"})
043    public AssignPlusExpr copy() {
044      
045      try {
046        AssignPlusExpr node = (AssignPlusExpr) clone();
047        node.parent = null;
048        if(children != null)
049          node.children = (ASTNode[]) children.clone();
050        
051        return node;
052      } catch (CloneNotSupportedException e) {
053        throw new Error("Error: clone not supported for " + getClass().getName());
054      }
055      
056    }/**
057     * Create a deep copy of the AST subtree at this node.
058     * The copy is dangling, i.e. has no parent.
059     * @return dangling copy of the subtree at this node
060     * @apilevel low-level
061     */
062      @SuppressWarnings({"unchecked", "cast"})
063    public AssignPlusExpr fullCopy() {
064      
065      AssignPlusExpr tree = (AssignPlusExpr) copy();
066      if (children != null) {
067        for (int i = 0; i < children.length; ++i) {
068          
069          ASTNode child = (ASTNode) children[i];
070          if(child != null) {
071            child = child.fullCopy();
072            tree.setChild(child, i);
073          }
074        }
075      }
076      return tree;
077      
078    }  /**
079       * @ast method 
080       * @aspect TypeCheck
081       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/TypeCheck.jrag:71
082       */
083      public void typeCheck() {
084        if(!getDest().isVariable())
085          error("left hand side is not a variable");
086        else if(getSource().type().isUnknown() || getDest().type().isUnknown())
087          return;
088        else if(getDest().type().isString() && !(getSource().type().isVoid()))
089          return;
090        else if(getSource().type().isBoolean() || getDest().type().isBoolean())
091          error("Operator + does not operate on boolean types");
092        else if(getSource().type().isPrimitive() && getDest().type().isPrimitive())
093          return;
094        else
095          error("can not assign " + getDest() + " of type " + getDest().type().typeName() +
096                " a value of type " + sourceType().typeName());
097      }
098      /**
099       * @ast method 
100       * @aspect CreateBCode
101       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Backend/CreateBCode.jrag:280
102       */
103      public void createBCode(CodeGeneration gen) {
104        TypeDecl dest = getDest().type();
105        TypeDecl source = getSource().type();
106        if(dest.isString()) {
107          getDest().createAssignLoadDest(gen);
108          
109          // new StringBuffer()
110          TypeDecl stringBuffer = lookupType("java.lang", "StringBuffer");
111          String classname = stringBuffer.constantPoolName();
112          String desc;
113          int index;
114          TypeDecl argumentType;
115          stringBuffer.emitNew(gen); // new StringBuffer
116          gen.emitDup();             // dup
117          desc = "()V";
118          index = gen.constantPool().addMethodref(classname, "<init>", desc);
119          gen.emit(Bytecode.INVOKESPECIAL, -1).add2(index); // invokespecial StringBuffer()
120    
121          gen.emitSwap();
122    
123          // append
124          argumentType = dest.stringPromotion();
125          desc = "(" + argumentType.typeDescriptor() + ")" + stringBuffer.typeDescriptor();
126          index = gen.constantPool().addMethodref(classname, "append", desc);
127          gen.emit(Bytecode.INVOKEVIRTUAL, -argumentType.variableSize()).add2(index); // StringBuffer.append
128          
129          getSource().createBCode(gen);
130    
131          // typed append
132          argumentType = source.stringPromotion();
133          desc = "(" + argumentType.typeDescriptor() + ")" + stringBuffer.typeDescriptor();
134          index = gen.constantPool().addMethodref(classname, "append", desc);
135          gen.emit(Bytecode.INVOKEVIRTUAL, -argumentType.variableSize()).add2(index); // StringBuffer.append
136          
137          // toString
138          desc = "()" + type().typeDescriptor();
139          index = gen.constantPool().addMethodref(classname, "toString", desc);
140          gen.emit(Bytecode.INVOKEVIRTUAL, 0).add2(index); // StringBuffer.toString
141          
142          if(needsPush()) {
143            getDest().createPushAssignmentResult(gen);
144          }
145          getDest().emitStore(gen);
146        }
147        else {
148          super.createBCode(gen);
149        }
150      }
151      /**
152       * @ast method 
153       * @aspect CreateBCode
154       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Backend/CreateBCode.jrag:425
155       */
156      public void createAssignOp(CodeGeneration gen, TypeDecl type)    { type.add(gen); }
157      /**
158       * @ast method 
159       * 
160       */
161      public AssignPlusExpr() {
162        super();
163    
164    
165      }
166      /**
167       * Initializes the child array to the correct size.
168       * Initializes List and Opt nta children.
169       * @apilevel internal
170       * @ast method
171       * @ast method 
172       * 
173       */
174      public void init$Children() {
175        children = new ASTNode[2];
176      }
177      /**
178       * @ast method 
179       * 
180       */
181      public AssignPlusExpr(Expr p0, Expr p1) {
182        setChild(p0, 0);
183        setChild(p1, 1);
184      }
185      /**
186       * @apilevel low-level
187       * @ast method 
188       * 
189       */
190      protected int numChildren() {
191        return 2;
192      }
193      /**
194       * @apilevel internal
195       * @ast method 
196       * 
197       */
198      public boolean mayHaveRewrite() {
199        return false;
200      }
201      /**
202       * Replaces the Dest child.
203       * @param node The new node to replace the Dest child.
204       * @apilevel high-level
205       * @ast method 
206       * 
207       */
208      public void setDest(Expr node) {
209        setChild(node, 0);
210      }
211      /**
212       * Retrieves the Dest child.
213       * @return The current node used as the Dest child.
214       * @apilevel high-level
215       * @ast method 
216       * 
217       */
218      public Expr getDest() {
219        return (Expr)getChild(0);
220      }
221      /**
222       * Retrieves the Dest child.
223       * <p><em>This method does not invoke AST transformations.</em></p>
224       * @return The current node used as the Dest child.
225       * @apilevel low-level
226       * @ast method 
227       * 
228       */
229      public Expr getDestNoTransform() {
230        return (Expr)getChildNoTransform(0);
231      }
232      /**
233       * Replaces the Source child.
234       * @param node The new node to replace the Source child.
235       * @apilevel high-level
236       * @ast method 
237       * 
238       */
239      public void setSource(Expr node) {
240        setChild(node, 1);
241      }
242      /**
243       * Retrieves the Source child.
244       * @return The current node used as the Source child.
245       * @apilevel high-level
246       * @ast method 
247       * 
248       */
249      public Expr getSource() {
250        return (Expr)getChild(1);
251      }
252      /**
253       * Retrieves the Source child.
254       * <p><em>This method does not invoke AST transformations.</em></p>
255       * @return The current node used as the Source child.
256       * @apilevel low-level
257       * @ast method 
258       * 
259       */
260      public Expr getSourceNoTransform() {
261        return (Expr)getChildNoTransform(1);
262      }
263      /**
264       * @attribute syn
265       * @aspect PrettyPrint
266       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/PrettyPrint.jadd:247
267       */
268      public String printOp() {
269        ASTNode$State state = state();
270        try {  return " += ";  }
271        finally {
272        }
273      }
274      /**
275       * @attribute syn
276       * @aspect TypeCheck
277       * @declaredat /home/jesper/svn/JastAddJ/Java1.4Frontend/TypeCheck.jrag:109
278       */
279      public TypeDecl sourceType() {
280        ASTNode$State state = state();
281        try {
282        TypeDecl left = getDest().type();
283        TypeDecl right = getSource().type();
284        if(!left.isString() && !right.isString())
285          return super.sourceType();
286        if(left.isVoid() || right.isVoid())
287          return unknownType();
288        return left.isString() ? left : right;
289      }
290        finally {
291        }
292      }
293      /**
294       * @apilevel internal
295       */
296      public ASTNode rewriteTo() {
297        return super.rewriteTo();
298      }
299    }