From ddaea40aba1c325b47cdac4894e6a8026d536b52 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 15 Dec 2025 15:55:42 +0100 Subject: [PATCH] IDEA-354817 [java]: find constructors correctly with both "Usages" and "Usages of constructors" is selected GitOrigin-RevId: 3f75d7e0a6ace0dd4124fc0a9dd1d4e67be6e9b6 --- .../daemon/impl/UnusedSymbolUtil.java | 3 ++- .../find/findUsages/JavaFindUsagesHelper.java | 11 +++----- .../SomeClass.java | 8 ++++++ .../HeadlessHorsewoman.java | 0 .../java/psi/search/FindUsagesTest.java | 25 +++++++++++++++---- 5 files changed, 34 insertions(+), 13 deletions(-) create mode 100644 java/java-tests/testData/psi/search/findUsages/findConstructorUsagesFromClass/SomeClass.java rename java/java-tests/testData/psi/search/findUsages/{findConstructorUsagesFromClass => findDefaultConstructorUsagesFromClass}/HeadlessHorsewoman.java (100%) diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/UnusedSymbolUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/UnusedSymbolUtil.java index 847374b751d4..556e6096a7e9 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/UnusedSymbolUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/UnusedSymbolUtil.java @@ -1,4 +1,4 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.codeInsight.daemon.impl; import com.intellij.codeInsight.daemon.ImplicitUsageProvider; @@ -283,6 +283,7 @@ public final class UnusedSymbolUtil { } else if (member instanceof PsiClass) { options = new JavaClassFindUsagesOptions(useScope); + ((JavaClassFindUsagesOptions)options).isConstructorUsages = false; options.isSearchForTextOccurrences = true; } else if (member instanceof PsiMethod method) { diff --git a/java/java-analysis-impl/src/com/intellij/find/findUsages/JavaFindUsagesHelper.java b/java/java-analysis-impl/src/com/intellij/find/findUsages/JavaFindUsagesHelper.java index 7b578834cd97..3210e268dccd 100644 --- a/java/java-analysis-impl/src/com/intellij/find/findUsages/JavaFindUsagesHelper.java +++ b/java/java-analysis-impl/src/com/intellij/find/findUsages/JavaFindUsagesHelper.java @@ -279,13 +279,10 @@ public final class JavaFindUsagesHelper { } } else { - if (!options.isUsages || !options.isConstructorUsages) { // ReferencesSearch on class already includes new instance creations. - PsiMethod[] methods = ReadAction.compute(() -> aClass.getMethods()); - for (PsiMethod method : methods) { - boolean include = ReadAction.compute(() -> method.isConstructor()) ? options.isConstructorUsages : options.isMethodsUsages; - if (!include) continue; - if (!addElementUsages(method, options, processor)) return false; - } + for (PsiMethod method : ReadAction.compute(() -> aClass.getMethods())) { + boolean include = ReadAction.compute(() -> method.isConstructor()) ? options.isConstructorUsages : options.isMethodsUsages; + if (!include) continue; + if (!addElementUsages(method, options, processor)) return false; } if (!options.isUsages && options.isConstructorUsages) { PsiMethod defaultConstructor = ReadAction.compute(() -> LightDefaultConstructor.create(aClass)); diff --git a/java/java-tests/testData/psi/search/findUsages/findConstructorUsagesFromClass/SomeClass.java b/java/java-tests/testData/psi/search/findUsages/findConstructorUsagesFromClass/SomeClass.java new file mode 100644 index 000000000000..449fccd7c8d3 --- /dev/null +++ b/java/java-tests/testData/psi/search/findUsages/findConstructorUsagesFromClass/SomeClass.java @@ -0,0 +1,8 @@ +public class SomeClass { + SomeClass() { + } + + SomeClass(int i) { + this(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/search/findUsages/findConstructorUsagesFromClass/HeadlessHorsewoman.java b/java/java-tests/testData/psi/search/findUsages/findDefaultConstructorUsagesFromClass/HeadlessHorsewoman.java similarity index 100% rename from java/java-tests/testData/psi/search/findUsages/findConstructorUsagesFromClass/HeadlessHorsewoman.java rename to java/java-tests/testData/psi/search/findUsages/findDefaultConstructorUsagesFromClass/HeadlessHorsewoman.java diff --git a/java/java-tests/testSrc/com/intellij/java/psi/search/FindUsagesTest.java b/java/java-tests/testSrc/com/intellij/java/psi/search/FindUsagesTest.java index ea89339ed43f..bd8ace17f169 100644 --- a/java/java-tests/testSrc/com/intellij/java/psi/search/FindUsagesTest.java +++ b/java/java-tests/testSrc/com/intellij/java/psi/search/FindUsagesTest.java @@ -121,20 +121,35 @@ public class FindUsagesTest extends JavaPsiTestCase { } public void testFindConstructorUsagesFromClass() { - PsiClass aClass = myJavaFacade.findClass("HeadlessHorsewoman", GlobalSearchScope.allScope(myProject)); + JavaClassFindUsagesOptions options = new JavaClassFindUsagesOptions(getProject()); + options.isUsages = true; + options.isConstructorUsages = true; + doTestFindUsages("SomeClass", options, "this()"); + options.isUsages = false; + doTestFindUsages("SomeClass", options, "this()"); + options.isUsages = true; + options.isConstructorUsages = false; + doTestFindUsages("SomeClass", options, ""); + } + + public void testFindDefaultConstructorUsagesFromClass() { JavaClassFindUsagesOptions options = new JavaClassFindUsagesOptions(getProject()); options.isUsages = false; options.isConstructorUsages = true; + doTestFindUsages("HeadlessHorsewoman", options, "new HeadlessHorsewoman()"); + } + + private void doTestFindUsages(String className, JavaClassFindUsagesOptions options, String expected) { + PsiClass aClass = myJavaFacade.findClass(className, GlobalSearchScope.allScope(myProject)); CommonProcessors.CollectProcessor processor = new CommonProcessors.CollectProcessor<>(); FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(myProject)).getFindUsagesManager(); FindUsagesHandler handler = findUsagesManager.getFindUsagesHandler(aClass, false); assertNotNull(handler); handler.processElementUsages(aClass, processor, options); Collection usages = processor.getResults(); - assertEquals(1, usages.size()); - assertEquals("new HeadlessHorsewoman()", StringUtil.join(usages, u -> u.getElement().getParent().getText() , ", ")); - } - + assertEquals(expected, StringUtil.join(usages, u -> u.getElement().getParent().getText() , "\n")); + } + public void testDefaultConstructor() { PsiClass aClass = myJavaFacade.findClass("Animal", GlobalSearchScope.allScope(myProject)); PsiMethod main = aClass.findMethodsByName("main", false)[0];