From 2ee7c6480195bf20445b16a3d6a14f473ff22cda Mon Sep 17 00:00:00 2001 From: fedejeanne Date: Fri, 10 Jan 2025 15:35:30 +0100 Subject: [PATCH] Avoid unnecessary calls to findOverriddenMethod #1922 This speeds up the quick outline. Fixes https://github.com/eclipse-jdt/eclipse.jdt.ui/issues/1922 --- .../corext/util/MethodOverrideTester.java | 18 +++++++++++++----- .../code/IntroduceIndirectionRefactoring.java | 3 ++- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/util/MethodOverrideTester.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/util/MethodOverrideTester.java index 04ef60c31bb..823f80ed2b3 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/util/MethodOverrideTester.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/util/MethodOverrideTester.java @@ -136,10 +136,12 @@ public IMethod findOverriddenMethod(IMethod overriding, boolean testVisibility) return null; } + Set visited = new HashSet<>(); + IType type= overriding.getDeclaringType(); IType superClass= fHierarchy.getSuperclass(type); if (superClass != null) { - IMethod res= findOverriddenMethodInHierarchy(superClass, overriding); + IMethod res= findOverriddenMethodInHierarchy(superClass, overriding, visited); if (res != null) { if (!testVisibility || JavaModelUtil.isVisibleInHierarchy(res, type.getPackageFragment())) { return res; @@ -147,7 +149,7 @@ public IMethod findOverriddenMethod(IMethod overriding, boolean testVisibility) } } for (IType intf : fHierarchy.getSuperInterfaces(type)) { - IMethod res= findOverriddenMethodInHierarchy(intf, overriding); + IMethod res= findOverriddenMethodInHierarchy(intf, overriding, visited); if (res != null) { return res; // methods from interfaces are always public and therefore visible } @@ -160,23 +162,29 @@ public IMethod findOverriddenMethod(IMethod overriding, boolean testVisibility) * With generics it is possible that 2 methods in the same type are overidden at the same time. In that case, the first overridden method found is returned. * @param type The type to find methods in * @param overriding The overriding method + * @param visited The types that were visited already * @return The first overridden method or null if no method is overridden * @throws JavaModelException if a problem occurs */ - public IMethod findOverriddenMethodInHierarchy(IType type, IMethod overriding) throws JavaModelException { + public IMethod findOverriddenMethodInHierarchy(IType type, IMethod overriding, Set visited) throws JavaModelException { + + if (!visited.add(type.getElementName())) { + return null; + } + IMethod method= findOverriddenMethodInType(type, overriding); if (method != null) { return method; } IType superClass= fHierarchy.getSuperclass(type); if (superClass != null) { - IMethod res= findOverriddenMethodInHierarchy(superClass, overriding); + IMethod res= findOverriddenMethodInHierarchy(superClass, overriding, visited); if (res != null) { return res; } } for (IType superInterface : fHierarchy.getSuperInterfaces(type)) { - IMethod res= findOverriddenMethodInHierarchy(superInterface, overriding); + IMethod res= findOverriddenMethodInHierarchy(superInterface, overriding, visited); if (res != null) { return res; } diff --git a/org.eclipse.jdt.core.manipulation/refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceIndirectionRefactoring.java b/org.eclipse.jdt.core.manipulation/refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceIndirectionRefactoring.java index 9f7dc40f2b0..e21ad59dd21 100644 --- a/org.eclipse.jdt.core.manipulation/refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceIndirectionRefactoring.java +++ b/org.eclipse.jdt.core.manipulation/refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceIndirectionRefactoring.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; @@ -540,7 +541,7 @@ public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreEx IType actualTargetType= (IType) fIntermediaryFirstParameterType.getJavaElement(); if (!fTargetMethod.getDeclaringType().equals(actualTargetType)) { - IMethod actualTargetMethod= new MethodOverrideTester(actualTargetType, actualTargetType.newSupertypeHierarchy(null)).findOverriddenMethodInHierarchy(actualTargetType, fTargetMethod); + IMethod actualTargetMethod= new MethodOverrideTester(actualTargetType, actualTargetType.newSupertypeHierarchy(null)).findOverriddenMethodInHierarchy(actualTargetType, fTargetMethod, new HashSet<>()); fTargetMethod= actualTargetMethod; fTargetMethodBinding= findMethodBindingInHierarchy(fIntermediaryFirstParameterType, actualTargetMethod); Assert.isNotNull(fTargetMethodBinding);