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:103
027     * @production AssignExpr : {@link Expr} ::= <span class="component">Dest:{@link Expr}</span> <span class="component">Source:{@link Expr}</span>;
028    
029     */
030    public abstract class AssignExpr extends Expr implements Cloneable {
031      /**
032       * @aspect DA
033       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:511
034       */
035      protected boolean checkDUeverywhere(Variable v) {
036        if (getDest().isVariable() && getDest().varDecl() == v) {
037          if (!getSource().isDAafter(v)) {
038            return false;
039          }
040        }
041        return super.checkDUeverywhere(v);
042      }
043      /**
044       * @aspect NodeConstructors
045       * @declaredat /home/jesper/git/extendj/java4/frontend/NodeConstructors.jrag:105
046       */
047      public static Stmt asStmt(Expr left, Expr right) {
048        return new ExprStmt(new AssignSimpleExpr(left, right));
049      }
050      /**
051       * @aspect Java4PrettyPrint
052       * @declaredat /home/jesper/git/extendj/java4/frontend/PrettyPrint.jadd:406
053       */
054      public void prettyPrint(PrettyPrinter out) {
055        out.print(getDest());
056        out.print(" ");
057        out.print(printOp());
058        out.print(" ");
059        out.print(getSource());
060      }
061      /**
062       * @aspect TypeCheck
063       * @declaredat /home/jesper/git/extendj/java4/frontend/TypeCheck.jrag:77
064       */
065      public void typeCheck() {
066        if (!getDest().isVariable()) {
067          error("left hand side is not a variable");
068        } else {
069          TypeDecl source = getSource().type();
070          TypeDecl dest = getDest().type();
071          if (getSource().type().isPrimitive() && getDest().type().isPrimitive()) {
072            return;
073          }
074          errorf("can not assign %s of type %s a value of type %s",
075              getDest().prettyPrint(), getDest().type().typeName(), getSource().type().typeName());
076        }
077      }
078      /**
079       * @aspect CreateBCode
080       * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:408
081       */
082      public void emitShiftExpr(CodeGeneration gen) {
083        TypeDecl dest = getDest().type();
084        TypeDecl source = getSource().type();
085        TypeDecl type = dest.unaryNumericPromotion();
086        getDest().createAssignLoadDest(gen);
087        dest.emitCastTo(gen, type);
088        getSource().createBCode(gen);
089        source.emitCastTo(gen, typeInt());
090        createAssignOp(gen, type);
091        type.emitCastTo(gen, dest);
092        if (needsPush()) {
093          getDest().createPushAssignmentResult(gen);
094        }
095        getDest().emitStore(gen);
096      }
097      /**
098       * @aspect CreateBCode
099       * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:499
100       */
101      public void createAssignOp(CodeGeneration gen, TypeDecl type) {
102        throw new Error("Operation createAssignOp is not implemented for " + getClass().getName());
103      }
104      /**
105       * @declaredat ASTNode:1
106       */
107      public AssignExpr() {
108        super();
109      }
110      /**
111       * Initializes the child array to the correct size.
112       * Initializes List and Opt nta children.
113       * @apilevel internal
114       * @ast method
115       * @declaredat ASTNode:10
116       */
117      public void init$Children() {
118        children = new ASTNode[2];
119      }
120      /**
121       * @declaredat ASTNode:13
122       */
123      public AssignExpr(Expr p0, Expr p1) {
124        setChild(p0, 0);
125        setChild(p1, 1);
126      }
127      /**
128       * @apilevel low-level
129       * @declaredat ASTNode:20
130       */
131      protected int numChildren() {
132        return 2;
133      }
134      /**
135       * @apilevel internal
136       * @declaredat ASTNode:26
137       */
138      public boolean mayHaveRewrite() {
139        return false;
140      }
141      /**
142       * @apilevel internal
143       * @declaredat ASTNode:32
144       */
145      public void flushAttrCache() {
146        super.flushAttrCache();
147        type_reset();
148        stmtCompatible_reset();
149      }
150      /**
151       * @apilevel internal
152       * @declaredat ASTNode:40
153       */
154      public void flushCollectionCache() {
155        super.flushCollectionCache();
156      }
157      /**
158       * @apilevel internal
159       * @declaredat ASTNode:46
160       */
161      public void flushRewriteCache() {
162        super.flushRewriteCache();
163      }
164      /**
165       * @apilevel internal
166       * @declaredat ASTNode:52
167       */
168      public AssignExpr clone() throws CloneNotSupportedException {
169        AssignExpr node = (AssignExpr) super.clone();
170        return node;
171      }
172      /**
173       * Create a deep copy of the AST subtree at this node.
174       * The copy is dangling, i.e. has no parent.
175       * @return dangling copy of the subtree at this node
176       * @apilevel low-level
177       * @deprecated Please use treeCopy or treeCopyNoTransform instead
178       * @declaredat ASTNode:63
179       */
180      @Deprecated
181      public abstract AssignExpr fullCopy();
182      /**
183       * Create a deep copy of the AST subtree at this node.
184       * The copy is dangling, i.e. has no parent.
185       * @return dangling copy of the subtree at this node
186       * @apilevel low-level
187       * @declaredat ASTNode:71
188       */
189      public abstract AssignExpr treeCopyNoTransform();
190      /**
191       * Create a deep copy of the AST subtree at this node.
192       * The subtree of this node is traversed to trigger rewrites before copy.
193       * The copy is dangling, i.e. has no parent.
194       * @return dangling copy of the subtree at this node
195       * @apilevel low-level
196       * @declaredat ASTNode:79
197       */
198      public abstract AssignExpr treeCopy();
199      /**
200       * Replaces the Dest child.
201       * @param node The new node to replace the Dest child.
202       * @apilevel high-level
203       */
204      public void setDest(Expr node) {
205        setChild(node, 0);
206      }
207      /**
208       * Retrieves the Dest child.
209       * @return The current node used as the Dest child.
210       * @apilevel high-level
211       */
212      @ASTNodeAnnotation.Child(name="Dest")
213      public Expr getDest() {
214        return (Expr) getChild(0);
215      }
216      /**
217       * Retrieves the Dest child.
218       * <p><em>This method does not invoke AST transformations.</em></p>
219       * @return The current node used as the Dest child.
220       * @apilevel low-level
221       */
222      public Expr getDestNoTransform() {
223        return (Expr) getChildNoTransform(0);
224      }
225      /**
226       * Replaces the Source child.
227       * @param node The new node to replace the Source child.
228       * @apilevel high-level
229       */
230      public void setSource(Expr node) {
231        setChild(node, 1);
232      }
233      /**
234       * Retrieves the Source child.
235       * @return The current node used as the Source child.
236       * @apilevel high-level
237       */
238      @ASTNodeAnnotation.Child(name="Source")
239      public Expr getSource() {
240        return (Expr) getChild(1);
241      }
242      /**
243       * Retrieves the Source child.
244       * <p><em>This method does not invoke AST transformations.</em></p>
245       * @return The current node used as the Source child.
246       * @apilevel low-level
247       */
248      public Expr getSourceNoTransform() {
249        return (Expr) getChildNoTransform(1);
250      }
251      /**
252       * @aspect AutoBoxingCodegen
253       * @declaredat /home/jesper/git/extendj/java5/backend/AutoBoxingCodegen.jrag:359
254       */
255        public void createBCode(CodeGeneration gen) {
256        TypeDecl dest = getDest().type();
257        TypeDecl source = getSource().type();
258        TypeDecl type;
259        if (dest.isNumericType() && source.isNumericType()) {
260          type = dest.binaryNumericPromotion(source);
261        } else if (dest.isBoolean() && source.isBoolean()) {
262          type = dest.isReferenceType() ? dest.unboxed() : dest;
263        } else {
264          type = dest;
265        }
266        getDest().createAssignLoadDest(gen);
267        dest.emitCastTo(gen, type);
268        getSource().createBCode(gen);
269        source.emitCastTo(gen, type);
270        createAssignOp(gen, type);
271        type.emitCastTo(gen, dest);
272        if (needsPush()) {
273          getDest().createPushAssignmentResult(gen);
274        }
275        getDest().emitStore(gen);
276      }
277      /** The operator string used for pretty printing this expression. 
278       * @attribute syn
279       * @aspect PrettyPrintUtil
280       * @declaredat /home/jesper/git/extendj/java4/frontend/PrettyPrintUtil.jrag:292
281       */
282      @ASTNodeAnnotation.Attribute
283      public abstract String printOp();
284      /**
285       * @attribute syn
286       * @aspect DA
287       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:259
288       */
289      @ASTNodeAnnotation.Attribute
290      public boolean isDAafter(Variable v) {
291        boolean isDAafter_Variable_value = (getDest().isVariable() && getDest().varDecl() == v) || getSource().isDAafter(v);
292    
293        return isDAafter_Variable_value;
294      }
295      /**
296       * @attribute syn
297       * @aspect DA
298       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:374
299       */
300      @ASTNodeAnnotation.Attribute
301      public boolean isDAafterTrue(Variable v) {
302        boolean isDAafterTrue_Variable_value = isFalse() || isDAafter(v);
303    
304        return isDAafterTrue_Variable_value;
305      }
306      /**
307       * @attribute syn
308       * @aspect DA
309       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:375
310       */
311      @ASTNodeAnnotation.Attribute
312      public boolean isDAafterFalse(Variable v) {
313        boolean isDAafterFalse_Variable_value = isTrue() || isDAafter(v);
314    
315        return isDAafterFalse_Variable_value;
316      }
317      /**
318       * @attribute syn
319       * @aspect DU
320       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:783
321       */
322      @ASTNodeAnnotation.Attribute
323      public boolean isDUafter(Variable v) {
324        {
325            if (getDest().isVariable() && getDest().varDecl() == v) {
326              return false;
327            } else {
328              return getSource().isDUafter(v);
329            }
330          }
331      }
332      /**
333       * @attribute syn
334       * @aspect DU
335       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:791
336       */
337      @ASTNodeAnnotation.Attribute
338      public boolean isDUafterTrue(Variable v) {
339        boolean isDUafterTrue_Variable_value = isDUafter(v);
340    
341        return isDUafterTrue_Variable_value;
342      }
343      /**
344       * @attribute syn
345       * @aspect DU
346       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:792
347       */
348      @ASTNodeAnnotation.Attribute
349      public boolean isDUafterFalse(Variable v) {
350        boolean isDUafterFalse_Variable_value = isDUafter(v);
351    
352        return isDUafterFalse_Variable_value;
353      }
354      /**
355       * @apilevel internal
356       */
357      protected boolean type_computed = false;
358      /**
359       * @apilevel internal
360       */
361      protected TypeDecl type_value;
362      /**
363       * @apilevel internal
364       */
365      private void type_reset() {
366        type_computed = false;
367        type_value = null;
368      }
369      /**
370       * @attribute syn
371       * @aspect TypeAnalysis
372       * @declaredat /home/jesper/git/extendj/java4/frontend/TypeAnalysis.jrag:302
373       */
374      @ASTNodeAnnotation.Attribute
375      public TypeDecl type() {
376        ASTNode$State state = state();
377        if (type_computed) {
378          return type_value;
379        }
380        boolean intermediate = state.INTERMEDIATE_VALUE;
381        state.INTERMEDIATE_VALUE = false;
382        int num = state.boundariesCrossed;
383        boolean isFinal = this.is$Final();
384        type_value = getDest().type();
385        if (isFinal && num == state().boundariesCrossed) {
386          type_computed = true;
387        } else {
388        }
389        state.INTERMEDIATE_VALUE |= intermediate;
390    
391        return type_value;
392      }
393      /**
394       * @attribute syn
395       * @aspect CreateBCode
396       * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:251
397       */
398      @ASTNodeAnnotation.Attribute
399      public boolean needsPop() {
400        boolean needsPop_value = getDest().isVarAccessWithAccessor();
401    
402        return needsPop_value;
403      }
404      /**
405       * @attribute syn
406       * @aspect PreciseRethrow
407       * @declaredat /home/jesper/git/extendj/java7/frontend/PreciseRethrow.jrag:149
408       */
409      @ASTNodeAnnotation.Attribute
410      public boolean modifiedInScope(Variable var) {
411        {
412            boolean isLeft = getDest().isVariable(var);
413            if (isLeft && var instanceof VariableDeclaration) {
414              VariableDeclaration decl = (VariableDeclaration) var;
415              if (!decl.hasInit()) {
416                // Variable is being written to in an inner class.
417                if (decl.hostType() != hostType()) {
418                  return true;
419                }
420                // 4.12.4;
421                return !getSource().isDUafter(var);
422              }
423              return true;
424            } else {
425              return isLeft || getSource().modifiedInScope(var);
426            }
427          }
428      }
429      /**
430       * @apilevel internal
431       */
432      protected boolean stmtCompatible_computed = false;
433      /**
434       * @apilevel internal
435       */
436      protected boolean stmtCompatible_value;
437      /**
438       * @apilevel internal
439       */
440      private void stmtCompatible_reset() {
441        stmtCompatible_computed = false;
442      }
443      /**
444       * @attribute syn
445       * @aspect StmtCompatible
446       * @declaredat /home/jesper/git/extendj/java8/frontend/LambdaExpr.jrag:140
447       */
448      @ASTNodeAnnotation.Attribute
449      public boolean stmtCompatible() {
450        ASTNode$State state = state();
451        if (stmtCompatible_computed) {
452          return stmtCompatible_value;
453        }
454        boolean intermediate = state.INTERMEDIATE_VALUE;
455        state.INTERMEDIATE_VALUE = false;
456        int num = state.boundariesCrossed;
457        boolean isFinal = this.is$Final();
458        stmtCompatible_value = true;
459        if (isFinal && num == state().boundariesCrossed) {
460          stmtCompatible_computed = true;
461        } else {
462        }
463        state.INTERMEDIATE_VALUE |= intermediate;
464    
465        return stmtCompatible_value;
466      }
467      /**
468       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:37
469       * @apilevel internal
470       */
471      public boolean Define_isDest(ASTNode caller, ASTNode child) {
472        if (caller == getSourceNoTransform()) {
473          // @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:41
474          return false;
475        }
476        else if (caller == getDestNoTransform()) {
477          // @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:40
478          return true;
479        }
480        else {
481          return getParent().Define_isDest(this, caller);
482        }
483      }
484      protected boolean canDefine_isDest(ASTNode caller, ASTNode child) {
485        return true;
486      }
487      /**
488       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:47
489       * @apilevel internal
490       */
491      public boolean Define_isSource(ASTNode caller, ASTNode child) {
492        if (caller == getSourceNoTransform()) {
493          // @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:51
494          return true;
495        }
496        else if (caller == getDestNoTransform()) {
497          // @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:50
498          return true;
499        }
500        else {
501          return getParent().Define_isSource(this, caller);
502        }
503      }
504      protected boolean canDefine_isSource(ASTNode caller, ASTNode child) {
505        return true;
506      }
507      /**
508       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:255
509       * @apilevel internal
510       */
511      public boolean Define_isDAbefore(ASTNode caller, ASTNode child, Variable v) {
512        if (caller == getDestNoTransform()) {
513          // @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:433
514          return isDAbefore(v);
515        }
516        else if (caller == getSourceNoTransform()) {
517          // @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:432
518          return getDest().isDAafter(v);
519        }
520        else {
521          return getParent().Define_isDAbefore(this, caller, v);
522        }
523      }
524      protected boolean canDefine_isDAbefore(ASTNode caller, ASTNode child, Variable v) {
525        return true;
526      }
527      /**
528       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:779
529       * @apilevel internal
530       */
531      public boolean Define_isDUbefore(ASTNode caller, ASTNode child, Variable v) {
532        if (caller == getDestNoTransform()) {
533          // @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:933
534          return isDUbefore(v);
535        }
536        else if (caller == getSourceNoTransform()) {
537          // @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:932
538          return getDest().isDUafter(v);
539        }
540        else {
541          return getParent().Define_isDUbefore(this, caller, v);
542        }
543      }
544      protected boolean canDefine_isDUbefore(ASTNode caller, ASTNode child, Variable v) {
545        return true;
546      }
547      /**
548       * @declaredat /home/jesper/git/extendj/java4/frontend/SyntacticClassification.jrag:36
549       * @apilevel internal
550       */
551      public NameType Define_nameType(ASTNode caller, ASTNode child) {
552        if (caller == getDestNoTransform()) {
553          // @declaredat /home/jesper/git/extendj/java4/frontend/SyntacticClassification.jrag:126
554          return NameType.EXPRESSION_NAME;
555        }
556        else {
557          return getParent().Define_nameType(this, caller);
558        }
559      }
560      protected boolean canDefine_nameType(ASTNode caller, ASTNode child) {
561        return true;
562      }
563      /**
564       * @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:30
565       * @apilevel internal
566       */
567      public TypeDecl Define_targetType(ASTNode caller, ASTNode child) {
568        if (caller == getSourceNoTransform()) {
569          // @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:38
570          return getDest().type();
571        }
572        else {
573          return getParent().Define_targetType(this, caller);
574        }
575      }
576      protected boolean canDefine_targetType(ASTNode caller, ASTNode child) {
577        return true;
578      }
579      /**
580       * @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:196
581       * @apilevel internal
582       */
583      public boolean Define_assignmentContext(ASTNode caller, ASTNode child) {
584        if (caller == getSourceNoTransform()) {
585          // @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:319
586          return true;
587        }
588        else if (caller == getDestNoTransform()) {
589          // @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:313
590          return false;
591        }
592        else {
593          return getParent().Define_assignmentContext(this, caller);
594        }
595      }
596      protected boolean canDefine_assignmentContext(ASTNode caller, ASTNode child) {
597        return true;
598      }
599      /**
600       * @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:197
601       * @apilevel internal
602       */
603      public boolean Define_invocationContext(ASTNode caller, ASTNode child) {
604        if (caller == getSourceNoTransform()) {
605          // @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:320
606          return false;
607        }
608        else if (caller == getDestNoTransform()) {
609          // @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:314
610          return false;
611        }
612        else {
613          return getParent().Define_invocationContext(this, caller);
614        }
615      }
616      protected boolean canDefine_invocationContext(ASTNode caller, ASTNode child) {
617        return true;
618      }
619      /**
620       * @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:198
621       * @apilevel internal
622       */
623      public boolean Define_castContext(ASTNode caller, ASTNode child) {
624        if (caller == getSourceNoTransform()) {
625          // @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:321
626          return false;
627        }
628        else if (caller == getDestNoTransform()) {
629          // @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:315
630          return false;
631        }
632        else {
633          return getParent().Define_castContext(this, caller);
634        }
635      }
636      protected boolean canDefine_castContext(ASTNode caller, ASTNode child) {
637        return true;
638      }
639      /**
640       * @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:200
641       * @apilevel internal
642       */
643      public boolean Define_numericContext(ASTNode caller, ASTNode child) {
644        if (caller == getSourceNoTransform()) {
645          // @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:323
646          return false;
647        }
648        else if (caller == getDestNoTransform()) {
649          // @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:316
650          return false;
651        }
652        else {
653          return getParent().Define_numericContext(this, caller);
654        }
655      }
656      protected boolean canDefine_numericContext(ASTNode caller, ASTNode child) {
657        return true;
658      }
659      /**
660       * @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:199
661       * @apilevel internal
662       */
663      public boolean Define_stringContext(ASTNode caller, ASTNode child) {
664        if (caller == getSourceNoTransform()) {
665          // @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:322
666          return false;
667        }
668        else if (caller == getDestNoTransform()) {
669          // @declaredat /home/jesper/git/extendj/java8/frontend/TargetType.jrag:317
670          return false;
671        }
672        else {
673          return getParent().Define_stringContext(this, caller);
674        }
675      }
676      protected boolean canDefine_stringContext(ASTNode caller, ASTNode child) {
677        return true;
678      }
679      /**
680       * @apilevel internal
681       */
682      public ASTNode rewriteTo() {
683        return super.rewriteTo();
684      }
685    }