KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > refactoring > structure > constraints > SuperTypeConstraintsCreator


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.corext.refactoring.structure.constraints;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Collection JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Stack JavaDoc;
18
19 import org.eclipse.core.runtime.Assert;
20
21 import org.eclipse.jdt.core.dom.ASTNode;
22 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
23 import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
24 import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
25 import org.eclipse.jdt.core.dom.ArrayAccess;
26 import org.eclipse.jdt.core.dom.ArrayCreation;
27 import org.eclipse.jdt.core.dom.ArrayInitializer;
28 import org.eclipse.jdt.core.dom.ArrayType;
29 import org.eclipse.jdt.core.dom.Assignment;
30 import org.eclipse.jdt.core.dom.CastExpression;
31 import org.eclipse.jdt.core.dom.CatchClause;
32 import org.eclipse.jdt.core.dom.ClassInstanceCreation;
33 import org.eclipse.jdt.core.dom.Comment;
34 import org.eclipse.jdt.core.dom.ConditionalExpression;
35 import org.eclipse.jdt.core.dom.ConstructorInvocation;
36 import org.eclipse.jdt.core.dom.Expression;
37 import org.eclipse.jdt.core.dom.FieldAccess;
38 import org.eclipse.jdt.core.dom.FieldDeclaration;
39 import org.eclipse.jdt.core.dom.IBinding;
40 import org.eclipse.jdt.core.dom.IMethodBinding;
41 import org.eclipse.jdt.core.dom.ITypeBinding;
42 import org.eclipse.jdt.core.dom.IVariableBinding;
43 import org.eclipse.jdt.core.dom.ImportDeclaration;
44 import org.eclipse.jdt.core.dom.InstanceofExpression;
45 import org.eclipse.jdt.core.dom.MethodDeclaration;
46 import org.eclipse.jdt.core.dom.MethodInvocation;
47 import org.eclipse.jdt.core.dom.Name;
48 import org.eclipse.jdt.core.dom.NullLiteral;
49 import org.eclipse.jdt.core.dom.PackageDeclaration;
50 import org.eclipse.jdt.core.dom.ParenthesizedExpression;
51 import org.eclipse.jdt.core.dom.QualifiedName;
52 import org.eclipse.jdt.core.dom.ReturnStatement;
53 import org.eclipse.jdt.core.dom.SimpleName;
54 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
55 import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
56 import org.eclipse.jdt.core.dom.SuperFieldAccess;
57 import org.eclipse.jdt.core.dom.SuperMethodInvocation;
58 import org.eclipse.jdt.core.dom.ThisExpression;
59 import org.eclipse.jdt.core.dom.Type;
60 import org.eclipse.jdt.core.dom.TypeLiteral;
61 import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
62 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
63 import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
64
65 import org.eclipse.jdt.internal.corext.SourceRange;
66 import org.eclipse.jdt.internal.corext.dom.Bindings;
67 import org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor;
68 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.CompilationUnitRange;
69 import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ConstraintVariable2;
70 import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
71
72 /**
73  * Type constraints creator to determine the necessary constraints to replace type occurrences by a given super type.
74  *
75  * @since 3.1
76  */

77 public final class SuperTypeConstraintsCreator extends HierarchicalASTVisitor {
78
79     /** The constraint variable property */
80     private static final String JavaDoc PROPERTY_CONSTRAINT_VARIABLE= "cv"; //$NON-NLS-1$
81

82     /**
83      * Returns the original methods of the method hierarchy of the specified method.
84      *
85      * @param binding the method binding
86      * @param type the current type
87      * @param originals the original methods which have already been found (element type: <code>IMethodBinding</code>)
88      * @param implementations <code>true</code> to favor implementation methods, <code>false</code> otherwise
89      */

90     private static void getOriginalMethods(final IMethodBinding binding, final ITypeBinding type, final Collection JavaDoc originals, final boolean implementations) {
91         final ITypeBinding ancestor= type.getSuperclass();
92         if (!implementations) {
93             final ITypeBinding[] types= type.getInterfaces();
94             for (int index= 0; index < types.length; index++)
95                 getOriginalMethods(binding, types[index], originals, implementations);
96             if (ancestor != null)
97                 getOriginalMethods(binding, ancestor, originals, implementations);
98         }
99         if (implementations && ancestor != null)
100             getOriginalMethods(binding, ancestor, originals, implementations);
101         final IMethodBinding[] methods= type.getDeclaredMethods();
102         IMethodBinding method= null;
103         for (int index= 0; index < methods.length; index++) {
104             method= methods[index];
105             if (!binding.getKey().equals(method.getKey())) {
106                 boolean match= false;
107                 IMethodBinding current= null;
108                 for (final Iterator JavaDoc iterator= originals.iterator(); iterator.hasNext();) {
109                     current= (IMethodBinding) iterator.next();
110                     if (Bindings.areOverriddenMethods(method, current))
111                         match= true;
112                 }
113                 if (!match && Bindings.areOverriddenMethods(binding, method))
114                     originals.add(method);
115             }
116         }
117     }
118
119     /** The current method declarations being processed (element type: <code>MethodDeclaration</code>) */
120     private final Stack JavaDoc fCurrentMethods= new Stack JavaDoc();
121
122     /** Should instanceof expressions be rewritten? */
123     private final boolean fInstanceOf;
124
125     /** The type constraint model to solve */
126     private final SuperTypeConstraintsModel fModel;
127
128     /**
129      * Creates a new super type constraints creator.
130      *
131      * @param model the model to create the type constraints for
132      * @param instanceofs <code>true</code> to rewrite instanceof expressions, <code>false</code> otherwise
133      */

134     public SuperTypeConstraintsCreator(final SuperTypeConstraintsModel model, final boolean instanceofs) {
135         Assert.isNotNull(model);
136
137         fModel= model;
138         fInstanceOf= instanceofs;
139     }
140
141     /*
142      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.ArrayAccess)
143      */

144     public final void endVisit(final ArrayAccess node) {
145         node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, node.getArray().getProperty(PROPERTY_CONSTRAINT_VARIABLE));
146     }
147
148     /*
149      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.ArrayCreation)
150      */

151     public final void endVisit(final ArrayCreation node) {
152         final ConstraintVariable2 ancestor= (ConstraintVariable2) node.getType().getProperty(PROPERTY_CONSTRAINT_VARIABLE);
153         node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, ancestor);
154         final ArrayInitializer initializer= node.getInitializer();
155         if (initializer != null) {
156             final ConstraintVariable2 descendant= (ConstraintVariable2) initializer.getProperty(PROPERTY_CONSTRAINT_VARIABLE);
157             if (descendant != null)
158                 fModel.createSubtypeConstraint(descendant, ancestor);
159         }
160     }
161
162     /*
163      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.ArrayInitializer)
164      */

165     public final void endVisit(final ArrayInitializer node) {
166         final ITypeBinding binding= node.resolveTypeBinding();
167         if (binding != null && binding.isArray()) {
168             final ConstraintVariable2 ancestor= fModel.createIndependentTypeVariable(binding.getElementType());
169             node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, ancestor);
170             Expression expression= null;
171             ConstraintVariable2 descendant= null;
172             final List JavaDoc expressions= node.expressions();
173             for (int index= 0; index < expressions.size(); index++) {
174                 expression= (Expression) expressions.get(index);
175                 descendant= (ConstraintVariable2) expression.getProperty(PROPERTY_CONSTRAINT_VARIABLE);
176                 if (descendant != null)
177                     fModel.createSubtypeConstraint(descendant, ancestor);
178             }
179         }
180     }
181
182     /*
183      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.ArrayType)
184      */

185     public final void endVisit(final ArrayType node) {
186         ArrayType array= null;
187         Type component= node.getComponentType();
188         while (component instanceof ArrayType) {
189             array= (ArrayType) component;
190             component= array.getComponentType();
191         }
192         final ConstraintVariable2 variable= fModel.createTypeVariable(component);
193         if (variable != null) {
194             component.setProperty(PROPERTY_CONSTRAINT_VARIABLE, variable);
195             node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, variable);
196         }
197     }
198
199     /*
200      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.Assignment)
201      */

202     public final void endVisit(final Assignment node) {
203         final ConstraintVariable2 ancestor= (ConstraintVariable2) node.getLeftHandSide().getProperty(PROPERTY_CONSTRAINT_VARIABLE);
204         final ConstraintVariable2 descendant= (ConstraintVariable2) node.getRightHandSide().getProperty(PROPERTY_CONSTRAINT_VARIABLE);
205         node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, ancestor);
206         if (ancestor != null && descendant != null)
207             fModel.createSubtypeConstraint(descendant, ancestor);
208     }
209
210     /*
211      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.CastExpression)
212      */

213     public final void endVisit(final CastExpression node) {
214         final ConstraintVariable2 first= (ConstraintVariable2) node.getType().getProperty(PROPERTY_CONSTRAINT_VARIABLE);
215         if (first != null) {
216             node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, first);
217             final ConstraintVariable2 second= (ConstraintVariable2) node.getExpression().getProperty(PROPERTY_CONSTRAINT_VARIABLE);
218             if (second != null)
219                 fModel.createCastVariable(node, second);
220         }
221     }
222
223     /*
224      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.CatchClause)
225      */

226     public final void endVisit(final CatchClause node) {
227         final SingleVariableDeclaration declaration= node.getException();
228         if (declaration != null) {
229             final ConstraintVariable2 descendant= (ConstraintVariable2) declaration.getProperty(PROPERTY_CONSTRAINT_VARIABLE);
230             if (descendant != null) {
231                 final ITypeBinding binding= node.getAST().resolveWellKnownType("java.lang.Throwable"); //$NON-NLS-1$
232
if (binding != null) {
233                     final ConstraintVariable2 ancestor= fModel.createImmutableTypeVariable(binding);
234                     if (ancestor != null)
235                         fModel.createSubtypeConstraint(descendant, ancestor);
236                 }
237             }
238         }
239     }
240
241     /*
242      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.ClassInstanceCreation)
243      */

244     public final void endVisit(final ClassInstanceCreation node) {
245         final IMethodBinding binding= node.resolveConstructorBinding();
246         if (binding != null) {
247             endVisit(node.arguments(), binding);
248             ConstraintVariable2 variable= null;
249             final AnonymousClassDeclaration declaration= node.getAnonymousClassDeclaration();
250             if (declaration != null) {
251                 final ITypeBinding type= declaration.resolveBinding();
252                 if (type != null)
253                     variable= fModel.createImmutableTypeVariable(type);
254             } else {
255                 final ITypeBinding type= node.resolveTypeBinding();
256                 if (type != null)
257                     variable= fModel.createImmutableTypeVariable(type);
258             }
259             if (variable != null)
260                 node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, variable);
261         }
262     }
263
264     /*
265      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.ConditionalExpression)
266      */

267     public final void endVisit(final ConditionalExpression node) {
268         ConstraintVariable2 thenVariable= null;
269         ConstraintVariable2 elseVariable= null;
270         final Expression thenExpression= node.getThenExpression();
271         if (thenExpression != null)
272             thenVariable= (ConstraintVariable2) thenExpression.getProperty(PROPERTY_CONSTRAINT_VARIABLE);
273         final Expression elseExpression= node.getElseExpression();
274         if (elseExpression != null)
275             elseVariable= (ConstraintVariable2) elseExpression.getProperty(PROPERTY_CONSTRAINT_VARIABLE);
276         ITypeBinding binding= node.resolveTypeBinding();
277         if (binding != null) {
278             if (binding.isArray())
279                 binding= binding.getElementType();
280             final ConstraintVariable2 ancestor= fModel.createIndependentTypeVariable(binding);
281             if (ancestor != null) {
282                 node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, ancestor);
283                 if (thenVariable != null)
284                     fModel.createSubtypeConstraint(thenVariable, ancestor);
285                 if (elseVariable != null)
286                     fModel.createSubtypeConstraint(elseVariable, ancestor);
287                 if (thenVariable != null && elseVariable != null)
288                     fModel.createConditionalTypeConstraint(ancestor, thenVariable, elseVariable);
289             }
290         }
291     }
292
293     /*
294      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.ConstructorInvocation)
295      */

296     public final void endVisit(final ConstructorInvocation node) {
297         final IMethodBinding binding= node.resolveConstructorBinding();
298         if (binding != null)
299             endVisit(node.arguments(), binding);
300     }
301
302     /*
303      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.FieldAccess)
304      */

305     public final void endVisit(final FieldAccess node) {
306         final IVariableBinding binding= node.resolveFieldBinding();
307         if (binding != null)
308             endVisit(binding, node.getExpression(), node);
309     }
310
311     /*
312      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.FieldDeclaration)
313      */

314     public final void endVisit(final FieldDeclaration node) {
315         endVisit(node.fragments(), node.getType(), node);
316     }
317
318     /**
319      * End of visit the specified method declaration.
320      *
321      * @param binding the method binding
322      */

323     private void endVisit(final IMethodBinding binding) {
324         IMethodBinding method= null;
325         ConstraintVariable2 ancestor= null;
326         final ConstraintVariable2 descendant= fModel.createReturnTypeVariable(binding);
327         if (descendant != null) {
328             final Collection JavaDoc originals= getOriginalMethods(binding);
329             for (final Iterator JavaDoc iterator= originals.iterator(); iterator.hasNext();) {
330                 method= (IMethodBinding) iterator.next();
331                 if (!method.getKey().equals(binding.getKey())) {
332                     ancestor= fModel.createReturnTypeVariable(method);
333                     if (ancestor != null)
334                         fModel.createCovariantTypeConstraint(descendant, ancestor);
335                 }
336             }
337         }
338     }
339
340     /**
341      * End of visit the specified method invocation.
342      *
343      * @param binding the method binding
344      * @param descendant the constraint variable of the invocation expression
345      */

346     private void endVisit(final IMethodBinding binding, final ConstraintVariable2 descendant) {
347         ITypeBinding declaring= null;
348         IMethodBinding method= null;
349         final Collection JavaDoc originals= getOriginalMethods(binding);
350         for (final Iterator JavaDoc iterator= originals.iterator(); iterator.hasNext();) {
351             method= (IMethodBinding) iterator.next();
352             declaring= method.getDeclaringClass();
353             if (declaring != null) {
354                 final ConstraintVariable2 ancestor= fModel.createDeclaringTypeVariable(declaring);
355                 if (ancestor != null)
356                     fModel.createSubtypeConstraint(descendant, ancestor);
357             }
358         }
359     }
360
361     /**
362      * End of visit the thrown exception
363      *
364      * @param binding the type binding of the thrown exception
365      * @param node the exception name node
366      */

367     private void endVisit(final ITypeBinding binding, final Name node) {
368         final ConstraintVariable2 variable= fModel.createExceptionVariable(node);
369         if (variable != null)
370             node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, variable);
371     }
372
373     /**
374      * End of visit the field access.
375      *
376      * @param binding the variable binding
377      * @param qualifier the qualifier expression, or <code>null</code>
378      * @param access the access expression
379      */

380     private void endVisit(final IVariableBinding binding, final Expression qualifier, final Expression access) {
381         access.setProperty(PROPERTY_CONSTRAINT_VARIABLE, fModel.createVariableVariable(binding));
382         if (qualifier != null) {
383             final ITypeBinding type= binding.getDeclaringClass();
384             if (type != null) {
385                 // array.length does not have a declaring class
386
final ConstraintVariable2 ancestor= fModel.createDeclaringTypeVariable(type);
387                 if (ancestor != null) {
388                     final ConstraintVariable2 descendant= (ConstraintVariable2) qualifier.getProperty(PROPERTY_CONSTRAINT_VARIABLE);
389                     if (descendant != null)
390                         fModel.createSubtypeConstraint(descendant, ancestor);
391                 }
392             }
393         }
394     }
395
396     /**
397      * End of visit the method argument list.
398      *
399      * @param arguments the arguments (element type: <code>Expression</code>)
400      * @param binding the method binding
401      */

402     private void endVisit(final List JavaDoc arguments, final IMethodBinding binding) {
403         Expression expression= null;
404         ConstraintVariable2 ancestor= null;
405         ConstraintVariable2 descendant= null;
406         for (int index= 0; index < arguments.size(); index++) {
407             expression= (Expression) arguments.get(index);
408             descendant= (ConstraintVariable2) expression.getProperty(PROPERTY_CONSTRAINT_VARIABLE);
409             ancestor= fModel.createMethodParameterVariable(binding, index);
410             if (ancestor != null && descendant != null)
411                 fModel.createSubtypeConstraint(descendant, ancestor);
412         }
413     }
414
415     /**
416      * End of visit the variable declaration fragment list.
417      *
418      * @param fragments the fragments (element type: <code>VariableDeclarationFragment</code>)
419      * @param type the type of the fragments
420      * @param parent the parent of the fragment list
421      */

422     private void endVisit(final List JavaDoc fragments, final Type type, final ASTNode parent) {
423         final ConstraintVariable2 ancestor= (ConstraintVariable2) type.getProperty(PROPERTY_CONSTRAINT_VARIABLE);
424         if (ancestor != null) {
425             IVariableBinding binding= null;
426             ConstraintVariable2 descendant= null;
427             VariableDeclarationFragment fragment= null;
428             for (int index= 0; index < fragments.size(); index++) {
429                 fragment= (VariableDeclarationFragment) fragments.get(index);
430                 descendant= (ConstraintVariable2) fragment.getProperty(PROPERTY_CONSTRAINT_VARIABLE);
431                 if (descendant != null)
432                     fModel.createSubtypeConstraint(descendant, ancestor);
433                 binding= fragment.resolveBinding();
434                 if (binding != null) {
435                     descendant= fModel.createVariableVariable(binding);
436                     if (descendant != null)
437                         fModel.createEqualityConstraint(ancestor, descendant);
438                 }
439             }
440             parent.setProperty(PROPERTY_CONSTRAINT_VARIABLE, ancestor);
441         }
442     }
443
444     /*
445      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.MethodDeclaration)
446      */

447     public final void endVisit(final MethodDeclaration node) {
448         fCurrentMethods.pop();
449         final IMethodBinding binding= node.resolveBinding();
450         if (binding != null) {
451             if (!binding.isConstructor()) {
452                 final Type type= node.getReturnType2();
453                 if (type != null) {
454                     final ConstraintVariable2 first= fModel.createReturnTypeVariable(binding);
455                     final ConstraintVariable2 second= (ConstraintVariable2) type.getProperty(PROPERTY_CONSTRAINT_VARIABLE);
456                     if (first != null) {
457                         if (second != null)
458                             fModel.createEqualityConstraint(first, second);
459                         endVisit(binding);
460                     }
461                 }
462             }
463             ConstraintVariable2 ancestor= null;
464             ConstraintVariable2 descendant= null;
465             IVariableBinding variable= null;
466             final List JavaDoc parameters= node.parameters();
467             if (!parameters.isEmpty()) {
468                 final Collection JavaDoc originals= getOriginalMethods(binding);
469                 SingleVariableDeclaration declaration= null;
470                 for (int index= 0; index < parameters.size(); index++) {
471                     declaration= (SingleVariableDeclaration) parameters.get(index);
472                     ancestor= fModel.createMethodParameterVariable(binding, index);
473                     if (ancestor != null) {
474                         descendant= (ConstraintVariable2) declaration.getType().getProperty(PROPERTY_CONSTRAINT_VARIABLE);
475                         if (descendant != null)
476                             fModel.createEqualityConstraint(descendant, ancestor);
477                         variable= declaration.resolveBinding();
478                         if (variable != null) {
479                             descendant= fModel.createVariableVariable(variable);
480                             if (descendant != null)
481                                 fModel.createEqualityConstraint(ancestor, descendant);
482                         }
483                         IMethodBinding method= null;
484                         for (final Iterator JavaDoc iterator= originals.iterator(); iterator.hasNext();) {
485                             method= (IMethodBinding) iterator.next();
486                             if (!method.getKey().equals(binding.getKey())) {
487                                 descendant= fModel.createMethodParameterVariable(method, index);
488                                 if (descendant != null)
489                                     fModel.createEqualityConstraint(ancestor, descendant);
490                             }
491                         }
492                     }
493                 }
494             }
495             final List JavaDoc exceptions= node.thrownExceptions();
496             if (!exceptions.isEmpty()) {
497                 final ITypeBinding throwable= node.getAST().resolveWellKnownType("java.lang.Throwable"); //$NON-NLS-1$
498
if (throwable != null) {
499                     ancestor= fModel.createImmutableTypeVariable(throwable);
500                     if (ancestor != null) {
501                         Name exception= null;
502                         for (int index= 0; index < exceptions.size(); index++) {
503                             exception= (Name) exceptions.get(index);
504                             descendant= (ConstraintVariable2) exception.getProperty(PROPERTY_CONSTRAINT_VARIABLE);
505                             if (descendant != null)
506                                 fModel.createSubtypeConstraint(descendant, ancestor);
507                         }
508                     }
509                 }
510             }
511         }
512     }
513
514     /*
515      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.MethodInvocation)
516      */

517     public final void endVisit(final MethodInvocation node) {
518         final IMethodBinding binding= node.resolveMethodBinding();
519         if (binding != null) {
520             endVisit(node, binding);
521             endVisit(node.arguments(), binding);
522             final Expression expression= node.getExpression();
523             if (expression != null) {
524                 final ConstraintVariable2 descendant= (ConstraintVariable2) expression.getProperty(PROPERTY_CONSTRAINT_VARIABLE);
525                 if (descendant != null)
526                     endVisit(binding, descendant);
527             }
528         }
529     }
530
531     /**
532      * End of visit the return type of a method invocation.
533      *
534      * @param invocation the method invocation
535      * @param binding the method binding
536      */

537     private void endVisit(final MethodInvocation invocation, final IMethodBinding binding) {
538         if (!binding.isConstructor()) {
539             final ConstraintVariable2 variable= fModel.createReturnTypeVariable(binding);
540             if (variable != null)
541                 invocation.setProperty(PROPERTY_CONSTRAINT_VARIABLE, variable);
542         }
543     }
544
545     /*
546      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.NullLiteral)
547      */

548     public final void endVisit(final NullLiteral node) {
549         node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, fModel.createImmutableTypeVariable(node.resolveTypeBinding()));
550     }
551
552     /*
553      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.ParenthesizedExpression)
554      */

555     public final void endVisit(final ParenthesizedExpression node) {
556         node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, node.getExpression().getProperty(PROPERTY_CONSTRAINT_VARIABLE));
557     }
558
559     /*
560      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.QualifiedName)
561      */

562     public final void endVisit(final QualifiedName node) {
563         final ASTNode parent= node.getParent();
564         final Name qualifier= node.getQualifier();
565         IBinding binding= qualifier.resolveBinding();
566         if (binding instanceof ITypeBinding) {
567             final ConstraintVariable2 variable= fModel.createTypeVariable((ITypeBinding) binding, new CompilationUnitRange(RefactoringASTParser.getCompilationUnit(node), new SourceRange(qualifier.getStartPosition(), qualifier.getLength())));
568             if (variable != null)
569                 qualifier.setProperty(PROPERTY_CONSTRAINT_VARIABLE, variable);
570         }
571         binding= node.getName().resolveBinding();
572         if (binding instanceof IVariableBinding && !(parent instanceof ImportDeclaration))
573             endVisit((IVariableBinding) binding, qualifier, node);
574         else if (binding instanceof ITypeBinding && parent instanceof MethodDeclaration)
575             endVisit((ITypeBinding) binding, node);
576     }
577
578     /*
579      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.ReturnStatement)
580      */

581     public final void endVisit(final ReturnStatement node) {
582         final Expression expression= node.getExpression();
583         if (expression != null) {
584             final ConstraintVariable2 descendant= (ConstraintVariable2) expression.getProperty(PROPERTY_CONSTRAINT_VARIABLE);
585             if (descendant != null) {
586                 final MethodDeclaration declaration= (MethodDeclaration) fCurrentMethods.peek();
587                 if (declaration != null) {
588                     final IMethodBinding binding= declaration.resolveBinding();
589                     if (binding != null) {
590                         final ConstraintVariable2 ancestor= fModel.createReturnTypeVariable(binding);
591                         if (ancestor != null) {
592                             node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, ancestor);
593                             fModel.createSubtypeConstraint(descendant, ancestor);
594                         }
595                     }
596                 }
597             }
598         }
599     }
600
601     /*
602      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.SimpleName)
603      */

604     public final void endVisit(final SimpleName node) {
605         final ASTNode parent= node.getParent();
606         if (!(parent instanceof ImportDeclaration) && !(parent instanceof PackageDeclaration) && !(parent instanceof AbstractTypeDeclaration)) {
607             final IBinding binding= node.resolveBinding();
608             if (binding instanceof IVariableBinding && !(parent instanceof MethodDeclaration))
609                 endVisit((IVariableBinding) binding, null, node);
610             else if (binding instanceof ITypeBinding && parent instanceof MethodDeclaration)
611                 endVisit((ITypeBinding) binding, node);
612         }
613     }
614
615     /*
616      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.SingleVariableDeclaration)
617      */

618     public final void endVisit(final SingleVariableDeclaration node) {
619         final ConstraintVariable2 ancestor= (ConstraintVariable2) node.getType().getProperty(PROPERTY_CONSTRAINT_VARIABLE);
620         if (ancestor != null) {
621             node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, ancestor);
622             final Expression expression= node.getInitializer();
623             if (expression != null) {
624                 final ConstraintVariable2 descendant= (ConstraintVariable2) expression.getProperty(PROPERTY_CONSTRAINT_VARIABLE);
625                 if (descendant != null)
626                     fModel.createSubtypeConstraint(descendant, ancestor);
627             }
628         }
629     }
630
631     /*
632      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.SuperConstructorInvocation)
633      */

634     public final void endVisit(final SuperConstructorInvocation node) {
635         final IMethodBinding binding= node.resolveConstructorBinding();
636         if (binding != null)
637             endVisit(node.arguments(), binding);
638     }
639
640     /*
641      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.SuperFieldAccess)
642      */

643     public final void endVisit(final SuperFieldAccess node) {
644         final Name name= node.getName();
645         final IBinding binding= name.resolveBinding();
646         if (binding instanceof IVariableBinding)
647             endVisit((IVariableBinding) binding, null, node);
648     }
649
650     /*
651      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.SuperMethodInvocation)
652      */

653     public final void endVisit(final SuperMethodInvocation node) {
654         final IMethodBinding superBinding= node.resolveMethodBinding();
655         if (superBinding != null) {
656             endVisit(node.arguments(), superBinding);
657             final MethodDeclaration declaration= (MethodDeclaration) fCurrentMethods.peek();
658             if (declaration != null) {
659                 final IMethodBinding subBinding= declaration.resolveBinding();
660                 if (subBinding != null) {
661                     final ConstraintVariable2 ancestor= fModel.createReturnTypeVariable(superBinding);
662                     if (ancestor != null) {
663                         node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, ancestor);
664                         final ConstraintVariable2 descendant= fModel.createReturnTypeVariable(subBinding);
665                         if (descendant != null)
666                             fModel.createEqualityConstraint(descendant, ancestor);
667                     }
668                 }
669             }
670         }
671     }
672
673     /*
674      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.ThisExpression)
675      */

676     public final void endVisit(final ThisExpression node) {
677         final ITypeBinding binding= node.resolveTypeBinding();
678         if (binding != null)
679             node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, fModel.createDeclaringTypeVariable(binding));
680     }
681
682     /*
683      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.Type)
684      */

685     public final void endVisit(final Type node) {
686         final ASTNode parent= node.getParent();
687         if (!(parent instanceof AbstractTypeDeclaration) && !(parent instanceof ClassInstanceCreation) && !(parent instanceof TypeLiteral) && (!(parent instanceof InstanceofExpression) || fInstanceOf))
688             node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, fModel.createTypeVariable(node));
689     }
690
691     /*
692      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.VariableDeclarationExpression)
693      */

694     public final void endVisit(final VariableDeclarationExpression node) {
695         endVisit(node.fragments(), node.getType(), node);
696     }
697
698     /*
699      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.VariableDeclarationFragment)
700      */

701     public final void endVisit(final VariableDeclarationFragment node) {
702         final Expression initializer= node.getInitializer();
703         if (initializer != null)
704             node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, initializer.getProperty(PROPERTY_CONSTRAINT_VARIABLE));
705     }
706
707     /*
708      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.VariableDeclarationStatement)
709      */

710     public final void endVisit(final VariableDeclarationStatement node) {
711         endVisit(node.fragments(), node.getType(), node);
712     }
713
714     /**
715      * Returns the original methods of the method hierarchy of the specified method.
716      *
717      * @param binding the method binding
718      * @return the original methods (element type: <code>IMethodBinding</code>)
719      */

720     private Collection JavaDoc getOriginalMethods(final IMethodBinding binding) {
721         final Collection JavaDoc originals= new ArrayList JavaDoc();
722         final ITypeBinding type= binding.getDeclaringClass();
723         getOriginalMethods(binding, type, originals, false);
724         getOriginalMethods(binding, type, originals, true);
725         if (originals.isEmpty())
726             originals.add(binding);
727         return originals;
728     }
729
730     /*
731      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#visit(org.eclipse.jdt.core.dom.AnnotationTypeDeclaration)
732      */

733     public final boolean visit(final AnnotationTypeDeclaration node) {
734         return false;
735     }
736
737     /*
738      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#visit(org.eclipse.jdt.core.dom.Comment)
739      */

740     public final boolean visit(final Comment node) {
741         return false;
742     }
743
744     /*
745      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#visit(org.eclipse.jdt.core.dom.ImportDeclaration)
746      */

747     public final boolean visit(final ImportDeclaration node) {
748         return false;
749     }
750
751     /*
752      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#visit(org.eclipse.jdt.core.dom.MethodDeclaration)
753      */

754     public final boolean visit(final MethodDeclaration node) {
755         fCurrentMethods.push(node);
756         return super.visit(node);
757     }
758
759     /*
760      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#visit(org.eclipse.jdt.core.dom.PackageDeclaration)
761      */

762     public final boolean visit(final PackageDeclaration node) {
763         return false;
764     }
765
766     /*
767      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#visit(org.eclipse.jdt.core.dom.ThisExpression)
768      */

769     public final boolean visit(final ThisExpression node) {
770         return false;
771     }
772
773     /*
774      * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#visit(org.eclipse.jdt.core.dom.Type)
775      */

776     public final boolean visit(final Type node) {
777         return false;
778     }
779 }
780
Popular Tags