[java-highlighting] IDEA-340063 Don't offer import from implicitly declared classes

GitOrigin-RevId: 7cda6a2eaa67c0c557ce53f61bfd345d5d773694
This commit is contained in:
Mikhail Pyltsin
2023-12-11 21:06:00 +00:00
committed by intellij-monorepo-bot
parent 0d55ac4678
commit 91cf1947e4
4 changed files with 49 additions and 1 deletions
@@ -32,6 +32,7 @@ import com.intellij.psi.codeStyle.JavaCodeStyleSettings;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiShortNamesCache;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ThreeState;
@@ -195,7 +196,9 @@ public abstract class ImportClassFixBase<T extends PsiElement, R extends PsiRefe
JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
classList.removeIf(aClass -> (anyAccessibleFound ||
!BaseIntentionAction.canModify(aClass) ||
facade.arePackagesTheSame(aClass, myReferenceElement)) && !isAccessible(aClass, myReferenceElement));
facade.arePackagesTheSame(aClass, myReferenceElement) ||
PsiTreeUtil.getParentOfType(aClass, PsiImplicitClass.class) != null) &&
!isAccessible(aClass, myReferenceElement));
filterByRequiredMemberName(classList);
@@ -16,6 +16,7 @@ import com.intellij.psi.scope.conflictResolvers.DuplicateConflictResolver;
import com.intellij.psi.scope.processor.MethodCandidatesProcessor;
import com.intellij.psi.scope.processor.MethodResolverProcessor;
import com.intellij.psi.scope.util.PsiScopesUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.SmartList;
@@ -130,9 +131,28 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
if (accessible && member instanceof PsiClass && !(member instanceof PsiTypeParameter)) {
accessible = isAccessible(moduleSystem -> moduleSystem.isAccessible(((PsiClass)member), place));
}
if (fromImplicitClass(member, place)) {
return false;
}
return accessible;
}
/**
* Determines whether the given member is from an implicit class or not.
* If it is from implicit class, that place is in the same class
*
* @param member the member to check
* @param place the place where the check is performed
* @return true if the member is not from an implicit class or if place and member are both in the same implicit class, false otherwise.
*/
private static boolean fromImplicitClass(@NotNull PsiMember member, @NotNull PsiElement place) {
PsiImplicitClass implicitClass = PsiTreeUtil.getParentOfType(member, PsiImplicitClass.class);
if (implicitClass == null) {
return false;
}
return !PsiTreeUtil.isAncestor(implicitClass, place, false);
}
@Override
public boolean isAccessible(@NotNull PsiPackage pkg, @NotNull PsiElement place) {
return isAccessible(moduleSystem -> moduleSystem.isAccessible(pkg.getQualifiedName(), null, place));
@@ -0,0 +1,5 @@
void main() {
Rar x = new R<caret>ar();
}
@@ -804,4 +804,24 @@ public class AddImportActionTest extends LightJavaCodeInsightFixtureTestCase {
final List<?> list = new @AssertTrue ArrayList<Object>();
}""");
}
public void testNotImportFromImplicitClass() {
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21_PREVIEW, ()->{
myFixture.addClass("""
enum E {A, B}
static class Rar {
}
void main() {
}
""");
myFixture.configureByText("a.java", """
void main() {
R<caret>ar x = new Rar();
}
""");
assertTrue(myFixture.filterAvailableIntentions("Import class").isEmpty());
});
}
}