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:200
027     * @production ConstCase : {@link Case} ::= <span class="component">Value:{@link Expr}</span>;
028    
029     */
030    public class ConstCase extends Case implements Cloneable {
031      /**
032       * @aspect NameCheck
033       * @declaredat /home/jesper/git/extendj/java4/frontend/NameCheck.jrag:483
034       */
035      public void nameCheck() {
036        if (getValue().isConstant() && bind(this) != this) {
037          errorf("constant expression %s is multiply declared in two case statements",
038              getValue().prettyPrint());
039        }
040      }
041      /**
042       * @aspect Java4PrettyPrint
043       * @declaredat /home/jesper/git/extendj/java4/frontend/PrettyPrint.jadd:272
044       */
045      public void prettyPrint(PrettyPrinter out) {
046        out.print("case ");
047        out.print(getValue());
048        out.print(":");
049      }
050      /**
051       * @aspect EnumsCodegen
052       * @declaredat /home/jesper/git/extendj/java5/backend/EnumsCodegen.jrag:53
053       */
054      public void transformation() {
055        if (getValue() instanceof VarAccess && getValue().varDecl() instanceof EnumConstant) {
056          int i = hostType().createEnumIndex((EnumConstant) getValue().varDecl());
057          setValue(Literal.buildIntegerLiteral(i));
058        }
059        super.transformation();
060      }
061      /**
062       * @declaredat ASTNode:1
063       */
064      public ConstCase() {
065        super();
066      }
067      /**
068       * Initializes the child array to the correct size.
069       * Initializes List and Opt nta children.
070       * @apilevel internal
071       * @ast method
072       * @declaredat ASTNode:10
073       */
074      public void init$Children() {
075        children = new ASTNode[1];
076      }
077      /**
078       * @declaredat ASTNode:13
079       */
080      public ConstCase(Expr p0) {
081        setChild(p0, 0);
082      }
083      /**
084       * @apilevel low-level
085       * @declaredat ASTNode:19
086       */
087      protected int numChildren() {
088        return 1;
089      }
090      /**
091       * @apilevel internal
092       * @declaredat ASTNode:25
093       */
094      public boolean mayHaveRewrite() {
095        return false;
096      }
097      /**
098       * @apilevel internal
099       * @declaredat ASTNode:31
100       */
101      public void flushAttrCache() {
102        super.flushAttrCache();
103      }
104      /**
105       * @apilevel internal
106       * @declaredat ASTNode:37
107       */
108      public void flushCollectionCache() {
109        super.flushCollectionCache();
110      }
111      /**
112       * @apilevel internal
113       * @declaredat ASTNode:43
114       */
115      public void flushRewriteCache() {
116        super.flushRewriteCache();
117      }
118      /**
119       * @apilevel internal
120       * @declaredat ASTNode:49
121       */
122      public ConstCase clone() throws CloneNotSupportedException {
123        ConstCase node = (ConstCase) super.clone();
124        return node;
125      }
126      /**
127       * @apilevel internal
128       * @declaredat ASTNode:56
129       */
130      public ConstCase copy() {
131        try {
132          ConstCase node = (ConstCase) clone();
133          node.parent = null;
134          if (children != null) {
135            node.children = (ASTNode[]) children.clone();
136          }
137          return node;
138        } catch (CloneNotSupportedException e) {
139          throw new Error("Error: clone not supported for " + getClass().getName());
140        }
141      }
142      /**
143       * Create a deep copy of the AST subtree at this node.
144       * The copy is dangling, i.e. has no parent.
145       * @return dangling copy of the subtree at this node
146       * @apilevel low-level
147       * @deprecated Please use treeCopy or treeCopyNoTransform instead
148       * @declaredat ASTNode:75
149       */
150      @Deprecated
151      public ConstCase fullCopy() {
152        return treeCopyNoTransform();
153      }
154      /**
155       * Create a deep copy of the AST subtree at this node.
156       * The copy is dangling, i.e. has no parent.
157       * @return dangling copy of the subtree at this node
158       * @apilevel low-level
159       * @declaredat ASTNode:85
160       */
161      public ConstCase treeCopyNoTransform() {
162        ConstCase tree = (ConstCase) copy();
163        if (children != null) {
164          for (int i = 0; i < children.length; ++i) {
165            ASTNode child = (ASTNode) children[i];
166            if (child != null) {
167              child = child.treeCopyNoTransform();
168              tree.setChild(child, i);
169            }
170          }
171        }
172        return tree;
173      }
174      /**
175       * Create a deep copy of the AST subtree at this node.
176       * The subtree of this node is traversed to trigger rewrites before copy.
177       * The copy is dangling, i.e. has no parent.
178       * @return dangling copy of the subtree at this node
179       * @apilevel low-level
180       * @declaredat ASTNode:105
181       */
182      public ConstCase treeCopy() {
183        doFullTraversal();
184        return treeCopyNoTransform();
185      }
186      /**
187       * @apilevel internal
188       * @declaredat ASTNode:112
189       */
190      protected boolean is$Equal(ASTNode node) {
191        return super.is$Equal(node);    
192      }
193      /**
194       * Replaces the Value child.
195       * @param node The new node to replace the Value child.
196       * @apilevel high-level
197       */
198      public void setValue(Expr node) {
199        setChild(node, 0);
200      }
201      /**
202       * Retrieves the Value child.
203       * @return The current node used as the Value child.
204       * @apilevel high-level
205       */
206      @ASTNodeAnnotation.Child(name="Value")
207      public Expr getValue() {
208        return (Expr) getChild(0);
209      }
210      /**
211       * Retrieves the Value child.
212       * <p><em>This method does not invoke AST transformations.</em></p>
213       * @return The current node used as the Value child.
214       * @apilevel low-level
215       */
216      public Expr getValueNoTransform() {
217        return (Expr) getChildNoTransform(0);
218      }
219      /**
220       * @aspect Enums
221       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:579
222       */
223        public void refined_Enums_ConstCase_typeCheck() {
224        boolean isEnumConstant = getValue().isEnumConstant();
225        if (switchType().isEnumDecl() && !isEnumConstant) {
226          error("Unqualified enumeration constant required");
227        } else {
228          TypeDecl switchType = switchType();
229          TypeDecl type = getValue().type();
230          if (!type.assignConversionTo(switchType, getValue())) {
231            error("Constant expression must be assignable to Expression");
232          }
233          if (!getValue().isConstant() && !getValue().type().isUnknown() &&
234              !isEnumConstant)
235            error("Switch expression must be constant");
236        }
237      }
238      /**
239       * Improve the type checking error messages given for case labels.
240       * @aspect StringsInSwitch
241       * @declaredat /home/jesper/git/extendj/java7/frontend/StringsInSwitch.jrag:91
242       */
243        public void typeCheck() {
244        boolean isEnumConstant = getValue().isEnumConstant();
245        TypeDecl switchType = switchType();
246        TypeDecl type = getValue().type();
247        if (switchType.isEnumDecl() && !isEnumConstant) {
248          error("Unqualified enumeration constant required");
249        }
250        if (!type.assignConversionTo(switchType, getValue())) {
251          errorf("Case label has incompatible type %s, expected type compatible with %s",
252              switchType.name(), type.name());
253        }
254        if (!getValue().isConstant() && !getValue().type().isUnknown() && !isEnumConstant) {
255          error("Case label must have constant expression");
256        }
257      }
258      /**
259       * @aspect NameCheck
260       * @declaredat /home/jesper/git/extendj/java4/frontend/NameCheck.jrag:513
261       */
262      private boolean refined_NameCheck_ConstCase_constValue_Case(Case c)
263    {
264        if (!(c instanceof ConstCase) || !getValue().isConstant()) {
265          return false;
266        }
267        if (!getValue().type().assignableToInt() || !((ConstCase) c).getValue().type().assignableToInt()) {
268          return false;
269        }
270        return getValue().constant().intValue() == ((ConstCase) c).getValue().constant().intValue();
271      }
272      /**
273       * @aspect Enums
274       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:594
275       */
276      private boolean refined_Enums_ConstCase_constValue_Case(Case c)
277    {
278        if (switchType().isEnumDecl()) {
279          if (!(c instanceof ConstCase) || !getValue().isConstant()) {
280            return false;
281          }
282          return getValue().varDecl() == ((ConstCase) c).getValue().varDecl();
283        } else {
284          return refined_NameCheck_ConstCase_constValue_Case(c);
285        }
286      }
287      /**
288       * @attribute syn
289       * @aspect NameCheck
290       * @declaredat /home/jesper/git/extendj/java4/frontend/NameCheck.jrag:512
291       */
292      @ASTNodeAnnotation.Attribute
293      public boolean constValue(Case c) {
294        {
295            if (isDefaultCase() || c.isDefaultCase()) {
296              return isDefaultCase() && c.isDefaultCase();
297            }
298        
299            Expr myValue = getValue();
300            Expr otherValue = ((ConstCase) c).getValue();
301            TypeDecl myType = myValue.type();
302            TypeDecl otherType = otherValue.type();
303            if (myType.isString() || otherType.isString()) {
304              if (!myType.isString() || !otherType.isString()) {
305                return false;
306              }
307              if (!myValue.isConstant() || !otherValue.isConstant()) {
308                return false;
309              }
310              return myValue.constant().stringValue().equals(otherValue.constant().stringValue());
311            }
312        
313            return refined_Enums_ConstCase_constValue_Case(c);
314          }
315      }
316      /**
317       * @declaredat /home/jesper/git/extendj/java8/frontend/LookupVariable.jrag:30
318       * @apilevel internal
319       */
320      public SimpleSet Define_lookupVariable(ASTNode caller, ASTNode child, String name) {
321        if (caller == getValueNoTransform()) {
322          // @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:573
323          return switchType().isEnumDecl() ? switchType().memberFields(name) : lookupVariable(name);
324        }
325        else {
326          return getParent().Define_lookupVariable(this, caller, name);
327        }
328      }
329      protected boolean canDefine_lookupVariable(ASTNode caller, ASTNode child, String name) {
330        return true;
331      }
332      /**
333       * @apilevel internal
334       */
335      public ASTNode rewriteTo() {
336        return super.rewriteTo();
337      }
338    }