From 5c444185a36da0669c541f35f1fd17ba20ab5a16 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 31 Jan 2023 18:16:44 +0100 Subject: [PATCH] [intention-preview] ExtendSealedClassFix and improvements to ImplementOrExtendFix GitOrigin-RevId: 6e68f66952d5a995a260f4c235fb48cd1217cdf3 --- .../src/messages/QuickFixBundle.properties | 7 +- .../impl/quickfix/ExtendSealedClassFix.java | 96 +++++++------- .../impl/quickfix/ImplementOrExtendFix.java | 121 ++++-------------- .../extendSealedClass/afterEnumSubclass.java | 2 +- .../extendSealedClass/afterFinalSubclass.java | 2 +- .../afterRecordSubclass.java | 2 +- .../extendSealedClass/afterSimple.java | 2 +- .../afterSubInterfaceWithParents.java | 2 +- .../afterSubclassWithParentObject.java | 2 +- .../extendSealedClass/afterSubinterface.java | 4 + .../extendSealedClass/beforeEnumSubclass.java | 2 +- .../beforeFinalSubclass.java | 2 +- .../beforeRecordSubclass.java | 2 +- .../extendSealedClass/beforeSimple.java | 2 +- .../beforeSubInterfaceWithParents.java | 2 +- .../beforeSubclassWithParentObject.java | 2 +- .../extendSealedClass/beforeSubinterface.java | 4 + 17 files changed, 102 insertions(+), 154 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterSubinterface.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeSubinterface.java diff --git a/java/java-analysis-impl/src/messages/QuickFixBundle.properties b/java/java-analysis-impl/src/messages/QuickFixBundle.properties index fae5c62a0945..fe9129131a0b 100644 --- a/java/java-analysis-impl/src/messages/QuickFixBundle.properties +++ b/java/java-analysis-impl/src/messages/QuickFixBundle.properties @@ -427,12 +427,11 @@ remove.unreachable.branches=Remove unreachable branches simplify.boolean.expression.extracting.side.effects=\ extracting side effects intention.move.parenthesis.name=Fix closing parenthesis placement -extend.sealed.title=Extend sealed class and mark as -implement.sealed.title=Implement sealed interface and mark as +extend.sealed.title=Make ''{0}'' {1, choice, 1#extend|2#implement} ''{2}'' and implement.or.extend.fix.family=Implement/Extend required base class -implement.or.extend.fix.implement.text=Implement ''{0}'' -implement.or.extend.fix.extend.text=Extend ''{0}'' +implement.or.extend.fix.implement.text=Make ''{0}'' implement ''{1}'' +implement.or.extend.fix.extend.text=Make ''{0}'' extend ''{1}'' seal.class.from.permits.list.fix=Seal inheritor diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ExtendSealedClassFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ExtendSealedClassFix.java index 5a76deef2936..799b1ba5e256 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ExtendSealedClassFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ExtendSealedClassFix.java @@ -1,7 +1,8 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2023 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.codeInsight.daemon.QuickFixBundle; +import com.intellij.codeInsight.intention.FileModifier; import com.intellij.codeInsight.intention.choice.ChoiceTitleIntentionAction; import com.intellij.codeInsight.intention.choice.ChoiceVariantIntentionAction; import com.intellij.codeInsight.intention.choice.DefaultIntentionActionWithChoice; @@ -16,7 +17,6 @@ import com.intellij.psi.*; import com.intellij.psi.search.searches.DirectClassInheritorsSearch; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.Query; -import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -25,61 +25,51 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -import static com.intellij.util.ObjectUtils.tryCast; public class ExtendSealedClassFix implements DefaultIntentionActionWithChoice { + @FileModifier.SafeFieldForPreview private final SmartPsiElementPointer myParentClassPointer; + @FileModifier.SafeFieldForPreview private final SmartPsiElementPointer mySubclassPointer; + private final @Nls String myName; - private static final String[] SUBCLASS_MODIFIERS = {PsiModifier.FINAL, PsiModifier.NON_SEALED, PsiModifier.SEALED}; - - private final boolean myParentIsInterface; - private final boolean myChildIsInterface; - private final SmartPsiElementPointer mySubclassReferencePointer; - - private ExtendSealedClassFix(PsiJavaCodeReferenceElement reference, boolean parentIsInterface, boolean childIsInterface) { - mySubclassReferencePointer = SmartPointerManager.createPointer(reference); - myParentIsInterface = parentIsInterface; - myChildIsInterface = childIsInterface; + private ExtendSealedClassFix(PsiClass parentClass, PsiClass subclass) { + myParentClassPointer = SmartPointerManager.createPointer(parentClass); + mySubclassPointer = SmartPointerManager.createPointer(subclass); + int extendsImplements = subclass.isInterface() || !parentClass.isInterface() ? 1 : 2; + myName = QuickFixBundle.message("extend.sealed.title", subclass.getName(), extendsImplements, parentClass.getName()); } @Override public @NotNull ChoiceTitleIntentionAction getTitle() { - String fixName = getName(); - return new ChoiceTitleIntentionAction(fixName, fixName); - } - - @NotNull - @Nls - private String getName() { - return QuickFixBundle.message(myParentIsInterface ? "implement.sealed.title" : "extend.sealed.title"); + return new ChoiceTitleIntentionAction(QuickFixBundle.message("implement.or.extend.fix.family"), myName); } @Override public @NotNull List getVariants() { - if (!myParentIsInterface && myChildIsInterface) return Collections.emptyList(); - if (myChildIsInterface) { - return Arrays.asList(new ExtendSealedClassVariantAction(0, PsiModifier.SEALED), - new ExtendSealedClassVariantAction(1, PsiModifier.NON_SEALED)); + PsiClass subclass = mySubclassPointer.getElement(); + PsiClass parentClass = myParentClassPointer.getElement(); + if (subclass == null || parentClass == null) return Collections.emptyList(); + boolean parentIsInterface = parentClass.isInterface(); + boolean subclassIsInterface = subclass.isInterface(); + if (!parentIsInterface && subclassIsInterface) return Collections.emptyList(); + if (subclassIsInterface) { + return Arrays.asList(new ExtendSealedClassVariantAction(0, PsiModifier.SEALED, myParentClassPointer, mySubclassPointer), + new ExtendSealedClassVariantAction(1, PsiModifier.NON_SEALED, myParentClassPointer, mySubclassPointer)); } - return IntStream.range(0, SUBCLASS_MODIFIERS.length) - .mapToObj(i -> new ExtendSealedClassVariantAction(i, SUBCLASS_MODIFIERS[i])) - .collect(Collectors.toList()); + return Arrays.asList(new ExtendSealedClassVariantAction(0, PsiModifier.FINAL, myParentClassPointer, mySubclassPointer), + new ExtendSealedClassVariantAction(1, PsiModifier.SEALED, myParentClassPointer, mySubclassPointer), + new ExtendSealedClassVariantAction(2, PsiModifier.NON_SEALED, myParentClassPointer, mySubclassPointer)); } /** * @return fixes or null if given case is not supported (but probably valid) */ - static LocalQuickFix @Nullable [] createFixes(@NotNull PsiJavaCodeReferenceElement subclassReference, - @NotNull PsiClass parentClass, - @NotNull PsiClass subclass) { + static LocalQuickFix @Nullable [] createFixes(@NotNull PsiClass parentClass, @NotNull PsiClass subclass) { if (!parentClass.hasModifierProperty(PsiModifier.SEALED) || !parentClass.getManager().isInProject(parentClass)) return null; boolean parentIsInterface = parentClass.isInterface(); if (parentIsInterface && (subclass.isRecord() || subclass.isEnum())) return null; PsiModifierList modifiers = subclass.getModifierList(); if (modifiers == null || hasSealedClassSubclassModifier(modifiers)) return null; - ExtendSealedClassFix extendSealedClassFix = new ExtendSealedClassFix(subclassReference, parentIsInterface, subclass.isInterface()); + ExtendSealedClassFix extendSealedClassFix = new ExtendSealedClassFix(parentClass, subclass); List actions = new ArrayList<>(); actions.add(extendSealedClassFix.getTitle()); actions.addAll(extendSealedClassFix.getVariants()); @@ -93,17 +83,25 @@ public class ExtendSealedClassFix implements DefaultIntentionActionWithChoice { } private static boolean hasSealedClassSubclassModifier(@NotNull PsiModifierList modifiers) { - return ContainerUtil.exists(SUBCLASS_MODIFIERS, m -> modifiers.hasExplicitModifier(m)); + return modifiers.hasExplicitModifier(PsiModifier.FINAL) || + modifiers.hasExplicitModifier(PsiModifier.SEALED) || + modifiers.hasExplicitModifier(PsiModifier.NON_SEALED); } - private class ExtendSealedClassVariantAction extends ChoiceVariantIntentionAction { + private static class ExtendSealedClassVariantAction extends ChoiceVariantIntentionAction { private final int myIndex; private final @NlsSafe String myModifier; + private final SmartPsiElementPointer myParentClassPointer; + private final SmartPsiElementPointer mySubclassPointer; - private ExtendSealedClassVariantAction(int index, @NotNull String modifier) { + private ExtendSealedClassVariantAction(int index, @NotNull String modifier, + SmartPsiElementPointer parentClassPointer, + SmartPsiElementPointer subclassPointer) { myIndex = index; myModifier = modifier; + myParentClassPointer = parentClassPointer; + mySubclassPointer = subclassPointer; } @Override @@ -118,7 +116,7 @@ public class ExtendSealedClassFix implements DefaultIntentionActionWithChoice { @Override public @IntentionFamilyName @NotNull String getFamilyName() { - return ExtendSealedClassFix.this.getName(); + return QuickFixBundle.message("implement.or.extend.fix.family"); } @Override @@ -126,14 +124,16 @@ public class ExtendSealedClassFix implements DefaultIntentionActionWithChoice { return getFamilyName() + " " + myModifier; } + @Override + public @Nullable PsiElement getElementToMakeWritable(@NotNull PsiFile currentFile) { + return mySubclassPointer.getContainingFile(); + } + @Override public void applyFix(@NotNull Project project, PsiFile file, @Nullable Editor editor) { - if (editor == null) return; - PsiJavaCodeReferenceElement referenceElement = mySubclassReferencePointer.getElement(); - if (referenceElement == null) return; - PsiClass parentClass = PsiTreeUtil.getParentOfType(referenceElement, PsiClass.class); + PsiClass parentClass = myParentClassPointer.getElement(); if (parentClass == null || !parentClass.hasModifierProperty(PsiModifier.SEALED)) return; - PsiClass subclass = tryCast(referenceElement.resolve(), PsiClass.class); + PsiClass subclass = mySubclassPointer.getElement(); if (subclass == null) return; if (ImplementOrExtendFix.implementOrExtend(parentClass, subclass) == null) return; PsiModifierList modifiers = subclass.getModifierList(); @@ -146,5 +146,13 @@ public class ExtendSealedClassFix implements DefaultIntentionActionWithChoice { subclass.navigate(true); } } + + @Override + public @Nullable FileModifier getFileModifierForPreview(@NotNull PsiFile target) { + PsiClass subclass = mySubclassPointer.getElement(); + PsiClass copy = PsiTreeUtil.findSameElementInCopy(subclass, target); + if (copy == null) return null; + return new ExtendSealedClassVariantAction(myIndex, myModifier, myParentClassPointer, SmartPointerManager.createPointer(copy)); + } } } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementOrExtendFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementOrExtendFix.java index 49262867934b..864a64edcc06 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementOrExtendFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementOrExtendFix.java @@ -1,102 +1,38 @@ -// 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-2023 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.CommonBundle; -import com.intellij.codeInsight.FileModificationService; import com.intellij.codeInsight.daemon.QuickFixBundle; +import com.intellij.codeInsight.intention.FileModifier; import com.intellij.codeInsight.intention.IntentionAction; -import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo; import com.intellij.codeInspection.LocalQuickFix; import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement; import com.intellij.codeInspection.util.IntentionFamilyName; import com.intellij.codeInspection.util.IntentionName; -import com.intellij.ide.highlighter.JavaFileType; -import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.pom.Navigatable; import com.intellij.psi.*; -import com.intellij.refactoring.RefactoringBundle; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.containers.ContainerUtil; import com.siyeh.ig.psiutils.TypeUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Objects; - -import static com.intellij.util.ObjectUtils.tryCast; - public final class ImplementOrExtendFix extends LocalQuickFixAndIntentionActionOnPsiElement { - private final SmartPsiElementPointer mySubclassPointer; - private final SmartPsiElementPointer myParentClassPointer; + @SafeFieldForPreview private final SmartPsiElementPointer mySubclassPointer; + @SafeFieldForPreview private final SmartPsiElementPointer myParentClassPointer; private final boolean myOnTheFly; + private final @IntentionName String myName; private ImplementOrExtendFix(@NotNull PsiElement place, @NotNull PsiClass subclass, @NotNull PsiClass parentClass, boolean onTheFly) { super(place); mySubclassPointer = SmartPointerManager.createPointer(subclass); myParentClassPointer = SmartPointerManager.createPointer(parentClass); myOnTheFly = onTheFly; - } - - @Override - public @NotNull IntentionPreviewInfo generatePreview(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) { - PsiClass subclass = mySubclassPointer.getElement(); - PsiClass parent = myParentClassPointer.getElement(); - if (subclass == null || !subclass.isValid() || parent == null || !parent.isValid()) return IntentionPreviewInfo.EMPTY; - PsiFile subclassFile = subclass.getContainingFile(); - - if (!subclassFile.isWritable() || subclass.getImplementsList() == null || subclass.getExtendsList() == null) { - return IntentionPreviewInfo.EMPTY; - } - - String before = createClassDescription(subclass, null, null); - String after = createClassDescription(subclass, parent.isInterface() ? null : parent, parent.isInterface() ? parent : null); - if (before == null || after == null) { - return IntentionPreviewInfo.EMPTY; - } - return new IntentionPreviewInfo.CustomDiff(JavaFileType.INSTANCE, subclassFile.getName(), before, after); - } - - @Nullable - private static String createClassDescription(@Nullable PsiClass psiClass, - @Nullable PsiClass addToExtends, - @Nullable PsiClass addToImplement) { - if (psiClass == null) { - return null; - } - StringBuilder stringBuilder = new StringBuilder(); - PsiElement brace = psiClass.getLBrace(); - for (PsiElement child : psiClass.getChildren()) { - if (child == brace) { - break; - } - if (child == psiClass.getImplementsList() && addToImplement!=null){ - String text = child.getText(); - PsiElementFactory elementFactory = JavaPsiFacade.getInstance(child.getProject()).getElementFactory(); - PsiClassType type = elementFactory.createType(addToImplement); - text = StringUtil.isNotEmpty(text) ? text + ", " + type.getName() : "implements " + type.getName(); - if (!(child.getPrevSibling() instanceof PsiWhiteSpace)) { - text = " " + text; - } - stringBuilder.append(text); - continue; - } - if (child == psiClass.getExtendsList() && addToExtends!=null) { - PsiElementFactory elementFactory = JavaPsiFacade.getInstance(child.getProject()).getElementFactory(); - PsiClassType type = elementFactory.createType(addToExtends); - String text = "extends " + type.getName(); - if (!(child.getPrevSibling() instanceof PsiWhiteSpace)) { - text = " " + text; - } - stringBuilder.append(text); - continue; - } - stringBuilder.append(child.getText()); - } - return stringBuilder.toString(); + myName = parentClass.isInterface() && !subclass.isInterface() + ? QuickFixBundle.message("implement.or.extend.fix.implement.text", subclass.getName(), parentClass.getName()) + : QuickFixBundle.message("implement.or.extend.fix.extend.text", subclass.getName(), parentClass.getName()); } @Override @@ -109,34 +45,32 @@ public final class ImplementOrExtendFix extends LocalQuickFixAndIntentionActionO // to plugin.xml or java class PsiClass subclass = mySubclassPointer.getElement(); if (subclass == null || !subclass.isValid()) return; - PsiFile subclassFile = subclass.getContainingFile(); - boolean external = file != subclassFile; - if (external && !subclassFile.isWritable()) { - String className = subclass.getQualifiedName(); - Messages.showErrorDialog(project, RefactoringBundle.message("0.is.read.only", className), CommonBundle.getErrorTitle()); - return; - } PsiClass parentClass = myParentClassPointer.getElement(); if (parentClass == null) return; - if (!FileModificationService.getInstance().prepareFileForWrite(subclassFile)) return; + boolean external = file != subclass.getContainingFile(); - WriteAction.run(() -> { - PsiElement e = implementOrExtend(parentClass, subclass); - if (myOnTheFly && external && e instanceof Navigatable) ((Navigatable)e).navigate(true); - }); + PsiElement e = implementOrExtend(parentClass, subclass); + if (myOnTheFly && external && e instanceof Navigatable) ((Navigatable)e).navigate(true); } @Override - public boolean startInWriteAction() { - return false; + public @Nullable PsiElement getElementToMakeWritable(@NotNull PsiFile currentFile) { + return mySubclassPointer.getElement(); + } + + @Override + public @Nullable FileModifier getFileModifierForPreview(@NotNull PsiFile target) { + PsiClass subclass = mySubclassPointer.getElement(); + PsiClass copy = PsiTreeUtil.findSameElementInCopy(subclass, target); + PsiElement place = myStartElement.getElement(); + PsiClass parentClass = myParentClassPointer.getElement(); + if (copy == null || place == null || parentClass == null) return null; + return new ImplementOrExtendFix(place, copy, parentClass, myOnTheFly); } @Override public @IntentionName @NotNull String getText() { - PsiClass parentClass = Objects.requireNonNull(myParentClassPointer.getElement()); - return parentClass.isInterface() - ? QuickFixBundle.message("implement.or.extend.fix.implement.text", parentClass.getQualifiedName()) - : QuickFixBundle.message("implement.or.extend.fix.extend.text", parentClass.getQualifiedName()); + return myName; } @Override @@ -165,10 +99,9 @@ public final class ImplementOrExtendFix extends LocalQuickFixAndIntentionActionO return LocalQuickFix.EMPTY_ARRAY; } - PsiJavaCodeReferenceElement subclassRef = tryCast(place, PsiJavaCodeReferenceElement.class); - LocalQuickFix[] fixes = subclassRef == null ? null : ExtendSealedClassFix.createFixes(subclassRef, parentClass, subclass); + LocalQuickFix[] fixes = ExtendSealedClassFix.createFixes(parentClass, subclass); if (fixes != null) return fixes; - return new LocalQuickFix[]{new ImplementOrExtendFix(place, subclass, parentClass, onTheFly)}; + return new LocalQuickFix[]{ new ImplementOrExtendFix(place, subclass, parentClass, onTheFly) }; } static boolean hasNonObjectParent(@NotNull PsiClass psiClass) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterEnumSubclass.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterEnumSubclass.java index 13c3a7f36a8f..ad7e8488c959 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterEnumSubclass.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterEnumSubclass.java @@ -1,4 +1,4 @@ -// "Implement 'Parent'" "true" +// "Make 'MyEnum' implement 'Parent'" "true-preview" sealed interface Parent permits MyEnum {} enum MyEnum implements Parent {} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterFinalSubclass.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterFinalSubclass.java index fe5064fc9991..b6736a03ffbd 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterFinalSubclass.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterFinalSubclass.java @@ -1,4 +1,4 @@ -// "Extend 'Parent'" "true" +// "Make 'Child' extend 'Parent'" "true-preview" sealed class Parent permits Child {} final class Child extends Parent {} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterRecordSubclass.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterRecordSubclass.java index 59f086b9e5a6..ea35f0ccc28b 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterRecordSubclass.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterRecordSubclass.java @@ -1,4 +1,4 @@ -// "Implement 'Parent'" "true" +// "Make 'User' implement 'Parent'" "true-preview" sealed interface Parent permits User {} record User(int age) implements Parent {} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterSimple.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterSimple.java index 47ac7f0fe5e4..c8aee416a5fc 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterSimple.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterSimple.java @@ -1,4 +1,4 @@ -// "final" "true" +// "final" "true-preview" sealed class Parent permits Child {} final class Child extends Parent {} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterSubInterfaceWithParents.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterSubInterfaceWithParents.java index ba7d5156356a..4f1a670f7c01 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterSubInterfaceWithParents.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterSubInterfaceWithParents.java @@ -1,4 +1,4 @@ -// "non-sealed" "true" +// "non-sealed" "true-preview" sealed interface Parent permits Child, Foo {} interface OtherParent {} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterSubclassWithParentObject.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterSubclassWithParentObject.java index 47ac7f0fe5e4..c8aee416a5fc 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterSubclassWithParentObject.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterSubclassWithParentObject.java @@ -1,4 +1,4 @@ -// "final" "true" +// "final" "true-preview" sealed class Parent permits Child {} final class Child extends Parent {} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterSubinterface.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterSubinterface.java new file mode 100644 index 000000000000..c2da987ef947 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/afterSubinterface.java @@ -0,0 +1,4 @@ +// "Make 'Child' extend 'Parent'" "true-preview" +sealed interface Parent permits Child {} + +non-sealed interface Child extends Parent {} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeEnumSubclass.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeEnumSubclass.java index 505bf3a924bd..e72d3f13bcbf 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeEnumSubclass.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeEnumSubclass.java @@ -1,4 +1,4 @@ -// "Implement 'Parent'" "true" +// "Make 'MyEnum' implement 'Parent'" "true-preview" sealed interface Parent permits MyEnum {} enum MyEnum {} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeFinalSubclass.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeFinalSubclass.java index f3cf14939396..5b4987f77d1d 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeFinalSubclass.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeFinalSubclass.java @@ -1,4 +1,4 @@ -// "Extend 'Parent'" "true" +// "Make 'Child' extend 'Parent'" "true-preview" sealed class Parent permits Child {} final class Child {} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeRecordSubclass.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeRecordSubclass.java index bee6f5e1a31f..a265ec254b54 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeRecordSubclass.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeRecordSubclass.java @@ -1,4 +1,4 @@ -// "Implement 'Parent'" "true" +// "Make 'User' implement 'Parent'" "true-preview" sealed interface Parent permits User {} record User(int age) {} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeSimple.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeSimple.java index 5122991f4860..686befa64482 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeSimple.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeSimple.java @@ -1,4 +1,4 @@ -// "final" "true" +// "final" "true-preview" sealed class Parent permits Child {} class Child {} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeSubInterfaceWithParents.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeSubInterfaceWithParents.java index 160559df9596..7f3fed347424 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeSubInterfaceWithParents.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeSubInterfaceWithParents.java @@ -1,4 +1,4 @@ -// "non-sealed" "true" +// "non-sealed" "true-preview" sealed interface Parent permits Child, Foo {} interface OtherParent {} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeSubclassWithParentObject.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeSubclassWithParentObject.java index ad72d12f8329..3c2bc0d37805 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeSubclassWithParentObject.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeSubclassWithParentObject.java @@ -1,4 +1,4 @@ -// "final" "true" +// "final" "true-preview" sealed class Parent permits Child {} class Child extends Object {} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeSubinterface.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeSubinterface.java new file mode 100644 index 000000000000..93ef04028d4f --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extendSealedClass/beforeSubinterface.java @@ -0,0 +1,4 @@ +// "Make 'Child' extend 'Parent'" "true-preview" +sealed interface Parent permits Child {} + +non-sealed interface Child {} \ No newline at end of file