mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-20 13:31:28 +07:00
[java] add move all members to class fix
GitOrigin-RevId: f5ad44f993f2f386c9847dc57ddac86cb4cf45d2
This commit is contained in:
committed by
intellij-monorepo-bot
parent
96dbed77fc
commit
31928210fc
@@ -658,3 +658,6 @@ error.unnamed.method.parameter.not.allowed=Unnamed method parameter is not allow
|
||||
error.unnamed.variable.not.allowed.in.this.context=Unnamed variable declaration is not allowed in this context
|
||||
error.unnamed.variable.brackets=Brackets are not allowed after unnamed variable declaration
|
||||
error.unnamed.variable.without.initializer=Unnamed variable declaration must have an initializer
|
||||
intention.family.name.move.members.into.class=Move members into class
|
||||
chooser.popup.title.select.class.to.move.members.to=Select Target Class
|
||||
intention.family.name.move.members.to=Move members to {0}
|
||||
|
||||
@@ -3730,6 +3730,7 @@ public final class HighlightUtil {
|
||||
return feature.level;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo.Builder checkFeature(@NotNull PsiElement element,
|
||||
@NotNull HighlightingFeature feature,
|
||||
@NotNull LanguageLevel level,
|
||||
@@ -3737,6 +3738,7 @@ public final class HighlightUtil {
|
||||
return checkFeature(element, feature, level, file, null, HighlightInfoType.ERROR);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo.Builder checkFeature(@NotNull PsiElement element,
|
||||
@NotNull HighlightingFeature feature,
|
||||
@NotNull LanguageLevel level,
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.daemon.JavaErrorBundle;
|
||||
import com.intellij.codeInsight.daemon.impl.*;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.AdjustFunctionContextFix;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.MoveMembersIntoClassFix;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.intention.QuickFixFactory;
|
||||
@@ -2219,12 +2220,25 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
|
||||
private HighlightInfo.Builder checkUnnamedClassMember(@NotNull PsiMember member) {
|
||||
if (!(member.getContainingClass() instanceof PsiUnnamedClass)) {
|
||||
if (!(member.getContainingClass() instanceof PsiUnnamedClass unnamedClass)) {
|
||||
return null;
|
||||
}
|
||||
return checkFeature(member, HighlightingFeature.UNNAMED_CLASSES);
|
||||
|
||||
HighlightInfo.Builder builder = checkFeature(member, HighlightingFeature.UNNAMED_CLASSES);
|
||||
if (builder == null) return null;
|
||||
|
||||
if (!(member instanceof PsiClass) && !HighlightingFeature.UNNAMED_CLASSES.isAvailable(member)) {
|
||||
boolean hasClassToRelocate = PsiTreeUtil.findChildOfType(unnamedClass, PsiClass.class) != null;
|
||||
if (hasClassToRelocate) {
|
||||
MoveMembersIntoClassFix fix = new MoveMembersIntoClassFix(unnamedClass);
|
||||
builder.registerFix(fix, null, null, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private HighlightInfo.Builder checkFeature(@NotNull PsiElement element, @NotNull HighlightingFeature feature) {
|
||||
return HighlightUtil.checkFeature(element, feature, myLanguageLevel, myFile);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
// 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.java.analysis.JavaAnalysisBundle;
|
||||
import com.intellij.modcommand.*;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class MoveMembersIntoClassFix implements ModCommandAction {
|
||||
private final SmartPsiElementPointer<PsiUnnamedClass> myUnnamedClass;
|
||||
|
||||
public MoveMembersIntoClassFix(PsiUnnamedClass unnamedClass) {
|
||||
myUnnamedClass = SmartPointerManager.createPointer(unnamedClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getFamilyName() {
|
||||
return JavaAnalysisBundle.message("intention.family.name.move.members.into.class");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Presentation getPresentation(@NotNull ActionContext context) {
|
||||
return Presentation.of(JavaAnalysisBundle.message("intention.family.name.move.members.into.class"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ModCommand perform(@NotNull ActionContext context) {
|
||||
PsiUnnamedClass unnamedClass = myUnnamedClass.getElement();
|
||||
if (unnamedClass == null) return ModCommand.nop();
|
||||
PsiClass[] innerClasses = unnamedClass.getInnerClasses();
|
||||
|
||||
List<? extends ModCommandAction> actionsPerClass = Arrays.stream(innerClasses).map(MoveAllMembersToParticularClassAction::new).toList();
|
||||
|
||||
return new ModChooseAction(JavaAnalysisBundle.message("chooser.popup.title.select.class.to.move.members.to"), actionsPerClass);
|
||||
}
|
||||
|
||||
private static class MoveAllMembersToParticularClassAction extends PsiUpdateModCommandAction<PsiClass> {
|
||||
private final @NonNls String className;
|
||||
|
||||
private MoveAllMembersToParticularClassAction(PsiClass cls) {
|
||||
super(cls);
|
||||
className = cls.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void invoke(@NotNull ActionContext context, @NotNull PsiClass element, @NotNull ModPsiUpdater updater) {
|
||||
if (!(element.getContainingClass() instanceof PsiUnnamedClass unn)) return;
|
||||
PsiMember[] members = PsiTreeUtil.getChildrenOfType(unn, PsiMember.class);
|
||||
if (members == null) return;
|
||||
List<PsiMember> membersWithoutClasses = Arrays.stream(members).filter(member -> !(member instanceof PsiClass)).toList();
|
||||
for (PsiMember member : membersWithoutClasses) {
|
||||
PsiElement copyMember = member.copy();
|
||||
member.delete();
|
||||
element.add(copyMember);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getFamilyName() {
|
||||
return JavaAnalysisBundle.message("intention.family.name.move.members.to", className);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// "Move members into class" "true-preview"
|
||||
|
||||
class A {
|
||||
|
||||
int field = 12;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Move members into class" "true-preview"
|
||||
|
||||
class A {
|
||||
|
||||
void foo() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
// "Move members into class" "true-preview"
|
||||
|
||||
class A {
|
||||
|
||||
static {
|
||||
System.out.println("initializer");
|
||||
}
|
||||
|
||||
int x = 21;
|
||||
String s = "asdsad";
|
||||
|
||||
void foo() {
|
||||
|
||||
}
|
||||
|
||||
void bar() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// "Move members into class" "true-preview"
|
||||
|
||||
int field<caret> = 12;
|
||||
|
||||
class A {
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// "Move members into class" "true-preview"
|
||||
|
||||
void foo<caret>() {
|
||||
|
||||
}
|
||||
|
||||
class A {
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// "Move members into class" "true-preview"
|
||||
|
||||
void foo<caret>() {
|
||||
|
||||
}
|
||||
|
||||
void bar<caret>() {
|
||||
|
||||
}
|
||||
|
||||
int x = 21;
|
||||
|
||||
String s = "asdsad";
|
||||
|
||||
static {
|
||||
System.out.println("initializer");
|
||||
}
|
||||
|
||||
class A {
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright 2000-2022 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.quickFix.LightQuickFixParameterizedTestCase;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
|
||||
public class MoveMembersIntoClassFixTest extends LightQuickFixParameterizedTestCase {
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/codeInsight/daemonCodeAnalyzer/quickFix/moveMembersIntoClass";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected LanguageLevel getLanguageLevel() {
|
||||
return LanguageLevel.JDK_16;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.java.codeInsight.daemon
|
||||
|
||||
import com.intellij.JavaTestUtil
|
||||
import com.intellij.pom.java.LanguageLevel
|
||||
import com.intellij.testFramework.IdeaTestUtil
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
|
||||
|
||||
class MoveMembersFixTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
override fun getProjectDescriptor() = JAVA_21
|
||||
override fun getBasePath() = JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/daemonCodeAnalyzer/unnamedClass"
|
||||
|
||||
fun testHighlightInsufficientLevel() {
|
||||
IdeaTestUtil.withLevel(module, LanguageLevel.JDK_20, Runnable {
|
||||
doTest()
|
||||
})
|
||||
}
|
||||
|
||||
fun testWithPackageStatement() {
|
||||
doTest()
|
||||
}
|
||||
|
||||
fun testStaticInitializer() {
|
||||
doTest()
|
||||
}
|
||||
|
||||
fun testHashCodeInMethod() {
|
||||
doTest()
|
||||
}
|
||||
|
||||
private fun doTest() {
|
||||
myFixture.configureByFile(getTestName(false) + ".java")
|
||||
myFixture.checkHighlighting()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user