KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > polyglot > visit > FwdReferenceChecker


1 package polyglot.visit;
2
3 import java.util.*;
4 import java.util.HashMap JavaDoc;
5 import java.util.Map JavaDoc;
6 import java.util.Set JavaDoc;
7
8 import polyglot.ast.*;
9 import polyglot.ast.ConstructorCall;
10 import polyglot.ast.Node;
11 import polyglot.ast.NodeFactory;
12 import polyglot.frontend.Job;
13 import polyglot.types.ConstructorInstance;
14 import polyglot.types.Context;
15 import polyglot.types.SemanticException;
16 import polyglot.types.TypeSystem;
17 import polyglot.util.InternalCompilerError;
18
19 /** Visitor which ensures that field intializers and initializers do not
20  * make illegal forward references to fields.
21  * This is an implementation of the rules of the Java Language Spec, 2nd
22  * Edition, Section 8.3.2.3
23  */

24 public class FwdReferenceChecker extends ContextVisitor
25 {
26     public FwdReferenceChecker(Job job, TypeSystem ts, NodeFactory nf) {
27     super(job, ts, nf);
28     }
29
30     private boolean inInitialization = false;
31     private boolean inStaticInit = false;
32     private Field fieldAssignLHS = null;
33     private Set JavaDoc declaredFields = new HashSet();
34     
35     protected NodeVisitor enterCall(Node n) throws SemanticException {
36         if (n instanceof FieldDecl) {
37             FieldDecl fd = (FieldDecl)n;
38             declaredFields.add(fd.fieldInstance());
39             
40             FwdReferenceChecker frc = (FwdReferenceChecker)this.copy();
41             frc.inInitialization = true;
42             frc.inStaticInit = fd.flags().isStatic();
43             return frc;
44         }
45         else if (n instanceof Initializer) {
46             FwdReferenceChecker frc = (FwdReferenceChecker)this.copy();
47             frc.inInitialization = true;
48             frc.inStaticInit = ((Initializer)n).flags().isStatic();
49             return frc;
50         }
51         else if (n instanceof FieldAssign) {
52             FwdReferenceChecker frc = (FwdReferenceChecker)this.copy();
53             frc.fieldAssignLHS = (Field)((FieldAssign)n).left();
54             return frc;
55         }
56         else if (n instanceof Field) {
57             if (fieldAssignLHS == n) {
58                 // the field is on the left hand side of an assignment.
59
// we can ignore it
60
fieldAssignLHS = null;
61             }
62             else if (inInitialization) {
63                 // we need to check if this is an illegal fwd reference.
64
Field f = (Field)n;
65                 
66                 // an illegal fwd reference if a usage of an instance
67
// (resp. static) field occurs in an instance (resp. static)
68
// initialization, and the innermost enclosing class or
69
// interface of the usage is the same as the container of
70
// the field, and we have not yet seen the field declaration.
71
//
72
// In addition, if a field is not accessed as a simple name,
73
// then all is ok
74

75                 if (inStaticInit == f.fieldInstance().flags().isStatic() &&
76                     context().currentClass().equals(f.fieldInstance().container()) &&
77                    !declaredFields.contains(f.fieldInstance()) &&
78                    f.isTargetImplicit()) {
79                     throw new SemanticException("Illegal forward reference",
80                                                 f.position());
81                 }
82             }
83         }
84         return this;
85     }
86 }
87
88
Popular Tags