From fe3554b98c404a904ddcbde28f9c46dcd6c2f1f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Kubitz?= Date: Wed, 18 Dec 2024 12:40:14 +0100 Subject: [PATCH] [performance] determineIfOnClasspath with last project used #3470 Instead of randomly looping over all projects try the last successful first. Tested by JavaModelTests.testCreatePkgHandleInDifferentProject() https://github.com/eclipse-jdt/eclipse.jdt.core/issues/3470 --- .../jdt/core/tests/model/JavaModelTests.java | 20 ++++++++++++++++- .../jdt/internal/core/JavaModelManager.java | 22 +++++++++++++++---- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaModelTests.java index 29349ed9976..324b602d2b7 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaModelTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaModelTests.java @@ -310,13 +310,31 @@ public void testCreatePkgHandleInDifferentProject() throws CoreException { try { createJavaProject("P1", new String[] {}, "bin"); IFolder folder = createFolder("/P1/lib/x/y"); - createJavaProject("P2", new String[] {}, new String[] {"/P1/lib"}, ""); + IJavaProject p2 = createJavaProject("P2", new String[] {}, new String[] {"/P1/lib"}, ""); IJavaElement element = JavaCore.create(folder); assertElementEquals( "Unexpected element", "x.y [in /P1/lib [in P2]]", element ); + IFolder folder2 = createFolder("/P1/lib/x/z"); + assertElementEquals( + "Unexpected element", + "x.z [in /P1/lib [in P2]]", + JavaCore.create(folder2) + ); + p2.getProject().close(null); + assertElementEquals( + "Unexpected element", + "", // closed + JavaCore.create(folder2) + ); + p2.getProject().open(null); + assertElementEquals( + "Unexpected element", + "x.z [in /P1/lib [in P2]]", // open again + JavaCore.create(folder2) + ); } finally { deleteProjects(new String[] {"P1", "P2"}); } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java index 6cfbdc3a809..ea1bbe92d6d 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java @@ -980,6 +980,8 @@ public static IJavaElement create(IFile file, IJavaProject project) { return null; } + private static volatile String lastProjectNameUsed; + /** * Returns the package fragment or package fragment root corresponding to the given folder, * its parent or great parent being the given project. @@ -999,6 +1001,15 @@ public static IJavaElement create(IFolder folder, IJavaProject project) { project = JavaCore.create(folder.getProject()); element = determineIfOnClasspath(folder, project); if (element == null) { + IJavaProject lastProject = lastProjectNameUsed == null ? null + : JavaModelManager.getJavaModelManager().getJavaModel().getJavaProject(lastProjectNameUsed); + if (lastProject != null) { + // try to avoid searching through all projects + element = determineIfOnClasspath(folder, lastProject); + if (element != null) { + return element; + } + } // walk all projects and find one that have the given folder on its classpath IJavaProject[] projects; try { @@ -1007,10 +1018,13 @@ public static IJavaElement create(IFolder folder, IJavaProject project) { return null; } for (IJavaProject p : projects) { - project = p; - element = determineIfOnClasspath(folder, project); - if (element != null) - break; + if (!p.equals(lastProject)) { + element = determineIfOnClasspath(folder, p); + if (element != null) { + lastProjectNameUsed = p.getElementName(); + return element; + } + } } } } else {