KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > codemanipulation > ImportReferencesCollector


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.corext.codemanipulation;
12
13 import java.util.Collection JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.eclipse.jface.text.Region;
18
19 import org.eclipse.jdt.core.IJavaProject;
20 import org.eclipse.jdt.core.dom.AST;
21 import org.eclipse.jdt.core.dom.ASTNode;
22 import org.eclipse.jdt.core.dom.ArrayType;
23 import org.eclipse.jdt.core.dom.ClassInstanceCreation;
24 import org.eclipse.jdt.core.dom.CompilationUnit;
25 import org.eclipse.jdt.core.dom.Expression;
26 import org.eclipse.jdt.core.dom.FieldAccess;
27 import org.eclipse.jdt.core.dom.IBinding;
28 import org.eclipse.jdt.core.dom.IMethodBinding;
29 import org.eclipse.jdt.core.dom.ITypeBinding;
30 import org.eclipse.jdt.core.dom.IVariableBinding;
31 import org.eclipse.jdt.core.dom.ImportDeclaration;
32 import org.eclipse.jdt.core.dom.MarkerAnnotation;
33 import org.eclipse.jdt.core.dom.MemberRef;
34 import org.eclipse.jdt.core.dom.MethodDeclaration;
35 import org.eclipse.jdt.core.dom.MethodInvocation;
36 import org.eclipse.jdt.core.dom.MethodRef;
37 import org.eclipse.jdt.core.dom.Modifier;
38 import org.eclipse.jdt.core.dom.Name;
39 import org.eclipse.jdt.core.dom.NormalAnnotation;
40 import org.eclipse.jdt.core.dom.PackageDeclaration;
41 import org.eclipse.jdt.core.dom.QualifiedName;
42 import org.eclipse.jdt.core.dom.QualifiedType;
43 import org.eclipse.jdt.core.dom.SimpleName;
44 import org.eclipse.jdt.core.dom.SimpleType;
45 import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
46 import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
47 import org.eclipse.jdt.core.dom.TagElement;
48 import org.eclipse.jdt.core.dom.ThisExpression;
49 import org.eclipse.jdt.core.dom.TypeDeclaration;
50
51 import org.eclipse.jdt.internal.corext.dom.GenericVisitor;
52 import org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer;
53 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
54
55
56 public class ImportReferencesCollector extends GenericVisitor {
57
58     public static void collect(ASTNode node, IJavaProject project, Region rangeLimit, Collection JavaDoc resultingTypeImports, Collection JavaDoc resultingStaticImports) {
59         CompilationUnit astRoot= (CompilationUnit) node.getRoot();
60         node.accept(new ImportReferencesCollector(project, astRoot, rangeLimit, resultingTypeImports, resultingStaticImports));
61     }
62     
63     
64     private CompilationUnit fASTRoot;
65     private Region fSubRange;
66     private Collection JavaDoc/*<Name>*/ fTypeImports;
67     private Collection JavaDoc/*<Name>*/ fStaticImports;
68
69     private ImportReferencesCollector(IJavaProject project, CompilationUnit astRoot, Region rangeLimit, Collection JavaDoc resultingTypeImports, Collection JavaDoc resultingStaticImports) {
70         super(true);
71         fTypeImports= resultingTypeImports;
72         fStaticImports= resultingStaticImports;
73         fSubRange= rangeLimit;
74         if (project == null || !JavaModelUtil.is50OrHigher(project)) {
75             fStaticImports= null; // do not collect
76
}
77         fASTRoot= astRoot;
78     }
79     
80     public ImportReferencesCollector(IJavaProject project, Region rangeLimit, Collection JavaDoc resultingTypeImports, Collection JavaDoc resultingStaticImports) {
81         this(project, null, rangeLimit, resultingTypeImports, resultingStaticImports);
82     }
83     
84     public CompilationUnit getASTRoot(ASTNode node) {
85         if (fASTRoot == null) {
86             fASTRoot= (CompilationUnit) node.getRoot();
87         }
88         return fASTRoot;
89     }
90     
91     private boolean isAffected(ASTNode node) {
92         if (fSubRange == null) {
93             return true;
94         }
95         int nodeStart= node.getStartPosition();
96         int offset= fSubRange.getOffset();
97         return nodeStart + node.getLength() > offset && (offset + fSubRange.getLength()) > nodeStart;
98     }
99     
100     
101     private void addReference(SimpleName name) {
102         if (isAffected(name)) {
103             fTypeImports.add(name);
104         }
105     }
106     
107     private void typeRefFound(Name node) {
108         if (node != null) {
109             while (node.isQualifiedName()) {
110                 node= ((QualifiedName) node).getQualifier();
111             }
112             addReference((SimpleName) node);
113         }
114     }
115
116     private void possibleTypeRefFound(Name node) {
117         while (node.isQualifiedName()) {
118             node= ((QualifiedName) node).getQualifier();
119         }
120         IBinding binding= node.resolveBinding();
121         if (binding == null || binding.getKind() == IBinding.TYPE) {
122             // if the binding is null, we cannot determine if
123
// we have a type binding or not, so we will assume
124
// we do.
125
addReference((SimpleName) node);
126         }
127     }
128     
129     private void possibleStaticImportFound(Name name) {
130         if (fStaticImports == null) {
131             return;
132         }
133         
134         while (name.isQualifiedName()) {
135             name= ((QualifiedName) name).getQualifier();
136         }
137         if (!isAffected(name)) {
138             return;
139         }
140         
141         IBinding binding= name.resolveBinding();
142         if (binding == null || binding instanceof ITypeBinding || !Modifier.isStatic(binding.getModifiers()) || ((SimpleName) name).isDeclaration()) {
143             return;
144         }
145         
146         if (binding instanceof IVariableBinding) {
147             IVariableBinding varBinding= (IVariableBinding) binding;
148             if (varBinding.isField()) {
149                 varBinding= varBinding.getVariableDeclaration();
150                 ITypeBinding declaringClass= varBinding.getDeclaringClass();
151                 if (declaringClass != null && !declaringClass.isLocal()) {
152                     if (new ScopeAnalyzer(getASTRoot(name)).isDeclaredInScope(varBinding, (SimpleName)name, ScopeAnalyzer.VARIABLES | ScopeAnalyzer.CHECK_VISIBILITY))
153                             return;
154                     fStaticImports.add(name);
155                 }
156             }
157         } else if (binding instanceof IMethodBinding) {
158             IMethodBinding methodBinding= ((IMethodBinding) binding).getMethodDeclaration();
159             ITypeBinding declaringClass= methodBinding.getDeclaringClass();
160             if (declaringClass != null && !declaringClass.isLocal()) {
161                 if (new ScopeAnalyzer(getASTRoot(name)).isDeclaredInScope(methodBinding, (SimpleName)name, ScopeAnalyzer.METHODS | ScopeAnalyzer.CHECK_VISIBILITY))
162                         return;
163                 fStaticImports.add(name);
164             }
165         }
166
167     }
168     
169     private void doVisitChildren(List JavaDoc elements) {
170         int nElements= elements.size();
171         for (int i= 0; i < nElements; i++) {
172             ((ASTNode) elements.get(i)).accept(this);
173         }
174     }
175     
176     private void doVisitNode(ASTNode node) {
177         if (node != null) {
178             node.accept(this);
179         }
180     }
181     
182     /* (non-Javadoc)
183      * @see org.eclipse.jdt.internal.corext.dom.GenericVisitor#visitNode(org.eclipse.jdt.core.dom.ASTNode)
184      */

185     protected boolean visitNode(ASTNode node) {
186         return isAffected(node);
187     }
188     
189     /*
190      * @see ASTVisitor#visit(ArrayType)
191      */

192     public boolean visit(ArrayType node) {
193         doVisitNode(node.getElementType());
194         return false;
195     }
196
197     /*
198      * @see ASTVisitor#visit(SimpleType)
199      */

200     public boolean visit(SimpleType node) {
201         typeRefFound(node.getName());
202         return false;
203     }
204     
205     /*
206      * @see ASTVisitor#visit(QualifiedType)
207      */

208     public boolean visit(QualifiedType node) {
209         // nothing to do here, let the qualifier be visited
210
return true;
211     }
212     
213     /*
214      * @see ASTVisitor#visit(QualifiedName)
215      */

216     public boolean visit(QualifiedName node) {
217         possibleTypeRefFound(node); // possible ref
218
possibleStaticImportFound(node);
219         return false;
220     }
221
222     /*
223      * @see ASTVisitor#visit(ImportDeclaration)
224      */

225     public boolean visit(ImportDeclaration node) {
226         return false;
227     }
228     
229     /*
230      * @see ASTVisitor#visit(PackageDeclaration)
231      */

232     public boolean visit(PackageDeclaration node) {
233         if (node.getAST().apiLevel() >= AST.JLS3) {
234             doVisitChildren(node.annotations());
235         }
236         return false;
237     }
238
239     /*
240      * @see ASTVisitor#visit(ThisExpression)
241      */

242     public boolean visit(ThisExpression node) {
243         typeRefFound(node.getQualifier());
244         return false;
245     }
246
247     private void evalQualifyingExpression(Expression expr, Name selector) {
248         if (expr != null) {
249             if (expr instanceof Name) {
250                 Name name= (Name) expr;
251                 possibleTypeRefFound(name);
252                 possibleStaticImportFound(name);
253             } else {
254                 expr.accept(this);
255             }
256         } else if (selector != null) {
257             possibleStaticImportFound(selector);
258         }
259     }
260
261     /*
262      * @see ASTVisitor#visit(ClassInstanceCreation)
263      */

264     public boolean visit(ClassInstanceCreation node) {
265         doVisitChildren(node.typeArguments());
266         doVisitNode(node.getType());
267         evalQualifyingExpression(node.getExpression(), null);
268         if (node.getAnonymousClassDeclaration() != null) {
269             node.getAnonymousClassDeclaration().accept(this);
270         }
271         doVisitChildren(node.arguments());
272         return false;
273     }
274
275     /*
276      * @see ASTVisitor#endVisit(MethodInvocation)
277      */

278     public boolean visit(MethodInvocation node) {
279         evalQualifyingExpression(node.getExpression(), node.getName());
280         doVisitChildren(node.typeArguments());
281         doVisitChildren(node.arguments());
282         return false;
283     }
284
285     /*
286      * @see ASTVisitor#visit(SuperConstructorInvocation)
287      */

288     public boolean visit(SuperConstructorInvocation node) {
289         if (!isAffected(node)) {
290             return false;
291         }
292         
293         evalQualifyingExpression(node.getExpression(), null);
294         doVisitChildren(node.typeArguments());
295         doVisitChildren(node.arguments());
296         return false;
297     }
298
299     /*
300      * @see ASTVisitor#visit(FieldAccess)
301      */

302     public boolean visit(FieldAccess node) {
303         evalQualifyingExpression(node.getExpression(), node.getName());
304         return false;
305     }
306     
307     /*
308      * @see ASTVisitor#visit(SimpleName)
309      */

310     public boolean visit(SimpleName node) {
311         // if the call gets here, it can only be a variable reference
312
possibleStaticImportFound(node);
313         return false;
314     }
315     
316     /* (non-Javadoc)
317      * @see org.eclipse.jdt.internal.corext.dom.GenericVisitor#visit(org.eclipse.jdt.core.dom.MarkerAnnotation)
318      */

319     public boolean visit(MarkerAnnotation node) {
320         typeRefFound(node.getTypeName());
321         return false;
322     }
323     
324     /* (non-Javadoc)
325      * @see org.eclipse.jdt.internal.corext.dom.GenericVisitor#visit(org.eclipse.jdt.core.dom.MarkerAnnotation)
326      */

327     public boolean visit(NormalAnnotation node) {
328         typeRefFound(node.getTypeName());
329         doVisitChildren(node.values());
330         return false;
331     }
332     
333     /* (non-Javadoc)
334      * @see org.eclipse.jdt.internal.corext.dom.GenericVisitor#visit(org.eclipse.jdt.core.dom.MarkerAnnotation)
335      */

336     public boolean visit(SingleMemberAnnotation node) {
337         typeRefFound(node.getTypeName());
338         doVisitNode(node.getValue());
339         return false;
340     }
341
342     /*
343      * @see ASTVisitor#visit(TypeDeclaration)
344      */

345     public boolean visit(TypeDeclaration node) {
346         if (!isAffected(node)) {
347             return false;
348         }
349         return true;
350     }
351     
352     /*
353      * @see ASTVisitor#visit(MethodDeclaration)
354      */

355     public boolean visit(MethodDeclaration node) {
356         if (!isAffected(node)) {
357             return false;
358         }
359         doVisitNode(node.getJavadoc());
360         
361         if (node.getAST().apiLevel() >= AST.JLS3) {
362             doVisitChildren(node.modifiers());
363             doVisitChildren(node.typeParameters());
364         }
365         
366         if (!node.isConstructor()) {
367             doVisitNode(node.getReturnType2());
368         }
369         doVisitChildren(node.parameters());
370         Iterator JavaDoc iter=node.thrownExceptions().iterator();
371         while (iter.hasNext()) {
372             typeRefFound((Name) iter.next());
373         }
374         doVisitNode(node.getBody());
375         return false;
376     }
377     
378     public boolean visit(TagElement node) {
379         String JavaDoc tagName= node.getTagName();
380         List JavaDoc list= node.fragments();
381         int idx= 0;
382         if (tagName != null && !list.isEmpty()) {
383             Object JavaDoc first= list.get(0);
384             if (first instanceof Name) {
385                 if ("@throws".equals(tagName) || "@exception".equals(tagName)) { //$NON-NLS-1$//$NON-NLS-2$
386
typeRefFound((Name) first);
387                 } else if ("@see".equals(tagName) || "@link".equals(tagName) || "@linkplain".equals(tagName)) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
388
Name name= (Name) first;
389                     possibleTypeRefFound(name);
390                 }
391                 idx++;
392             }
393         }
394         for (int i= idx; i < list.size(); i++) {
395             doVisitNode((ASTNode) list.get(i));
396         }
397         return false;
398     }
399     
400     public boolean visit(MemberRef node) {
401         Name qualifier= node.getQualifier();
402         if (qualifier != null) {
403             typeRefFound(qualifier);
404         }
405         return false;
406     }
407     
408     public boolean visit(MethodRef node) {
409         Name qualifier= node.getQualifier();
410         if (qualifier != null) {
411             typeRefFound(qualifier);
412         }
413         List JavaDoc list= node.parameters();
414         if (list != null) {
415             doVisitChildren(list); // visit MethodRefParameter with Type
416
}
417         return false;
418     }
419 }
420
Popular Tags