Source code: com/puppycrawl/tools/checkstyle/bcel/classfile/ReferenceDAO.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.classfile;
5
6 import java.util.HashMap;
7 import java.util.Iterator;
8 import java.util.Map;
9 import java.util.Set;
10
11 import org.apache.bcel.Repository;
12 import org.apache.bcel.classfile.JavaClass;
13 import org.apache.bcel.generic.Type;
14
15 import com.puppycrawl.tools.checkstyle.bcel.generic.FieldReference;
16 import com.puppycrawl.tools.checkstyle.bcel.generic.InvokeReference;
17
18 /**
19 * Accesses Method and Field references for a set of JavaClasses.
20 * @author Rick Giles
21 */
22 public class ReferenceDAO
23 {
24 /**
25 * Creates a <code>ReferenceDAO</code> from a set of JavaClasses.
26 * @param aJavaClasses the set of JavaClasses for this DAO.
27 * @param aFieldScopes the scopes for field references.
28 * @param aMethodScopes the scopes for method references.
29 */
30 public ReferenceDAO(Set aJavaClasses, Set aFieldScopes, Set aMethodScopes)
31 {
32 mJavaClasses = new HashMap(aJavaClasses.size());
33 final Iterator it = aJavaClasses.iterator();
34 while (it.hasNext()) {
35 final JavaClass javaClass = (JavaClass) it.next();
36 final JavaClassDefinition javaClassDef =
37 new JavaClassDefinition(javaClass, aFieldScopes, aMethodScopes);
38 mJavaClasses.put(javaClass, javaClassDef);
39 }
40 }
41
42 /** maps a JavaClass to a JavaClassDefinition */
43 private Map mJavaClasses = null;
44
45 /**
46 * Finds the JavaClassDefinition for a given JavaClass.
47 * @param aJavaClass the JavaClass.
48 * @return the JavaClassDefinition keyed on aJavaClass.
49 */
50 public JavaClassDefinition findJavaClassDef(JavaClass aJavaClass)
51 {
52 return (JavaClassDefinition) mJavaClasses.get(aJavaClass);
53 }
54
55 /**
56 * Adds a reference for an invocation in the invoked method definition.
57 * The invocation is of the form class.method(args).
58 * @param aInvokeRef the invocation reference.
59 */
60 public void addInvokeReference(InvokeReference aInvokeRef)
61 {
62 // find the class for the instruction
63 final String className = aInvokeRef.getClassName();
64 JavaClass javaClass = Repository.lookupClass(className);
65 final String methodName = aInvokeRef.getName();
66 final Type[] argTypes = aInvokeRef.getArgTypes();
67
68 // search up the class hierarchy for the class containing the
69 // method definition.
70 MethodDefinition narrowest = null;
71 while ((javaClass != null) && (narrowest == null)) {
72 final JavaClassDefinition javaClassDef =
73 (JavaClassDefinition) mJavaClasses.get(javaClass);
74 if (javaClassDef != null) {
75 // find narrowest compatible in the current class
76 narrowest =
77 javaClassDef.findNarrowestMethod(
78 className,
79 methodName,
80 argTypes);
81 if (narrowest != null) {
82 narrowest.addReference(aInvokeRef);
83 }
84 }
85 // search the parent
86 javaClass = javaClass.getSuperClass();
87 }
88 }
89
90 /**
91 * Adds a reference to a field.
92 * @param aFieldRef the field reference.
93 */
94 public void addFieldReference(FieldReference aFieldRef)
95 {
96 final String className = aFieldRef.getClassName();
97 JavaClass javaClass = Repository.lookupClass(className);
98 final String fieldName = aFieldRef.getName();
99 // search up the class hierarchy for the class containing the
100 // method definition.
101 FieldDefinition fieldDef = null;
102 while ((javaClass != null) && (fieldDef == null)) {
103 final JavaClassDefinition javaClassDef =
104 (JavaClassDefinition) mJavaClasses.get(javaClass);
105 if (javaClassDef != null) {
106 fieldDef = javaClassDef.findFieldDef(fieldName);
107 if (fieldDef != null) {
108 fieldDef.addReference(aFieldRef);
109 }
110 }
111 //search the parent
112 javaClass = javaClass.getSuperClass();
113 }
114 }
115
116 /**
117 * Finds the definition of the field of a field reference.
118 * @param aFieldRef the reference to a field.
119 * @return the definition of the field for aFieldRef.
120 */
121 public FieldDefinition findFieldDef(FieldReference aFieldRef)
122 {
123 final String className = aFieldRef.getClassName();
124 JavaClass javaClass = Repository.lookupClass(className);
125 final String fieldName = aFieldRef.getName();
126 // search up the class hierarchy for the class containing the
127 // method definition.
128 FieldDefinition result = null;
129 while ((javaClass != null) && (result == null)) {
130 final JavaClassDefinition javaClassDef =
131 (JavaClassDefinition) mJavaClasses.get(javaClass);
132 if (javaClassDef != null) {
133 result = javaClassDef.findFieldDef(fieldName);
134 }
135 //search the parent
136 javaClass = javaClass.getSuperClass();
137 }
138 return result;
139 }
140 }