| /******************************************************************************* |
| * Copyright (c) 2000, 2006 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.rename; |
| |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.SubProgressMonitor; |
| |
| import org.eclipse.ltk.core.refactoring.RefactoringStatus; |
| import org.eclipse.ltk.core.refactoring.RefactoringStatusContext; |
| |
| import org.eclipse.jdt.core.IMethod; |
| import org.eclipse.jdt.core.IType; |
| import org.eclipse.jdt.core.ITypeHierarchy; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jdt.core.dom.IMethodBinding; |
| import org.eclipse.jdt.core.dom.Modifier; |
| |
| import org.eclipse.jdt.internal.corext.Corext; |
| import org.eclipse.jdt.internal.corext.refactoring.Checks; |
| import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; |
| import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext; |
| import org.eclipse.jdt.internal.corext.refactoring.base.RefactoringStatusCodes; |
| import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil; |
| import org.eclipse.jdt.internal.corext.util.JavaModelUtil; |
| import org.eclipse.jdt.internal.corext.util.JdtFlags; |
| import org.eclipse.jdt.internal.corext.util.Messages; |
| import org.eclipse.jdt.internal.corext.util.MethodOverrideTester; |
| |
| public class MethodChecks { |
| |
| //no instances |
| private MethodChecks(){ |
| } |
| |
| public static boolean isVirtual(IMethod method) throws JavaModelException { |
| if (method.isConstructor()) |
| return false; |
| if (JdtFlags.isPrivate(method)) |
| return false; |
| if (JdtFlags.isStatic(method)) |
| return false; |
| return true; |
| } |
| |
| public static boolean isVirtual(IMethodBinding methodBinding){ |
| if (methodBinding.isConstructor()) |
| return false; |
| if (Modifier.isPrivate(methodBinding.getModifiers())) //TODO is this enough? |
| return false; |
| if (Modifier.isStatic(methodBinding.getModifiers())) //TODO is this enough? |
| return false; |
| return true; |
| } |
| |
| public static RefactoringStatus checkIfOverridesAnother(IMethod method, ITypeHierarchy hierarchy) throws JavaModelException { |
| IMethod overrides= MethodChecks.overridesAnotherMethod(method, hierarchy); |
| if (overrides == null) |
| return null; |
| |
| RefactoringStatusContext context= JavaStatusContext.create(overrides); |
| String message= Messages.format(RefactoringCoreMessages.MethodChecks_overrides, |
| new String[]{JavaElementUtil.createMethodSignature(overrides), JavaModelUtil.getFullyQualifiedName(overrides.getDeclaringType())}); |
| return RefactoringStatus.createStatus(RefactoringStatus.FATAL, message, context, Corext.getPluginId(), RefactoringStatusCodes.OVERRIDES_ANOTHER_METHOD, overrides); |
| } |
| |
| /** |
| * Checks if the given method is declared in an interface. If the method's declaring type |
| * is an interface the method returns <code>false</code> if it is only declared in that |
| * interface. |
| */ |
| public static RefactoringStatus checkIfComesFromInterface(IMethod method, ITypeHierarchy hierarchy, IProgressMonitor monitor) throws JavaModelException { |
| IMethod inInterface= MethodChecks.isDeclaredInInterface(method, hierarchy, monitor); |
| |
| if (inInterface == null) |
| return null; |
| |
| RefactoringStatusContext context= JavaStatusContext.create(inInterface); |
| String message= Messages.format(RefactoringCoreMessages.MethodChecks_implements, |
| new String[]{JavaElementUtil.createMethodSignature(inInterface), JavaModelUtil.getFullyQualifiedName(inInterface.getDeclaringType())}); |
| return RefactoringStatus.createStatus(RefactoringStatus.FATAL, message, context, Corext.getPluginId(), RefactoringStatusCodes.METHOD_DECLARED_IN_INTERFACE, inInterface); |
| } |
| |
| /** |
| * Checks if the given method is declared in an interface. If the method's declaring type |
| * is an interface the method returns <code>false</code> if it is only declared in that |
| * interface. |
| */ |
| public static IMethod isDeclaredInInterface(IMethod method, ITypeHierarchy hierarchy, IProgressMonitor monitor) throws JavaModelException { |
| Assert.isTrue(isVirtual(method)); |
| IProgressMonitor subMonitor= new SubProgressMonitor(monitor, 1); |
| try { |
| IType[] classes= hierarchy.getAllClasses(); |
| subMonitor.beginTask("", classes.length); //$NON-NLS-1$ |
| for (int i= 0; i < classes.length; i++) { |
| final IType clazz= classes[i]; |
| IType[] superinterfaces= null; |
| if (clazz.equals(hierarchy.getType())) |
| superinterfaces= hierarchy.getAllSuperInterfaces(clazz); |
| else |
| superinterfaces= clazz.newSupertypeHierarchy(new SubProgressMonitor(subMonitor, 1)).getAllSuperInterfaces(clazz); |
| for (int j= 0; j < superinterfaces.length; j++) { |
| IMethod found= Checks.findSimilarMethod(method, superinterfaces[j]); |
| if (found != null && !found.equals(method)) |
| return found; |
| } |
| subMonitor.worked(1); |
| } |
| return null; |
| } finally { |
| subMonitor.done(); |
| } |
| } |
| |
| public static IMethod overridesAnotherMethod(IMethod method, ITypeHierarchy hierarchy) throws JavaModelException { |
| MethodOverrideTester tester= new MethodOverrideTester(method.getDeclaringType(), hierarchy); |
| IMethod found= tester.findDeclaringMethod(method, true); |
| boolean overrides= (found != null && !found.equals(method) && (!JdtFlags.isStatic(found)) && (!JdtFlags.isPrivate(found))); |
| if (overrides) |
| return found; |
| else |
| return null; |
| } |
| |
| /** |
| * Locates the topmost method of an override ripple and returns it. If none |
| * is found, null is returned. |
| * |
| * @param method the IMethod which may be part of a ripple |
| * @param typeHierarchy a ITypeHierarchy of the declaring type of the method. May be null |
| * @param monitor an IProgressMonitor |
| * @return the topmost method of the ripple, or null if none |
| * @throws JavaModelException |
| */ |
| public static IMethod getTopmostMethod(IMethod method, ITypeHierarchy typeHierarchy, IProgressMonitor monitor) throws JavaModelException { |
| |
| Assert.isNotNull(method); |
| |
| ITypeHierarchy hierarchy= typeHierarchy; |
| IMethod topmostMethod= null; |
| final IType declaringType= method.getDeclaringType(); |
| if (!declaringType.isInterface()) { |
| if ((hierarchy == null) || !declaringType.equals(hierarchy.getType())) |
| hierarchy= declaringType.newTypeHierarchy(monitor); |
| |
| IMethod inInterface= isDeclaredInInterface(method, hierarchy, monitor); |
| if (inInterface != null && !inInterface.equals(method)) |
| topmostMethod= inInterface; |
| } |
| if (topmostMethod == null) { |
| if (hierarchy == null) |
| hierarchy= declaringType.newSupertypeHierarchy(monitor); |
| IMethod overrides= overridesAnotherMethod(method, hierarchy); |
| if (overrides != null && !overrides.equals(method)) |
| topmostMethod= overrides; |
| } |
| return topmostMethod; |
| } |
| |
| /** |
| * Finds all overridden methods of a certain method. |
| * |
| */ |
| public static IMethod[] getOverriddenMethods(IMethod method, IProgressMonitor monitor) throws CoreException { |
| |
| Assert.isNotNull(method); |
| return RippleMethodFinder2.getRelatedMethods(method, monitor, null); |
| } |
| } |