mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[mod-commands] IDEA-333301 Support suggested refactoring in ModCommands
GitOrigin-RevId: dbd1401630a68e3e6ca932c5671f428f81e8324d
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d3f9b07ae2
commit
320c3f2442
+14
@@ -48,6 +48,20 @@ class JavaSuggestedRefactoringAvailability(refactoringSupport: SuggestedRefactor
|
||||
}
|
||||
}
|
||||
|
||||
override fun isAvailable(state: SuggestedRefactoringState): Boolean {
|
||||
val method = state.declaration as? PsiMethod
|
||||
val declarationCopy = state.restoredDeclarationCopy()
|
||||
if (method != null && method.canHaveOverrides(state.oldSignature)) {
|
||||
val restoredMethod = declarationCopy as PsiMethod
|
||||
if (OverridingMethodsSearch.search(restoredMethod, false).findFirst() != null) return true
|
||||
}
|
||||
if (declarationCopy != null) {
|
||||
if (ReferencesSearch.search(declarationCopy, LocalSearchScope(declarationCopy.containingFile)).findFirst() != null) return true
|
||||
if (ReferencesSearch.search(declarationCopy, declarationCopy.useScope).findFirst() != null) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun callStateToDeclarationState(state: SuggestedRefactoringState): SuggestedRefactoringState? {
|
||||
val anchor = state.anchor as? PsiCallExpression ?: return null
|
||||
val resolveResult = anchor.resolveMethodGenerics()
|
||||
|
||||
+8
-10
@@ -5,10 +5,7 @@ import com.intellij.openapi.application.runUndoTransparentWriteAction
|
||||
import com.intellij.openapi.command.executeCommand
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager
|
||||
import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor
|
||||
import com.intellij.refactoring.changeSignature.JavaThrownExceptionInfo
|
||||
import com.intellij.refactoring.changeSignature.ParameterInfoImpl
|
||||
import com.intellij.refactoring.changeSignature.ThrownExceptionInfo
|
||||
import com.intellij.refactoring.changeSignature.*
|
||||
import com.intellij.refactoring.suggested.SuggestedChangeSignatureData
|
||||
import com.intellij.refactoring.suggested.SuggestedRefactoringExecution
|
||||
import com.intellij.refactoring.suggested.SuggestedRefactoringSupport
|
||||
@@ -103,17 +100,18 @@ class JavaSuggestedRefactoringExecution(refactoringSupport: SuggestedRefactoring
|
||||
|
||||
val exceptionInfos = prepareExceptionInfos(newExceptionTypes, oldExceptionTypes)
|
||||
|
||||
val processor = ChangeSignatureProcessor(
|
||||
project,
|
||||
val changeInfo = JavaChangeInfoImpl.generateChangeInfo(
|
||||
declaration,
|
||||
false,
|
||||
false,
|
||||
data.newSignature.visibility?.takeIf { it != data.oldSignature.visibility },
|
||||
data.newSignature.name,
|
||||
returnType,
|
||||
returnType?.let(CanonicalTypes::createTypeWrapper),
|
||||
newParameters.toTypedArray(),
|
||||
exceptionInfos.toTypedArray()
|
||||
)
|
||||
processor.run()
|
||||
exceptionInfos.toTypedArray(),
|
||||
null,
|
||||
null)
|
||||
ChangeSignatureProcessor(project, changeInfo).run()
|
||||
}
|
||||
|
||||
private fun typesEqualWithAnnotations(type1: PsiType?, type2: PsiType?) = type1?.getCanonicalText(true) == type2?.getCanonicalText(true)
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@ public class ChangeSignatureProcessor extends ChangeSignatureProcessorBase {
|
||||
ThrownExceptionInfo[] thrownExceptions,
|
||||
Set<PsiMethod> propagateParametersMethods,
|
||||
Set<PsiMethod> propagateExceptionsMethods) {
|
||||
this(project, JavaChangeInfoImpl.generateChangeInfo(method, generateDelegate, newVisibility, newName, newType, parameterInfo, thrownExceptions,
|
||||
this(project, JavaChangeInfoImpl.generateChangeInfo(method, generateDelegate, true, newVisibility, newName, newType, parameterInfo, thrownExceptions,
|
||||
propagateParametersMethods, propagateExceptionsMethods));
|
||||
}
|
||||
|
||||
|
||||
+6
-1
@@ -1031,7 +1031,12 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
|
||||
final List<PsiParameter> newParameters = ContainerUtil.map(newElements, element -> (PsiParameter)element.variable());
|
||||
final List<String> newParameterNames = ContainerUtil.map(newElements, VariableWrapper::getName);
|
||||
final boolean[] toRemove = myChangeInfo.toRemoveParm();
|
||||
resolveVariableVsFieldsConflicts(newParameters, newParameterNames, myParent, toRemove, myMethodBody, ParameterList.INSTANCE);
|
||||
if (myChangeInfo.isFixFieldConflicts()) {
|
||||
resolveVariableVsFieldsConflicts(newParameters, newParameterNames, myParent, toRemove, myMethodBody, ParameterList.INSTANCE);
|
||||
} else {
|
||||
ChangeSignatureUtil.synchronizeList(myParent, newParameters, ParameterList.INSTANCE, toRemove);
|
||||
JavaCodeStyleManager.getInstance(myParent.getProject()).shortenClassReferences(myParent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -151,7 +151,7 @@ public class JavaRefactoringFactoryImpl extends JavaRefactoringFactory {
|
||||
Set<PsiMethod> propagateParametersMethods,
|
||||
Set<PsiMethod> propagateExceptionsMethods,
|
||||
Consumer<? super List<ParameterInfo>> callback) {
|
||||
JavaChangeInfo changeInfo = JavaChangeInfoImpl.generateChangeInfo(method, generateDelegate, newVisibility,
|
||||
JavaChangeInfo changeInfo = JavaChangeInfoImpl.generateChangeInfo(method, generateDelegate, true, newVisibility,
|
||||
newName, newReturnType != null ? CanonicalTypes.createTypeWrapper(newReturnType) : null,
|
||||
(ParameterInfoImpl[])parameterInfo,
|
||||
thrownExceptions, propagateParametersMethods, propagateExceptionsMethods);
|
||||
|
||||
@@ -30,6 +30,13 @@ public interface JavaChangeInfo extends ChangeInfo {
|
||||
return type != null ? type.getCanonicalText() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if it's desired to fix conflicts between new parameters and field names (adding {@code this.} qualifier to field accesses)
|
||||
*/
|
||||
default boolean isFixFieldConflicts() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
JavaParameterInfo @NotNull [] getNewParameters();
|
||||
|
||||
|
||||
+13
-2
@@ -58,6 +58,7 @@ public class JavaChangeInfoImpl extends UserDataHolderBase implements JavaChange
|
||||
private final PsiExpression[] defaultValues;
|
||||
|
||||
private final boolean isGenerateDelegate;
|
||||
private boolean isFixFieldConflicts = true;
|
||||
final Set<PsiMethod> propagateParametersMethods;
|
||||
final Set<PsiMethod> propagateExceptionsMethods;
|
||||
|
||||
@@ -65,8 +66,8 @@ public class JavaChangeInfoImpl extends UserDataHolderBase implements JavaChange
|
||||
|
||||
public static JavaChangeInfo generateChangeInfo(PsiMethod method,
|
||||
boolean generateDelegate,
|
||||
@Nullable // null means unchanged
|
||||
@PsiModifier.ModifierConstant String newVisibility,
|
||||
boolean fixFieldConflicts,
|
||||
@Nullable("Null means unchanged") @PsiModifier.ModifierConstant String newVisibility,
|
||||
String newName,
|
||||
CanonicalTypes.Type newType,
|
||||
ParameterInfoImpl @NotNull [] parameterInfo,
|
||||
@@ -91,6 +92,7 @@ public class JavaChangeInfoImpl extends UserDataHolderBase implements JavaChange
|
||||
new JavaChangeInfoImpl(newVisibility, method, newName, newType, parameterInfo, thrownExceptions, generateDelegate,
|
||||
propagateParametersMethods, propagateExceptionsMethods);
|
||||
javaChangeInfo.setCheckUnusedParameter();
|
||||
javaChangeInfo.setFixFieldConflicts(fixFieldConflicts);
|
||||
return javaChangeInfo;
|
||||
}
|
||||
|
||||
@@ -236,6 +238,15 @@ public class JavaChangeInfoImpl extends UserDataHolderBase implements JavaChange
|
||||
myCheckUnusedParameter = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFixFieldConflicts() {
|
||||
return isFixFieldConflicts;
|
||||
}
|
||||
|
||||
public void setFixFieldConflicts(boolean fixFieldConflicts) {
|
||||
isFixFieldConflicts = fixFieldConflicts;
|
||||
}
|
||||
|
||||
protected void fillOldParams(PsiMethod method) {
|
||||
PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
oldParameterNames = new String[parameters.length];
|
||||
|
||||
@@ -31,8 +31,8 @@ import java.util.function.Function;
|
||||
*/
|
||||
public sealed interface ModCommand
|
||||
permits ModChooseAction, ModChooseMember, ModCompositeCommand, ModCopyToClipboard, ModCreateFile, ModDeleteFile, ModDisplayMessage,
|
||||
ModHighlight, ModNavigate, ModNothing, ModRenameSymbol, ModShowConflicts, ModStartTemplate, ModUpdateFileText,
|
||||
ModUpdateInspectionOptions {
|
||||
ModHighlight, ModNavigate, ModNothing, ModRenameSymbol, ModShowConflicts, ModStartTemplate, ModUpdateReferences,
|
||||
ModUpdateFileText, ModUpdateInspectionOptions {
|
||||
|
||||
/**
|
||||
* @return true if the command does nothing
|
||||
|
||||
@@ -80,6 +80,18 @@ public interface ModPsiUpdater extends ModPsiNavigator {
|
||||
*/
|
||||
void rename(@NotNull PsiNameIdentifierOwner element, @NotNull List<@NotNull String> suggestedNames);
|
||||
|
||||
/**
|
||||
* Tracks subsequent changes in a given declaration (e.g., method) and produce a command to
|
||||
* update the references to the declaration (maybe displaying UI).
|
||||
* The current file may be changed if the declaration is located in the different file.
|
||||
* <p>
|
||||
* This method must be called before you actually update the declaration (e.g., change method parameters).
|
||||
* </p>
|
||||
*
|
||||
* @param declaration declaration to track
|
||||
*/
|
||||
void trackDeclaration(@NotNull PsiElement declaration);
|
||||
|
||||
/**
|
||||
* @return a builder that allows you to create a template.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// 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.modcommand;
|
||||
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A command to update the references to the declaration if possible. A common use-case is to
|
||||
* invoke "change signature" refactoring automatically. May do nothing, if particular language,
|
||||
* or particular kind of declaration change is not supported. The command should follow actual
|
||||
* text update in the file via {@link ModUpdateFileText}.
|
||||
*
|
||||
* @implNote In IntelliJ IDEA interactive executor, it invokes the "suggested refactoring" mechanism.
|
||||
*
|
||||
* @param file virtual file where the declaration resides
|
||||
* @param oldText the complete content of the virtual file before the declaration was updated
|
||||
* @param oldRange the complete text range of the declaration within the oldText
|
||||
* @param newRange the complete current text range of the declaration
|
||||
*/
|
||||
public record ModUpdateReferences(@NotNull VirtualFile file, @NotNull String oldText, @NotNull TextRange oldRange,
|
||||
@NotNull TextRange newRange) implements ModCommand {
|
||||
/**
|
||||
* @param newRange updated new range
|
||||
* @return the equivalent command but with updated newRange.
|
||||
*/
|
||||
public @NotNull ModUpdateReferences withNewRange(@NotNull TextRange newRange) {
|
||||
return newRange.equals(newRange()) ? this : new ModUpdateReferences(file, oldText, oldRange, newRange);
|
||||
}
|
||||
}
|
||||
@@ -219,6 +219,7 @@ final class PsiUpdateImpl {
|
||||
private final List<ModHighlight.HighlightInfo> myHighlightInfos = new ArrayList<>();
|
||||
private final List<ModStartTemplate.TemplateField> myTemplateFields = new ArrayList<>();
|
||||
private @Nullable ModRenameSymbol myRenameSymbol;
|
||||
private final List<ModUpdateReferences> myTrackedDeclarations = new ArrayList<>();
|
||||
private boolean myPositionUpdated = false;
|
||||
private @NlsContexts.Tooltip String myErrorMessage;
|
||||
private @NlsContexts.Tooltip String myInfoMessage;
|
||||
@@ -426,6 +427,16 @@ final class PsiUpdateImpl {
|
||||
myRenameSymbol = new ModRenameSymbol(myNavigationFile, range, suggestedNames);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trackDeclaration(@NotNull PsiElement declaration) {
|
||||
TextRange range = getRange(declaration);
|
||||
if (range == null) {
|
||||
throw new IllegalArgumentException("Element disappeared after postponed operations: " + declaration);
|
||||
}
|
||||
String oldText = myTracker.myCopyFile.getText();
|
||||
myTrackedDeclarations.add(new ModUpdateReferences(myNavigationFile, oldText, range, range));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel(@NotNull @NlsContexts.Tooltip String errorMessage) {
|
||||
if (myErrorMessage != null) {
|
||||
@@ -481,6 +492,7 @@ final class PsiUpdateImpl {
|
||||
mySelection = updateRange(event, mySelection);
|
||||
myHighlightInfos.replaceAll(info -> info.withRange(updateRange(event, info.range())));
|
||||
myTemplateFields.replaceAll(info -> info.withRange(updateRange(event, info.range())));
|
||||
myTrackedDeclarations.replaceAll(range -> range.withNewRange(updateRange(event, range.newRange())));
|
||||
if (myRenameSymbol != null) {
|
||||
myRenameSymbol = myRenameSymbol.withRange(updateRange(event, myRenameSymbol.symbolRange()));
|
||||
}
|
||||
@@ -513,11 +525,13 @@ final class PsiUpdateImpl {
|
||||
if (myErrorMessage != null) {
|
||||
return error(myErrorMessage);
|
||||
}
|
||||
return myChangedFiles.values().stream().map(FileTracker::getUpdateCommand).reduce(nop(), ModCommand::andThen)
|
||||
return myChangedFiles.values().stream()
|
||||
.map(fileTracker -> fileTracker.getUpdateCommand()).reduce(nop(), ModCommand::andThen)
|
||||
.andThen(myChangedDirectories.values().stream()
|
||||
.flatMap(info -> info.createFileCommands(myTracker.myProject))
|
||||
.reduce(nop(), ModCommand::andThen))
|
||||
.andThen(getNavigateCommand()).andThen(getHighlightCommand()).andThen(getTemplateCommand())
|
||||
.andThen(myTrackedDeclarations.stream().<ModCommand>map(c -> c).reduce(nop(), ModCommand::andThen))
|
||||
.andThen(myRenameSymbol == null ? nop() : myRenameSymbol)
|
||||
.andThen(myInfoMessage == null ? nop() : ModCommand.info(myInfoMessage));
|
||||
}
|
||||
@@ -554,7 +568,7 @@ final class PsiUpdateImpl {
|
||||
private final TextRange myRange;
|
||||
private final @NotNull PsiElement myElement;
|
||||
|
||||
public DummyContext(TextRange range, @NotNull PsiElement element) {
|
||||
private DummyContext(TextRange range, @NotNull PsiElement element) {
|
||||
myRange = range;
|
||||
myElement = element;
|
||||
}
|
||||
|
||||
@@ -593,3 +593,4 @@ executor.one.of.actions={0} of {1}: {2}
|
||||
command.title.finishing.template=Finishing Template
|
||||
notification.group.batch.quick.fix=Batch quick fix
|
||||
command.check.availability.for=Check Availability for {0}
|
||||
dialog.title.searching.for.usages=Searching for Usages
|
||||
|
||||
+5
@@ -43,6 +43,11 @@ abstract class SuggestedRefactoringAvailability(protected val refactoringSupport
|
||||
*/
|
||||
open fun amendStateInBackground(state: SuggestedRefactoringState): Iterator<SuggestedRefactoringState> = iterator { }
|
||||
|
||||
/**
|
||||
* Slow way to determine whether the action is available. Intended to be executed in background thread.
|
||||
*/
|
||||
open fun isAvailable(state: SuggestedRefactoringState): Boolean = true
|
||||
|
||||
/**
|
||||
* Determines refactoring availability for a given state and returns instance of [SuggestedRefactoringData],
|
||||
* providing information for presentation and execution of the refactoring.
|
||||
|
||||
+2
-2
@@ -46,7 +46,7 @@ abstract class SuggestedRefactoringStateChanges(protected val refactoringSupport
|
||||
val signatureRange = refactoringSupport.signatureRange(anchor) ?: return null
|
||||
val psiDocumentManager = PsiDocumentManager.getInstance(anchor.project)
|
||||
val file = anchor.containingFile
|
||||
val document = psiDocumentManager.getDocument(file)!!
|
||||
val document = file.viewProvider.document!!
|
||||
require(psiDocumentManager.isCommitted(document))
|
||||
return SuggestedRefactoringState(
|
||||
anchor,
|
||||
@@ -163,7 +163,7 @@ abstract class SuggestedRefactoringStateChanges(protected val refactoringSupport
|
||||
}
|
||||
|
||||
fun SuggestedRefactoringStateChanges.parameterMarkers(declaration: PsiElement, signature: Signature): List<ParameterMarker> {
|
||||
val document = PsiDocumentManager.getInstance(declaration.project).getDocument(declaration.containingFile)!!
|
||||
val document = declaration.containingFile.viewProvider.document!!
|
||||
val markerRanges = parameterMarkerRanges(declaration)
|
||||
require(markerRanges.size == signature.parameters.size)
|
||||
return markerRanges.zip(signature.parameters)
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.intellij.lang.LangBundle;
|
||||
import com.intellij.modcommand.*;
|
||||
import com.intellij.modcommand.ModChooseMember.SelectionMode;
|
||||
import com.intellij.modcommand.ModUpdateFileText.Fragment;
|
||||
import com.intellij.openapi.actionSystem.ActionPlaces;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
@@ -52,6 +53,7 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.rename.RenamePsiElementProcessor;
|
||||
import com.intellij.refactoring.rename.inplace.MemberInplaceRenamer;
|
||||
import com.intellij.refactoring.suggested.*;
|
||||
import com.intellij.refactoring.ui.ConflictsDialog;
|
||||
import com.intellij.util.concurrency.AppExecutorUtil;
|
||||
import com.intellij.util.concurrency.annotations.RequiresEdt;
|
||||
@@ -162,6 +164,9 @@ public class ModCommandExecutorImpl implements ModCommandExecutor {
|
||||
if (command instanceof ModUpdateFileText upd) {
|
||||
return executeUpdate(project, upd);
|
||||
}
|
||||
if (command instanceof ModUpdateReferences decl) {
|
||||
return !executeTrackDeclaration(context, decl, editor);
|
||||
}
|
||||
if (command instanceof ModCompositeCommand cmp) {
|
||||
return executeComposite(context, cmp, editor);
|
||||
}
|
||||
@@ -207,6 +212,54 @@ public class ModCommandExecutorImpl implements ModCommandExecutor {
|
||||
throw new IllegalArgumentException("Unknown command: " + command);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiElement findElementAtRange(PsiFile psiFile, TextRange declarationRange) {
|
||||
PsiElement element = psiFile.findElementAt(declarationRange.getStartOffset());
|
||||
while (element != null && !element.getTextRange().contains(declarationRange)) {
|
||||
element = element.getParent();
|
||||
}
|
||||
if (element == null || !element.getTextRange().equals(declarationRange)) return null;
|
||||
return element;
|
||||
}
|
||||
|
||||
private static boolean executeTrackDeclaration(@NotNull ActionContext context, @NotNull ModUpdateReferences decl, @Nullable Editor editor) {
|
||||
// TODO: properly support multiple tracked declarations
|
||||
VirtualFile file = decl.file();
|
||||
Project project = context.project();
|
||||
Callable<SuggestedRefactoringState> computeNewState = () -> {
|
||||
PsiFile psiFile = PsiManagerEx.getInstanceEx(project).findFile(file);
|
||||
if (psiFile == null) return null;
|
||||
SuggestedRefactoringSupport support = SuggestedRefactoringSupport.Companion.forLanguage(psiFile.getLanguage());
|
||||
if (support == null) return null;
|
||||
PsiElement newElement = findElementAtRange(psiFile, decl.newRange());
|
||||
if (newElement == null || !support.isAnchor(newElement)) return null;
|
||||
SuggestedRefactoringStateChanges stateChanges = support.getStateChanges();
|
||||
PsiFile fileCopy = (PsiFile)psiFile.copy();
|
||||
Document documentCopy = fileCopy.getViewProvider().getDocument();
|
||||
documentCopy.replaceString(0, documentCopy.getTextLength(), decl.oldText());
|
||||
PsiDocumentManager.getInstance(project).commitDocument(documentCopy);
|
||||
PsiElement element = findElementAtRange(fileCopy, decl.oldRange());
|
||||
if (element == null) return null;
|
||||
if (!support.isAnchor(element) || stateChanges.findDeclaration(element) != element) return null;
|
||||
SuggestedRefactoringState state = stateChanges.createInitialState(element);
|
||||
if (state == null) return null;
|
||||
SuggestedRefactoringAvailability availability = support.getAvailability();
|
||||
SuggestedRefactoringState newState = stateChanges.updateState(state, newElement);
|
||||
if (newState.getErrorLevel() != SuggestedRefactoringState.ErrorLevel.NO_ERRORS) return null;
|
||||
if (availability.detectAvailableRefactoring(newState) != null && availability.isAvailable(newState)) return newState;
|
||||
return null;
|
||||
};
|
||||
SuggestedRefactoringState finalState = ProgressManager.getInstance().runProcessWithProgressSynchronously(
|
||||
() -> ReadAction.nonBlocking(computeNewState).executeSynchronously(),
|
||||
LangBundle.message("dialog.title.searching.for.usages"), true, project);
|
||||
if (finalState == null) return false;
|
||||
Editor finalEditor = getEditor(project, editor, decl.file());
|
||||
if (finalEditor == null) return false;
|
||||
PerformSuggestedRefactoringKt.performSuggestedRefactoring(
|
||||
finalState, finalEditor, project, ActionPlaces.INTENTION_MENU, true, null, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean executeUpdateInspectionOptions(@NotNull ActionContext context, @NotNull ModUpdateInspectionOptions options) {
|
||||
VirtualFile vFile = context.file().getVirtualFile();
|
||||
Project project = context.project();
|
||||
|
||||
+13
@@ -62,6 +62,19 @@ internal fun performSuggestedRefactoring(
|
||||
?.let {
|
||||
it.refactoringSupport.availability.refineSignaturesWithResolve(it)
|
||||
} ?: return
|
||||
performSuggestedRefactoring(state, originalEditor, project, actionPlace, showReviewBalloon, popupAnchorComponent, popupAnchorPoint)
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch suggested refactoring based on the specified state
|
||||
*/
|
||||
fun performSuggestedRefactoring(state: SuggestedRefactoringState,
|
||||
originalEditor: Editor,
|
||||
project: Project,
|
||||
actionPlace: String,
|
||||
showReviewBalloon: Boolean,
|
||||
popupAnchorComponent: JComponent?,
|
||||
popupAnchorPoint: Point?) {
|
||||
if (state.errorLevel != ErrorLevel.NO_ERRORS || state.oldSignature == state.newSignature) return
|
||||
val refactoringSupport = state.refactoringSupport
|
||||
|
||||
|
||||
Reference in New Issue
Block a user