UnimplementInterfaceAction: sealed parent support (IDEA-243902)

GitOrigin-RevId: 9718672f06b58358200d5d7156adb0081e6154d7
This commit is contained in:
Artemiy Sartakov
2020-07-29 10:30:08 +07:00
committed by intellij-monorepo-bot
parent 3e40f1a28a
commit 69c40bf3bb
14 changed files with 92 additions and 0 deletions

View File

@@ -119,6 +119,21 @@ public class UnimplementInterfaceAction implements IntentionAction {
if (target == psiClass) return;
if (targetClass.hasModifierProperty(PsiModifier.SEALED)) {
PsiReferenceList permitsList = targetClass.getPermitsList();
if (permitsList != null) {
Arrays.stream(permitsList.getReferenceElements())
.filter(r -> r.resolve() == psiClass).findFirst()
.ifPresent(r -> r.delete());
PsiModifierList modifiers = psiClass.getModifierList();
if (modifiers != null && modifiers.hasExplicitModifier(PsiModifier.NON_SEALED)) {
boolean hasAnotherSealedParent = hasSealedParent(psiClass.getExtendsListTypes(), targetClass);
if (!hasAnotherSealedParent) hasAnotherSealedParent = hasSealedParent(psiClass.getImplementsListTypes(), targetClass);
if (!hasAnotherSealedParent) modifiers.setModifierProperty(PsiModifier.NON_SEALED, false);
}
}
}
final Set<PsiMethod> superMethods = new HashSet<>();
for (PsiClass aClass : psiClass.getSupers()) {
Collections.addAll(superMethods, aClass.getAllMethods());
@@ -131,6 +146,12 @@ public class UnimplementInterfaceAction implements IntentionAction {
}
}
private static boolean hasSealedParent(PsiClassType[] types, PsiClass toExclude) {
return Arrays.stream(types)
.map(t -> t.resolve())
.anyMatch(parent -> parent != null && parent != toExclude && parent.hasModifierProperty(PsiModifier.SEALED));
}
@Override
public boolean startInWriteAction() {
return true;

View File

@@ -0,0 +1,6 @@
// "Unimplement Class" "true"
public sealed interface A permits B {}
sealed class C {}
non-sealed class B implements A {}

View File

@@ -0,0 +1,6 @@
// "Unimplement Class" "true"
sealed class A {
}
final class B {}

View File

@@ -0,0 +1,4 @@
// "Unimplement Class" "true"
sealed class A {}
final class B {}

View File

@@ -0,0 +1,6 @@
// "Unimplement Class" "true"
sealed class A permits C {}
class B {}
final class C extends A {}

View File

@@ -0,0 +1,4 @@
// "Unimplement Class" "true"
sealed class A {}
class B {}

View File

@@ -0,0 +1,6 @@
// "Unimplement Class" "true"
sealed class A {}
sealed class B permits C {}
final class C extends B {}

View File

@@ -0,0 +1,6 @@
// "Unimplement Class" "true"
public sealed interface A permits B {}
sealed class C permits B {}
non-sealed class B extends C<caret> implements A {}

View File

@@ -0,0 +1,6 @@
// "Unimplement Class" "true"
sealed class A permits B {
}
final class B extends <caret>A {}

View File

@@ -0,0 +1,4 @@
// "Unimplement Class" "true"
sealed class A permits B {}
final class B extends <caret>A {}

View File

@@ -0,0 +1,6 @@
// "Unimplement Class" "true"
sealed class A permits B, C {}
non-sealed class B extends A<caret> {}
final class C extends A {}

View File

@@ -0,0 +1,4 @@
// "Unimplement Class" "true"
sealed class A permits B {}
non-sealed class B extends <caret>A {}

View File

@@ -0,0 +1,6 @@
// "Unimplement Class" "true"
sealed class A permits B {}
sealed class B extends <caret>A permits C {}
final class C extends B {}

View File

@@ -16,8 +16,15 @@
package com.intellij.java.codeInsight.daemon.quickFix;
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
public class UnimplementIntentionTest extends LightQuickFixParameterizedTestCase {
@Override
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
return LightJavaCodeInsightFixtureTestCase.JAVA_15;
}
@Override
protected String getBasePath() {