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:18
027     * @production VarAccess : {@link Access} ::= <span class="component">&lt;ID:String&gt;</span>;
028    
029     */
030    public class VarAccess extends Access implements Cloneable {
031      /**
032       * @aspect DefiniteAssignment
033       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:117
034       */
035      public void definiteAssignment() {
036        if (isSource()) {
037          if (decl() instanceof VariableDeclaration) {
038            VariableDeclaration v = (VariableDeclaration) decl();
039            if (v.isValue()) {
040            } else if (v.isBlankFinal()) {
041              if (!isDAbefore(v)) {
042                errorf("Final variable %s is not assigned before used", v.name());
043              }
044            } else {
045              if (!isDAbefore(v)) {
046                errorf("Local variable %s is not assigned before used", v.name());
047              }
048            }
049          } else if (decl() instanceof FieldDeclaration && !isQualified()) {
050            FieldDeclaration f = (FieldDeclaration) decl();
051            if (f.isFinal() && !f.hasInit() && !isDAbefore(f)) {
052              errorf("Final field %s is not assigned before used", f);
053            }
054          }
055    
056        }
057        if (isDest()) {
058          Variable v = decl();
059          // Blank final field
060          if (v.isFinal() && v.isBlank() && !hostType().instanceOf(v.hostType())) {
061            error("The final variable is not a blank final in this context, so it may not be assigned.");
062          } else if (v.isFinal() && isQualified() && (!qualifier().isThisAccess() || ((Access) qualifier()).isQualified())) {
063            errorf("the blank final field %s may only be assigned by simple name", v.name());
064          }
065    
066          // local variable or parameter
067          else if (v instanceof VariableDeclaration) {
068            VariableDeclaration var = (VariableDeclaration) v;
069            //System.out.println("### is variable");
070            if (!var.isValue() && var.getParent().getParent().getParent() instanceof SwitchStmt && var.isFinal()) {
071              if (!isDUbefore(var)) {
072                errorf("Final variable %s may only be assigned once", var.name());
073              }
074            } else if (var.isValue()) {
075              if (var.hasInit() || !isDUbefore(var)) {
076                errorf("Final variable %s may only be assigned once", var.name());
077              }
078            } else if (var.isBlankFinal()) {
079              if (var.hasInit() || !isDUbefore(var)) {
080                errorf("Final variable %s may only be assigned once", var.name());
081              }
082            }
083            if (var.isFinal() && (var.hasInit() || !isDUbefore(var))) {
084            //if (var.isFinal() && ((var.hasInit() && var.getInit().isConstant()) || !isDUbefore(var))) {
085            }
086          }
087          // field
088          else if (v instanceof FieldDeclaration) {
089            FieldDeclaration f = (FieldDeclaration) v;
090            if (f.isFinal()) {
091              if (f.hasInit()) {
092                errorf("already initialized final field %s can not be assigned", f.name());
093              } else {
094                BodyDecl bodyDecl = enclosingBodyDecl();
095                if (!(bodyDecl instanceof ConstructorDecl) && !(bodyDecl instanceof InstanceInitializer) && !(bodyDecl instanceof StaticInitializer) && !(bodyDecl instanceof FieldDeclaration)) {
096                  errorf("final field %s may only be assigned in constructors and initializers", f.name());
097                } else if (!isDUbefore(f)) {
098                  errorf("blank final field %s may only be assigned once", f.name());
099                }
100              }
101            }
102          } else if (v.isParameter()) {
103            // 8.4.1
104            if (v.isFinal()) {
105              errorf("Final parameter %s may not be assigned", v.name());
106            }
107          }
108    
109        }
110      }
111      /**
112       * @aspect DA
113       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:504
114       */
115      protected boolean checkDUeverywhere(Variable v) {
116        if (isDest() && decl() == v) {
117          return false;
118        }
119        return super.checkDUeverywhere(v);
120      }
121      /**
122       * @aspect NameCheck
123       * @declaredat /home/jesper/git/extendj/java4/frontend/NameCheck.jrag:275
124       */
125      public BodyDecl closestBodyDecl(TypeDecl t) {
126        ASTNode node = this;
127        while (!(node.getParent().getParent() instanceof Program) && node.getParent().getParent() != t) {
128          node = node.getParent();
129        }
130        if (node instanceof BodyDecl) {
131          return (BodyDecl) node;
132        }
133        return null;
134      }
135      /**
136       * @aspect NodeConstructors
137       * @declaredat /home/jesper/git/extendj/java4/frontend/NodeConstructors.jrag:49
138       */
139      public VarAccess(String name, int start, int end) {
140        this(name);
141        this.start = this.IDstart = start;
142        this.end = this.IDend = end;
143      }
144      /**
145       * @aspect Java4PrettyPrint
146       * @declaredat /home/jesper/git/extendj/java4/frontend/PrettyPrint.jadd:492
147       */
148      public void prettyPrint(PrettyPrinter out) {
149        out.print(getID());
150      }
151      /**
152       * @aspect CodeGeneration
153       * @declaredat /home/jesper/git/extendj/java4/backend/CodeGeneration.jrag:356
154       */
155      public void refined_CodeGeneration_VarAccess_emitStore(CodeGeneration gen) {
156        Variable v = decl();
157        if (v instanceof VariableDeclaration) {
158          VariableDeclaration decl = (VariableDeclaration) v;
159          if (isDUbefore(v)) {
160             gen.addLocalVariableEntryAtCurrentPC(decl.name(), decl.type().typeDescriptor(), decl.localNum(), decl.variableScopeEndLabel(gen));
161          }
162          decl.type().emitStoreLocal(gen, decl.localNum());
163        } else if (v instanceof ParameterDeclaration) {
164          ParameterDeclaration decl = (ParameterDeclaration) v;
165          decl.type().emitStoreLocal(gen, decl.localNum());
166        } else if (v instanceof FieldDeclaration) {
167          FieldDeclaration f = (FieldDeclaration) v;
168          if (f.isPrivate() && !hostType().hasField(v.name())) {
169            f.createAccessorWrite(fieldQualifierType()).emitInvokeMethod(gen, fieldQualifierType());
170          } else {
171            f.emitStoreField(gen, fieldQualifierType());
172          }
173        }
174      }
175      /**
176       * @aspect CreateBCode
177       * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:433
178       */
179      public void createAssignSimpleLoadDest(CodeGeneration gen) {
180        createLoadQualifier(gen);
181      }
182      /**
183       * @aspect CreateBCode
184       * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:449
185       */
186      public void createPushAssignmentResult(CodeGeneration gen) {
187        if (hostType().needsAccessorFor(decl())) {
188          return;
189        }
190        if (decl().isInstanceVariable()) {
191          type().emitDup_x1(gen);
192        } else {
193          type().emitDup(gen);
194        }
195      }
196      /**
197       * @aspect CreateBCode
198       * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:469
199       */
200      public void refined_CreateBCode_VarAccess_createAssignLoadDest(CodeGeneration gen) {
201        createLoadQualifier(gen);
202        Variable v = decl();
203        if (v.isInstanceVariable()) {
204          gen.emitDup();
205        }
206        if (v instanceof VariableDeclaration) {
207          VariableDeclaration decl = (VariableDeclaration) v;
208          decl.type().emitLoadLocal(gen, decl.localNum());
209        } else if (v instanceof ParameterDeclaration) {
210          ParameterDeclaration decl = (ParameterDeclaration) v;
211          decl.type().emitLoadLocal(gen, decl.localNum());
212        } else if (v instanceof FieldDeclaration) {
213          FieldDeclaration f = (FieldDeclaration) v;
214          if (requiresAccessor()) {
215            f.createAccessor(fieldQualifierType()).emitInvokeMethod(gen, fieldQualifierType());
216          } else {
217            f.emitLoadField(gen, fieldQualifierType());
218          }
219        }
220      }
221      /**
222       * @aspect CreateBCode
223       * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:518
224       */
225      public void refined_CreateBCode_VarAccess_createBCode(CodeGeneration gen) {
226        Variable v = decl();
227        if (v instanceof VariableDeclaration) {
228          VariableDeclaration decl = (VariableDeclaration) v;
229          if (decl.hostType() == hostType()) {
230            decl.type().emitLoadLocal(gen, decl.localNum());
231          } else {
232            emitLoadLocalInNestedClass(gen, decl);
233          }
234        } else if (v instanceof ParameterDeclaration) {
235          ParameterDeclaration decl = (ParameterDeclaration) v;
236          if (decl.hostType() == hostType()) {
237            decl.type().emitLoadLocal(gen, decl.localNum());
238          } else {
239            emitLoadLocalInNestedClass(gen, decl);
240          }
241        } else if (v instanceof FieldDeclaration) {
242          FieldDeclaration f = (FieldDeclaration) v;
243          createLoadQualifier(gen);
244          if (f.isConstant() && (f.type().isPrimitive() || f.type().isString())) {
245            if (!f.isStatic()) {
246              fieldQualifierType().emitPop(gen);
247            }
248            f.constant().createBCode(gen);
249          } else if (requiresAccessor()) {
250            f.createAccessor(fieldQualifierType()).emitInvokeMethod(gen, fieldQualifierType());
251          } else {
252            f.emitLoadField(gen, fieldQualifierType());
253          }
254        }
255      }
256      /**
257       * @aspect CreateBCode
258       * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:576
259       */
260      protected void createLoadQualifier(CodeGeneration gen) {
261        Variable v = decl();
262        if (v instanceof FieldDeclaration) {
263          FieldDeclaration f = (FieldDeclaration) v;
264          if (hasPrevExpr()) {
265            // load explicit qualifier
266            prevExpr().createBCode(gen);
267            // pop qualifier stack element for class variables
268            // this qualifier must be computed to ensure side effects
269            if (!prevExpr().isTypeAccess() && f.isClassVariable()) {
270              prevExpr().type().emitPop(gen);
271            }
272          } else if (f.isInstanceVariable()) {
273            emitThis(gen, fieldQualifierType());
274          }
275        }
276      }
277      /**
278       * @aspect InnerClasses
279       * @declaredat /home/jesper/git/extendj/java4/backend/InnerClasses.jrag:48
280       */
281      private TypeDecl refined_InnerClasses_VarAccess_fieldQualifierType() {
282        if (hasPrevExpr()) {
283          return prevExpr().type();
284        }
285        TypeDecl typeDecl = hostType();
286        while (typeDecl != null && !typeDecl.hasField(name())) {
287          typeDecl = typeDecl.enclosingType();
288        }
289        if (typeDecl != null) {
290          return typeDecl;
291        }
292        return decl().hostType();
293      }
294      /**
295       * @aspect InnerClasses
296       * @declaredat /home/jesper/git/extendj/java4/backend/InnerClasses.jrag:197
297       */
298      public void collectEnclosingVariables(HashSet set, TypeDecl typeDecl) {
299        Variable v = decl();
300        if (!v.isInstanceVariable() && !v.isClassVariable() && v.hostType() == typeDecl) {
301          set.add(v);
302        }
303        super.collectEnclosingVariables(set, typeDecl);
304      }
305      /**
306       * @aspect Transformations
307       * @declaredat /home/jesper/git/extendj/java4/backend/Transformations.jrag:95
308       */
309      public void transformation() {
310        Variable v = decl();
311        if (v instanceof FieldDeclaration) {
312          FieldDeclaration f = (FieldDeclaration) v;
313          if (requiresAccessor()) {
314            TypeDecl typeDecl = fieldQualifierType();
315            if (isSource()) {
316              f.createAccessor(typeDecl);
317            }
318            if (isDest()) {
319              f.createAccessorWrite(typeDecl);
320            }
321          }
322        }
323        super.transformation();
324      }
325      /**
326       * @aspect Annotations
327       * @declaredat /home/jesper/git/extendj/java5/frontend/Annotations.jrag:420
328       */
329      public void checkModifiers() {
330        if (decl() instanceof FieldDeclaration) {
331          FieldDeclaration f = (FieldDeclaration) decl();
332          if (f.isDeprecated() &&
333            !withinDeprecatedAnnotation() &&
334            hostType().topLevelType() != f.hostType().topLevelType() &&
335            !withinSuppressWarnings("deprecation"))
336              warning(f.name() + " in " + f.hostType().typeName() + " has been deprecated");
337        }
338      }
339      /**
340       * @aspect Enums
341       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:515
342       */
343      protected void checkEnum(EnumDecl enumDecl) {
344        super.checkEnum(enumDecl);
345        if (decl().isStatic() && decl().hostType() == enumDecl && !isConstant()) {
346          error("may not reference a static field of an enum type from here");
347        }
348      }
349      /**
350       * @declaredat ASTNode:1
351       */
352      public VarAccess() {
353        super();
354      }
355      /**
356       * Initializes the child array to the correct size.
357       * Initializes List and Opt nta children.
358       * @apilevel internal
359       * @ast method
360       * @declaredat ASTNode:10
361       */
362      public void init$Children() {
363      }
364      /**
365       * @declaredat ASTNode:12
366       */
367      public VarAccess(String p0) {
368        setID(p0);
369      }
370      /**
371       * @declaredat ASTNode:15
372       */
373      public VarAccess(beaver.Symbol p0) {
374        setID(p0);
375      }
376      /**
377       * @apilevel low-level
378       * @declaredat ASTNode:21
379       */
380      protected int numChildren() {
381        return 0;
382      }
383      /**
384       * @apilevel internal
385       * @declaredat ASTNode:27
386       */
387      public boolean mayHaveRewrite() {
388        return false;
389      }
390      /**
391       * @apilevel internal
392       * @declaredat ASTNode:33
393       */
394      public void flushAttrCache() {
395        super.flushAttrCache();
396        isConstant_reset();
397        isDAafter_Variable_reset();
398        decls_reset();
399        decl_reset();
400        isFieldAccess_reset();
401        type_reset();
402        enclosingLambda_reset();
403      }
404      /**
405       * @apilevel internal
406       * @declaredat ASTNode:46
407       */
408      public void flushCollectionCache() {
409        super.flushCollectionCache();
410      }
411      /**
412       * @apilevel internal
413       * @declaredat ASTNode:52
414       */
415      public void flushRewriteCache() {
416        super.flushRewriteCache();
417      }
418      /**
419       * @apilevel internal
420       * @declaredat ASTNode:58
421       */
422      public VarAccess clone() throws CloneNotSupportedException {
423        VarAccess node = (VarAccess) super.clone();
424        return node;
425      }
426      /**
427       * @apilevel internal
428       * @declaredat ASTNode:65
429       */
430      public VarAccess copy() {
431        try {
432          VarAccess node = (VarAccess) clone();
433          node.parent = null;
434          if (children != null) {
435            node.children = (ASTNode[]) children.clone();
436          }
437          return node;
438        } catch (CloneNotSupportedException e) {
439          throw new Error("Error: clone not supported for " + getClass().getName());
440        }
441      }
442      /**
443       * Create a deep copy of the AST subtree at this node.
444       * The copy is dangling, i.e. has no parent.
445       * @return dangling copy of the subtree at this node
446       * @apilevel low-level
447       * @deprecated Please use treeCopy or treeCopyNoTransform instead
448       * @declaredat ASTNode:84
449       */
450      @Deprecated
451      public VarAccess fullCopy() {
452        return treeCopyNoTransform();
453      }
454      /**
455       * Create a deep copy of the AST subtree at this node.
456       * The copy is dangling, i.e. has no parent.
457       * @return dangling copy of the subtree at this node
458       * @apilevel low-level
459       * @declaredat ASTNode:94
460       */
461      public VarAccess treeCopyNoTransform() {
462        VarAccess tree = (VarAccess) copy();
463        if (children != null) {
464          for (int i = 0; i < children.length; ++i) {
465            ASTNode child = (ASTNode) children[i];
466            if (child != null) {
467              child = child.treeCopyNoTransform();
468              tree.setChild(child, i);
469            }
470          }
471        }
472        return tree;
473      }
474      /**
475       * Create a deep copy of the AST subtree at this node.
476       * The subtree of this node is traversed to trigger rewrites before copy.
477       * The copy is dangling, i.e. has no parent.
478       * @return dangling copy of the subtree at this node
479       * @apilevel low-level
480       * @declaredat ASTNode:114
481       */
482      public VarAccess treeCopy() {
483        doFullTraversal();
484        return treeCopyNoTransform();
485      }
486      /**
487       * @apilevel internal
488       * @declaredat ASTNode:121
489       */
490      protected boolean is$Equal(ASTNode node) {
491        return super.is$Equal(node) && (tokenString_ID == ((VarAccess)node).tokenString_ID);    
492      }
493      /**
494       * Replaces the lexeme ID.
495       * @param value The new value for the lexeme ID.
496       * @apilevel high-level
497       */
498      public void setID(String value) {
499        tokenString_ID = value;
500      }
501      /**
502       * @apilevel internal
503       */
504      protected String tokenString_ID;
505      /**
506       */
507      public int IDstart;
508      /**
509       */
510      public int IDend;
511      /**
512       * JastAdd-internal setter for lexeme ID using the Beaver parser.
513       * @param symbol Symbol containing the new value for the lexeme ID
514       * @apilevel internal
515       */
516      public void setID(beaver.Symbol symbol) {
517        if (symbol.value != null && !(symbol.value instanceof String))
518        throw new UnsupportedOperationException("setID is only valid for String lexemes");
519        tokenString_ID = (String)symbol.value;
520        IDstart = symbol.getStart();
521        IDend = symbol.getEnd();
522      }
523      /**
524       * Retrieves the value for the lexeme ID.
525       * @return The value for the lexeme ID.
526       * @apilevel high-level
527       */
528      @ASTNodeAnnotation.Token(name="ID")
529      public String getID() {
530        return tokenString_ID != null ? tokenString_ID : "";
531      }
532      /**
533       * @aspect Java8NameCheck
534       * @declaredat /home/jesper/git/extendj/java8/frontend/NameCheck.jrag:181
535       */
536       
537      public void nameCheck() {
538        if (decls().isEmpty() && (!isQualified() || !qualifier().type().isUnknown()
539              || qualifier().isPackageAccess())) {
540          errorf("no field named %s is accessible", name());
541        }
542        if (decls().size() > 1) {
543          StringBuffer sb = new StringBuffer();
544          sb.append("several fields named " + name());
545          for (Iterator iter = decls().iterator(); iter.hasNext(); ) {
546            Variable v = (Variable) iter.next();
547            sb.append("\n    " + v.type().typeName() + "." + v.name() + " declared in "
548                + v.hostType().typeName());
549          }
550          error(sb.toString());
551        }
552    
553        // 8.8.5.1
554        if (inExplicitConstructorInvocation() && !isQualified() && decl().isInstanceVariable()
555            && hostType() == decl().hostType()) {
556          errorf("instance variable %s may not be accessed in an explicit constructor invocation",
557              name());
558        }
559    
560        Variable v = decl();
561        if (!v.isClassVariable() && !v.isInstanceVariable() && v.hostType() != hostType()
562            && !v.isEffectivelyFinal()) {
563          error("A parameter/variable used but not declared in an inner class must be"
564              + " final or effectively final");
565        }
566    
567        // 8.3.2.3
568        if ((decl().isInstanceVariable() || decl().isClassVariable()) && !isQualified()) {
569          if (hostType() != null && !hostType().declaredBeforeUse(decl(), this)) {
570            if (inSameInitializer() && !simpleAssignment() && inDeclaringClass()) {
571              BodyDecl b = closestBodyDecl(hostType());
572              errorf("variable %s is used in %s before it is declared", decl().name(), b.prettyPrint());
573            }
574          }
575        }
576    
577        if (!v.isClassVariable() && !v.isInstanceVariable() && enclosingLambda() != null) {
578          if (v instanceof ParameterDeclaration) {
579            ParameterDeclaration decl = (ParameterDeclaration) v;
580            if (decl.enclosingLambda() != enclosingLambda()) {
581              // 15.27.2
582              if (!decl.isEffectivelyFinal()) {
583                errorf("Parameter %s must be effectively final", v.name());
584              }
585            }
586          } else if (v instanceof InferredParameterDeclaration) {
587            InferredParameterDeclaration decl = (InferredParameterDeclaration) v;
588            if (decl.enclosingLambda() != enclosingLambda()) {
589              // 15.27.2
590              if (!decl.isEffectivelyFinal()) {
591                errorf("Parameter %s must be effectively final", v.name());
592              }
593            }
594          } else if (v instanceof VariableDeclaration) {
595            VariableDeclaration decl = (VariableDeclaration) v;
596            if (decl.enclosingLambda() != enclosingLambda()) {
597              // 15.27.2
598              if (!decl.isEffectivelyFinal()) {
599                errorf("Variable %s must be effectively final", v.name());
600              }
601              // 15.27.2
602              if (!enclosingLambda().isDAbefore(decl)) {
603                errorf("Variable %s must be definitely assigned before used in a lambda", v.name());
604              }
605            }
606          }
607        }
608    
609      }
610      /**
611       * @aspect GenericsCodegen
612       * @declaredat /home/jesper/git/extendj/java5/backend/GenericsCodegen.jrag:74
613       */
614        public void emitStore(CodeGeneration gen) {
615        Variable v = decl();
616        if (v instanceof FieldDeclaration) {
617          FieldDeclaration f = (FieldDeclaration) v;
618          f = f.erasedField();
619          if (requiresAccessor()) {
620            f.createAccessorWrite(fieldQualifierType()).emitInvokeMethod(gen, fieldQualifierType());
621          } else {
622            f.emitStoreField(gen, fieldQualifierType());
623          }
624        } else {
625          refined_CodeGeneration_VarAccess_emitStore(gen);
626        }
627      }
628      /**
629       * @aspect GenericsCodegen
630       * @declaredat /home/jesper/git/extendj/java5/backend/GenericsCodegen.jrag:88
631       */
632        public void refined_GenericsCodegen_VarAccess_createAssignLoadDest(CodeGeneration gen) {
633        Variable v = decl();
634        if (v instanceof FieldDeclaration) {
635          createLoadQualifier(gen);
636          if (v.isInstanceVariable()) {
637            gen.emitDup();
638          }
639          FieldDeclaration f = (FieldDeclaration) v;
640          f = f.erasedField();
641          if (requiresAccessor()) {
642            f.createAccessor(fieldQualifierType()).emitInvokeMethod(gen, fieldQualifierType());
643          } else {
644            f.emitLoadField(gen, fieldQualifierType());
645          }
646        } else {
647          refined_CreateBCode_VarAccess_createAssignLoadDest(gen);
648        }
649      }
650      /**
651       * @aspect GenericsCodegen
652       * @declaredat /home/jesper/git/extendj/java5/backend/GenericsCodegen.jrag:107
653       */
654        public void refined_GenericsCodegen_VarAccess_createBCode(CodeGeneration gen) {
655        Variable v = decl();
656        if (v instanceof FieldDeclaration) {
657          FieldDeclaration f = (FieldDeclaration) v;
658          f = f.erasedField();
659          createLoadQualifier(gen);
660          if (f.isConstant() && (f.type().isPrimitive() || f.type().isString())) {
661            if (!f.isStatic()) {
662              fieldQualifierType().emitPop(gen);
663            }
664            f.constant().createBCode(gen);
665          } else if (requiresAccessor()) {
666            f.createAccessor(fieldQualifierType()).emitInvokeMethod(gen, fieldQualifierType());
667          } else {
668            f.emitLoadField(gen, fieldQualifierType());
669          }
670          if (f.type() != decl().type()) {
671            gen.emitCheckCast(decl().type());
672          }
673        } else {
674          refined_CreateBCode_VarAccess_createBCode(gen);
675        }
676      }
677      /**
678       * @aspect GenericsCodegen
679       * @declaredat /home/jesper/git/extendj/java5/backend/GenericsCodegen.jrag:194
680       */
681        protected TypeDecl refined_GenericsCodegen_VarAccess_fieldQualifierType() {
682        TypeDecl typeDecl = refined_InnerClasses_VarAccess_fieldQualifierType();
683        return typeDecl == null ? null : typeDecl.erasure();
684      }
685      /**
686       * @aspect MultiCatch
687       * @declaredat /home/jesper/git/extendj/java7/backend/MultiCatch.jrag:70
688       */
689       
690      public void createAssignLoadDest(CodeGeneration gen) {
691        Variable v = decl();
692        if (v instanceof CatchParameterDeclaration) {
693          if (v.isInstanceVariable()) {
694            gen.emitDup();
695          }
696          CatchParameterDeclaration decl = (CatchParameterDeclaration) v;
697          decl.type().emitLoadLocal(gen, decl.localNum());
698        } else {
699          refined_GenericsCodegen_VarAccess_createAssignLoadDest(gen);
700        }
701      }
702      /**
703       * @aspect MultiCatch
704       * @declaredat /home/jesper/git/extendj/java7/backend/MultiCatch.jrag:84
705       */
706       
707      public void createBCode(CodeGeneration gen) {
708        Variable v = decl();
709        if (v instanceof CatchParameterDeclaration) {
710          CatchParameterDeclaration decl = (CatchParameterDeclaration) v;
711          if (decl.hostType() == hostType()) {
712            decl.type().emitLoadLocal(gen, decl.localNum());
713          } else {
714            emitLoadLocalInNestedClass(gen, decl);
715          }
716        } else {
717          refined_GenericsCodegen_VarAccess_createBCode(gen);
718        }
719      }
720      /**
721       * @aspect StaticImportsCodegen
722       * @declaredat /home/jesper/git/extendj/java5/backend/StaticImportsCodegen.jrag:32
723       */
724        protected TypeDecl fieldQualifierType() {
725        TypeDecl typeDecl = refined_GenericsCodegen_VarAccess_fieldQualifierType();
726        if (typeDecl != null) {
727          return typeDecl;
728        }
729        return decl().hostType();
730      }
731      /**
732       * @attribute syn
733       * @aspect ConstantExpression
734       * @declaredat /home/jesper/git/extendj/java4/frontend/ConstantExpression.jrag:32
735       */
736      @ASTNodeAnnotation.Attribute
737      public Constant constant() {
738        Constant constant_value = type().cast(decl().getInit().constant());
739    
740        return constant_value;
741      }
742      /**
743       * @apilevel internal
744       */
745      protected int isConstant_visited = -1;
746      /**
747       * @apilevel internal
748       */
749      private void isConstant_reset() {
750        isConstant_computed = false;
751        isConstant_initialized = false;
752        isConstant_visited = -1;
753      }
754      /**
755       * @apilevel internal
756       */
757      protected boolean isConstant_computed = false;
758      /**
759       * @apilevel internal
760       */
761      protected boolean isConstant_initialized = false;
762      /**
763       * @apilevel internal
764       */
765      protected boolean isConstant_value;
766      @ASTNodeAnnotation.Attribute
767      public boolean isConstant() {
768        if (isConstant_computed) {
769          return isConstant_value;
770        }
771        ASTNode$State state = state();
772        boolean new_isConstant_value;
773        if (!isConstant_initialized) {
774          isConstant_initialized = true;
775          isConstant_value = false;
776        }
777        if (!state.IN_CIRCLE) {
778          state.IN_CIRCLE = true;
779          int num = state.boundariesCrossed;
780          boolean isFinal = this.is$Final();
781          do {
782            isConstant_visited = state.CIRCLE_INDEX;
783            state.CHANGE = false;
784            new_isConstant_value = isConstant_compute();
785            if (new_isConstant_value != isConstant_value) {
786              state.CHANGE = true;
787            }
788            isConstant_value = new_isConstant_value;
789            state.CIRCLE_INDEX++;
790          } while (state.CHANGE);
791          if (isFinal && num == state().boundariesCrossed) {
792            isConstant_computed = true;
793          } else {
794            state.RESET_CYCLE = true;
795            boolean $tmp = isConstant_compute();
796            state.RESET_CYCLE = false;
797            isConstant_computed = false;
798            isConstant_initialized = false;
799          }
800          state.IN_CIRCLE = false;
801          state.INTERMEDIATE_VALUE = false;
802          return isConstant_value;
803        }
804        if (isConstant_visited != state.CIRCLE_INDEX) {
805          isConstant_visited = state.CIRCLE_INDEX;
806          if (state.RESET_CYCLE) {
807            isConstant_computed = false;
808            isConstant_initialized = false;
809            isConstant_visited = -1;
810            return isConstant_value;
811          }
812          new_isConstant_value = isConstant_compute();
813          if (new_isConstant_value != isConstant_value) {
814            state.CHANGE = true;
815          }
816          isConstant_value = new_isConstant_value;
817          state.INTERMEDIATE_VALUE = true;
818          return isConstant_value;
819        }
820        state.INTERMEDIATE_VALUE = true;
821        return isConstant_value;
822      }
823      /**
824       * @apilevel internal
825       */
826      private boolean isConstant_compute() {
827          Variable v = decl();
828          if (v instanceof FieldDeclaration) {
829            FieldDeclaration f = (FieldDeclaration) v;
830            return f.isConstant() && (!isQualified() || (isQualified() && qualifier().isTypeAccess()));
831          }
832          boolean result = v.isFinal() && v.hasInit() && v.getInit().isConstant() && (v.type().isPrimitive() || v.type().isString());
833          return result && (!isQualified() || (isQualified() && qualifier().isTypeAccess()));
834        }
835      /**
836       * @attribute syn
837       * @aspect DefiniteAssignment
838       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:81
839       */
840      @ASTNodeAnnotation.Attribute
841      public Variable varDecl() {
842        Variable varDecl_value = decl();
843    
844        return varDecl_value;
845      }
846      /**
847       * @apilevel internal
848       */
849      protected java.util.Map isDAafter_Variable_values;
850      /**
851       * @apilevel internal
852       */
853      private void isDAafter_Variable_reset() {
854        isDAafter_Variable_values = null;
855      }
856      /**
857       * @attribute syn
858       * @aspect DA
859       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:392
860       */
861      @ASTNodeAnnotation.Attribute
862      public boolean isDAafter(Variable v) {
863        Object _parameters = v;
864        if (isDAafter_Variable_values == null) isDAafter_Variable_values = new org.jastadd.util.RobustMap(new java.util.HashMap());
865        ASTNode$State state = state();
866        if (isDAafter_Variable_values.containsKey(_parameters)) {
867          return (Boolean) isDAafter_Variable_values.get(_parameters);
868        }
869        boolean intermediate = state.INTERMEDIATE_VALUE;
870        state.INTERMEDIATE_VALUE = false;
871        int num = state.boundariesCrossed;
872        boolean isFinal = this.is$Final();
873        boolean isDAafter_Variable_value = isDAbefore(v);
874        if (isFinal && num == state().boundariesCrossed) {
875          isDAafter_Variable_values.put(_parameters, isDAafter_Variable_value);
876        } else {
877        }
878        state.INTERMEDIATE_VALUE |= intermediate;
879    
880        return isDAafter_Variable_value;
881      }
882      /**
883       * @attribute syn
884       * @aspect DU
885       * @declaredat /home/jesper/git/extendj/java4/frontend/DefiniteAssignment.jrag:937
886       */
887      @ASTNodeAnnotation.Attribute
888      public boolean isDUafter(Variable v) {
889        boolean isDUafter_Variable_value = isDUbefore(v);
890    
891        return isDUafter_Variable_value;
892      }
893      /**
894       * @apilevel internal
895       */
896      protected boolean decls_computed = false;
897      /**
898       * @apilevel internal
899       */
900      protected SimpleSet decls_value;
901      /**
902       * @apilevel internal
903       */
904      private void decls_reset() {
905        decls_computed = false;
906        decls_value = null;
907      }
908      /**
909       * @attribute syn
910       * @aspect VariableScopePropagation
911       * @declaredat /home/jesper/git/extendj/java4/frontend/LookupVariable.jrag:336
912       */
913      @ASTNodeAnnotation.Attribute
914      public SimpleSet decls() {
915        ASTNode$State state = state();
916        if (decls_computed) {
917          return decls_value;
918        }
919        boolean intermediate = state.INTERMEDIATE_VALUE;
920        state.INTERMEDIATE_VALUE = false;
921        int num = state.boundariesCrossed;
922        boolean isFinal = this.is$Final();
923        decls_value = decls_compute();
924        if (isFinal && num == state().boundariesCrossed) {
925          decls_computed = true;
926        } else {
927        }
928        state.INTERMEDIATE_VALUE |= intermediate;
929    
930        return decls_value;
931      }
932      /**
933       * @apilevel internal
934       */
935      private SimpleSet decls_compute() {
936          SimpleSet set = lookupVariable(name());
937          if (set.size() == 1) {
938            Variable v = (Variable) set.iterator().next();
939            if (!isQualified() && inStaticContext()) {
940              if (v.isInstanceVariable() && !hostType().memberFields(v.name()).isEmpty()) {
941                return SimpleSet.emptySet;
942              }
943            } else if (isQualified() && qualifier().staticContextQualifier()) {
944              if (v.isInstanceVariable()) {
945                return SimpleSet.emptySet;
946              }
947            }
948          }
949          return set;
950        }
951      /**
952       * @apilevel internal
953       */
954      protected boolean decl_computed = false;
955      /**
956       * @apilevel internal
957       */
958      protected Variable decl_value;
959      /**
960       * @apilevel internal
961       */
962      private void decl_reset() {
963        decl_computed = false;
964        decl_value = null;
965      }
966      /**
967       * @attribute syn
968       * @aspect VariableScopePropagation
969       * @declaredat /home/jesper/git/extendj/java4/frontend/LookupVariable.jrag:352
970       */
971      @ASTNodeAnnotation.Attribute
972      public Variable decl() {
973        ASTNode$State state = state();
974        if (decl_computed) {
975          return decl_value;
976        }
977        boolean intermediate = state.INTERMEDIATE_VALUE;
978        state.INTERMEDIATE_VALUE = false;
979        int num = state.boundariesCrossed;
980        boolean isFinal = this.is$Final();
981        decl_value = decl_compute();
982        if (isFinal && num == state().boundariesCrossed) {
983          decl_computed = true;
984        } else {
985        }
986        state.INTERMEDIATE_VALUE |= intermediate;
987    
988        return decl_value;
989      }
990      /**
991       * @apilevel internal
992       */
993      private Variable decl_compute() {
994          SimpleSet decls = decls();
995          if (decls.size() == 1) {
996            return (Variable) decls.iterator().next();
997          }
998          return unknownField();
999        }
1000      /**
1001       * @attribute syn
1002       * @aspect NameCheck
1003       * @declaredat /home/jesper/git/extendj/java4/frontend/NameCheck.jrag:286
1004       */
1005      @ASTNodeAnnotation.Attribute
1006      public boolean inSameInitializer() {
1007        {
1008            BodyDecl b = closestBodyDecl(decl().hostType());
1009            if (b == null) {
1010              return false;
1011            }
1012            if (b instanceof FieldDeclaration && ((FieldDeclaration) b).isStatic() == decl().isStatic()) {
1013              return true;
1014            }
1015            if (b instanceof InstanceInitializer && !decl().isStatic()) {
1016              return true;
1017            }
1018            if (b instanceof StaticInitializer && decl().isStatic()) {
1019              return true;
1020            }
1021            return false;
1022          }
1023      }
1024      /**
1025       * @attribute syn
1026       * @aspect NameCheck
1027       * @declaredat /home/jesper/git/extendj/java4/frontend/NameCheck.jrag:303
1028       */
1029      @ASTNodeAnnotation.Attribute
1030      public boolean simpleAssignment() {
1031        boolean simpleAssignment_value = isDest() && getParent() instanceof AssignSimpleExpr;
1032    
1033        return simpleAssignment_value;
1034      }
1035      /**
1036       * @attribute syn
1037       * @aspect NameCheck
1038       * @declaredat /home/jesper/git/extendj/java4/frontend/NameCheck.jrag:305
1039       */
1040      @ASTNodeAnnotation.Attribute
1041      public boolean inDeclaringClass() {
1042        boolean inDeclaringClass_value = hostType() == decl().hostType();
1043    
1044        return inDeclaringClass_value;
1045      }
1046      /**
1047       * @attribute syn
1048       * @aspect Names
1049       * @declaredat /home/jesper/git/extendj/java4/frontend/QualifiedNames.jrag:36
1050       */
1051      @ASTNodeAnnotation.Attribute
1052      public String name() {
1053        String name_value = getID();
1054    
1055        return name_value;
1056      }
1057      /**
1058       * @apilevel internal
1059       */
1060      protected boolean isFieldAccess_computed = false;
1061      /**
1062       * @apilevel internal
1063       */
1064      protected boolean isFieldAccess_value;
1065      /**
1066       * @apilevel internal
1067       */
1068      private void isFieldAccess_reset() {
1069        isFieldAccess_computed = false;
1070      }
1071      /**
1072       * @attribute syn
1073       * @aspect AccessTypes
1074       * @declaredat /home/jesper/git/extendj/java4/frontend/ResolveAmbiguousNames.jrag:45
1075       */
1076      @ASTNodeAnnotation.Attribute
1077      public boolean isFieldAccess() {
1078        ASTNode$State state = state();
1079        if (isFieldAccess_computed) {
1080          return isFieldAccess_value;
1081        }
1082        boolean intermediate = state.INTERMEDIATE_VALUE;
1083        state.INTERMEDIATE_VALUE = false;
1084        int num = state.boundariesCrossed;
1085        boolean isFinal = this.is$Final();
1086        isFieldAccess_value = decl().isClassVariable() || decl().isInstanceVariable();
1087        if (isFinal && num == state().boundariesCrossed) {
1088          isFieldAccess_computed = true;
1089        } else {
1090        }
1091        state.INTERMEDIATE_VALUE |= intermediate;
1092    
1093        return isFieldAccess_value;
1094      }
1095      /**
1096       * Defines the expected kind of name for the left hand side in a qualified
1097       * expression.
1098       * @attribute syn
1099       * @aspect SyntacticClassification
1100       * @declaredat /home/jesper/git/extendj/java4/frontend/SyntacticClassification.jrag:58
1101       */
1102      @ASTNodeAnnotation.Attribute
1103      public NameType predNameType() {
1104        NameType predNameType_value = NameType.AMBIGUOUS_NAME;
1105    
1106        return predNameType_value;
1107      }
1108      /**
1109       * @apilevel internal
1110       */
1111      protected boolean type_computed = false;
1112      /**
1113       * @apilevel internal
1114       */
1115      protected TypeDecl type_value;
1116      /**
1117       * @apilevel internal
1118       */
1119      private void type_reset() {
1120        type_computed = false;
1121        type_value = null;
1122      }
1123      /**
1124       * @attribute syn
1125       * @aspect TypeAnalysis
1126       * @declaredat /home/jesper/git/extendj/java4/frontend/TypeAnalysis.jrag:302
1127       */
1128      @ASTNodeAnnotation.Attribute
1129      public TypeDecl type() {
1130        ASTNode$State state = state();
1131        if (type_computed) {
1132          return type_value;
1133        }
1134        boolean intermediate = state.INTERMEDIATE_VALUE;
1135        state.INTERMEDIATE_VALUE = false;
1136        int num = state.boundariesCrossed;
1137        boolean isFinal = this.is$Final();
1138        type_value = decl().type();
1139        if (isFinal && num == state().boundariesCrossed) {
1140          type_computed = true;
1141        } else {
1142        }
1143        state.INTERMEDIATE_VALUE |= intermediate;
1144    
1145        return type_value;
1146      }
1147      /**
1148       * @attribute syn
1149       * @aspect TypeCheck
1150       * @declaredat /home/jesper/git/extendj/java4/frontend/TypeCheck.jrag:36
1151       */
1152      @ASTNodeAnnotation.Attribute
1153      public boolean isVariable() {
1154        boolean isVariable_value = true;
1155    
1156        return isVariable_value;
1157      }
1158      /**
1159       * @attribute syn
1160       * @aspect CreateBCode
1161       * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:263
1162       */
1163      @ASTNodeAnnotation.Attribute
1164      public boolean isVarAccessWithAccessor() {
1165        boolean isVarAccessWithAccessor_value = decl() instanceof FieldDeclaration &&
1166                decl().isInstanceVariable() && requiresAccessor();
1167    
1168        return isVarAccessWithAccessor_value;
1169      }
1170      /**
1171       * @attribute syn
1172       * @aspect InnerClasses
1173       * @declaredat /home/jesper/git/extendj/java4/backend/InnerClasses.jrag:430
1174       */
1175      @ASTNodeAnnotation.Attribute
1176      public boolean requiresAccessor() {
1177        {
1178            Variable v = decl();
1179            if (!(v instanceof FieldDeclaration)) {
1180              return false;
1181            }
1182            FieldDeclaration f = (FieldDeclaration) v;
1183            if (f.isPrivate() && !hostType().hasField(v.name())) {
1184              return true;
1185            }
1186            if (f.isProtected() && !f.hostPackage().equals(hostPackage()) && !hostType().hasField(v.name())) {
1187              return true;
1188            }
1189            return false;
1190          }
1191      }
1192      /**
1193       * @attribute syn
1194       * @aspect Enums
1195       * @declaredat /home/jesper/git/extendj/java5/frontend/Enums.jrag:576
1196       */
1197      @ASTNodeAnnotation.Attribute
1198      public boolean isEnumConstant() {
1199        boolean isEnumConstant_value = varDecl() instanceof EnumConstant;
1200    
1201        return isEnumConstant_value;
1202      }
1203      /**
1204       * @attribute syn
1205       * @aspect PreciseRethrow
1206       * @declaredat /home/jesper/git/extendj/java7/frontend/PreciseRethrow.jrag:33
1207       */
1208      @ASTNodeAnnotation.Attribute
1209      public Collection<TypeDecl> throwTypes() {
1210        Collection<TypeDecl> throwTypes_value = decl().throwTypes();
1211    
1212        return throwTypes_value;
1213      }
1214      /**
1215       * @attribute syn
1216       * @aspect PreciseRethrow
1217       * @declaredat /home/jesper/git/extendj/java7/frontend/PreciseRethrow.jrag:149
1218       */
1219      @ASTNodeAnnotation.Attribute
1220      public boolean modifiedInScope(Variable var) {
1221        boolean modifiedInScope_Variable_value = false;
1222    
1223        return modifiedInScope_Variable_value;
1224      }
1225      /**
1226       * @attribute syn
1227       * @aspect PreciseRethrow
1228       * @declaredat /home/jesper/git/extendj/java7/frontend/PreciseRethrow.jrag:200
1229       */
1230      @ASTNodeAnnotation.Attribute
1231      public boolean isVariable(Variable var) {
1232        boolean isVariable_Variable_value = decl() == var;
1233    
1234        return isVariable_Variable_value;
1235      }
1236      /**
1237       * @attribute inh
1238       * @aspect TypeHierarchyCheck
1239       * @declaredat /home/jesper/git/extendj/java4/frontend/TypeHierarchyCheck.jrag:160
1240       */
1241      /**
1242       * @attribute inh
1243       * @aspect TypeHierarchyCheck
1244       * @declaredat /home/jesper/git/extendj/java4/frontend/TypeHierarchyCheck.jrag:160
1245       */
1246      @ASTNodeAnnotation.Attribute
1247      public boolean inExplicitConstructorInvocation() {
1248        boolean inExplicitConstructorInvocation_value = getParent().Define_inExplicitConstructorInvocation(this, null);
1249    
1250        return inExplicitConstructorInvocation_value;
1251      }
1252      /**
1253       * @attribute inh
1254       * @aspect EnclosingLambda
1255       * @declaredat /home/jesper/git/extendj/java8/frontend/EnclosingLambda.jrag:32
1256       */
1257      /**
1258       * @attribute inh
1259       * @aspect EnclosingLambda
1260       * @declaredat /home/jesper/git/extendj/java8/frontend/EnclosingLambda.jrag:32
1261       */
1262      @ASTNodeAnnotation.Attribute
1263      public LambdaExpr enclosingLambda() {
1264        ASTNode$State state = state();
1265        if (enclosingLambda_computed) {
1266          return enclosingLambda_value;
1267        }
1268        boolean intermediate = state.INTERMEDIATE_VALUE;
1269        state.INTERMEDIATE_VALUE = false;
1270        int num = state.boundariesCrossed;
1271        boolean isFinal = this.is$Final();
1272        enclosingLambda_value = getParent().Define_enclosingLambda(this, null);
1273        if (isFinal && num == state().boundariesCrossed) {
1274          enclosingLambda_computed = true;
1275        } else {
1276        }
1277        state.INTERMEDIATE_VALUE |= intermediate;
1278    
1279        return enclosingLambda_value;
1280      }
1281      /**
1282       * @apilevel internal
1283       */
1284      protected boolean enclosingLambda_computed = false;
1285      /**
1286       * @apilevel internal
1287       */
1288      protected LambdaExpr enclosingLambda_value;
1289      /**
1290       * @apilevel internal
1291       */
1292      private void enclosingLambda_reset() {
1293        enclosingLambda_computed = false;
1294        enclosingLambda_value = null;
1295      }
1296      /**
1297       * @apilevel internal
1298       */
1299      public ASTNode rewriteTo() {
1300        return super.rewriteTo();
1301      }
1302    }