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:36
027     * @production ClassAccess : {@link Access};
028    
029     */
030    public class ClassAccess extends Access implements Cloneable {
031      /**
032       * @aspect NameCheck
033       * @declaredat /home/jesper/git/extendj/java4/frontend/NameCheck.jrag:232
034       */
035      public void nameCheck() {
036        if (isQualified() && !qualifier().isTypeAccess()) {
037          error("class literal may only contain type names");
038        }
039      }
040      /**
041       * @aspect Java4PrettyPrint
042       * @declaredat /home/jesper/git/extendj/java4/frontend/PrettyPrint.jadd:227
043       */
044      public void prettyPrint(PrettyPrinter out) {
045        out.print("class");
046      }
047      /**
048       * @aspect CreateBCode
049       * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:1871
050       */
051      public void refined_CreateBCode_ClassAccess_createBCode(CodeGeneration gen) {
052        if (prevExpr().type().isPrimitiveType() || prevExpr().type().isVoid()) {
053          TypeDecl typeDecl = lookupType("java.lang", prevExpr().type().primitiveClassName());
054          SimpleSet c = typeDecl.memberFields("TYPE");
055          FieldDeclaration f = (FieldDeclaration) c.iterator().next();
056          f.emitLoadField(gen, typeDecl);
057        } else {
058          FieldDeclaration f = hostType().topLevelType().createStaticClassField(prevExpr().type().referenceClassFieldName());
059          // add method to perform lookup as a side-effect
060          MethodDecl m = hostType().topLevelType().createStaticClassMethod();
061    
062          int next_label = gen.constantPool().newLabel();
063          int end_label = gen.constantPool().newLabel();
064          f.emitLoadField(gen, hostType());
065          gen.emitBranchNonNull(next_label);
066    
067          // emit string literal
068    
069          StringLiteral.push(gen, prevExpr().type().jvmName());
070          m.emitInvokeMethod(gen, hostType());
071          gen.emitDup();
072          f.emitStoreField(gen, hostType());
073          gen.emitGoto(end_label);
074          gen.addLabel(next_label);
075          gen.changeStackDepth(-1);
076          f.emitLoadField(gen, hostType());
077          gen.addLabel(end_label);
078        }
079      }
080      /**
081       * @declaredat ASTNode:1
082       */
083      public ClassAccess() {
084        super();
085      }
086      /**
087       * Initializes the child array to the correct size.
088       * Initializes List and Opt nta children.
089       * @apilevel internal
090       * @ast method
091       * @declaredat ASTNode:10
092       */
093      public void init$Children() {
094      }
095      /**
096       * @apilevel low-level
097       * @declaredat ASTNode:15
098       */
099      protected int numChildren() {
100        return 0;
101      }
102      /**
103       * @apilevel internal
104       * @declaredat ASTNode:21
105       */
106      public boolean mayHaveRewrite() {
107        return false;
108      }
109      /**
110       * @apilevel internal
111       * @declaredat ASTNode:27
112       */
113      public void flushAttrCache() {
114        super.flushAttrCache();
115        type_reset();
116      }
117      /**
118       * @apilevel internal
119       * @declaredat ASTNode:34
120       */
121      public void flushCollectionCache() {
122        super.flushCollectionCache();
123      }
124      /**
125       * @apilevel internal
126       * @declaredat ASTNode:40
127       */
128      public void flushRewriteCache() {
129        super.flushRewriteCache();
130      }
131      /**
132       * @apilevel internal
133       * @declaredat ASTNode:46
134       */
135      public ClassAccess clone() throws CloneNotSupportedException {
136        ClassAccess node = (ClassAccess) super.clone();
137        return node;
138      }
139      /**
140       * @apilevel internal
141       * @declaredat ASTNode:53
142       */
143      public ClassAccess copy() {
144        try {
145          ClassAccess node = (ClassAccess) clone();
146          node.parent = null;
147          if (children != null) {
148            node.children = (ASTNode[]) children.clone();
149          }
150          return node;
151        } catch (CloneNotSupportedException e) {
152          throw new Error("Error: clone not supported for " + getClass().getName());
153        }
154      }
155      /**
156       * Create a deep copy of the AST subtree at this node.
157       * The copy is dangling, i.e. has no parent.
158       * @return dangling copy of the subtree at this node
159       * @apilevel low-level
160       * @deprecated Please use treeCopy or treeCopyNoTransform instead
161       * @declaredat ASTNode:72
162       */
163      @Deprecated
164      public ClassAccess fullCopy() {
165        return treeCopyNoTransform();
166      }
167      /**
168       * Create a deep copy of the AST subtree at this node.
169       * The copy is dangling, i.e. has no parent.
170       * @return dangling copy of the subtree at this node
171       * @apilevel low-level
172       * @declaredat ASTNode:82
173       */
174      public ClassAccess treeCopyNoTransform() {
175        ClassAccess tree = (ClassAccess) copy();
176        if (children != null) {
177          for (int i = 0; i < children.length; ++i) {
178            ASTNode child = (ASTNode) children[i];
179            if (child != null) {
180              child = child.treeCopyNoTransform();
181              tree.setChild(child, i);
182            }
183          }
184        }
185        return tree;
186      }
187      /**
188       * Create a deep copy of the AST subtree at this node.
189       * The subtree of this node is traversed to trigger rewrites before copy.
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       * @declaredat ASTNode:102
194       */
195      public ClassAccess treeCopy() {
196        doFullTraversal();
197        return treeCopyNoTransform();
198      }
199      /**
200       * @apilevel internal
201       * @declaredat ASTNode:109
202       */
203      protected boolean is$Equal(ASTNode node) {
204        return super.is$Equal(node);    
205      }
206      /**
207       * @aspect Version
208       * @declaredat /home/jesper/git/extendj/java5/backend/Version.jrag:40
209       */
210        public void createBCode(CodeGeneration gen) {
211        if (prevExpr().type().isPrimitiveType() || prevExpr().type().isVoid()) {
212          refined_CreateBCode_ClassAccess_createBCode(gen);
213        } else {
214          int index = gen.constantPool().addClass(prevExpr().type().jvmName());
215          if (index < 256) {
216            gen.emit(Bytecode.LDC).add(index);
217          } else {
218            gen.emit(Bytecode.LDC_W).add2(index);
219          }
220        }
221      }
222      /**
223       * @aspect Version
224       * @declaredat /home/jesper/git/extendj/java5/backend/Version.jrag:37
225       */
226        public void transformation() {
227        super.transformation();
228      }
229      /**
230       * @aspect TypeAnalysis
231       * @declaredat /home/jesper/git/extendj/java4/frontend/TypeAnalysis.jrag:436
232       */
233      private TypeDecl refined_TypeAnalysis_ClassAccess_type()
234    { return lookupType("java.lang", "Class"); }
235      /**
236       * @attribute syn
237       * @aspect AccessTypes
238       * @declaredat /home/jesper/git/extendj/java4/frontend/ResolveAmbiguousNames.jrag:67
239       */
240      @ASTNodeAnnotation.Attribute
241      public boolean isClassAccess() {
242        boolean isClassAccess_value = true;
243    
244        return isClassAccess_value;
245      }
246      /**
247       * Defines the expected kind of name for the left hand side in a qualified
248       * expression.
249       * @attribute syn
250       * @aspect SyntacticClassification
251       * @declaredat /home/jesper/git/extendj/java4/frontend/SyntacticClassification.jrag:58
252       */
253      @ASTNodeAnnotation.Attribute
254      public NameType predNameType() {
255        NameType predNameType_value = NameType.TYPE_NAME;
256    
257        return predNameType_value;
258      }
259      /**
260       * @apilevel internal
261       */
262      protected boolean type_computed = false;
263      /**
264       * @apilevel internal
265       */
266      protected TypeDecl type_value;
267      /**
268       * @apilevel internal
269       */
270      private void type_reset() {
271        type_computed = false;
272        type_value = null;
273      }
274      /**
275       * @attribute syn
276       * @aspect TypeAnalysis
277       * @declaredat /home/jesper/git/extendj/java4/frontend/TypeAnalysis.jrag:302
278       */
279      @ASTNodeAnnotation.Attribute
280      public TypeDecl type() {
281        ASTNode$State state = state();
282        if (type_computed) {
283          return type_value;
284        }
285        boolean intermediate = state.INTERMEDIATE_VALUE;
286        state.INTERMEDIATE_VALUE = false;
287        int num = state.boundariesCrossed;
288        boolean isFinal = this.is$Final();
289        type_value = type_compute();
290        if (isFinal && num == state().boundariesCrossed) {
291          type_computed = true;
292        } else {
293        }
294        state.INTERMEDIATE_VALUE |= intermediate;
295    
296        return type_value;
297      }
298      /**
299       * @apilevel internal
300       */
301      private TypeDecl type_compute() {
302          TypeDecl decl = refined_TypeAnalysis_ClassAccess_type();
303          if (decl instanceof GenericClassDecl) {
304            GenericClassDecl d = (GenericClassDecl) refined_TypeAnalysis_ClassAccess_type();
305            TypeDecl type = qualifier().type();
306            if (type.isPrimitiveType()) {
307              type = type.boxed();
308            }
309            ArrayList<TypeDecl> list = new ArrayList<TypeDecl>();
310            list.add(type);
311            return d.lookupParTypeDecl(list);
312          }
313          // Using non-generic java.lang.Class
314          return decl;
315        }
316      /**
317       * @apilevel internal
318       */
319      public ASTNode rewriteTo() {
320        return super.rewriteTo();
321      }
322    }