From a8eae4ac10382f4559ca5ed57e2c27126173c151 Mon Sep 17 00:00:00 2001 From: Ihor Mielientiev Date: Fri, 17 Jul 2026 14:02:21 +0200 Subject: [PATCH 1/3] Add project-only reference search scope --- .../internal/handlers/ReferencesHandler.java | 14 +++++++---- .../internal/preferences/Preferences.java | 11 ++++----- .../handlers/ReferencesHandlerTest.java | 23 +++++++++++++++++++ .../internal/preferences/PreferencesTest.java | 18 +++++++++++++++ 4 files changed, 55 insertions(+), 11 deletions(-) diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/ReferencesHandler.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/ReferencesHandler.java index 47ead81786..83dcac7a87 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/ReferencesHandler.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/ReferencesHandler.java @@ -61,11 +61,15 @@ public ReferencesHandler(PreferenceManager preferenceManager) { private IJavaSearchScope createSearchScope(IJavaElement elementToSearch) throws JavaModelException { IJavaProject[] projects = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot()).getJavaProjects(); - int includeMask = IJavaSearchScope.SOURCES | IJavaSearchScope.REFERENCED_PROJECTS | IJavaSearchScope.APPLICATION_LIBRARIES; - if (isInsideJRE(elementToSearch)) { - includeMask |= IJavaSearchScope.SYSTEM_LIBRARIES; + SearchScope searchScope = preferenceManager.getPreferences().getSearchScope(); + int includeMask = IJavaSearchScope.SOURCES | IJavaSearchScope.REFERENCED_PROJECTS; + if (searchScope != SearchScope.projectOnly) { + includeMask |= IJavaSearchScope.APPLICATION_LIBRARIES; + if (isInsideJRE(elementToSearch)) { + includeMask |= IJavaSearchScope.SYSTEM_LIBRARIES; + } } - var excludeTestCode = preferenceManager.getPreferences().getSearchScope() == SearchScope.main; + var excludeTestCode = searchScope == SearchScope.main; return SearchEngine.createJavaSearchScope(excludeTestCode, projects, includeMask); } @@ -218,4 +222,4 @@ public void acceptSearchMatch(SearchMatch match) throws CoreException { }, monitor); } -} \ No newline at end of file +} diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/preferences/Preferences.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/preferences/Preferences.java index 1deb03dfdc..40ed2d7301 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/preferences/Preferences.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/preferences/Preferences.java @@ -842,15 +842,14 @@ static FeatureStatus fromString(String value, FeatureStatus defaultStatus) { } public static enum SearchScope { - all, main; + all, main, projectOnly; static SearchScope fromString(String value, SearchScope defaultScope) { if (value != null) { - String val = value.toLowerCase(); - try { - return valueOf(val); - } catch(Exception e) { - //fall back to default severity + for (SearchScope scope : values()) { + if (scope.name().equalsIgnoreCase(value)) { + return scope; + } } } return defaultScope; diff --git a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/ReferencesHandlerTest.java b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/ReferencesHandlerTest.java index da21d8182c..079c5fb8f8 100644 --- a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/ReferencesHandlerTest.java +++ b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/ReferencesHandlerTest.java @@ -13,6 +13,7 @@ package org.eclipse.jdt.ls.core.internal.handlers; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; @@ -34,6 +35,7 @@ import org.eclipse.jdt.ls.core.internal.WorkspaceHelper; import org.eclipse.jdt.ls.core.internal.managers.AbstractProjectsManagerBasedTest; import org.eclipse.jdt.ls.core.internal.preferences.PreferenceManager; +import org.eclipse.jdt.ls.core.internal.preferences.Preferences.SearchScope; import org.eclipse.lsp4j.Location; import org.eclipse.lsp4j.Position; import org.eclipse.lsp4j.Range; @@ -140,6 +142,16 @@ public void testEnumInClassFile() throws Exception { assertEquals(refereeUri, l.getUri()); l = references.get(1); assertEquals(fileURI, l.getUri()); + + SearchScope searchScope = preferences.getSearchScope(); + try { + preferences.setSearchScope(SearchScope.projectOnly); + references = handler.findReferences(param, monitor); + assertEquals(1, references.size()); + assertEquals(refereeUri, references.get(0).getUri()); + } finally { + preferences.setSearchScope(searchScope); + } } // https://github.com/redhat-developer/vscode-java/issues/2227 @@ -190,6 +202,17 @@ public void testReferencesInJRE() throws Exception { assertNotNull(references, "findReferences should not return null"); Location location = references.stream().filter(r -> r.getUri().startsWith("jdt://contents/rtstubs.jar/java.lang/System.class")).findFirst().get(); assertNotNull(location); + + SearchScope searchScope = preferences.getSearchScope(); + try { + preferences.setSearchScope(SearchScope.projectOnly); + references.clear(); + handler.search(field, references, monitor, true); + assertFalse(references.isEmpty()); + assertTrue(references.stream().allMatch(reference -> reference.getUri().startsWith("file:"))); + } finally { + preferences.setSearchScope(searchScope); + } } } diff --git a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/preferences/PreferencesTest.java b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/preferences/PreferencesTest.java index 9e69adda46..9b3f7f7d8a 100644 --- a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/preferences/PreferencesTest.java +++ b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/preferences/PreferencesTest.java @@ -28,10 +28,28 @@ import org.eclipse.jdt.ls.core.internal.IConstants; import org.eclipse.jdt.ls.core.internal.handlers.CompletionGuessMethodArgumentsMode; import org.eclipse.jdt.ls.core.internal.handlers.MapFlattener; +import org.eclipse.jdt.ls.core.internal.preferences.Preferences.SearchScope; import org.junit.jupiter.api.Test; public class PreferencesTest { + @Test + public void testProjectOnlySearchScope() { + Map config = new HashMap<>(); + MapFlattener.setValue(config, Preferences.JAVA_SEARCH_SCOPE, "projectOnly"); + + Preferences preferences = Preferences.createFrom(config); + assertEquals(SearchScope.projectOnly, preferences.getSearchScope()); + + MapFlattener.setValue(config, Preferences.JAVA_SEARCH_SCOPE, "PROJECTONLY"); + preferences = Preferences.createFrom(config); + assertEquals(SearchScope.projectOnly, preferences.getSearchScope()); + + MapFlattener.setValue(config, Preferences.JAVA_SEARCH_SCOPE, "invalid"); + preferences = Preferences.createFrom(config); + assertEquals(SearchScope.all, preferences.getSearchScope()); + } + @Test public void testSetImportOnDemandThreshold() throws Exception { Preferences preferences = new Preferences(); From dd8a78d9f908a0bd444184be49693f65fa198de9 Mon Sep 17 00:00:00 2001 From: Ihor Mielientiev Date: Fri, 17 Jul 2026 14:10:28 +0200 Subject: [PATCH 2/3] Add dedicated test for project-only search scope --- .../handlers/ReferencesHandlerTest.java | 38 +++++++++++++------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/ReferencesHandlerTest.java b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/ReferencesHandlerTest.java index 079c5fb8f8..cc9cbd2c00 100644 --- a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/ReferencesHandlerTest.java +++ b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/ReferencesHandlerTest.java @@ -142,13 +142,38 @@ public void testEnumInClassFile() throws Exception { assertEquals(refereeUri, l.getUri()); l = references.get(1); assertEquals(fileURI, l.getUri()); + } + + @Test + public void testProjectOnlySearchScope() throws Exception { + when(preferenceManager.isClientSupportsClassFileContent()).thenReturn(true); + importProjects("eclipse/reference"); + IProject referenceProject = WorkspaceHelper.getProject("reference"); + IJavaProject referenceJavaProject = JavaCore.create(referenceProject); + IType element = referenceJavaProject.findType("org.sample.Foo"); + IClassFile cf = (IClassFile) element.getAncestor(IJavaElement.CLASS_FILE); + URI uri = JDTUtils.toURI(JDTUtils.toUri(cf)); + String fileURI = ResourceUtils.fixURI(uri); + ReferenceParams param = new ReferenceParams(); + param.setPosition(new Position(5, 6)); + param.setContext(new ReferenceContext(false)); + param.setTextDocument(new TextDocumentIdentifier(fileURI)); SearchScope searchScope = preferences.getSearchScope(); try { preferences.setSearchScope(SearchScope.projectOnly); - references = handler.findReferences(param, monitor); + List references = handler.findReferences(param, monitor); assertEquals(1, references.size()); + String refereeUri = ResourceUtils.fixURI(referenceProject.getFile("src/org/reference/Main.java").getRawLocationURI()); assertEquals(refereeUri, references.get(0).getUri()); + + IType system = referenceJavaProject.findType("java.lang.System"); + IField field = system.getField("out"); + assertTrue(field.exists()); + references.clear(); + handler.search(field, references, monitor, true); + assertFalse(references.isEmpty()); + assertTrue(references.stream().allMatch(reference -> reference.getUri().startsWith("file:"))); } finally { preferences.setSearchScope(searchScope); } @@ -202,17 +227,6 @@ public void testReferencesInJRE() throws Exception { assertNotNull(references, "findReferences should not return null"); Location location = references.stream().filter(r -> r.getUri().startsWith("jdt://contents/rtstubs.jar/java.lang/System.class")).findFirst().get(); assertNotNull(location); - - SearchScope searchScope = preferences.getSearchScope(); - try { - preferences.setSearchScope(SearchScope.projectOnly); - references.clear(); - handler.search(field, references, monitor, true); - assertFalse(references.isEmpty()); - assertTrue(references.stream().allMatch(reference -> reference.getUri().startsWith("file:"))); - } finally { - preferences.setSearchScope(searchScope); - } } } From ad1a781878539be05b257f16b2a32fa6872e310f Mon Sep 17 00:00:00 2001 From: Ihor Mielientiev Date: Fri, 17 Jul 2026 14:12:46 +0200 Subject: [PATCH 3/3] Document project-only search scope --- .../jdt/ls/core/internal/preferences/Preferences.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/preferences/Preferences.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/preferences/Preferences.java index 40ed2d7301..859903fa48 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/preferences/Preferences.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/preferences/Preferences.java @@ -574,12 +574,14 @@ public class Preferences { public static final String CHAIN_COMPLETION_KEY = "java.completion.chain.enabled"; /** - * Preference key to set the scope value to use when searching java code. Allowed value are + * Preference key to set the scope value to use when searching Java code. Allowed values are *
    - *
  • main - Scope for main code
  • - *
  • all - Scope for both test and main code
  • + *
  • main - Search main source code and libraries
  • + *
  • all - Search main and test source code and libraries
  • + *
  • projectOnly - For reference searches, include main and test + * source code and referenced projects, excluding application and system libraries
  • *
- * Any other unknown value will be treated as all. + * Any unknown value will be treated as all. */ public static final String JAVA_SEARCH_SCOPE = "java.search.scope";