--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.corext.refactoring.structure.constraints;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Stack;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.SourceRange;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.ASTRequestor;
+import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
+import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
+import org.eclipse.jdt.core.dom.ArrayAccess;
+import org.eclipse.jdt.core.dom.ArrayCreation;
+import org.eclipse.jdt.core.dom.ArrayInitializer;
+import org.eclipse.jdt.core.dom.ArrayType;
+import org.eclipse.jdt.core.dom.Assignment;
+import org.eclipse.jdt.core.dom.CastExpression;
+import org.eclipse.jdt.core.dom.CatchClause;
+import org.eclipse.jdt.core.dom.ClassInstanceCreation;
+import org.eclipse.jdt.core.dom.Comment;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.ConditionalExpression;
+import org.eclipse.jdt.core.dom.ConstructorInvocation;
+import org.eclipse.jdt.core.dom.EnhancedForStatement;
+import org.eclipse.jdt.core.dom.Expression;
+import org.eclipse.jdt.core.dom.FieldAccess;
+import org.eclipse.jdt.core.dom.FieldDeclaration;
+import org.eclipse.jdt.core.dom.IBinding;
+import org.eclipse.jdt.core.dom.IMethodBinding;
+import org.eclipse.jdt.core.dom.ITypeBinding;
+import org.eclipse.jdt.core.dom.IVariableBinding;
+import org.eclipse.jdt.core.dom.ImportDeclaration;
+import org.eclipse.jdt.core.dom.InstanceofExpression;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.MethodInvocation;
+import org.eclipse.jdt.core.dom.Name;
+import org.eclipse.jdt.core.dom.NullLiteral;
+import org.eclipse.jdt.core.dom.PackageDeclaration;
+import org.eclipse.jdt.core.dom.ParenthesizedExpression;
+import org.eclipse.jdt.core.dom.QualifiedName;
+import org.eclipse.jdt.core.dom.ReturnStatement;
+import org.eclipse.jdt.core.dom.SimpleName;
+import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
+import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
+import org.eclipse.jdt.core.dom.SuperFieldAccess;
+import org.eclipse.jdt.core.dom.SuperMethodInvocation;
+import org.eclipse.jdt.core.dom.ThisExpression;
+import org.eclipse.jdt.core.dom.Type;
+import org.eclipse.jdt.core.dom.TypeLiteral;
+import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
+import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
+import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
+import org.eclipse.jdt.core.search.SearchMatch;
+
+import org.eclipse.jdt.internal.corext.dom.Bindings;
+import org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor;
+import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
+import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup;
+import org.eclipse.jdt.internal.corext.refactoring.typeconstraints.CompilationUnitRange;
+import org.eclipse.jdt.internal.corext.refactoring.typeconstraints2.ConstraintVariable2;
+import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
+import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
+
+/**
+ * Type constraints creator to determine the necessary constraints to replace type occurrences by a given super type.
+ *
+ * @since 3.1
+ */
+public final class SuperTypeConstraintsCreator extends HierarchicalASTVisitor {
+
+ /** The constraint variable property */
+ public static final String PROPERTY_CONSTRAINT_VARIABLE= "cv"; //$NON-NLS-1$
+
+ /**
+ * Returns the original methods of the method hierarchy of the specified method.
+ *
+ * @param binding the method binding
+ * @param type the current type
+ * @param originals the original methods which have already been found (element type: <code>IMethodBinding</code>)
+ * @param implementations <code>true</code> to favor implementation methods, <code>false</code> otherwise
+ */
+ private static void getOriginalMethods(final IMethodBinding binding, final ITypeBinding type, final Collection<IMethodBinding> originals, final boolean implementations) {
+ final ITypeBinding ancestor= type.getSuperclass();
+ if (!implementations) {
+ final ITypeBinding[] types= type.getInterfaces();
+ for (int index= 0; index < types.length; index++)
+ getOriginalMethods(binding, types[index], originals, implementations);
+ if (ancestor != null)
+ getOriginalMethods(binding, ancestor, originals, implementations);
+ }
+ if (implementations && ancestor != null)
+ getOriginalMethods(binding, ancestor, originals, implementations);
+ final IMethodBinding[] methods= type.getDeclaredMethods();
+ IMethodBinding method= null;
+ for (int index= 0; index < methods.length; index++) {
+ method= methods[index];
+ if (!binding.getKey().equals(method.getKey())) {
+ boolean match= false;
+ IMethodBinding current= null;
+ for (final Iterator<IMethodBinding> iterator= originals.iterator(); iterator.hasNext();) {
+ current= iterator.next();
+ if (Bindings.isSubsignature(method, current))
+ match= true;
+ }
+ if (!match && Bindings.isSubsignature(binding, method))
+ originals.add(method);
+ }
+ }
+ }
+
+ /** The current method declarations being processed (element type: <code>MethodDeclaration</code>) */
+ final Stack<MethodDeclaration> fCurrentMethods= new Stack<MethodDeclaration>();
+
+ /** Should instanceof expressions be rewritten? */
+ private final boolean fInstanceOf;
+
+ /** The type constraint model to solve */
+ public final SuperTypeConstraintsModel fModel;
+
+ /**
+ * Creates a new super type constraints creator.
+ *
+ * @param model the model to create the type constraints for
+ * @param instanceofs <code>true</code> to rewrite instanceof expressions, <code>false</code> otherwise
+ */
+ public SuperTypeConstraintsCreator(final SuperTypeConstraintsModel model, final boolean instanceofs) {
+ Assert.isNotNull(model);
+
+ fModel= model;
+ fInstanceOf= instanceofs;
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.ArrayAccess)
+ */
+ @Override
+ public final void endVisit(final ArrayAccess node) {
+ node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, node.getArray().getProperty(PROPERTY_CONSTRAINT_VARIABLE));
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.ArrayCreation)
+ */
+ @Override
+ public final void endVisit(final ArrayCreation node) {
+ final ConstraintVariable2 ancestor= (ConstraintVariable2) node.getType().getProperty(PROPERTY_CONSTRAINT_VARIABLE);
+ ancestor.generated_3319778059208724692(node, this);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.ArrayInitializer)
+ */
+ @Override
+ public final void endVisit(final ArrayInitializer node) {
+ final ITypeBinding binding= node.resolveTypeBinding();
+ if (binding != null && binding.isArray()) {
+ final ConstraintVariable2 ancestor= fModel.createIndependentTypeVariable(binding.getElementType());
+ ancestor.generated_7463163005758190751(node, this);
+ }
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.ArrayType)
+ */
+ @Override
+ public final void endVisit(final ArrayType node) {
+ Type elementType= node.getElementType();
+ final ConstraintVariable2 variable= fModel.createTypeVariable(elementType);
+ if (variable != null) {
+ variable.generated_2436106722252692197(node, elementType);
+ }
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.Assignment)
+ */
+ @Override
+ public final void endVisit(final Assignment node) {
+ final ConstraintVariable2 ancestor= (ConstraintVariable2) node.getLeftHandSide().getProperty(PROPERTY_CONSTRAINT_VARIABLE);
+ final ConstraintVariable2 descendant= (ConstraintVariable2) node.getRightHandSide().getProperty(PROPERTY_CONSTRAINT_VARIABLE);
+ node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, ancestor);
+ if (ancestor != null && descendant != null)
+ fModel.createSubtypeConstraint(descendant, ancestor);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.CastExpression)
+ */
+ @Override
+ public final void endVisit(final CastExpression node) {
+ final ConstraintVariable2 first= (ConstraintVariable2) node.getType().getProperty(PROPERTY_CONSTRAINT_VARIABLE);
+ if (first != null) {
+ node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, first);
+ final ConstraintVariable2 second= (ConstraintVariable2) node.getExpression().getProperty(PROPERTY_CONSTRAINT_VARIABLE);
+ if (second != null)
+ fModel.createCastVariable(node, second);
+ }
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.CatchClause)
+ */
+ @Override
+ public final void endVisit(final CatchClause node) {
+ final SingleVariableDeclaration declaration= node.getException();
+ fModel.generated_3596084942154206346(node, declaration);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.ClassInstanceCreation)
+ */
+ @Override
+ public final void endVisit(final ClassInstanceCreation node) {
+ final IMethodBinding binding= node.resolveConstructorBinding();
+ if (binding != null) {
+ endVisit(node.arguments(), binding);
+ ConstraintVariable2 variable= fModel.generated_6398684183617125146(node);
+ if (variable != null)
+ node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, variable);
+ }
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.ConditionalExpression)
+ */
+ @Override
+ public final void endVisit(final ConditionalExpression node) {
+ ConstraintVariable2 thenVariable= null;
+ fModel.generated_5635755444992102224(node, thenVariable);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.ConstructorInvocation)
+ */
+ @Override
+ public final void endVisit(final ConstructorInvocation node) {
+ final IMethodBinding binding= node.resolveConstructorBinding();
+ if (binding != null)
+ endVisit(node.arguments(), binding);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.FieldAccess)
+ */
+ @Override
+ public final void endVisit(final FieldAccess node) {
+ final IVariableBinding binding= node.resolveFieldBinding();
+ if (binding != null)
+ endVisit(binding, node.getExpression(), node);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.FieldDeclaration)
+ */
+ @Override
+ public final void endVisit(final FieldDeclaration node) {
+ endVisit(node.fragments(), node.getType(), node);
+ }
+
+ /**
+ * End of visit the specified method declaration.
+ *
+ * @param binding the method binding
+ */
+ void endVisit(final IMethodBinding binding) {
+ IMethodBinding method= null;
+ ConstraintVariable2 ancestor= null;
+ fModel.generated_1741477689489230340(this, binding);
+ }
+
+ /**
+ * End of visit the specified method invocation.
+ *
+ * @param binding the method binding
+ * @param descendant the constraint variable of the invocation expression
+ */
+ private void endVisit(final IMethodBinding binding, final ConstraintVariable2 descendant) {
+ ITypeBinding declaring= null;
+ IMethodBinding method= null;
+ final Collection<IMethodBinding> originals= getOriginalMethods(binding);
+ for (final Iterator<IMethodBinding> iterator= originals.iterator(); iterator.hasNext();) {
+ method= iterator.next();
+ declaring= method.getDeclaringClass();
+ fModel.generated_1228220860573994096(descendant, declaring);
+ }
+ }
+
+ /**
+ * End of visit the thrown exception
+ *
+ * @param binding the type binding of the thrown exception
+ * @param node the exception name node
+ */
+ private void endVisit(final ITypeBinding binding, final Name node) {
+ final ConstraintVariable2 variable= fModel.createExceptionVariable(node);
+ if (variable != null)
+ node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, variable);
+ }
+
+ /**
+ * End of visit the field access.
+ *
+ * @param binding the variable binding
+ * @param qualifier the qualifier expression, or <code>null</code>
+ * @param access the access expression
+ */
+ private void endVisit(final IVariableBinding binding, final Expression qualifier, final Expression access) {
+ fModel.generated_1321538627382250556(binding, qualifier, access);
+ }
+
+ /**
+ * End of visit the method argument list.
+ *
+ * @param arguments the arguments (element type: <code>Expression</code>)
+ * @param binding the method binding
+ */
+ private void endVisit(final List<Expression> arguments, final IMethodBinding binding) {
+ fModel.generated_6180728033145346378(arguments, binding);
+ }
+
+ /**
+ * End of visit the variable declaration fragment list.
+ *
+ * @param fragments the fragments (element type: <code>VariableDeclarationFragment</code>)
+ * @param type the type of the fragments
+ * @param parent the parent of the fragment list
+ */
+ private void endVisit(final List<VariableDeclarationFragment> fragments, final Type type, final ASTNode parent) {
+ final ConstraintVariable2 ancestor= (ConstraintVariable2) type.getProperty(PROPERTY_CONSTRAINT_VARIABLE);
+ fModel.generated_9014216741694380625(fragments, parent, ancestor);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.MethodDeclaration)
+ */
+ @Override
+ public final void endVisit(final MethodDeclaration node) {
+ fModel.generated_8452332151086221663(this, node);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.MethodInvocation)
+ */
+ @Override
+ public final void endVisit(final MethodInvocation node) {
+ final IMethodBinding binding= node.resolveMethodBinding();
+ if (binding != null) {
+ endVisit(node, binding);
+ endVisit(node.arguments(), binding);
+ final Expression expression= node.getExpression();
+ if (expression != null) {
+ final ConstraintVariable2 descendant= (ConstraintVariable2) expression.getProperty(PROPERTY_CONSTRAINT_VARIABLE);
+ if (descendant != null)
+ endVisit(binding, descendant);
+ }
+ }
+ }
+
+ /**
+ * End of visit the return type of a method invocation.
+ *
+ * @param invocation the method invocation
+ * @param binding the method binding
+ */
+ private void endVisit(final MethodInvocation invocation, final IMethodBinding binding) {
+ if (!binding.isConstructor()) {
+ final ConstraintVariable2 variable= fModel.createReturnTypeVariable(binding);
+ if (variable != null)
+ invocation.setProperty(PROPERTY_CONSTRAINT_VARIABLE, variable);
+ }
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.NullLiteral)
+ */
+ @Override
+ public final void endVisit(final NullLiteral node) {
+ node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, fModel.createImmutableTypeVariable(node.resolveTypeBinding()));
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.ParenthesizedExpression)
+ */
+ @Override
+ public final void endVisit(final ParenthesizedExpression node) {
+ node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, node.getExpression().getProperty(PROPERTY_CONSTRAINT_VARIABLE));
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.QualifiedName)
+ */
+ @Override
+ public final void endVisit(final QualifiedName node) {
+ final ASTNode parent= node.getParent();
+ final Name qualifier= node.getQualifier();
+ IBinding binding= qualifier.resolveBinding();
+ if (binding instanceof ITypeBinding) {
+ final ConstraintVariable2 variable= fModel.createTypeVariable((ITypeBinding) binding, new CompilationUnitRange(RefactoringASTParser.getCompilationUnit(node), new SourceRange(qualifier.getStartPosition(), qualifier.getLength())));
+ if (variable != null)
+ qualifier.setProperty(PROPERTY_CONSTRAINT_VARIABLE, variable);
+ }
+ binding= node.getName().resolveBinding();
+ if (binding instanceof IVariableBinding && !(parent instanceof ImportDeclaration))
+ endVisit((IVariableBinding) binding, qualifier, node);
+ else if (binding instanceof ITypeBinding && parent instanceof MethodDeclaration)
+ endVisit((ITypeBinding) binding, node);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.ReturnStatement)
+ */
+ @Override
+ public final void endVisit(final ReturnStatement node) {
+ final Expression expression= node.getExpression();
+ if (expression != null) {
+ final ConstraintVariable2 descendant= (ConstraintVariable2) expression.getProperty(PROPERTY_CONSTRAINT_VARIABLE);
+ if (descendant != null) {
+ final MethodDeclaration declaration= fCurrentMethods.peek();
+ if (declaration != null) {
+ final IMethodBinding binding= declaration.resolveBinding();
+ if (binding != null) {
+ final ConstraintVariable2 ancestor= fModel.createReturnTypeVariable(binding);
+ if (ancestor != null) {
+ ancestor.generated_4577479343463029947(node, descendant, this);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.SimpleName)
+ */
+ @Override
+ public final void endVisit(final SimpleName node) {
+ final ASTNode parent= node.getParent();
+ if (!(parent instanceof ImportDeclaration) && !(parent instanceof PackageDeclaration) && !(parent instanceof AbstractTypeDeclaration)) {
+ final IBinding binding= node.resolveBinding();
+ if (binding instanceof IVariableBinding && !(parent instanceof MethodDeclaration))
+ endVisit((IVariableBinding) binding, null, node);
+ else if (binding instanceof ITypeBinding && parent instanceof MethodDeclaration)
+ endVisit((ITypeBinding) binding, node);
+ }
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.SingleVariableDeclaration)
+ */
+ @Override
+ public final void endVisit(final SingleVariableDeclaration node) {
+ final ConstraintVariable2 ancestor= (ConstraintVariable2) node.getType().getProperty(PROPERTY_CONSTRAINT_VARIABLE);
+ if (ancestor != null) {
+ ancestor.generated_8118103395270929895(node, this);
+ }
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.EnhancedForStatement)
+ */
+ @Override
+ public void endVisit(EnhancedForStatement node) {
+ SingleVariableDeclaration parameter= node.getParameter();
+ final ConstraintVariable2 ancestor= (ConstraintVariable2) parameter.getType().getProperty(PROPERTY_CONSTRAINT_VARIABLE);
+ fModel.generated_8726177456238846700(node, parameter, ancestor);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.SuperConstructorInvocation)
+ */
+ @Override
+ public final void endVisit(final SuperConstructorInvocation node) {
+ final IMethodBinding binding= node.resolveConstructorBinding();
+ if (binding != null)
+ endVisit(node.arguments(), binding);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.SuperFieldAccess)
+ */
+ @Override
+ public final void endVisit(final SuperFieldAccess node) {
+ final Name name= node.getName();
+ final IBinding binding= name.resolveBinding();
+ if (binding instanceof IVariableBinding)
+ endVisit((IVariableBinding) binding, null, node);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.SuperMethodInvocation)
+ */
+ @Override
+ public final void endVisit(final SuperMethodInvocation node) {
+ final IMethodBinding superBinding= node.resolveMethodBinding();
+ if (superBinding != null) {
+ endVisit(node.arguments(), superBinding);
+ final MethodDeclaration declaration= fCurrentMethods.peek();
+ if (declaration != null) {
+ fModel.generated_1580866905225090421(node, superBinding, declaration);
+ }
+ }
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.ThisExpression)
+ */
+ @Override
+ public final void endVisit(final ThisExpression node) {
+ final ITypeBinding binding= node.resolveTypeBinding();
+ if (binding != null)
+ node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, fModel.createDeclaringTypeVariable(binding));
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.Type)
+ */
+ @Override
+ public final void endVisit(final Type node) {
+ final ASTNode parent= node.getParent();
+ if (!(parent instanceof AbstractTypeDeclaration) && !(parent instanceof ClassInstanceCreation) && !(parent instanceof TypeLiteral) && (!(parent instanceof InstanceofExpression) || fInstanceOf))
+ node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, fModel.createTypeVariable(node));
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.VariableDeclarationExpression)
+ */
+ @Override
+ public final void endVisit(final VariableDeclarationExpression node) {
+ endVisit(node.fragments(), node.getType(), node);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.VariableDeclarationFragment)
+ */
+ @Override
+ public final void endVisit(final VariableDeclarationFragment node) {
+ final Expression initializer= node.getInitializer();
+ if (initializer != null)
+ node.setProperty(PROPERTY_CONSTRAINT_VARIABLE, initializer.getProperty(PROPERTY_CONSTRAINT_VARIABLE));
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#endVisit(org.eclipse.jdt.core.dom.VariableDeclarationStatement)
+ */
+ @Override
+ public final void endVisit(final VariableDeclarationStatement node) {
+ endVisit(node.fragments(), node.getType(), node);
+ }
+
+ /**
+ * Returns the original methods of the method hierarchy of the specified method.
+ *
+ * @param binding the method binding
+ * @return the original methods (element type: <code>IMethodBinding</code>)
+ */
+ Collection<IMethodBinding> getOriginalMethods(final IMethodBinding binding) {
+ final Collection<IMethodBinding> originals= new ArrayList<IMethodBinding>();
+ final ITypeBinding type= binding.getDeclaringClass();
+ getOriginalMethods(binding, type, originals, false);
+ getOriginalMethods(binding, type, originals, true);
+ if (originals.isEmpty())
+ originals.add(binding);
+ return originals;
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#visit(org.eclipse.jdt.core.dom.AnnotationTypeDeclaration)
+ */
+ @Override
+ public final boolean visit(final AnnotationTypeDeclaration node) {
+ return false;
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#visit(org.eclipse.jdt.core.dom.Comment)
+ */
+ @Override
+ public final boolean visit(final Comment node) {
+ return false;
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#visit(org.eclipse.jdt.core.dom.ImportDeclaration)
+ */
+ @Override
+ public final boolean visit(final ImportDeclaration node) {
+ return false;
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#visit(org.eclipse.jdt.core.dom.MethodDeclaration)
+ */
+ @Override
+ public final boolean visit(final MethodDeclaration node) {
+ fCurrentMethods.push(node);
+ return super.visit(node);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#visit(org.eclipse.jdt.core.dom.PackageDeclaration)
+ */
+ @Override
+ public final boolean visit(final PackageDeclaration node) {
+ return false;
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#visit(org.eclipse.jdt.core.dom.ThisExpression)
+ */
+ @Override
+ public final boolean visit(final ThisExpression node) {
+ return false;
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor#visit(org.eclipse.jdt.core.dom.Type)
+ */
+ @Override
+ public final boolean visit(final Type node) {
+ return false;
+ }
+
+ public int generated_6997570073737353639(final ICompilationUnit subUnit, final CompilationUnit subNode, final IProgressMonitor monitor, int level, final SuperTypeConstraintsModel model, final SuperTypeRefactoringProcessor supertyperefactoringprocessor, final Map<IJavaProject, Set<SearchResultGroup>> firstPass, final Map<IJavaProject, Set<ICompilationUnit>> secondPass, final ASTParser parser, final Map<ICompilationUnit, SearchResultGroup> groups, final Set<ICompilationUnit> processed) {
+ IJavaProject project;
+ Collection<SearchResultGroup> collection;
+ Object element;
+ ICompilationUnit current;
+ SearchResultGroup group;
+ SearchMatch[] matches;
+ Set<ICompilationUnit> units;
+ if (subUnit != null)
+ processed.add(subUnit);
+ model.beginCreation();
+ IProgressMonitor subMonitor= new SubProgressMonitor(monitor, 120);
+ try {
+ final Set<IJavaProject> keySet= firstPass.keySet();
+ subMonitor.beginTask("", keySet.size() * 100); //$NON-NLS-1$
+ subMonitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating);
+ for (final Iterator<IJavaProject> outer= keySet.iterator(); outer.hasNext();) {
+ project= outer.next();
+ collection= firstPass.get(project);
+ if (collection != null) {
+ units= new HashSet<ICompilationUnit>(collection.size());
+ for (final Iterator<SearchResultGroup> inner= collection.iterator(); inner.hasNext();) {
+ group= inner.next();
+ matches= group.getSearchResults();
+ for (int index= 0; index < matches.length; index++) {
+ element= matches[index].getElement();
+ if (element instanceof IMember) {
+ current= ((IMember) element).getCompilationUnit();
+ if (current != null)
+ units.add(current);
+ }
+ }
+ }
+ final List<ICompilationUnit> batches= new ArrayList<ICompilationUnit>(units);
+ final int size= batches.size();
+ final int iterations= (size - 1) / SuperTypeRefactoringProcessor.SIZE_BATCH + 1;
+ final IProgressMonitor subsubMonitor= new SubProgressMonitor(subMonitor, 100);
+ try {
+ subsubMonitor.beginTask("", iterations * 100); //$NON-NLS-1$
+ subsubMonitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating);
+ final Map<String, String> options= RefactoringASTParser.getCompilerOptions(project);
+ for (int index= 0; index < iterations; index++) {
+ final List<ICompilationUnit> iteration= batches.subList(index * SuperTypeRefactoringProcessor.SIZE_BATCH, Math.min(size, (index + 1) * SuperTypeRefactoringProcessor.SIZE_BATCH));
+ parser.setWorkingCopyOwner(supertyperefactoringprocessor.fOwner);
+ parser.setResolveBindings(true);
+ parser.setProject(project);
+ parser.setCompilerOptions(options);
+ final IProgressMonitor subsubsubMonitor= new SubProgressMonitor(subsubMonitor, 100);
+ try {
+ final int count= iteration.size();
+ subsubsubMonitor.beginTask("", count * 100); //$NON-NLS-1$
+ subsubsubMonitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating);
+ parser.createASTs(iteration.toArray(new ICompilationUnit[count]), new String[0], new ASTRequestor() {
+
+ @Override
+ public final void acceptAST(final ICompilationUnit unit, final CompilationUnit node) {
+ if (!processed.contains(unit)) {
+ supertyperefactoringprocessor.performFirstPass(SuperTypeConstraintsCreator.this, secondPass, groups, unit, node, new SubProgressMonitor(subsubsubMonitor, 100));
+ processed.add(unit);
+ } else
+ subsubsubMonitor.worked(100);
+ }
+
+ @Override
+ public final void acceptBinding(final String key, final IBinding binding) {
+ // Do nothing
+ }
+ }, new NullProgressMonitor());
+ } finally {
+ subsubsubMonitor.done();
+ }
+ }
+ } finally {
+ subsubMonitor.done();
+ }
+ }
+ }
+ } finally {
+ firstPass.clear();
+ subMonitor.done();
+ }
+ if (subUnit != null && subNode != null)
+ supertyperefactoringprocessor.performFirstPass(this, secondPass, groups, subUnit, subNode, new SubProgressMonitor(subMonitor, 20));
+ subMonitor= new SubProgressMonitor(monitor, 100);
+ try {
+ final Set<IJavaProject> keySet= secondPass.keySet();
+ subMonitor.beginTask("", keySet.size() * 100); //$NON-NLS-1$
+ subMonitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating);
+ for (final Iterator<IJavaProject> iterator= keySet.iterator(); iterator.hasNext();) {
+ project= iterator.next();
+ if (level == 3 && !JavaModelUtil.is50OrHigher(project))
+ level= 2;
+ Collection<ICompilationUnit> cuCollection= null;
+ cuCollection= secondPass.get(project);
+ if (cuCollection != null) {
+ parser.setWorkingCopyOwner(supertyperefactoringprocessor.fOwner);
+ parser.setResolveBindings(true);
+ parser.setProject(project);
+ parser.setCompilerOptions(RefactoringASTParser.getCompilerOptions(project));
+ final IProgressMonitor subsubMonitor= new SubProgressMonitor(subMonitor, 100);
+ try {
+ subsubMonitor.beginTask("", cuCollection.size() * 100); //$NON-NLS-1$
+ subsubMonitor.setTaskName(RefactoringCoreMessages.SuperTypeRefactoringProcessor_creating);
+ parser.createASTs(cuCollection.toArray(new ICompilationUnit[cuCollection.size()]), new String[0], new ASTRequestor() {
+
+ @Override
+ public final void acceptAST(final ICompilationUnit unit, final CompilationUnit node) {
+ if (!processed.contains(unit))
+ supertyperefactoringprocessor.performSecondPass(SuperTypeConstraintsCreator.this, unit, node, new SubProgressMonitor(subsubMonitor, 100));
+ else
+ subsubMonitor.worked(100);
+ }
+
+ @Override
+ public final void acceptBinding(final String key, final IBinding binding) {
+ // Do nothing
+ }
+ }, new NullProgressMonitor());
+ } finally {
+ subsubMonitor.done();
+ }
+ }
+ }
+ } finally {
+ secondPass.clear();
+ subMonitor.done();
+ }
+ return level;
+ }
+}