1 /*******************************************************************************
2  * Copyright (c) 2000, 2011 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.jdt.internal.corext.refactoring.typeconstraints;
15 
16 import java.util.Arrays;
17 import java.util.LinkedHashSet;
18 import java.util.Set;
19 
20 import org.eclipse.core.runtime.Assert;
21 
22 import org.eclipse.jdt.core.dom.ASTVisitor;
23 import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
24 import org.eclipse.jdt.core.dom.ArrayAccess;
25 import org.eclipse.jdt.core.dom.ArrayCreation;
26 import org.eclipse.jdt.core.dom.ArrayInitializer;
27 import org.eclipse.jdt.core.dom.ArrayType;
28 import org.eclipse.jdt.core.dom.AssertStatement;
29 import org.eclipse.jdt.core.dom.Assignment;
30 import org.eclipse.jdt.core.dom.Block;
31 import org.eclipse.jdt.core.dom.BooleanLiteral;
32 import org.eclipse.jdt.core.dom.BreakStatement;
33 import org.eclipse.jdt.core.dom.CastExpression;
34 import org.eclipse.jdt.core.dom.CatchClause;
35 import org.eclipse.jdt.core.dom.CharacterLiteral;
36 import org.eclipse.jdt.core.dom.ClassInstanceCreation;
37 import org.eclipse.jdt.core.dom.CompilationUnit;
38 import org.eclipse.jdt.core.dom.ConditionalExpression;
39 import org.eclipse.jdt.core.dom.ConstructorInvocation;
40 import org.eclipse.jdt.core.dom.ContinueStatement;
41 import org.eclipse.jdt.core.dom.DoStatement;
42 import org.eclipse.jdt.core.dom.EmptyStatement;
43 import org.eclipse.jdt.core.dom.ExpressionStatement;
44 import org.eclipse.jdt.core.dom.FieldAccess;
45 import org.eclipse.jdt.core.dom.FieldDeclaration;
46 import org.eclipse.jdt.core.dom.ForStatement;
47 import org.eclipse.jdt.core.dom.IfStatement;
48 import org.eclipse.jdt.core.dom.ImportDeclaration;
49 import org.eclipse.jdt.core.dom.InfixExpression;
50 import org.eclipse.jdt.core.dom.Initializer;
51 import org.eclipse.jdt.core.dom.InstanceofExpression;
52 import org.eclipse.jdt.core.dom.Javadoc;
53 import org.eclipse.jdt.core.dom.LabeledStatement;
54 import org.eclipse.jdt.core.dom.MarkerAnnotation;
55 import org.eclipse.jdt.core.dom.MethodDeclaration;
56 import org.eclipse.jdt.core.dom.MethodInvocation;
57 import org.eclipse.jdt.core.dom.NormalAnnotation;
58 import org.eclipse.jdt.core.dom.NullLiteral;
59 import org.eclipse.jdt.core.dom.NumberLiteral;
60 import org.eclipse.jdt.core.dom.PackageDeclaration;
61 import org.eclipse.jdt.core.dom.ParenthesizedExpression;
62 import org.eclipse.jdt.core.dom.PostfixExpression;
63 import org.eclipse.jdt.core.dom.PrefixExpression;
64 import org.eclipse.jdt.core.dom.PrimitiveType;
65 import org.eclipse.jdt.core.dom.QualifiedName;
66 import org.eclipse.jdt.core.dom.ReturnStatement;
67 import org.eclipse.jdt.core.dom.SimpleName;
68 import org.eclipse.jdt.core.dom.SimpleType;
69 import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
70 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
71 import org.eclipse.jdt.core.dom.StringLiteral;
72 import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
73 import org.eclipse.jdt.core.dom.SuperFieldAccess;
74 import org.eclipse.jdt.core.dom.SuperMethodInvocation;
75 import org.eclipse.jdt.core.dom.SwitchCase;
76 import org.eclipse.jdt.core.dom.SwitchStatement;
77 import org.eclipse.jdt.core.dom.SynchronizedStatement;
78 import org.eclipse.jdt.core.dom.ThisExpression;
79 import org.eclipse.jdt.core.dom.ThrowStatement;
80 import org.eclipse.jdt.core.dom.TryStatement;
81 import org.eclipse.jdt.core.dom.TypeDeclaration;
82 import org.eclipse.jdt.core.dom.TypeDeclarationStatement;
83 import org.eclipse.jdt.core.dom.TypeLiteral;
84 import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
85 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
86 import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
87 import org.eclipse.jdt.core.dom.WhileStatement;
88 
89 
90 public final class ConstraintCollector extends ASTVisitor {
91 
92 	private final ConstraintCreator fCreator;
93 	private final Set<ITypeConstraint> fConstraints;
94 
ConstraintCollector()95 	public ConstraintCollector() {
96 		this(new FullConstraintCreator());
97 	}
98 
ConstraintCollector(ConstraintCreator creator)99 	public ConstraintCollector(ConstraintCreator creator) {
100 		Assert.isNotNull(creator);
101 		fCreator= creator;
102 		fConstraints= new LinkedHashSet<>();
103 	}
104 
add(ITypeConstraint[] constraints)105 	private void add(ITypeConstraint[] constraints){
106 		fConstraints.addAll(Arrays.asList(constraints));
107 	}
108 
clear()109 	public void clear(){
110 		fConstraints.clear();
111 	}
112 
getConstraints()113 	public ITypeConstraint[] getConstraints(){
114 		return fConstraints.toArray(new ITypeConstraint[fConstraints.size()]);
115 	}
116 
117 	//------------------------- visit methods -------------------------//
118 
119 	@Override
visit(AnonymousClassDeclaration node)120 	public boolean visit(AnonymousClassDeclaration node) {
121 		add(fCreator.create(node));
122 		return true;
123 	}
124 
125 	@Override
visit(ArrayAccess node)126 	public boolean visit(ArrayAccess node) {
127 		add(fCreator.create(node));
128 		return true;
129 	}
130 
131 	@Override
visit(ArrayCreation node)132 	public boolean visit(ArrayCreation node) {
133 		add(fCreator.create(node));
134 		return true;
135 	}
136 
137 	@Override
visit(ArrayInitializer node)138 	public boolean visit(ArrayInitializer node) {
139 		add(fCreator.create(node));
140 		return true;
141 	}
142 
143 	@Override
visit(ArrayType node)144 	public boolean visit(ArrayType node) {
145 		add(fCreator.create(node));
146 		return true;
147 	}
148 
149 	@Override
visit(AssertStatement node)150 	public boolean visit(AssertStatement node) {
151 		add(fCreator.create(node));
152 		return true;
153 	}
154 
155 	@Override
visit(Assignment node)156 	public boolean visit(Assignment node) {
157 		add(fCreator.create(node));
158 		return true;
159 	}
160 
161 	@Override
visit(Block node)162 	public boolean visit(Block node) {
163 		add(fCreator.create(node));
164 		return true;
165 	}
166 
167 	@Override
visit(BooleanLiteral node)168 	public boolean visit(BooleanLiteral node) {
169 		add(fCreator.create(node));
170 		return true;
171 	}
172 
173 	@Override
visit(BreakStatement node)174 	public boolean visit(BreakStatement node) {
175 		add(fCreator.create(node));
176 		return true;
177 	}
178 
179 	@Override
visit(CastExpression node)180 	public boolean visit(CastExpression node) {
181 		add(fCreator.create(node));
182 		return true;
183 	}
184 
185 	@Override
visit(CatchClause node)186 	public boolean visit(CatchClause node) {
187 		add(fCreator.create(node));
188 		return true;
189 	}
190 
191 	@Override
visit(CharacterLiteral node)192 	public boolean visit(CharacterLiteral node) {
193 		add(fCreator.create(node));
194 		return true;
195 	}
196 
197 	@Override
visit(ClassInstanceCreation node)198 	public boolean visit(ClassInstanceCreation node) {
199 		add(fCreator.create(node));
200 		return true;
201 	}
202 
203 	@Override
visit(CompilationUnit node)204 	public boolean visit(CompilationUnit node) {
205 		add(fCreator.create(node));
206 		return true;
207 	}
208 
209 	@Override
visit(ConditionalExpression node)210 	public boolean visit(ConditionalExpression node) {
211 		add(fCreator.create(node));
212 		return true;
213 	}
214 
215 	@Override
visit(ConstructorInvocation node)216 	public boolean visit(ConstructorInvocation node) {
217 		add(fCreator.create(node));
218 		return true;
219 	}
220 
221 	@Override
visit(ContinueStatement node)222 	public boolean visit(ContinueStatement node) {
223 		add(fCreator.create(node));
224 		return true;
225 	}
226 
227 	@Override
visit(DoStatement node)228 	public boolean visit(DoStatement node) {
229 		add(fCreator.create(node));
230 		return true;
231 	}
232 
233 	@Override
visit(EmptyStatement node)234 	public boolean visit(EmptyStatement node) {
235 		add(fCreator.create(node));
236 		return true;
237 	}
238 
239 	@Override
visit(ExpressionStatement node)240 	public boolean visit(ExpressionStatement node) {
241 		add(fCreator.create(node));
242 		return true;
243 	}
244 
245 	@Override
visit(FieldAccess node)246 	public boolean visit(FieldAccess node) {
247 		add(fCreator.create(node));
248 		return true;
249 	}
250 
251 	@Override
visit(FieldDeclaration node)252 	public boolean visit(FieldDeclaration node) {
253 		add(fCreator.create(node));
254 		return true;
255 	}
256 
257 	@Override
visit(ForStatement node)258 	public boolean visit(ForStatement node) {
259 		add(fCreator.create(node));
260 		return true;
261 	}
262 
263 	@Override
visit(IfStatement node)264 	public boolean visit(IfStatement node) {
265 		add(fCreator.create(node));
266 		return true;
267 	}
268 
269 	@Override
visit(ImportDeclaration node)270 	public boolean visit(ImportDeclaration node) {
271 		add(fCreator.create(node));
272 		return true;
273 	}
274 
275 	@Override
visit(InfixExpression node)276 	public boolean visit(InfixExpression node) {
277 		add(fCreator.create(node));
278 		return true;
279 	}
280 
281 	@Override
visit(Initializer node)282 	public boolean visit(Initializer node) {
283 		add(fCreator.create(node));
284 		return true;
285 	}
286 
287 	@Override
visit(InstanceofExpression node)288 	public boolean visit(InstanceofExpression node) {
289 		add(fCreator.create(node));
290 		return true;
291 	}
292 
293 	@Override
visit(Javadoc node)294 	public boolean visit(Javadoc node) {
295 		add(fCreator.create(node));
296 		return true;
297 	}
298 
299 	@Override
visit(LabeledStatement node)300 	public boolean visit(LabeledStatement node) {
301 		add(fCreator.create(node));
302 		return true;
303 	}
304 
305 	@Override
visit(MarkerAnnotation node)306 	public boolean visit(MarkerAnnotation node) {
307 		return false;
308 	}
309 	@Override
visit(MethodDeclaration node)310 	public boolean visit(MethodDeclaration node) {
311 		add(fCreator.create(node));
312 		return true;
313 	}
314 
315 	@Override
visit(MethodInvocation node)316 	public boolean visit(MethodInvocation node) {
317 		add(fCreator.create(node));
318 		return true;
319 	}
320 	@Override
visit(NormalAnnotation node)321 	public boolean visit(NormalAnnotation node) {
322 		return false;
323 	}
324 	@Override
visit(NullLiteral node)325 	public boolean visit(NullLiteral node) {
326 		add(fCreator.create(node));
327 		return true;
328 	}
329 
330 	@Override
visit(NumberLiteral node)331 	public boolean visit(NumberLiteral node) {
332 		add(fCreator.create(node));
333 		return true;
334 	}
335 
336 	@Override
visit(PackageDeclaration node)337 	public boolean visit(PackageDeclaration node) {
338 		add(fCreator.create(node));
339 		return true;
340 	}
341 
342 	@Override
visit(ParenthesizedExpression node)343 	public boolean visit(ParenthesizedExpression node) {
344 		add(fCreator.create(node));
345 		return true;
346 	}
347 
348 	@Override
visit(PostfixExpression node)349 	public boolean visit(PostfixExpression node) {
350 		add(fCreator.create(node));
351 		return true;
352 	}
353 
354 	@Override
visit(PrefixExpression node)355 	public boolean visit(PrefixExpression node) {
356 		add(fCreator.create(node));
357 		return true;
358 	}
359 
360 	@Override
visit(PrimitiveType node)361 	public boolean visit(PrimitiveType node) {
362 		add(fCreator.create(node));
363 		return true;
364 	}
365 
366 	@Override
visit(QualifiedName node)367 	public boolean visit(QualifiedName node) {
368 		add(fCreator.create(node));
369 		return true;
370 	}
371 
372 	@Override
visit(ReturnStatement node)373 	public boolean visit(ReturnStatement node) {
374 		add(fCreator.create(node));
375 		return true;
376 	}
377 
378 	@Override
visit(SimpleName node)379 	public boolean visit(SimpleName node) {
380 		add(fCreator.create(node));
381 		return true;
382 	}
383 
384 	@Override
visit(SimpleType node)385 	public boolean visit(SimpleType node) {
386 		add(fCreator.create(node));
387 		return true;
388 	}
389 
390 	@Override
visit(SingleMemberAnnotation node)391 	public boolean visit(SingleMemberAnnotation node) {
392 		return false;
393 	}
394 
395 	@Override
visit(SingleVariableDeclaration node)396 	public boolean visit(SingleVariableDeclaration node) {
397 		add(fCreator.create(node));
398 		return true;
399 	}
400 
401 	@Override
visit(StringLiteral node)402 	public boolean visit(StringLiteral node) {
403 		add(fCreator.create(node));
404 		return true;
405 	}
406 
407 	@Override
visit(SuperConstructorInvocation node)408 	public boolean visit(SuperConstructorInvocation node) {
409 		add(fCreator.create(node));
410 		return true;
411 	}
412 
413 	@Override
visit(SuperFieldAccess node)414 	public boolean visit(SuperFieldAccess node) {
415 		add(fCreator.create(node));
416 		return true;
417 	}
418 
419 	@Override
visit(SuperMethodInvocation node)420 	public boolean visit(SuperMethodInvocation node) {
421 		add(fCreator.create(node));
422 		return true;
423 	}
424 
425 	@Override
visit(SwitchCase node)426 	public boolean visit(SwitchCase node) {
427 		add(fCreator.create(node));
428 		return true;
429 	}
430 
431 	@Override
visit(SwitchStatement node)432 	public boolean visit(SwitchStatement node) {
433 		add(fCreator.create(node));
434 		return true;
435 	}
436 
437 	@Override
visit(SynchronizedStatement node)438 	public boolean visit(SynchronizedStatement node) {
439 		add(fCreator.create(node));
440 		return true;
441 	}
442 
443 	@Override
visit(ThisExpression node)444 	public boolean visit(ThisExpression node) {
445 		add(fCreator.create(node));
446 		return true;
447 	}
448 
449 	@Override
visit(ThrowStatement node)450 	public boolean visit(ThrowStatement node) {
451 		add(fCreator.create(node));
452 		return true;
453 	}
454 
455 	@Override
visit(TryStatement node)456 	public boolean visit(TryStatement node) {
457 		add(fCreator.create(node));
458 		return true;
459 	}
460 
461 	@Override
visit(TypeDeclaration node)462 	public boolean visit(TypeDeclaration node) {
463 		add(fCreator.create(node));
464 		return true;
465 
466 		// TODO account for enums and annotations
467 	}
468 
469 	@Override
visit(TypeDeclarationStatement node)470 	public boolean visit(TypeDeclarationStatement node) {
471 		add(fCreator.create(node));
472 		return true;
473 	}
474 
475 	@Override
visit(TypeLiteral node)476 	public boolean visit(TypeLiteral node) {
477 		add(fCreator.create(node));
478 		return true;
479 	}
480 
481 	@Override
visit(VariableDeclarationExpression node)482 	public boolean visit(VariableDeclarationExpression node) {
483 		add(fCreator.create(node));
484 		return true;
485 	}
486 
487 	@Override
visit(VariableDeclarationFragment node)488 	public boolean visit(VariableDeclarationFragment node) {
489 		add(fCreator.create(node));
490 		return true;
491 	}
492 
493 	@Override
visit(VariableDeclarationStatement node)494 	public boolean visit(VariableDeclarationStatement node) {
495 		add(fCreator.create(node));
496 		return true;
497 	}
498 
499 	@Override
visit(WhileStatement node)500 	public boolean visit(WhileStatement node) {
501 		add(fCreator.create(node));
502 		return true;
503 	}
504 }
505