Source code: com/puppycrawl/tools/checkstyle/bcel/ReferenceVisitor.java
1 //Tested with BCEL-5.1
2 //http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/
3
4 package com.puppycrawl.tools.checkstyle.bcel;
5
6 import java.util.HashSet;
7 import java.util.Set;
8
9 import org.apache.bcel.classfile.ConstantPool;
10 import org.apache.bcel.classfile.JavaClass;
11 import org.apache.bcel.generic.ConstantPoolGen;
12 import org.apache.bcel.generic.GETFIELD;
13 import org.apache.bcel.generic.GETSTATIC;
14 import org.apache.bcel.generic.INVOKESPECIAL;
15 import org.apache.bcel.generic.INVOKESTATIC;
16 import org.apache.bcel.generic.INVOKEVIRTUAL;
17 import org.apache.bcel.generic.PUTFIELD;
18 import org.apache.bcel.generic.PUTSTATIC;
19
20 import com.puppycrawl.tools.checkstyle.api.Scope;
21 import com.puppycrawl.tools.checkstyle.bcel.classfile.JavaClassDefinition;
22 import com.puppycrawl.tools.checkstyle.bcel.classfile.ReferenceDAO;
23 import com.puppycrawl.tools.checkstyle.bcel.generic.FieldReference;
24 import com.puppycrawl.tools.checkstyle.bcel.generic.GETFIELDReference;
25 import com.puppycrawl.tools.checkstyle.bcel.generic.GETSTATICReference;
26 import com.puppycrawl.tools.checkstyle.bcel.generic.InvokeReference;
27 import com.puppycrawl.tools.checkstyle.bcel.generic.PUTFIELDReference;
28 import com.puppycrawl.tools.checkstyle.bcel.generic.PUTSTATICReference;
29
30 /**
31 * Records references during a deep parse tree traversal.
32 * @author Rick Giles
33 */
34 public final class ReferenceVisitor extends EmptyDeepVisitor
35 {
36 /** singleton */
37 private static ReferenceVisitor sInstance = new ReferenceVisitor();
38
39 /** scope for checking field references */
40 private Set mFieldScopes = new HashSet();
41
42 /** scope for checking method references */
43 private Set mMethodScopes = new HashSet();
44
45 /** maps a JavaClass to a JavaClassDefinition */
46 private ReferenceDAO mReferenceDAO;
47
48 /** access to current constant pool */
49 private ConstantPoolGen mCurrentPoolGen;
50
51 /**
52 * Adds a reference when it visits an instruction that invokes
53 * a method or references a field.
54 * @author Rick Giles
55 * @version 18-Jun-2003
56 */
57 private class GenericVisitor extends org.apache.bcel.generic.EmptyVisitor
58 {
59 /** @see org.apache.bcel.generic.Visitor */
60 public void visitINVOKESPECIAL(INVOKESPECIAL aINVOKESPECIAL)
61 {
62 addInvokeReference(
63 new InvokeReference(aINVOKESPECIAL, mCurrentPoolGen));
64 }
65
66 /** @see org.apache.bcel.generic.Visitor */
67 public void visitINVOKESTATIC(INVOKESTATIC aINVOKESTATIC)
68 {
69 addInvokeReference(
70 new InvokeReference(aINVOKESTATIC, mCurrentPoolGen));
71 }
72
73 /** @see org.apache.bcel.generic.Visitor */
74 public void visitINVOKEVIRTUAL(INVOKEVIRTUAL aINVOKEVIRTUAL)
75 {
76 addInvokeReference(
77 new InvokeReference(aINVOKEVIRTUAL, mCurrentPoolGen));
78 }
79
80 /** @see org.apache.bcel.generic.Visitor */
81 public void visitGETSTATIC(GETSTATIC aGETSTATIC)
82 {
83 addFieldReference(
84 new GETSTATICReference(aGETSTATIC, mCurrentPoolGen));
85 }
86
87 /** @see org.apache.bcel.generic.Visitor */
88 public void visitGETFIELD(GETFIELD aGETFIELD)
89 {
90 addFieldReference(
91 new GETFIELDReference(aGETFIELD, mCurrentPoolGen));
92 }
93
94 /** @see org.apache.bcel.generic.Visitor */
95 public void visitPUTSTATIC(PUTSTATIC aPUTSTATIC)
96 {
97 addFieldReference(
98 new PUTSTATICReference(aPUTSTATIC, mCurrentPoolGen));
99 }
100
101 /** @see org.apache.bcel.generic.Visitor */
102 public void visitPUTFIELD(PUTFIELD aPUTFIELD)
103 {
104 addFieldReference(
105 new PUTFIELDReference(aPUTFIELD, mCurrentPoolGen));
106 }
107 }
108
109 /** prevent client construction */
110 private ReferenceVisitor()
111 {
112 setGenericVisitor(new GenericVisitor());
113 addFieldScope(Scope.PRIVATE);
114 }
115
116 /**
117 * Returns the singleton ReferencesVisitor
118 * @return the singleton
119 */
120 public static ReferenceVisitor getInstance()
121 {
122 return sInstance;
123 }
124
125 /**
126 * Adds an invoke reference to the reference DAO.
127 * @param aReference the reference.
128 */
129 private void addInvokeReference(InvokeReference aReference)
130 {
131 getReferenceDAO().addInvokeReference(aReference);
132 }
133
134 /**
135 * Adds an field reference to the reference DAO.
136 * @param aReference the reference.
137 */
138 private void addFieldReference(FieldReference aReference)
139 {
140 getReferenceDAO().addFieldReference(aReference);
141 }
142
143 /** @see com.puppycrawl.tools.checkstyle.bcel.IDeepVisitor */
144 public void visitSet(Set aJavaClasses)
145 {
146 mReferenceDAO =
147 new ReferenceDAO(aJavaClasses, mFieldScopes, mMethodScopes);
148 }
149
150 /**
151 * Gets the reference DAO.
152 * @return the reference DAO.
153 */
154 public ReferenceDAO getReferenceDAO()
155 {
156 return mReferenceDAO;
157 }
158
159 /** @see com.puppycrawl.tools.checkstyle.bcel.IDeepVisitor */
160 public void visitObject(Object aObject)
161 {
162 final JavaClass javaClass = (JavaClass) aObject;
163 final ConstantPool pool = javaClass.getConstantPool();
164 mCurrentPoolGen = new ConstantPoolGen(pool);
165 }
166
167 /**
168 * Finds the JavaClassDefinition for a given JavaClass.
169 * @param aJavaClass the JavaClass.
170 * @return the JavaClassDefinition for aJavaClass.
171 */
172 public JavaClassDefinition findJavaClassDef(JavaClass aJavaClass)
173 {
174 return getReferenceDAO().findJavaClassDef(aJavaClass);
175 }
176
177 /**
178 * Includes a scope in the scope for checking field references.
179 * @param aScope the scope to include.
180 */
181 public void addFieldScope(Scope aScope)
182 {
183 mFieldScopes.add(aScope);
184 }
185
186 /**
187 * Includes a scope in the scope for checking method references.
188 * @param aScope the scope to include.
189 */
190 public void addMethodScope(Scope aScope)
191 {
192 mMethodScopes.add(aScope);
193 }
194 }