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