mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-inspections] CreateTypeParameterFromUsageFix: mod-command
Part of IDEA-322693 Migrate as much as possible Java intentions and quick-fixes to ModCommand API GitOrigin-RevId: 898bf526ac0700c29641e09ffccd10bf2a7ab3f1
This commit is contained in:
committed by
intellij-monorepo-bot
parent
f94d4a27d9
commit
b59721ab73
@@ -120,7 +120,7 @@ create.method.body=Create Method Body
|
||||
create.method.from.usage.text=Create method ''{0}''
|
||||
create.type.parameter.from.usage.family=Create type parameter from usage
|
||||
create.type.parameter.from.usage.text=Create type parameter ''{0}''
|
||||
create.type.parameter.from.usage.chooser.title=Place to add type parameter
|
||||
create.type.parameter.from.usage.chooser.title=Place to Add Type Parameter
|
||||
create.parameter.from.usage.family=Create parameter from Usage
|
||||
create.property.from.usage.family=Create property From Usage
|
||||
create.property.from.usage.text=Create property ''{0}''
|
||||
|
||||
+31
-74
@@ -1,40 +1,27 @@
|
||||
// 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.FileModificationService;
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInsight.intention.impl.BaseIntentionAction;
|
||||
import com.intellij.ide.highlighter.JavaFileType;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.modcommand.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pass;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.refactoring.IntroduceTargetChooser;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.intellij.util.ObjectUtils.tryCast;
|
||||
|
||||
public class CreateTypeParameterFromUsageFix extends BaseIntentionAction {
|
||||
private final SmartPsiElementPointer<PsiJavaCodeReferenceElement> myRef;
|
||||
|
||||
public class CreateTypeParameterFromUsageFix extends PsiBasedModCommandAction<PsiJavaCodeReferenceElement> {
|
||||
public CreateTypeParameterFromUsageFix(PsiJavaCodeReferenceElement refElement) {
|
||||
myRef = SmartPointerManager.getInstance(refElement.getProject()).createSmartPsiElementPointer(refElement);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiJavaCodeReferenceElement getElement() {
|
||||
return myRef.getElement();
|
||||
super(refElement);
|
||||
}
|
||||
|
||||
@Nls(capitalization = Nls.Capitalization.Sentence)
|
||||
@@ -45,77 +32,47 @@ public class CreateTypeParameterFromUsageFix extends BaseIntentionAction {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
PsiJavaCodeReferenceElement element = getElement();
|
||||
if (element == null) return false;
|
||||
protected @Nullable Presentation getPresentation(@NotNull ActionContext actionContext, @NotNull PsiJavaCodeReferenceElement element) {
|
||||
Context context = Context.from(element, true);
|
||||
boolean available = context != null;
|
||||
if (available) {
|
||||
setText(QuickFixBundle.message("create.type.parameter.from.usage.text", context.typeName));
|
||||
}
|
||||
return available;
|
||||
if (context == null) return null;
|
||||
return Presentation.of(QuickFixBundle.message("create.type.parameter.from.usage.text", context.typeName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
PsiJavaCodeReferenceElement element = getElement();
|
||||
if (element == null) return;
|
||||
protected @NotNull ModCommand perform(@NotNull ActionContext actionContext, @NotNull PsiJavaCodeReferenceElement element) {
|
||||
Context context = Context.from(element, false);
|
||||
if (context == null) return;
|
||||
if (context == null) return ModCommand.nop();
|
||||
List<PsiNameIdentifierOwner> placesToAdd = context.placesToAdd;
|
||||
|
||||
Application application = ApplicationManager.getApplication();
|
||||
if (placesToAdd.size() == 1 || application.isUnitTestMode() || editor == null) {
|
||||
PsiElement first = placesToAdd.get(0);
|
||||
createTypeParameter(first, context.typeName);
|
||||
}
|
||||
else {
|
||||
IntroduceTargetChooser.showChooser(
|
||||
editor,
|
||||
placesToAdd,
|
||||
new Pass<>() {
|
||||
@Override
|
||||
public void pass(PsiNameIdentifierOwner owner) {
|
||||
createTypeParameter(owner, context.typeName);
|
||||
}
|
||||
},
|
||||
PsiNamedElement::getName,
|
||||
QuickFixBundle.message("create.type.parameter.from.usage.chooser.title")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return false;
|
||||
return new ModChooseAction(QuickFixBundle.message("create.type.parameter.from.usage.chooser.title"),
|
||||
ContainerUtil.map(placesToAdd, place ->
|
||||
ModCommand.psiUpdateStep(place, Objects.requireNonNull(place.getName()),
|
||||
(owner, updater) -> createTypeParameter(owner, context.typeName))));
|
||||
}
|
||||
|
||||
private static void createTypeParameter(@NotNull PsiElement methodOrClass, @NotNull String name) {
|
||||
Project project = methodOrClass.getProject();
|
||||
if (!FileModificationService.getInstance().preparePsiElementsForWrite(methodOrClass)) return;
|
||||
WriteCommandAction.runWriteCommandAction(project, QuickFixBundle.message("create.type.parameter.from.usage.family"), null, () -> {
|
||||
PsiTypeParameterListOwner typeParameterListOwner = tryCast(methodOrClass, PsiTypeParameterListOwner.class);
|
||||
if (typeParameterListOwner == null) {
|
||||
throw new IllegalStateException("Only methods and classes allowed here, but was: " + methodOrClass.getClass());
|
||||
}
|
||||
PsiTypeParameterList typeParameterList = typeParameterListOwner.getTypeParameterList();
|
||||
final String typeParameterListText;
|
||||
if (typeParameterList == null) {
|
||||
PsiTypeParameterListOwner typeParameterListOwner = tryCast(methodOrClass, PsiTypeParameterListOwner.class);
|
||||
if (typeParameterListOwner == null) {
|
||||
throw new IllegalStateException("Only methods and classes allowed here, but was: " + methodOrClass.getClass());
|
||||
}
|
||||
PsiTypeParameterList typeParameterList = typeParameterListOwner.getTypeParameterList();
|
||||
final String typeParameterListText;
|
||||
if (typeParameterList == null) {
|
||||
typeParameterListText = "<" + name + ">";
|
||||
}
|
||||
else {
|
||||
String existingTypeParameterText = typeParameterList.getText();
|
||||
if (typeParameterList.getTypeParameters().length == 0) {
|
||||
typeParameterListText = "<" + name + ">";
|
||||
}
|
||||
else {
|
||||
String existingTypeParameterText = typeParameterList.getText();
|
||||
if (typeParameterList.getTypeParameters().length == 0) {
|
||||
typeParameterListText = "<" + name + ">";
|
||||
}
|
||||
else {
|
||||
String prefix = existingTypeParameterText.substring(0, existingTypeParameterText.length() - 1);
|
||||
typeParameterListText = prefix + ", " + name + ">";
|
||||
}
|
||||
String prefix = existingTypeParameterText.substring(0, existingTypeParameterText.length() - 1);
|
||||
typeParameterListText = prefix + ", " + name + ">";
|
||||
}
|
||||
PsiTypeParameterList newTypeParameterList = createTypeParameterList(typeParameterListText, project);
|
||||
replaceOrAddTypeParameterList(methodOrClass, typeParameterList, newTypeParameterList);
|
||||
});
|
||||
}
|
||||
PsiTypeParameterList newTypeParameterList = createTypeParameterList(typeParameterListText, project);
|
||||
replaceOrAddTypeParameterList(methodOrClass, typeParameterList, newTypeParameterList);
|
||||
}
|
||||
|
||||
private static void replaceOrAddTypeParameterList(@NotNull PsiElement methodOrClass,
|
||||
|
||||
+1
-1
@@ -74,7 +74,7 @@ public class DefaultQuickFixProvider extends UnresolvedReferenceQuickFixProvider
|
||||
SurroundWithQuotesAnnotationParameterValueFix.register(registrar, ref);
|
||||
|
||||
if (PsiUtil.isLanguageLevel5OrHigher(ref)) {
|
||||
registrar.register(new CreateTypeParameterFromUsageFix(ref));
|
||||
registrar.register(new CreateTypeParameterFromUsageFix(ref).asIntention());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Create type parameter 'T'" "true"
|
||||
// "Create type parameter 'T'" "true-preview"
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class Test<T> extends Callable<T> {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Create type parameter 'T'" "true"
|
||||
// "Create type parameter 'T'" "true-preview"
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class Test<T> extends Callable<T> {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Create type parameter 'T'" "true"
|
||||
// "Create type parameter 'T'" "true-preview"
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class Test<B, T> extends Callable<T> {
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// "Create type parameter 'T'|->foo" "true-preview"
|
||||
|
||||
public class InMethod {
|
||||
<T> void foo(T t) {
|
||||
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// "Create type parameter 'T'|->InMethod" "true-preview"
|
||||
|
||||
public class InMethod<T> {
|
||||
void foo(T t) {
|
||||
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Create type parameter 'T'" "true"
|
||||
// "Create type parameter 'T'" "true-preview"
|
||||
|
||||
public class Test {
|
||||
<T> T foo() {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Create type parameter 'T'" "true"
|
||||
// "Create type parameter 'T'" "true-preview"
|
||||
|
||||
record Point<T>(T x, T y) {
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Create type parameter 'U'" "true"
|
||||
// "Create type parameter 'U'" "true-preview"
|
||||
|
||||
public class Helpers {
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Create type parameter 'T'" "true"
|
||||
// "Create type parameter 'T'" "true-preview"
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class Test extends Callable<T<caret>> {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Create type parameter 'T'" "true"
|
||||
// "Create type parameter 'T'" "true-preview"
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class Test<> extends Callable<T<caret>> {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Create type parameter 'T'" "true"
|
||||
// "Create type parameter 'T'" "true-preview"
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class Test<B> extends Callable<T<caret>> {
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// "Create type parameter 'T'|->foo" "true-preview"
|
||||
|
||||
public class InMethod {
|
||||
void foo(<caret>T t) {
|
||||
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// "Create type parameter 'T'|->InMethod" "true-preview"
|
||||
|
||||
public class InMethod {
|
||||
void foo(<caret>T t) {
|
||||
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Create type parameter 'T'" "true"
|
||||
// "Create type parameter 'T'" "true-preview"
|
||||
|
||||
public class Test {
|
||||
T<caret> foo() {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Create type parameter 'T'" "true"
|
||||
// "Create type parameter 'T'" "true-preview"
|
||||
|
||||
record Point(T<caret> x, T y) {
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Create type parameter 'U'" "true"
|
||||
// "Create type parameter 'U'" "true-preview"
|
||||
|
||||
public class Helpers {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user