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:223
027     * @production AssertStmt : {@link Stmt} ::= <span class="component">Condition:{@link Expr}</span> <span class="component">[Message:{@link Expr}]</span>;
028    
029     */
030    public class AssertStmt extends Stmt implements Cloneable {
031      /**
032       * @aspect Java4PrettyPrint
033       * @declaredat /home/jesper/git/extendj/java4/frontend/PrettyPrint.jadd:419
034       */
035      public void prettyPrint(PrettyPrinter out) {
036        if (hasMessage()) {
037          out.print("assert ");
038          out.print(getCondition());
039          out.print(" : ");
040          out.print(getMessage());
041          out.print(";");
042        } else {
043          out.print("assert ");
044          out.print(getCondition());
045          out.print(";");
046        }
047      }
048      /**
049       * @aspect TypeCheck
050       * @declaredat /home/jesper/git/extendj/java4/frontend/TypeCheck.jrag:443
051       */
052      public void typeCheck() {
053        // 14.10
054        if (!getCondition().type().isBoolean()) {
055          error("Assert requires boolean condition");
056        }
057        if (hasMessage() && getMessage().type().isVoid()) {
058          error("The detail message of an assert statement may not be void");
059        }
060      }
061      /**
062       * Assert statement bytecode is generated through the transformed
063       * version of the assert statement!
064       * 
065       * @see java4/backend/Transformations.jrag
066       * @aspect CreateBCode
067       * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:1864
068       */
069      public void createBCode(CodeGeneration gen) {
070        throw new UnsupportedOperationException("Assert not yet implemented");
071      }
072      /**
073       * @aspect Transformations
074       * @declaredat /home/jesper/git/extendj/java4/backend/Transformations.jrag:164
075       */
076      public void transformation() {
077        super.transformation();
078        // add field to hold cached result as a side-effect
079        FieldDeclaration f = hostType().topLevelType().createStaticClassField(hostType().topLevelType().referenceClassFieldName());
080        FieldDeclaration assertionsDisabled = hostType().createAssertionsDisabled();
081        Expr condition = (Expr) getCondition().treeCopyNoTransform();
082        List args = new List();
083        if (hasMessage()) {
084          if (getMessage().type().isString()) {
085            args.add(new CastExpr(new TypeAccess("java.lang", "Object"), (Expr) getMessage().treeCopyNoTransform()));
086          } else {
087            args.add(getMessage().treeCopyNoTransform());
088          }
089        }
090        Stmt stmt = new IfStmt(
091            new LogNotExpr(
092              new ParExpr(
093                new OrLogicalExpr(
094                  new BoundFieldAccess(assertionsDisabled),
095                  condition
096                )
097              )
098            ),
099            new ThrowStmt(
100              new ClassInstanceExpr(
101                lookupType("java.lang", "AssertionError").createQualifiedAccess(),
102                args,
103                new Opt()
104              )
105            ),
106            new Opt()
107          );
108    
109        this.replaceWith(stmt);
110        stmt.transformation();
111      }
112      /**
113       * @declaredat ASTNode:1
114       */
115      public AssertStmt() {
116        super();
117      }
118      /**
119       * Initializes the child array to the correct size.
120       * Initializes List and Opt nta children.
121       * @apilevel internal
122       * @ast method
123       * @declaredat ASTNode:10
124       */
125      public void init$Children() {
126        children = new ASTNode[2];
127        setChild(new Opt(), 1);
128      }
129      /**
130       * @declaredat ASTNode:14
131       */
132      public AssertStmt(Expr p0, Opt<Expr> p1) {
133        setChild(p0, 0);
134        setChild(p1, 1);
135      }
136      /**
137       * @apilevel low-level
138       * @declaredat ASTNode:21
139       */
140      protected int numChildren() {
141        return 2;
142      }
143      /**
144       * @apilevel internal
145       * @declaredat ASTNode:27
146       */
147      public boolean mayHaveRewrite() {
148        return false;
149      }
150      /**
151       * @apilevel internal
152       * @declaredat ASTNode:33
153       */
154      public void flushAttrCache() {
155        super.flushAttrCache();
156        isDAafter_Variable_reset();
157        isDUafter_Variable_reset();
158      }
159      /**
160       * @apilevel internal
161       * @declaredat ASTNode:41
162       */
163      public void flushCollectionCache() {
164        super.flushCollectionCache();
165      }
166      /**
167       * @apilevel internal
168       * @declaredat ASTNode:47
169       */
170      public void flushRewriteCache() {
171        super.flushRewriteCache();
172      }
173      /**
174       * @apilevel internal
175       * @declaredat ASTNode:53
176       */
177      public AssertStmt clone() throws CloneNotSupportedException {
178        AssertStmt node = (AssertStmt) super.clone();
179        return node;
180      }
181      /**
182       * @apilevel internal
183       * @declaredat ASTNode:60
184       */
185      public AssertStmt copy() {
186        try {
187          AssertStmt node = (AssertStmt) clone();
188          node.parent = null;
189          if (children != null) {
190            node.children = (ASTNode[]) children.clone();
191          }
192          return node;
193        } catch (CloneNotSupportedException e) {
194          throw new Error("Error: clone not supported for " + getClass().getName());
195        }
196      }
197      /**
198       * Create a deep copy of the AST subtree at this node.
199       * The copy is dangling, i.e. has no parent.
200       * @return dangling copy of the subtree at this node
201       * @apilevel low-level
202       * @deprecated Please use treeCopy or treeCopyNoTransform instead
203       * @declaredat ASTNode:79
204       */
205      @Deprecated
206      public AssertStmt fullCopy() {
207        return treeCopyNoTransform();
208      }
209      /**
210       * Create a deep copy of the AST subtree at this node.
211       * The copy is dangling, i.e. has no parent.
212       * @return dangling copy of the subtree at this node
213       * @apilevel low-level
214       * @declaredat ASTNode:89
215       */
216      public AssertStmt treeCopyNoTransform() {
217        AssertStmt tree = (AssertStmt) copy();
218        if (children != null) {
219          for (int i = 0; i < children.length; ++i) {
220            ASTNode child = (ASTNode) children[i];
221            if (child != null) {
222              child = child.treeCopyNoTransform();
223              tree.setChild(child, i);
224            }
225          }
226        }
227        return tree;
228      }
229      /**
230       * Create a deep copy of the AST subtree at this node.
231       * The subtree of this node is traversed to trigger rewrites before copy.
232       * The copy is dangling, i.e. has no parent.
233       * @return dangling copy of the subtree at this node
234       * @apilevel low-level
235       * @declaredat ASTNode:109
236       */
237      public AssertStmt treeCopy() {
238        doFullTraversal();
239        return treeCopyNoTransform();
240      }
241      /**
242       * @apilevel internal
243       * @declaredat ASTNode:116
244       */
245      protected boolean is$Equal(ASTNode node) {
246        return super.is$Equal(node);    
247      }
248      /**
249       * Replaces the Condition child.
250       * @param node The new node to replace the Condition child.
251       * @apilevel high-level
252       */
253      public void setCondition(Expr node) {
254        setChild(node, 0);
255      }
256      /**
257       * Retrieves the Condition child.
258       * @return The current node used as the Condition child.
259       * @apilevel high-level
260       */
261      @ASTNodeAnnotation.Child(name="Condition")
262      public Expr getCondition() {
263        return (Expr) getChild(0);
264      }
265      /**
266       * Retrieves the Condition child.
267       * <p><em>This method does not invoke AST transformations.</em></p>
268       * @return The current node used as the Condition child.
269       * @apilevel low-level
270       */
271      public Expr getConditionNoTransform() {
272        return (Expr) getChildNoTransform(0);
273      }
274      /**
275       * Replaces the optional node for the Message child. This is the <code>Opt</code>
276       * node containing the child Message, not the actual child!
277       * @param opt The new node to be used as the optional node for the Message child.
278       * @apilevel low-level
279       */
280      public void setMessageOpt(Opt<Expr> opt) {
281        setChild(opt, 1);
282      }
283      /**
284       * Replaces the (optional) Message child.
285       * @param node The new node to be used as the Message child.
286       * @apilevel high-level
287       */
288      public void setMessage(Expr node) {
289        getMessageOpt().setChild(node, 0);
290      }
291      /**
292       * Check whether the optional Message child exists.
293       * @return {@code true} if the optional Message child exists, {@code false} if it does not.
294       * @apilevel high-level
295       */
296      public boolean hasMessage() {
297        return getMessageOpt().getNumChild() != 0;
298      }
299      /**
300       * Retrieves the (optional) Message child.
301       * @return The Message child, if it exists. Returns {@code null} otherwise.
302       * @apilevel low-level
303       */
304      public Expr getMessage() {
305        return (Expr) getMessageOpt().getChild(0);
306      }
307      /**
308       * Retrieves the optional node for the Message child. This is the <code>Opt</code> node containing the child Message, not the actual child!
309       * @return The optional node for child the Message child.
310       * @apilevel low-level
311       */
312      @ASTNodeAnnotation.OptChild(name="Message")
313      public Opt<Expr> getMessageOpt() {
314        return (Opt<Expr>) getChild(1);
315      }
316      /**
317       * Retrieves the optional node for child Message. This is the <code>Opt</code> node containing the child Message, not the actual child!
318       * <p><em>This method does not invoke AST transformations.</em></p>
319       * @return The optional node for child Message.
320       * @apilevel low-level
321       */
322      public Opt<Expr> getMessageOptNoTransform() {
323        return (Opt<Expr>) getChildNoTransform(1);
324      }
325      /**
326       * @apilevel internal
327       */
328      protected java.util.Map isDAafter_Variable_values;
329      /**
330       * @apilevel internal
331       */
332      private void isDAafter_Variable_reset() {
333        isDAafter_Variable_values = null;
334      }
335      /**
336       * @attribute syn
337       * @aspect DA
338       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:257
339       */
340      @ASTNodeAnnotation.Attribute
341      public boolean isDAafter(Variable v) {
342        Object _parameters = v;
343        if (isDAafter_Variable_values == null) isDAafter_Variable_values = new org.jastadd.util.RobustMap(new java.util.HashMap());
344        ASTNode$State state = state();
345        if (isDAafter_Variable_values.containsKey(_parameters)) {
346          return (Boolean) isDAafter_Variable_values.get(_parameters);
347        }
348        boolean intermediate = state.INTERMEDIATE_VALUE;
349        state.INTERMEDIATE_VALUE = false;
350        int num = state.boundariesCrossed;
351        boolean isFinal = this.is$Final();
352        boolean isDAafter_Variable_value = getCondition().isDAafter(v);
353        if (isFinal && num == state().boundariesCrossed) {
354          isDAafter_Variable_values.put(_parameters, isDAafter_Variable_value);
355        } else {
356        }
357        state.INTERMEDIATE_VALUE |= intermediate;
358    
359        return isDAafter_Variable_value;
360      }
361      /**
362       * @apilevel internal
363       */
364      protected java.util.Map isDUafter_Variable_values;
365      /**
366       * @apilevel internal
367       */
368      private void isDUafter_Variable_reset() {
369        isDUafter_Variable_values = null;
370      }
371      /**
372       * @attribute syn
373       * @aspect DU
374       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:781
375       */
376      @ASTNodeAnnotation.Attribute
377      public boolean isDUafter(Variable v) {
378        Object _parameters = v;
379        if (isDUafter_Variable_values == null) isDUafter_Variable_values = new org.jastadd.util.RobustMap(new java.util.HashMap());
380        ASTNode$State state = state();
381        if (isDUafter_Variable_values.containsKey(_parameters)) {
382          return (Boolean) isDUafter_Variable_values.get(_parameters);
383        }
384        boolean intermediate = state.INTERMEDIATE_VALUE;
385        state.INTERMEDIATE_VALUE = false;
386        int num = state.boundariesCrossed;
387        boolean isFinal = this.is$Final();
388        boolean isDUafter_Variable_value = getCondition().isDUafter(v);
389        if (isFinal && num == state().boundariesCrossed) {
390          isDUafter_Variable_values.put(_parameters, isDUafter_Variable_value);
391        } else {
392        }
393        state.INTERMEDIATE_VALUE |= intermediate;
394    
395        return isDUafter_Variable_value;
396      }
397      /**
398       * @attribute syn
399       * @aspect PreciseRethrow
400       * @declaredat /home/jesper/git/extendj/java7/frontend/PreciseRethrow.jrag:84
401       */
402      @ASTNodeAnnotation.Attribute
403      public boolean modifiedInScope(Variable var) {
404        boolean modifiedInScope_Variable_value = false;
405    
406        return modifiedInScope_Variable_value;
407      }
408      /**
409       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:255
410       * @apilevel internal
411       */
412      public boolean Define_isDAbefore(ASTNode caller, ASTNode child, Variable v) {
413        if (caller == getMessageOptNoTransform()) {
414          // @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:460
415          return getCondition().isDAafter(v);
416        }
417        else {
418          return getParent().Define_isDAbefore(this, caller, v);
419        }
420      }
421      protected boolean canDefine_isDAbefore(ASTNode caller, ASTNode child, Variable v) {
422        return true;
423      }
424      /**
425       * @apilevel internal
426       */
427      public ASTNode rewriteTo() {
428        return super.rewriteTo();
429      }
430    }