mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
Java: add error for class extending sealed class from another package (IDEA-358672)
GitOrigin-RevId: d7b0c68100ddc60f42bfedc1f3b88e54cbd3ce74
This commit is contained in:
committed by
intellij-monorepo-bot
parent
8b80330e6e
commit
a016f884d3
@@ -186,8 +186,9 @@ move.catch.up.family=Move 'catch' up
|
||||
move.catch.up.text=Move catch for ''{0}'' before ''{1}''
|
||||
move.class.to.separate.file.family=Move class to separate file
|
||||
move.class.to.separate.file.text=Move class ''{0}'' to ''{0}.java''
|
||||
move.class.to.package.family=Move Class to Package
|
||||
move.class.to.package.family=Move to package
|
||||
move.class.to.package.text=Move to package ''{0}''
|
||||
move.class.0.to.package.text=Move {0} ''{1}'' to package ''{2}''
|
||||
|
||||
# change if (!a == b) ... => if (!(a == b)) ...
|
||||
negation.broader.scope.family=Negation broader scope
|
||||
|
||||
+26
-5
@@ -27,6 +27,7 @@ import com.intellij.openapi.util.NlsContexts;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.java.JavaFeature;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
@@ -1148,6 +1149,23 @@ public final class HighlightClassUtil {
|
||||
return info;
|
||||
}
|
||||
|
||||
if (!JavaPsiFacade.getInstance(aClass.getProject()).arePackagesTheSame(aClass, superClass) &&
|
||||
JavaModuleGraphUtil.findDescriptorByElement(aClass) == null) {
|
||||
String description = StringUtil.capitalize(JavaErrorBundle.message(
|
||||
"class.not.allowed.to.extend.sealed.class.from.another.package",
|
||||
JavaElementKind.fromElement(aClass).subject(), HighlightUtil.formatClass(aClass, false),
|
||||
JavaElementKind.fromElement(superClass).object(), HighlightUtil.formatClass(superClass, true)));
|
||||
HighlightInfo.Builder info =
|
||||
HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(elementToHighlight).descriptionAndTooltip(description);
|
||||
PsiFile parentFile = superClass.getContainingFile();
|
||||
if (parentFile instanceof PsiClassOwner classOwner) {
|
||||
String parentPackage = classOwner.getPackageName();
|
||||
IntentionAction action = QuickFixFactory.getInstance().createMoveClassToPackageFix(aClass, parentPackage);
|
||||
info.registerFix(action, null, null, null, null);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
PsiClassType[] permittedTypes = superClass.getPermitsListTypes();
|
||||
if (permittedTypes.length > 0) {
|
||||
PsiManager manager = superClass.getManager();
|
||||
@@ -1262,12 +1280,15 @@ public final class HighlightClassUtil {
|
||||
}
|
||||
else {
|
||||
if (currentModule == null && !psiFacade.arePackagesTheSame(aClass, inheritorClass)) {
|
||||
HighlightInfo.Builder info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
|
||||
.range(permitted)
|
||||
.descriptionAndTooltip(JavaErrorBundle.message("class.not.allowed.to.extend.sealed.class.from.another.package"));
|
||||
String description = StringUtil.capitalize(
|
||||
JavaErrorBundle.message("class.not.allowed.to.extend.sealed.class.from.another.package",
|
||||
JavaElementKind.fromElement(inheritorClass).subject(), HighlightUtil.formatClass(inheritorClass, true),
|
||||
JavaElementKind.fromElement(aClass).object(), HighlightUtil.formatClass(aClass, false)));
|
||||
HighlightInfo.Builder info =
|
||||
HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(permitted).descriptionAndTooltip(description);
|
||||
PsiFile parentFile = aClass.getContainingFile();
|
||||
if (parentFile instanceof PsiClassOwner) {
|
||||
String parentPackage = ((PsiClassOwner)parentFile).getPackageName();
|
||||
if (parentFile instanceof PsiClassOwner classOwner) {
|
||||
String parentPackage = classOwner.getPackageName();
|
||||
IntentionAction action = QuickFixFactory.getInstance().createMoveClassToPackageFix(inheritorClass, parentPackage);
|
||||
info.registerFix(action, null, null, null, null);
|
||||
}
|
||||
|
||||
+1
-1
@@ -967,7 +967,7 @@ public final class QuickFixFactoryImpl extends QuickFixFactory {
|
||||
|
||||
@Override
|
||||
public @NotNull IntentionAction createMoveClassToPackageFix(@NotNull PsiClass classToMove, @NotNull String packageName) {
|
||||
return new MoveToPackageFix(classToMove.getContainingFile(), packageName);
|
||||
return new MoveToPackageFix(classToMove, packageName);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.JavaElementKind;
|
||||
import com.intellij.refactoring.JavaRefactoringFactory;
|
||||
import com.intellij.refactoring.PackageWrapper;
|
||||
import com.intellij.refactoring.move.moveClassesOrPackages.SingleSourceRootMoveDestination;
|
||||
@@ -22,14 +23,29 @@ import org.jetbrains.annotations.Nullable;
|
||||
public class MoveToPackageFix extends LocalQuickFixAndIntentionActionOnPsiElement {
|
||||
private static final Logger LOG = Logger.getInstance(MoveToPackageFix.class);
|
||||
private final String myTargetPackage;
|
||||
private final @Nullable SmartPsiElementPointer<@NotNull PsiClass> myClass;
|
||||
|
||||
public MoveToPackageFix(@NotNull PsiFile psiFile, @NotNull String targetPackage) {
|
||||
super(psiFile);
|
||||
myTargetPackage = targetPackage;
|
||||
myClass = null;
|
||||
}
|
||||
|
||||
public MoveToPackageFix(@NotNull PsiClass aClass, @NotNull String targetPackage) {
|
||||
super(aClass.getContainingFile());
|
||||
myTargetPackage = targetPackage;
|
||||
myClass = SmartPointerManager.getInstance(aClass.getProject()).createSmartPsiElementPointer(aClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @IntentionName @NotNull String getText() {
|
||||
if (myClass != null) {
|
||||
PsiClass aClass = myClass.getElement();
|
||||
if (aClass != null) {
|
||||
return QuickFixBundle.message("move.class.0.to.package.text",
|
||||
JavaElementKind.fromElement(aClass).object(), aClass.getName(), myTargetPackage);
|
||||
}
|
||||
}
|
||||
return QuickFixBundle.message("move.class.to.package.text", myTargetPackage);
|
||||
}
|
||||
|
||||
|
||||
@@ -581,7 +581,7 @@ permits.list.generics.are.not.allowed=Generics are not allowed in permits list
|
||||
sealed.cannot.be.functional.interface=Sealed class can not be used as functional interface
|
||||
local.classes.must.not.extend.sealed.classes=Local classes must not extend sealed classes
|
||||
anonymous.classes.must.not.extend.sealed.classes=Anonymous classes must not extend sealed classes
|
||||
class.not.allowed.to.extend.sealed.class.from.another.package=Class is not allowed to extend sealed class from another package
|
||||
class.not.allowed.to.extend.sealed.class.from.another.package={0} ''{1}'' from another package not allowed to extend sealed {2} ''{3}'' in unnamed module
|
||||
class.not.allowed.to.extend.sealed.class.from.another.module=Class is not allowed to extend sealed class from another module
|
||||
annotation.cannot.be.local=Local annotations are not allowed
|
||||
create.class.action.this.not.valid.java.qualified.name=This is not a valid Java qualified name
|
||||
|
||||
+2
-1
@@ -20,7 +20,8 @@ sealed interface Indirect permits <error descr="Invalid permits clause: 'Indirec
|
||||
non-sealed interface MiddleMan extends Indirect {}
|
||||
final class IndirectInheritor implements MiddleMan {}
|
||||
|
||||
sealed class AnotherPackage permits <error descr="Class is not allowed to extend sealed class from another package">p1.P1</error> {}
|
||||
sealed class AnotherPackage permits <error descr="Class 'p1.P1' from another package not allowed to extend sealed class 'AnotherPackage' in unnamed module">p1.P1</error> {}
|
||||
final class Mail extends <error descr="Class 'Mail' from another package not allowed to extend sealed class 'p1.Envelope' in unnamed module">p1.Envelope</error> {}
|
||||
|
||||
enum ImlicitlySealedWithPermitsClause <error descr="'permits' not allowed on enum">permits</error> FOO {
|
||||
FOO {};
|
||||
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2024 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.quickfix;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
@@ -9,20 +9,20 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class MoveToPackageTest extends LightJavaCodeInsightFixtureTestCase {
|
||||
@Override
|
||||
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
|
||||
return LightJavaCodeInsightFixtureTestCase.JAVA_LATEST_WITH_LATEST_JDK;
|
||||
return JAVA_LATEST_WITH_LATEST_JDK;
|
||||
}
|
||||
|
||||
public void testSimple() {
|
||||
PsiClass bClass = myFixture.addClass("package foo;\nimport bar.A;\npublic final class B extends A {}");
|
||||
myFixture.configureByText("A.java", "package bar;\n import foo.B;\npublic sealed class A permits <caret>B {}");
|
||||
invokeFix("Move to package 'bar'");
|
||||
invokeFix("Move class 'B' to package 'bar'");
|
||||
assertEquals("package bar;\n\npublic final class B extends A {}", bClass.getContainingFile().getText());
|
||||
}
|
||||
|
||||
public void testNestedClass() {
|
||||
PsiClass bClass = myFixture.addClass("package foo;\nimport bar.A;\npublic class B { public static final class C extends A {} }");
|
||||
myFixture.configureByText("A.java", "package bar;\n import foo.B;\npublic sealed class A permits <caret>B.C {}");
|
||||
invokeFix("Move to package 'bar'");
|
||||
invokeFix("Move class 'C' to package 'bar'");
|
||||
assertEquals("package bar;\n\npublic class B { public static final class C extends A {} }",
|
||||
bClass.getContainingFile().getText());
|
||||
}
|
||||
|
||||
+2
-1
@@ -29,7 +29,8 @@ public class LightSealedTypesHighlightingTest extends LightJavaCodeInsightFixtur
|
||||
public void testPermitsList() {
|
||||
myFixture.addClass("package p1; public class P1 extends p.AnotherPackage {}");
|
||||
myFixture.addClass("package p; public class P extends A {}");
|
||||
doTest();
|
||||
myFixture.addClass("package p1; public sealed class Envelope permits p.Mail {}");
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testPermitsListInLibrarySources() {
|
||||
|
||||
Reference in New Issue
Block a user