KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > search > OccurrencesFinder


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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.ui.search;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Collection JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18
19 import org.eclipse.jface.text.BadLocationException;
20 import org.eclipse.jface.text.IDocument;
21 import org.eclipse.jface.text.IRegion;
22
23 import org.eclipse.search.ui.text.Match;
24
25 import org.eclipse.jdt.core.IJavaElement;
26 import org.eclipse.jdt.core.dom.ASTNode;
27 import org.eclipse.jdt.core.dom.ASTVisitor;
28 import org.eclipse.jdt.core.dom.Assignment;
29 import org.eclipse.jdt.core.dom.ClassInstanceCreation;
30 import org.eclipse.jdt.core.dom.CompilationUnit;
31 import org.eclipse.jdt.core.dom.Expression;
32 import org.eclipse.jdt.core.dom.FieldAccess;
33 import org.eclipse.jdt.core.dom.IBinding;
34 import org.eclipse.jdt.core.dom.IMethodBinding;
35 import org.eclipse.jdt.core.dom.ITypeBinding;
36 import org.eclipse.jdt.core.dom.IVariableBinding;
37 import org.eclipse.jdt.core.dom.ImportDeclaration;
38 import org.eclipse.jdt.core.dom.MethodInvocation;
39 import org.eclipse.jdt.core.dom.Modifier;
40 import org.eclipse.jdt.core.dom.Name;
41 import org.eclipse.jdt.core.dom.ParameterizedType;
42 import org.eclipse.jdt.core.dom.PostfixExpression;
43 import org.eclipse.jdt.core.dom.PrefixExpression;
44 import org.eclipse.jdt.core.dom.QualifiedName;
45 import org.eclipse.jdt.core.dom.SimpleName;
46 import org.eclipse.jdt.core.dom.SimpleType;
47 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
48 import org.eclipse.jdt.core.dom.Type;
49 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
50 import org.eclipse.jdt.core.dom.PrefixExpression.Operator;
51
52 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
53 import org.eclipse.jdt.internal.corext.dom.Bindings;
54 import org.eclipse.jdt.internal.corext.dom.NodeFinder;
55
56 public class OccurrencesFinder extends ASTVisitor implements IOccurrencesFinder {
57     
58     public static final String JavaDoc IS_WRITEACCESS= "writeAccess"; //$NON-NLS-1$
59
public static final String JavaDoc IS_VARIABLE= "variable"; //$NON-NLS-1$
60

61     private CompilationUnit fRoot;
62     private Name fSelectedNode;
63     private IBinding fTarget;
64     private List JavaDoc fUsages= new ArrayList JavaDoc/*<ASTNode>*/();
65     private List JavaDoc fWriteUsages= new ArrayList JavaDoc/*<ASTNode>*/();
66     private boolean fTargetIsStaticMethodImport;
67
68     public OccurrencesFinder(IBinding target) {
69         super(true);
70         fTarget= target;
71     }
72     
73     public OccurrencesFinder() {
74         super(true);
75     }
76     
77     public String JavaDoc initialize(CompilationUnit root, int offset, int length) {
78         return initialize(root, NodeFinder.perform(root, offset, length));
79     }
80     
81     public String JavaDoc initialize(CompilationUnit root, ASTNode node) {
82         if (!(node instanceof Name))
83             return SearchMessages.OccurrencesFinder_no_element;
84         fRoot= root;
85         fSelectedNode= (Name)node;
86         fTarget= fSelectedNode.resolveBinding();
87         if (fTarget == null)
88             return SearchMessages.OccurrencesFinder_no_binding;
89         fTarget= getBindingDeclaration(fTarget);
90         
91         fTargetIsStaticMethodImport= isStaticImport(fSelectedNode.getParent());
92         return null;
93     }
94     
95     public List JavaDoc perform() {
96         fRoot.accept(this);
97         return fUsages;
98     }
99     
100     public void collectOccurrenceMatches(IJavaElement element, IDocument document, Collection JavaDoc resultingMatches) {
101         boolean isVariable= fTarget instanceof IVariableBinding;
102         HashMap JavaDoc lineToGroup= new HashMap JavaDoc();
103         
104         for (Iterator JavaDoc iter= fUsages.iterator(); iter.hasNext();) {
105             ASTNode node= (ASTNode) iter.next();
106             int startPosition= node.getStartPosition();
107             int length= node.getLength();
108             try {
109                 boolean isWriteAccess= fWriteUsages.contains(node);
110                 int line= document.getLineOfOffset(startPosition);
111                 Integer JavaDoc lineInteger= new Integer JavaDoc(line);
112                 OccurrencesGroupKey groupKey= (OccurrencesGroupKey) lineToGroup.get(lineInteger);
113                 if (groupKey == null) {
114                     IRegion region= document.getLineInformation(line);
115                     String JavaDoc lineContents= document.get(region.getOffset(), region.getLength()).trim();
116                     groupKey= new OccurrencesGroupKey(element, line, lineContents, isWriteAccess, isVariable);
117                     lineToGroup.put(lineInteger, groupKey);
118                 } else if (isWriteAccess) {
119                     // a line with read an write access is considered as write access:
120
groupKey.setWriteAccess(true);
121                 }
122                 Match match= new Match(groupKey, startPosition, length);
123                 resultingMatches.add(match);
124             } catch (BadLocationException e) {
125                 //nothing
126
}
127         }
128     }
129     
130     /*
131      * @see org.eclipse.jdt.internal.ui.search.IOccurrencesFinder#getJobLabel()
132      */

133     public String JavaDoc getJobLabel() {
134         return SearchMessages.OccurrencesFinder_searchfor ;
135     }
136     
137     public String JavaDoc getElementName() {
138         if (fSelectedNode != null) {
139             return ASTNodes.asString(fSelectedNode);
140         }
141         return null;
142     }
143     
144     public String JavaDoc getUnformattedPluralLabel() {
145         return SearchMessages.OccurrencesFinder_label_plural;
146     }
147     
148     public String JavaDoc getUnformattedSingularLabel() {
149         return SearchMessages.OccurrencesFinder_label_singular;
150     }
151     
152     public boolean visit(QualifiedName node) {
153         final IBinding binding= node.resolveBinding();
154         if (binding instanceof IVariableBinding && ((IVariableBinding)binding).isField()) {
155             SimpleName name= node.getName();
156             return !match(name, fUsages, name.resolveBinding());
157         }
158         if (binding instanceof IMethodBinding) {
159             if (isStaticImport(node)) {
160                 SimpleName name= node.getName();
161                 return !matchStaticImport(name, fUsages, (IMethodBinding)binding);
162             }
163         }
164         return !match(node, fUsages, binding);
165     }
166     
167     private static boolean isStaticImport(ASTNode node) {
168         if (!(node instanceof QualifiedName))
169             return false;
170         
171         ASTNode parent= ((QualifiedName)node).getParent();
172         return parent instanceof ImportDeclaration && ((ImportDeclaration)parent).isStatic();
173     }
174
175     public boolean visit(MethodInvocation node) {
176         if (fTargetIsStaticMethodImport)
177             return !matchStaticImport(node.getName(), fUsages, node.resolveMethodBinding());
178         
179         return true;
180     }
181     
182     public boolean visit(SimpleName node) {
183         return !match(node, fUsages, node.resolveBinding());
184     }
185
186     /*
187      * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ConstructorInvocation)
188      */

189     public boolean visit(ClassInstanceCreation node) {
190         // match with the constructor and the type.
191
Type type= node.getType();
192         if (type instanceof ParameterizedType) {
193             type= ((ParameterizedType) type).getType();
194         }
195         if (type instanceof SimpleType) {
196             Name name= ((SimpleType) type).getName();
197             if (name instanceof QualifiedName)
198                 name= ((QualifiedName)name).getName();
199             match(name, fUsages, node.resolveConstructorBinding());
200         }
201         return super.visit(node);
202     }
203     
204     public boolean visit(Assignment node) {
205         Expression lhs= node.getLeftHandSide();
206         SimpleName name= getSimpleName(lhs);
207         if (name != null)
208             match(name, fWriteUsages, name.resolveBinding());
209         lhs.accept(this);
210         node.getRightHandSide().accept(this);
211         return false;
212     }
213     
214     public boolean visit(SingleVariableDeclaration node) {
215         match(node.getName(), fWriteUsages, node.resolveBinding());
216         return super.visit(node);
217     }
218     
219     public boolean visit(VariableDeclarationFragment node) {
220         if (node.getParent().getNodeType() == ASTNode.FIELD_DECLARATION || node.getInitializer() != null)
221             match(node.getName(), fWriteUsages, node.resolveBinding());
222         return super.visit(node);
223     }
224
225     public boolean visit(PrefixExpression node) {
226         PrefixExpression.Operator operator= node.getOperator();
227         if (operator == Operator.INCREMENT || operator == Operator.DECREMENT) {
228             Expression operand= node.getOperand();
229             SimpleName name= getSimpleName(operand);
230             if (name != null)
231                 match(name, fWriteUsages, name.resolveBinding());
232         }
233         return super.visit(node);
234     }
235
236     public boolean visit(PostfixExpression node) {
237         Expression operand= node.getOperand();
238         SimpleName name= getSimpleName(operand);
239         if (name != null)
240             match(name, fWriteUsages, name.resolveBinding());
241         return super.visit(node);
242     }
243     
244     private boolean match(Name node, List JavaDoc result, IBinding binding) {
245         if (binding != null && Bindings.equals(getBindingDeclaration(binding), fTarget)) {
246             result.add(node);
247             return true;
248         }
249         return false;
250     }
251     
252     private boolean matchStaticImport(Name node, List JavaDoc result, IMethodBinding binding) {
253         if (binding == null || node == null || !(fTarget instanceof IMethodBinding) || !Modifier.isStatic(binding.getModifiers()))
254             return false;
255         
256         IMethodBinding targetMethodBinding= (IMethodBinding)fTarget;
257         if ((fTargetIsStaticMethodImport || Modifier.isStatic(targetMethodBinding.getModifiers())) && (targetMethodBinding.getDeclaringClass().getTypeDeclaration() == binding.getDeclaringClass().getTypeDeclaration())) {
258             if (node.getFullyQualifiedName().equals(targetMethodBinding.getName())) {
259                 result.add(node);
260                 return true;
261             }
262         }
263         return false;
264     }
265
266     private SimpleName getSimpleName(Expression expression) {
267         if (expression instanceof SimpleName)
268             return ((SimpleName)expression);
269         else if (expression instanceof QualifiedName)
270             return (((QualifiedName) expression).getName());
271         else if (expression instanceof FieldAccess)
272             return ((FieldAccess)expression).getName();
273         return null;
274     }
275     
276     private IBinding getBindingDeclaration(IBinding binding) {
277         switch (binding.getKind()) {
278             case IBinding.TYPE :
279                 return ((ITypeBinding)binding).getTypeDeclaration();
280             case IBinding.METHOD :
281                 return ((IMethodBinding)binding).getMethodDeclaration();
282             case IBinding.VARIABLE :
283                 return ((IVariableBinding)binding).getVariableDeclaration();
284             default:
285                 return binding;
286         }
287     }
288 }
289
Popular Tags