KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > dom > CodeScopeBuilder


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 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.dom;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.eclipse.jdt.core.dom.*;
18 import org.eclipse.jdt.core.dom.ASTNode;
19 import org.eclipse.jdt.core.dom.ASTVisitor;
20 import org.eclipse.jdt.core.dom.Block;
21 import org.eclipse.jdt.core.dom.BodyDeclaration;
22 import org.eclipse.jdt.core.dom.Expression;
23 import org.eclipse.jdt.core.dom.ForStatement;
24 import org.eclipse.jdt.core.dom.IBinding;
25 import org.eclipse.jdt.core.dom.MethodInvocation;
26 import org.eclipse.jdt.core.dom.QualifiedName;
27 import org.eclipse.jdt.core.dom.SimpleName;
28 import org.eclipse.jdt.core.dom.TypeDeclarationStatement;
29
30
31 public class CodeScopeBuilder extends ASTVisitor {
32
33     public static class Scope {
34         private Scope fParent;
35         private int fStart;
36         private int fLength;
37         private List JavaDoc fNames;
38         private List JavaDoc fChildren;
39         private int fCursorOffset;
40         Scope(Scope parent, int start, int length) {
41             fParent= parent;
42             fStart= start;
43             fLength= length;
44             if (fParent != null)
45                 fParent.addChild(this);
46         }
47         public void setCursor(int offset) {
48             fCursorOffset= offset;
49         }
50         private void addChild(Scope child) {
51             if (fChildren == null)
52                 fChildren= new ArrayList JavaDoc(2);
53             fChildren.add(child);
54         }
55         private void addName(String JavaDoc name) {
56             if (fNames == null)
57                 fNames= new ArrayList JavaDoc(2);
58             fNames.add(name);
59         }
60         public Scope findScope(int start, int length) {
61             if (fStart <= start && start + length <= fStart + fLength) {
62                 if (fChildren == null)
63                     return this;
64                 for (Iterator JavaDoc iter= fChildren.iterator(); iter.hasNext();) {
65                     Scope scope= ((Scope)iter.next()).findScope(start, length);
66                     if (scope != null)
67                         return scope;
68                 }
69                 return this;
70             }
71             return null;
72         }
73         public String JavaDoc createName(String JavaDoc candidate, boolean add) {
74             int i= 1;
75             String JavaDoc result= candidate;
76             while(isInUse(result)) {
77                 result= candidate + i++;
78             }
79             if (add)
80                 addName(result);
81             return result;
82         }
83         public boolean isInUse(String JavaDoc name) {
84             if (internalIsInUse(name))
85                 return true;
86             if (fChildren != null) {
87                 for (Iterator JavaDoc iter= fChildren.iterator(); iter.hasNext();) {
88                     Scope child= (Scope) iter.next();
89                     if (fCursorOffset < child.fStart && child.isInUseDown(name)) {
90                         return true;
91                     }
92                 }
93             }
94             return false;
95         }
96         private boolean internalIsInUse(String JavaDoc name) {
97             if (fNames != null && fNames.contains(name))
98                 return true;
99             if (fParent != null)
100                 return fParent.internalIsInUse(name);
101             return false;
102             
103         }
104         private boolean isInUseDown(String JavaDoc name) {
105             if (fNames != null && fNames.contains(name))
106                 return true;
107             if (fChildren == null)
108                 return false;
109             for (Iterator JavaDoc iter= fChildren.iterator(); iter.hasNext();) {
110                 Scope scope= (Scope) iter.next();
111                 if (scope.isInUseDown(name))
112                     return true;
113             }
114             return false;
115         }
116     }
117     
118     private IBinding fIgnoreBinding;
119     private Selection fIgnoreRange;
120     private Scope fScope;
121     private List JavaDoc fScopes;
122
123     public static Scope perform(BodyDeclaration node, IBinding ignore) {
124         CodeScopeBuilder collector= new CodeScopeBuilder(node, ignore);
125         node.accept(collector);
126         return collector.fScope;
127     }
128
129     public static Scope perform(BodyDeclaration node, Selection ignore) {
130         CodeScopeBuilder collector= new CodeScopeBuilder(node, ignore);
131         node.accept(collector);
132         return collector.fScope;
133     }
134
135     private CodeScopeBuilder(ASTNode node, IBinding ignore) {
136         fScope= new Scope(null, node.getStartPosition(), node.getLength());
137         fScopes= new ArrayList JavaDoc();
138         fIgnoreBinding= ignore;
139     }
140     
141     private CodeScopeBuilder(ASTNode node, Selection ignore) {
142         fScope= new Scope(null, node.getStartPosition(), node.getLength());
143         fScopes= new ArrayList JavaDoc();
144         fIgnoreRange= ignore;
145     }
146     
147     public boolean visit(CatchClause node) {
148         // open a new scope for the exception declaration.
149
fScopes.add(fScope);
150         fScope= new Scope(fScope, node.getStartPosition(), node.getLength());
151         return true;
152     }
153     
154     public void endVisit(CatchClause node) {
155         fScope= (Scope)fScopes.remove(fScopes.size() - 1);
156     }
157     
158     public boolean visit(SimpleName node) {
159         if (fIgnoreBinding != null && Bindings.equals(fIgnoreBinding, node.resolveBinding()))
160             return false;
161         if (fIgnoreRange != null && fIgnoreRange.covers(node))
162             return false;
163         fScope.addName(node.getIdentifier());
164         return false;
165     }
166     
167     public boolean visit(QualifiedName node) {
168         // only consider the left most identifier.
169
node.getQualifier().accept(this);
170         return false;
171     }
172     
173     public boolean visit(MethodInvocation node) {
174         Expression receiver= node.getExpression();
175         if (receiver == null) {
176             SimpleName name= node.getName();
177             if (fIgnoreBinding == null || !Bindings.equals(fIgnoreBinding, name.resolveBinding()))
178                 node.getName().accept(this);
179         } else {
180             receiver.accept(this);
181         }
182         accept(node.arguments());
183         return false;
184     }
185     
186     public boolean visit(TypeDeclarationStatement node) {
187         if (node.getAST().apiLevel() == AST.JLS2) {
188             fScope.addName(node.getTypeDeclaration().getName().getIdentifier());
189         } else {
190             fScope.addName(node.getDeclaration().getName().getIdentifier());
191         }
192         return false;
193     }
194     
195     public boolean visit(Block node) {
196         fScopes.add(fScope);
197         fScope= new Scope(fScope, node.getStartPosition(), node.getLength());
198         return true;
199     }
200     
201     public void endVisit(Block node) {
202         fScope= (Scope)fScopes.remove(fScopes.size() - 1);
203     }
204     
205     public boolean visit(ForStatement node) {
206         fScopes.add(fScope);
207         fScope= new Scope(fScope, node.getStartPosition(), node.getLength());
208         return true;
209     }
210     
211     public void endVisit(ForStatement node) {
212         fScope= (Scope)fScopes.remove(fScopes.size() - 1);
213     }
214     
215     private void accept(List JavaDoc list) {
216         int size;
217         if (list == null || (size= list.size()) == 0)
218             return;
219         for (int i= 0; i < size; i++) {
220             ((ASTNode)list.get(i)).accept(this);
221         }
222     }
223 }
224
Popular Tags