mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-06 06:21:16 +07:00
[java] Consider candidates from all class finders in class finder
This will make sure the best class is always found. For example, when there are multiple dependencies that contain the same class, the class from the first dependency should be picked, even if it only is found by a PsiElementFinder that appears later in the chain. #IDEA-342753 Fixed (cherry picked from commit fcd905b1cea47dd488664eff62e2ff1049c4e336) IJ-MR-155802 GitOrigin-RevId: 7d99cc055ddb03678d162f471dfb0e4fb46cd0a3
This commit is contained in:
committed by
intellij-monorepo-bot
parent
e078b269b6
commit
2342dbb3ff
@@ -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.psi.impl;
|
||||
|
||||
import com.intellij.lang.jvm.JvmClass;
|
||||
@@ -23,6 +23,7 @@ import com.intellij.psi.impl.source.resolve.FileContextUtil;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.psi.util.PsiClassUtil;
|
||||
import com.intellij.psi.util.PsiModificationTracker;
|
||||
import com.intellij.util.ConcurrencyUtil;
|
||||
import com.intellij.util.Processor;
|
||||
@@ -103,18 +104,20 @@ public final class JavaPsiFacadeImpl extends JavaPsiFacadeEx {
|
||||
}
|
||||
List<PsiElementFinder> finders = filteredFinders();
|
||||
Predicate<PsiClass> classesFilter = getFilterFromFinders(scope, finders);
|
||||
PsiClass bestClass = null;
|
||||
for (PsiElementFinder finder : finders) {
|
||||
try {
|
||||
PsiClass aClass = finder.findClass(qualifiedName, scope);
|
||||
if (aClass != null && (classesFilter == null || classesFilter.test(aClass))) {
|
||||
return aClass;
|
||||
}
|
||||
PsiClass candidateClass = finder.findClass(qualifiedName, scope);
|
||||
if (candidateClass == null) continue;
|
||||
if (classesFilter != null && !classesFilter.test(candidateClass)) continue;
|
||||
if (bestClass != null && PsiClassUtil.createScopeComparator(scope).compare(candidateClass, bestClass) >= 0) continue;
|
||||
bestClass = candidateClass;
|
||||
}
|
||||
catch (IndexNotReadyException ex) {
|
||||
handleIndexNotReadyException(ex);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return bestClass;
|
||||
}
|
||||
|
||||
private PsiClass @NotNull [] findClassesInDumbMode(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
|
||||
|
||||
+3
-2
@@ -1,11 +1,11 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// 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.java.psi.resolve;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.extensions.impl.ExtensionPointImpl;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.*;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -134,6 +134,7 @@ public class ResolveClassInModulesWithDependenciesTest extends JavaResolveTestCa
|
||||
PsiElementFinder.class.getDeclaredMethods(),
|
||||
m -> !ignoredMethods.contains(m.getName()) && !Modifier.isPrivate(m.getModifiers()) && !Modifier.isStatic(m.getModifiers()));
|
||||
PsiElementFinder mock = createMockBuilder(PsiElementFinder.class).addMockedMethods(methods).createMock();
|
||||
expect(mock.findClass(anyObject(), anyObject())).andReturn(null).anyTimes();
|
||||
expect(mock.findClasses(anyObject(), anyObject())).andReturn(PsiClass.EMPTY_ARRAY).anyTimes();
|
||||
expect(mock.findPackage(eq("foo"))).andReturn(null);
|
||||
expect(mock.getSubPackages(rootPackage(), anyObject())).andReturn(PsiPackage.EMPTY_ARRAY);
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.plugins.groovy.lang.resolve
|
||||
|
||||
import com.intellij.openapi.module.StdModuleTypes
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.testFramework.PsiTestUtil
|
||||
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase
|
||||
|
||||
class GroovyMultiModuleResolveTest : JavaCodeInsightFixtureTestCase() {
|
||||
fun `test same class from different modules`() {
|
||||
val groovyModule = PsiTestUtil.addModule(project, StdModuleTypes.JAVA, "groovyModule", myFixture.tempDirFixture.findOrCreateDir("groovyModule"))
|
||||
myFixture.addFileToProject("groovyModule/foo/Foo.groovy", """
|
||||
package foo
|
||||
|
||||
class Foo {}
|
||||
""".trimIndent())
|
||||
ModuleRootModificationUtil.addDependency(myFixture.module, groovyModule)
|
||||
|
||||
val javaModule = PsiTestUtil.addModule(project, StdModuleTypes.JAVA, "javaModule", myFixture.tempDirFixture.findOrCreateDir("javaModule"))
|
||||
myFixture.addFileToProject("javaModule/foo/Foo.java", """
|
||||
package foo;
|
||||
|
||||
public class Foo {}
|
||||
""".trimIndent())
|
||||
ModuleRootModificationUtil.addDependency(myFixture.module, javaModule)
|
||||
|
||||
myFixture.configureByText("Main.groovy", """
|
||||
import foo.Foo
|
||||
|
||||
class Main {
|
||||
F<caret>oo foo = new Foo()
|
||||
}
|
||||
""".trimIndent())
|
||||
val resolved = (myFixture.file.findElementAt(myFixture.caretOffset)?.parent as? PsiReference)?.resolve()
|
||||
|
||||
// resolve to Groovy because dependency was added first and has higher priority
|
||||
assertEquals("Foo.groovy", resolved?.containingFile?.name)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user