From b9a8ae7250c5280207dabeefddeef5f4ead46713 Mon Sep 17 00:00:00 2001 From: UNV Date: Fri, 19 Dec 2025 02:51:49 +0300 Subject: [PATCH] Java inspections and refactoring processors refactoring (part 2). --- .../extractMethod/ExtractMethodDialog.java | 155 +++--- .../extractMethod/ExtractMethodHandler.java | 110 ++-- .../extractMethod/ExtractMethodProcessor.java | 486 +++++++++--------- .../ExtractMethodObjectProcessor.java | 465 +++++++++-------- .../tempWithQuery/TempWithQueryHandler.java | 58 +-- 5 files changed, 663 insertions(+), 611 deletions(-) diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethod/ExtractMethodDialog.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethod/ExtractMethodDialog.java index be8e613b8..28d36d09f 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethod/ExtractMethodDialog.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethod/ExtractMethodDialog.java @@ -30,8 +30,10 @@ import com.intellij.java.language.psi.util.PsiUtil; import com.intellij.java.language.psi.util.TypeConversionUtil; import com.intellij.java.language.util.VisibilityUtil; +import consulo.annotation.access.RequiredReadAction; +import consulo.annotation.access.RequiredWriteAction; import consulo.application.ui.NonFocusableSetting; -import consulo.java.impl.refactoring.JavaRefactoringBundle; +import consulo.java.localize.JavaRefactoringLocalize; import consulo.language.editor.refactoring.localize.RefactoringLocalize; import consulo.language.editor.refactoring.ui.ComboBoxVisibilityPanel; import consulo.language.editor.refactoring.ui.ConflictsDialog; @@ -46,6 +48,7 @@ import consulo.ui.CheckBox; import consulo.ui.Component; import consulo.ui.Label; +import consulo.ui.annotation.RequiredUIAccess; import consulo.ui.ex.awt.*; import consulo.ui.ex.awtUnsafe.TargetAWT; import consulo.ui.layout.DockLayout; @@ -98,19 +101,22 @@ public class ExtractMethodDialog extends DialogWrapper implements AbstractExtrac private VariableData[] myInputVariables; private TypeSelector mySelector; - public ExtractMethodDialog(Project project, - PsiClass targetClass, - final InputVariables inputVariables, - PsiType returnType, - PsiTypeParameterList typeParameterList, - PsiType[] exceptions, - boolean isStatic, - boolean canBeStatic, - final boolean canBeChainedConstructor, - String title, - String helpId, - Nullability nullability, - final PsiElement[] elementsToExtract) { + @RequiredUIAccess + public ExtractMethodDialog( + Project project, + PsiClass targetClass, + InputVariables inputVariables, + PsiType returnType, + PsiTypeParameterList typeParameterList, + PsiType[] exceptions, + boolean isStatic, + boolean canBeStatic, + boolean canBeChainedConstructor, + String title, + String helpId, + Nullability nullability, + PsiElement[] elementsToExtract + ) { super(project, true); myProject = project; myTargetClass = targetClass; @@ -153,10 +159,7 @@ protected boolean areTypesDirected() { @Override public boolean isMakeStatic() { - if (myStaticFlag) { - return true; - } - return myCanBeStatic && myMakeStatic.getValueOrError(); + return myStaticFlag || myCanBeStatic && myMakeStatic.getValueOrError(); } @Override @@ -193,6 +196,7 @@ public VariableData[] getChosenParameters() { } @Override + @RequiredUIAccess public JComponent getPreferredFocusedComponent() { return myNameField; } @@ -203,11 +207,12 @@ protected String getHelpId() { } @Override + @RequiredWriteAction protected void doOKAction() { MultiMap conflicts = new MultiMap<>(); checkMethodConflicts(conflicts); if (!conflicts.isEmpty()) { - final ConflictsDialog conflictsDialog = new ConflictsDialog(myProject, conflicts); + ConflictsDialog conflictsDialog = new ConflictsDialog(myProject, conflicts); if (!conflictsDialog.showAndGet()) { if (conflictsDialog.isShowConflicts()) { close(CANCEL_EXIT_CODE); @@ -217,27 +222,29 @@ protected void doOKAction() { } if (myMakeVarargs != null && myMakeVarargs.getValueOrError()) { - final VariableData data = myInputVariables[myInputVariables.length - 1]; + VariableData data = myInputVariables[myInputVariables.length - 1]; if (data.type instanceof PsiArrayType) { data.type = new PsiEllipsisType(((PsiArrayType) data.type).getComponentType()); } } - final PsiMethod containingMethod = getContainingMethod(); - if (containingMethod != null && containingMethod.hasModifierProperty(PsiModifier.PUBLIC)) { + PsiMethod containingMethod = getContainingMethod(); + if (containingMethod != null && containingMethod.isPublic()) { ProjectPropertiesComponent.getInstance(myProject).setValue(EXTRACT_METHOD_DEFAULT_VISIBILITY, getVisibility()); } if (myGenerateAnnotations != null && myGenerateAnnotations.isEnabled()) { - ProjectPropertiesComponent.getInstance(myProject).setValue(EXTRACT_METHOD_GENERATE_ANNOTATIONS, myGenerateAnnotations.getValueOrError(), true); + ProjectPropertiesComponent.getInstance(myProject) + .setValue(EXTRACT_METHOD_GENERATE_ANNOTATIONS, myGenerateAnnotations.getValueOrError(), true); } super.doOKAction(); } @Override + @RequiredUIAccess protected JComponent createNorthPanel() { - final DockLayout main = DockLayout.create(); - final DockLayout namePanel = DockLayout.create(); - final Label nameLabel = Label.create(RefactoringLocalize.changesignatureNamePrompt()); + DockLayout main = DockLayout.create(); + DockLayout namePanel = DockLayout.create(); + Label nameLabel = Label.create(RefactoringLocalize.changesignatureNamePrompt()); namePanel.top(nameLabel); Component nameFieldWrap = TargetAWT.wrap(myNameField); @@ -248,17 +255,17 @@ protected JComponent createNorthPanel() { myVisibilityPanel = createVisibilityPanel(); myVisibilityPanel.registerUpDownActionsFor(myNameField); - final DockLayout visibilityAndReturnType = DockLayout.create(); + DockLayout visibilityAndReturnType = DockLayout.create(); if (!myTargetClass.isInterface()) { visibilityAndReturnType.left(TargetAWT.wrap(myVisibilityPanel)); } - final DockLayout returnTypePanel = createReturnTypePanel(); + DockLayout returnTypePanel = createReturnTypePanel(); if (returnTypePanel != null) { visibilityAndReturnType.right(returnTypePanel); } - final DockLayout visibilityAndName = DockLayout.create(); + DockLayout visibilityAndName = DockLayout.create(); visibilityAndName.left(visibilityAndReturnType); visibilityAndName.center(namePanel); main.center(visibilityAndName); @@ -278,31 +285,31 @@ protected boolean isVoidReturn() { } @Nullable + @RequiredUIAccess private DockLayout createReturnTypePanel() { if (TypeConversionUtil.isPrimitiveWrapper(myReturnType) && myNullability == Nullability.NULLABLE) { return null; } - final TypeSelectorManagerImpl manager = new TypeSelectorManagerImpl(myProject, myReturnType, findOccurrences(), areTypesDirected()) { + TypeSelectorManagerImpl manager = new TypeSelectorManagerImpl(myProject, myReturnType, findOccurrences(), areTypesDirected()) { @Override public PsiType[] getTypesForAll(boolean direct) { - final PsiType[] types = super.getTypesForAll(direct); + PsiType[] types = super.getTypesForAll(direct); return !isVoidReturn() ? types : ArrayUtil.prepend(PsiType.VOID, types); } }; mySelector = manager.getTypeSelector(); - final JComponent component = mySelector.getComponent(); - if (component instanceof JComboBox) { + if (mySelector.getComponent() instanceof JComboBox comboBox) { if (isVoidReturn()) { mySelector.selectType(PsiType.VOID); } DockLayout returnTypePanel = DockLayout.create(); returnTypePanel.top(Label.create(RefactoringLocalize.changesignatureReturnTypePrompt())); - returnTypePanel.bottom(TargetAWT.wrap(component)); + returnTypePanel.bottom(TargetAWT.wrap(comboBox)); - ((JComboBox) component).addActionListener(e -> { + comboBox.addActionListener(e -> { if (myGenerateAnnotations != null) { - final PsiType selectedType = mySelector.getSelectedType(); - final boolean enabled = PsiUtil.resolveClassInType(selectedType) != null; + PsiType selectedType = mySelector.getSelectedType(); + boolean enabled = PsiUtil.resolveClassInType(selectedType) != null; if (!enabled) { myGenerateAnnotations.setValue(false); } @@ -319,6 +326,7 @@ protected PsiExpression[] findOccurrences() { return PsiExpression.EMPTY_ARRAY; } + @RequiredUIAccess protected Component createOptionsPanel() { VerticalLayout layout = VerticalLayout.create(); @@ -328,12 +336,13 @@ protected Component createOptionsPanel() { myMakeStatic.setEnabled(!myStaticFlag); myMakeStatic.setValue(myStaticFlag); if (myVariableData.hasInstanceFields()) { - myMakeStatic.setLabelText(LocalizeValue.localizeTODO(JavaRefactoringBundle.message("declare.static.pass.fields.checkbox"))); + myMakeStatic.setLabelText(JavaRefactoringLocalize.declareStaticPassFieldsCheckbox()); } myMakeStatic.addValueListener(e -> { if (myVariableData.hasInstanceFields()) { myVariableData.setPassFields(myMakeStatic.getValueOrError()); - myInputVariables = myVariableData.getInputVariables().toArray(new VariableData[myVariableData.getInputVariables().size()]); + myInputVariables = + myVariableData.getInputVariables().toArray(new VariableData[myVariableData.getInputVariables().size()]); updateVarargsEnabled(); createParametersPanel(); } @@ -377,8 +386,9 @@ protected Component createOptionsPanel() { } if (myNullability != null && myNullability != Nullability.UNKNOWN) { - final boolean isSelected = ProjectPropertiesComponent.getInstance(myProject).getBoolean(EXTRACT_METHOD_GENERATE_ANNOTATIONS, true); - myGenerateAnnotations = CheckBox.create(JavaRefactoringBundle.message("declare.generated.annotations"), isSelected); + boolean isSelected = + ProjectPropertiesComponent.getInstance(myProject).getBoolean(EXTRACT_METHOD_GENERATE_ANNOTATIONS, true); + myGenerateAnnotations = CheckBox.create(JavaRefactoringLocalize.declareGeneratedAnnotations(), isSelected); myGenerateAnnotations.addValueListener(e -> updateSignature()); layout.add(myGenerateAnnotations); } @@ -407,10 +417,13 @@ protected Component createOptionsPanel() { } private ComboBoxVisibilityPanel createVisibilityPanel() { - final JavaComboBoxVisibilityPanel panel = new JavaComboBoxVisibilityPanel(); - final PsiMethod containingMethod = getContainingMethod(); - panel.setVisibility(containingMethod != null && containingMethod.hasModifierProperty(PsiModifier.PUBLIC) ? ProjectPropertiesComponent.getInstance(myProject).getValue - (EXTRACT_METHOD_DEFAULT_VISIBILITY, PsiModifier.PRIVATE) : PsiModifier.PRIVATE); + JavaComboBoxVisibilityPanel panel = new JavaComboBoxVisibilityPanel(); + PsiMethod containingMethod = getContainingMethod(); + panel.setVisibility( + containingMethod != null && containingMethod.isPublic() + ? ProjectPropertiesComponent.getInstance(myProject).getValue(EXTRACT_METHOD_DEFAULT_VISIBILITY, PsiModifier.PRIVATE) + : PsiModifier.PRIVATE + ); panel.addListener(e -> { updateSignature(); if (!myChangingVisibility) { @@ -424,12 +437,14 @@ private PsiMethod getContainingMethod() { return PsiTreeUtil.getParentOfType(PsiTreeUtil.findCommonParent(myElementsToExtract), PsiMethod.class); } + @RequiredUIAccess private void updateVarargsEnabled() { if (myMakeVarargs != null) { myMakeVarargs.setEnabled(myInputVariables[myInputVariables.length - 1].type instanceof PsiArrayType); } } + @RequiredUIAccess private void update() { myNameField.setEnabled(!isChainedConstructor()); if (myMakeStatic != null) { @@ -449,7 +464,7 @@ protected JComponent createCenterPanel() { myCenterPanel = new JPanel(new BorderLayout()); createParametersPanel(); - final Splitter splitter = new Splitter(true); + Splitter splitter = new Splitter(true); splitter.setShowDividerIcon(false); splitter.setFirstComponent(myCenterPanel); splitter.setSecondComponent(createSignaturePanel()); @@ -475,8 +490,8 @@ protected void createParametersPanel() { @Override public void focusGained(FocusEvent e) { if (table.getRowCount() > 0) { - final int col = table.getSelectedColumn(); - final int row = table.getSelectedRow(); + int col = table.getSelectedColumn(); + int row = table.getSelectedRow(); if (col == -1 || row == -1) { table.getSelectionModel().setSelectionInterval(0, 0); table.getColumnModel().getSelectionModel().setSelectionInterval(0, 0); @@ -490,6 +505,7 @@ public void focusGained(FocusEvent e) { protected ParameterTablePanel createParameterTableComponent() { return new ParameterTablePanel(myProject, myInputVariables, myElementsToExtract) { @Override + @RequiredUIAccess protected void updateSignature() { updateVarargsEnabled(); ExtractMethodDialog.this.updateSignature(); @@ -517,8 +533,9 @@ protected boolean isUsedAfter(PsiVariable variable) { }; } + @RequiredReadAction protected JComponent createSignaturePanel() { - final JPanel panel = new JPanel(new BorderLayout()); + JPanel panel = new JPanel(new BorderLayout()); panel.add(SeparatorFactory.createSeparator(RefactoringLocalize.signaturePreviewBorderTitle().get(), null), BorderLayout.NORTH); panel.add(mySignature, BorderLayout.CENTER); @@ -526,22 +543,27 @@ protected JComponent createSignaturePanel() { return panel; } + @RequiredReadAction protected void updateSignature() { if (mySignature != null) { mySignature.setSignature(getSignature()); } } + @RequiredReadAction protected String getSignature() { - final StringBuilder buffer = new StringBuilder(); + StringBuilder buffer = new StringBuilder(); if (myGenerateAnnotations != null && myGenerateAnnotations.getValueOrError()) { - final NullableNotNullManager nullManager = NullableNotNullManager.getInstance(myProject); + NullableNotNullManager nullManager = NullableNotNullManager.getInstance(myProject); buffer.append("@"); - buffer.append( - StringUtil.getShortName(myNullability == Nullability.NULLABLE ? nullManager.getDefaultNullable() : nullManager.getDefaultNotNull())); + buffer.append(StringUtil.getShortName( + myNullability == Nullability.NULLABLE + ? nullManager.getDefaultNullable() + : nullManager.getDefaultNotNull() + )); buffer.append("\n"); } - final String visibilityString = VisibilityUtil.getVisibilityString(getVisibility()); + String visibilityString = VisibilityUtil.getVisibilityString(getVisibility()); buffer.append(visibilityString); if (buffer.length() > 0) { buffer.append(" "); @@ -550,7 +572,7 @@ protected String getSignature() { buffer.append("static "); } if (myTypeParameterList != null) { - final String typeParamsText = myTypeParameterList.getText(); + String typeParamsText = myTypeParameterList.getText(); if (!typeParamsText.isEmpty()) { buffer.append(typeParamsText); buffer.append(" "); @@ -561,15 +583,19 @@ protected String getSignature() { buffer.append(myTargetClass.getName()); } else { - buffer.append(PsiFormatUtil.formatType(mySelector != null ? mySelector.getSelectedType() : myReturnType, 0, PsiSubstitutor.EMPTY)); + buffer.append(PsiFormatUtil.formatType( + mySelector != null ? mySelector.getSelectedType() : myReturnType, + 0, + PsiSubstitutor.EMPTY + )); buffer.append(" "); buffer.append(myNameField.getEnteredName()); } buffer.append("("); - final String INDENT = StringUtil.repeatSymbol(' ', buffer.length()); + String indent = StringUtil.repeatSymbol(' ', buffer.length()); - final VariableData[] datas = myInputVariables; + VariableData[] datas = myInputVariables; int count = 0; for (int i = 0; i < datas.length; i++) { VariableData data = datas[i]; @@ -577,14 +603,17 @@ protected String getSignature() { //String typeAndModifiers = PsiFormatUtil.formatVariable(data.variable, // PsiFormatUtil.SHOW_MODIFIERS | PsiFormatUtil.SHOW_TYPE); PsiType type = data.type; - if (i == datas.length - 1 && type instanceof PsiArrayType && myMakeVarargs != null && myMakeVarargs.getValueOrError()) { - type = new PsiEllipsisType(((PsiArrayType) type).getComponentType()); + if (i == datas.length - 1 + && type instanceof PsiArrayType arrayType + && myMakeVarargs != null + && myMakeVarargs.getValueOrError()) { + type = new PsiEllipsisType(arrayType.getComponentType()); } String typeText = type.getPresentableText(); if (count > 0) { buffer.append(",\n"); - buffer.append(INDENT); + buffer.append(indent); } buffer.append(typeText); buffer.append(" "); @@ -597,7 +626,7 @@ protected String getSignature() { buffer.append("\n"); buffer.append("throws\n"); for (PsiType exception : myExceptions) { - buffer.append(INDENT); + buffer.append(indent); buffer.append(PsiFormatUtil.formatType(exception, 0, PsiSubstitutor.EMPTY)); buffer.append("\n"); } @@ -610,12 +639,14 @@ protected String getDimensionServiceKey() { return "extract.method.dialog"; } + @RequiredReadAction protected void checkMethodConflicts(MultiMap conflicts) { PsiMethod prototype; try { PsiElementFactory factory = JavaPsiFacade.getInstance(myProject).getElementFactory(); prototype = factory.createMethod(myNameField.getEnteredName().trim(), myReturnType); if (myTypeParameterList != null) { + //noinspection RequiredXAction prototype.getTypeParameterList().replace(myTypeParameterList); } for (VariableData data : myInputVariables) { diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethod/ExtractMethodHandler.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethod/ExtractMethodHandler.java index 961472411..38daa18ca 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethod/ExtractMethodHandler.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethod/ExtractMethodHandler.java @@ -25,6 +25,7 @@ import com.intellij.java.language.psi.PsiStatement; import com.intellij.java.language.psi.PsiType; import com.intellij.java.language.psi.util.PsiExpressionTrimRenderer; +import consulo.annotation.access.RequiredReadAction; import consulo.codeEditor.Editor; import consulo.codeEditor.EditorColors; import consulo.codeEditor.LogicalPosition; @@ -34,7 +35,6 @@ import consulo.fileEditor.FileEditorManager; import consulo.language.codeStyle.PostprocessReformattingAspect; import consulo.language.editor.highlight.HighlightManager; -import consulo.language.editor.refactoring.RefactoringBundle; import consulo.language.editor.refactoring.action.RefactoringActionHandler; import consulo.language.editor.refactoring.introduce.IntroduceTargetChooser; import consulo.language.editor.refactoring.localize.RefactoringLocalize; @@ -63,10 +63,11 @@ public class ExtractMethodHandler implements RefactoringActionHandler { public static final LocalizeValue REFACTORING_NAME = RefactoringLocalize.extractMethodTitle(); @Override + @RequiredUIAccess public void invoke(@Nonnull Project project, @Nonnull PsiElement[] elements, DataContext dataContext) { if (dataContext != null) { - final PsiFile file = dataContext.getData(PsiFile.KEY); - final Editor editor = dataContext.getData(Editor.KEY); + PsiFile file = dataContext.getData(PsiFile.KEY); + Editor editor = dataContext.getData(Editor.KEY); if (file != null && editor != null) { invokeOnElements(project, editor, file, elements); } @@ -74,21 +75,24 @@ public void invoke(@Nonnull Project project, @Nonnull PsiElement[] elements, Dat } @Override - public void invoke(@Nonnull final Project project, final Editor editor, final PsiFile file, DataContext dataContext) { - final Consumer callback = selectedValue -> invokeOnElements(project, editor, file, selectedValue); + @RequiredUIAccess + public void invoke(@Nonnull Project project, Editor editor, PsiFile file, DataContext dataContext) { + @RequiredUIAccess + Consumer callback = selectedValue -> invokeOnElements(project, editor, file, selectedValue); selectAndPass(project, editor, file, callback); } + @RequiredReadAction public static void selectAndPass( - @Nonnull final Project project, - @Nonnull final Editor editor, - @Nonnull final PsiFile file, - @Nonnull final Consumer callback + @Nonnull Project project, + @Nonnull Editor editor, + @Nonnull PsiFile file, + @Nonnull @RequiredUIAccess Consumer callback ) { editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); if (!editor.getSelectionModel().hasSelection()) { - final int offset = editor.getCaretModel().getOffset(); - final List expressions = IntroduceVariableBase.collectExpressions(file, editor, offset, true); + int offset = editor.getCaretModel().getOffset(); + List expressions = IntroduceVariableBase.collectExpressions(file, editor, offset, true); if (expressions.isEmpty()) { editor.getSelectionModel().selectLineAtCaret(); } @@ -120,9 +124,9 @@ else if (expressions.size() == 1) { else { elements = CodeInsightUtil.findStatementsInRange(file, startOffset, endOffset); if (elements.length == 0) { - final PsiExpression expression = IntroduceVariableBase.getSelectedExpression(project, file, startOffset, endOffset); + PsiExpression expression = IntroduceVariableBase.getSelectedExpression(project, file, startOffset, endOffset); if (expression != null && IntroduceVariableBase.getErrorMessage(expression) == null) { - final PsiType originalType = RefactoringUtil.getTypeByExpressionWithExpectedType(expression); + PsiType originalType = RefactoringUtil.getTypeByExpressionWithExpectedType(expression); if (originalType != null) { elements = new PsiElement[]{expression}; } @@ -132,15 +136,17 @@ else if (expressions.size() == 1) { callback.accept(elements); } - private static void invokeOnElements(final Project project, final Editor editor, PsiFile file, PsiElement[] elements) { + @RequiredUIAccess + private static void invokeOnElements(Project project, Editor editor, PsiFile file, PsiElement[] elements) { getProcessor(elements, project, file, editor, true, processor -> invokeOnElements(project, editor, processor, true)); } + @RequiredUIAccess private static boolean invokeOnElements( - final Project project, - final Editor editor, - @Nonnull final ExtractMethodProcessor processor, - final boolean directTypes + Project project, + Editor editor, + @Nonnull ExtractMethodProcessor processor, + boolean directTypes ) { if (!CommonRefactoringUtil.checkReadOnlyStatus(project, processor.getTargetClass().getContainingFile())) { return false; @@ -153,31 +159,29 @@ private static boolean invokeOnElements( return false; } - public static void run(@Nonnull final Project project, final Editor editor, final ExtractMethodProcessor processor) { - CommandProcessor.getInstance().executeCommand( - project, - () -> PostprocessReformattingAspect.getInstance(project).postponeFormattingInside(() -> { + public static void run(@Nonnull Project project, Editor editor, ExtractMethodProcessor processor) { + CommandProcessor.getInstance().newCommand() + .project(project) + .name(REFACTORING_NAME) + .run(() -> PostprocessReformattingAspect.getInstance(project).postponeFormattingInside(() -> { try { processor.doRefactoring(); } catch (IncorrectOperationException e) { LOG.error(e); } - }), - REFACTORING_NAME.get(), - null - ); + })); } @Nullable @RequiredUIAccess private static ExtractMethodProcessor getProcessor( - final PsiElement[] elements, - final Project project, - final PsiFile file, - final Editor editor, - final boolean showErrorMessages, - final @Nullable Consumer pass + PsiElement[] elements, + Project project, + PsiFile file, + Editor editor, + boolean showErrorMessages, + @Nullable @RequiredUIAccess Consumer pass ) { if (elements == null || elements.length == 0) { if (showErrorMessages) { @@ -201,8 +205,8 @@ private static ExtractMethodProcessor getProcessor( } } - final ExtractMethodProcessor processor = - new ExtractMethodProcessor(project, editor, elements, null, REFACTORING_NAME.get(), "", HelpID.EXTRACT_METHOD); + ExtractMethodProcessor processor = + new ExtractMethodProcessor(project, editor, elements, null, REFACTORING_NAME, "", HelpID.EXTRACT_METHOD); processor.setShowErrorDialogs(showErrorMessages); try { if (!processor.prepare(pass)) { @@ -211,7 +215,13 @@ private static ExtractMethodProcessor getProcessor( } catch (PrepareFailedException e) { if (showErrorMessages) { - CommonRefactoringUtil.showErrorHint(project, editor, LocalizeValue.ofNullable(e.getMessage()), REFACTORING_NAME, HelpID.EXTRACT_METHOD); + CommonRefactoringUtil.showErrorHint( + project, + editor, + LocalizeValue.ofNullable(e.getMessage()), + REFACTORING_NAME, + HelpID.EXTRACT_METHOD + ); highlightPrepareError(e, file, editor, project); } return null; @@ -219,10 +229,10 @@ private static ExtractMethodProcessor getProcessor( return processor; } - public static void highlightPrepareError(PrepareFailedException e, PsiFile file, Editor editor, final Project project) { + public static void highlightPrepareError(PrepareFailedException e, PsiFile file, Editor editor, Project project) { if (e.getFile() == file) { - final TextRange textRange = e.getTextRange(); - final HighlightManager highlightManager = HighlightManager.getInstance(project); + TextRange textRange = e.getTextRange(); + HighlightManager highlightManager = HighlightManager.getInstance(project); highlightManager.addRangeHighlight( editor, textRange.getStartOffset(), @@ -231,35 +241,27 @@ public static void highlightPrepareError(PrepareFailedException e, PsiFile file, true, null ); - final LogicalPosition logicalPosition = editor.offsetToLogicalPosition(textRange.getStartOffset()); + LogicalPosition logicalPosition = editor.offsetToLogicalPosition(textRange.getStartOffset()); editor.getScrollingModel().scrollTo(logicalPosition, ScrollType.MAKE_VISIBLE); } } @Nullable - public static ExtractMethodProcessor getProcessor( - final Project project, - final PsiElement[] elements, - final PsiFile file, - final boolean openEditor - ) { + @RequiredUIAccess + public static ExtractMethodProcessor getProcessor(Project project, PsiElement[] elements, PsiFile file, boolean openEditor) { return getProcessor(elements, project, file, openEditor ? openEditor(project, file) : null, false, null); } - public static boolean invokeOnElements( - final Project project, - @Nonnull final ExtractMethodProcessor processor, - final PsiFile file, - final boolean directTypes - ) { + @RequiredUIAccess + public static boolean invokeOnElements(Project project, @Nonnull ExtractMethodProcessor processor, PsiFile file, boolean directTypes) { return invokeOnElements(project, openEditor(project, file), processor, directTypes); } @Nullable - private static Editor openEditor(final Project project, final PsiFile file) { - final VirtualFile virtualFile = file.getVirtualFile(); + private static Editor openEditor(Project project, PsiFile file) { + VirtualFile virtualFile = file.getVirtualFile(); LOG.assertTrue(virtualFile != null); - final OpenFileDescriptor fileDescriptor = OpenFileDescriptorFactory.getInstance(project).newBuilder(virtualFile).build(); + OpenFileDescriptor fileDescriptor = OpenFileDescriptorFactory.getInstance(project).newBuilder(virtualFile).build(); return FileEditorManager.getInstance(project).openTextEditor(fileDescriptor, false); } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethod/ExtractMethodProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethod/ExtractMethodProcessor.java index f9ab771d9..86c2d3a91 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethod/ExtractMethodProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethod/ExtractMethodProcessor.java @@ -54,6 +54,7 @@ import com.intellij.java.language.psi.util.*; import com.intellij.java.language.util.VisibilityUtil; import consulo.annotation.access.RequiredReadAction; +import consulo.annotation.access.RequiredWriteAction; import consulo.application.progress.ProgressManager; import consulo.codeEditor.*; import consulo.content.scope.SearchScope; @@ -80,6 +81,8 @@ import consulo.logging.Logger; import consulo.project.Project; import consulo.project.ProjectPropertiesComponent; +import consulo.ui.annotation.RequiredUIAccess; +import consulo.ui.ex.awt.UIUtil; import consulo.ui.ex.popup.JBPopup; import consulo.util.collection.ArrayUtil; import consulo.util.collection.ContainerUtil; @@ -89,7 +92,6 @@ import consulo.virtualFileSystem.VirtualFile; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.TestOnly; import java.util.*; @@ -105,7 +107,7 @@ public class ExtractMethodProcessor implements MatchProvider { protected final PsiElement[] myElements; private final PsiBlockStatement myEnclosingBlockStatement; private final PsiType myForcedReturnType; - private final String myRefactoringName; + private final LocalizeValue myRefactoringName; protected final String myInitialMethodName; private final String myHelpId; @@ -154,21 +156,22 @@ public class ExtractMethodProcessor implements MatchProvider { protected boolean myNotNullConditionalCheck = false; protected Nullability myNullability; + @RequiredReadAction public ExtractMethodProcessor( Project project, Editor editor, PsiElement[] elements, PsiType forcedReturnType, - String refactoringName, + LocalizeValue refactoringName, String initialMethodName, String helpId ) { myProject = project; myEditor = editor; if (elements.length != 1 || !(elements[0] instanceof PsiBlockStatement)) { - myElements = - elements.length == 1 && elements[0] instanceof PsiParenthesizedExpression ? new PsiElement[]{PsiUtil.skipParenthesizedExprDown( - (PsiExpression) elements[0])} : elements; + myElements = elements.length == 1 && elements[0] instanceof PsiParenthesizedExpression parenthesized + ? new PsiElement[]{PsiUtil.skipParenthesizedExprDown(parenthesized)} + : elements; myEnclosingBlockStatement = null; } else { @@ -193,16 +196,15 @@ private static PsiElement[] processCodeBlockChildren(PsiElement[] codeBlockChild return PsiElement.EMPTY_ARRAY; } - final PsiElement first = codeBlockChildren[0]; int resultStart = 0; - if (first instanceof PsiJavaToken && ((PsiJavaToken) first).getTokenType() == JavaTokenType.LBRACE) { + if (codeBlockChildren[0] instanceof PsiJavaToken firstToken && firstToken.getTokenType() == JavaTokenType.LBRACE) { resultStart++; } - final PsiElement last = codeBlockChildren[codeBlockChildren.length - 1]; - if (last instanceof PsiJavaToken && ((PsiJavaToken) last).getTokenType() == JavaTokenType.RBRACE) { + PsiElement last = codeBlockChildren[codeBlockChildren.length - 1]; + if (last instanceof PsiJavaToken lastToken && lastToken.getTokenType() == JavaTokenType.RBRACE) { resultLast--; } - final ArrayList result = new ArrayList<>(); + List result = new ArrayList<>(); for (int i = resultStart; i < resultLast; i++) { PsiElement element = codeBlockChildren[i]; if (!(element instanceof PsiWhiteSpace)) { @@ -220,11 +222,11 @@ public void setShowErrorDialogs(boolean showErrorDialogs) { myShowErrorDialogs = showErrorDialogs; } - public void setChainedConstructor(final boolean isChainedConstructor) { + public void setChainedConstructor(boolean isChainedConstructor) { myIsChainedConstructor = isChainedConstructor; } - + @RequiredUIAccess public boolean prepare() throws PrepareFailedException { return prepare(null); } @@ -232,10 +234,10 @@ public boolean prepare() throws PrepareFailedException { /** * Invoked in atomic action */ + @RequiredUIAccess public boolean prepare(@Nullable Consumer pass) throws PrepareFailedException { myExpression = null; - if (myElements.length == 1 && myElements[0] instanceof PsiExpression) { - final PsiExpression expression = (PsiExpression) myElements[0]; + if (myElements.length == 1 && myElements[0] instanceof PsiExpression expression) { if (expression instanceof PsiAssignmentExpression && expression.getParent() instanceof PsiExpressionStatement) { myElements[0] = expression.getParent(); } @@ -244,7 +246,7 @@ public boolean prepare(@Nullable Consumer pass) throws P } } - final PsiElement codeFragment = ControlFlowUtil.findCodeFragment(myElements[0]); + PsiElement codeFragment = ControlFlowUtil.findCodeFragment(myElements[0]); myCodeFragmentMember = codeFragment.getUserData(ElementToWorkOn.PARENT); if (myCodeFragmentMember == null) { myCodeFragmentMember = codeFragment.getParent(); @@ -279,6 +281,7 @@ public boolean prepare(@Nullable Consumer pass) throws P return chooseTargetClass(codeFragment, pass); } + @RequiredUIAccess private boolean checkExitPoints() throws PrepareFailedException { PsiType expressionType = null; if (myExpression != null) { @@ -297,15 +300,15 @@ private boolean checkExitPoints() throws PrepareFailedException { } myHasExpressionOutput = !PsiType.VOID.equals(expressionType); - final PsiType returnStatementType = getExpectedReturnType(); + PsiType returnStatementType = getExpectedReturnType(); myHasReturnStatementOutput = myHasReturnStatement && returnStatementType != null && !PsiType.VOID.equals(returnStatementType); if (myGenerateConditionalExit && myOutputVariables.length == 1) { if (!(myOutputVariables[0].getType() instanceof PsiPrimitiveType)) { myNullConditionalCheck = true; for (PsiStatement exitStatement : myExitStatements) { - if (exitStatement instanceof PsiReturnStatement) { - final PsiExpression returnValue = ((PsiReturnStatement) exitStatement).getReturnValue(); + if (exitStatement instanceof PsiReturnStatement returnStmt) { + PsiExpression returnValue = returnStmt.getReturnValue(); myNullConditionalCheck &= returnValue == null || isNullInferred(returnValue.getText(), true); } } @@ -339,8 +342,8 @@ else if (myGenerateConditionalExit) { } PsiElement container = PsiTreeUtil.getParentOfType(myElements[0], PsiClass.class, PsiMethod.class); - while (container instanceof PsiMethod && ((PsiMethod) container).getContainingClass() != myTargetClass) { - container = PsiTreeUtil.getParentOfType(container, PsiMethod.class, true); + while (container instanceof PsiMethod method && method.getContainingClass() != myTargetClass) { + container = PsiTreeUtil.getParentOfType(method, PsiMethod.class, true); } if (container instanceof PsiMethod method) { PsiElement[] elements = myElements; @@ -379,12 +382,13 @@ private PsiVariable getArtificialOutputVariable() { for (PsiElement element : myElements) { element.accept(new JavaRecursiveElementWalkingVisitor() { @Override + @RequiredReadAction public void visitReferenceExpression(PsiReferenceExpression expression) { super.visitReferenceExpression(expression); - final PsiElement resolve = expression.resolve(); - if (resolve instanceof PsiField field && field.hasModifierProperty(PsiModifier.FINAL) && - PsiUtil.isAccessedForWriting(expression)) { - fields.add((PsiField) resolve); + if (expression.resolve() instanceof PsiField field + && field.isFinal() + && PsiUtil.isAccessedForWriting(expression)) { + fields.add(field); } } }); @@ -393,8 +397,9 @@ public void visitReferenceExpression(PsiReferenceExpression expression) { return fields.size() == 1 ? fields.iterator().next() : null; } } - final VariablesProcessor processor = new VariablesProcessor(true) { + VariablesProcessor processor = new VariablesProcessor(true) { @Override + @RequiredReadAction protected boolean check(PsiVariable var, ResolveState state) { return isDeclaredInside(var); } @@ -407,12 +412,13 @@ protected boolean check(PsiVariable var, ResolveState state) { return null; } + @RequiredReadAction private boolean areAllExitPointsAreNotNull(PsiType returnStatementType) { if (insertNotNullCheckIfPossible() && myControlFlowWrapper.getOutputVariables(false).length == 0) { boolean isNotNull = returnStatementType != null && !PsiType.VOID.equals(returnStatementType); for (PsiStatement statement : myExitStatements) { - if (statement instanceof PsiReturnStatement) { - final PsiExpression returnValue = ((PsiReturnStatement) statement).getReturnValue(); + if (statement instanceof PsiReturnStatement returnStmt) { + PsiExpression returnValue = returnStmt.getReturnValue(); isNotNull &= returnValue != null && !isNullInferred(returnValue.getText(), true); } } @@ -425,8 +431,9 @@ protected boolean insertNotNullCheckIfPossible() { return true; } + @RequiredReadAction private boolean isNullInferred(String exprText, boolean trueSet) { - final PsiCodeBlock block = myElementFactory.createCodeBlockFromText("{}", myElements[0]); + PsiCodeBlock block = myElementFactory.createCodeBlockFromText("{}", myElements[0]); for (PsiElement element : myElements) { block.add(element); } @@ -437,8 +444,9 @@ private boolean isNullInferred(String exprText, boolean trueSet) { return inferNullability(block, Objects.requireNonNull(statementFromText.getReturnValue())) == Nullability.NOT_NULL; } + @RequiredReadAction private static Nullability inferNullability(@Nonnull PsiCodeBlock block, @Nonnull PsiExpression expr) { - final DataFlowRunner dfaRunner = new DataFlowRunner(block.getProject()); + DataFlowRunner dfaRunner = new DataFlowRunner(block.getProject()); class Visitor extends StandardInstructionVisitor { DfaNullability myNullability = DfaNullability.NOT_NULL; @@ -458,7 +466,7 @@ protected void beforeExpressionPush( } } Visitor visitor = new Visitor(); - final RunnerResult rc = dfaRunner.analyzeMethod(block, visitor); + RunnerResult rc = dfaRunner.analyzeMethod(block, visitor); return rc == RunnerResult.OK && visitor.myVisited ? DfaNullability.toNullability(visitor.myNullability) : Nullability.UNKNOWN; } @@ -468,48 +476,48 @@ protected boolean checkOutputVariablesCount() { } private void checkCanBeChainedConstructor() { - if (!(myCodeFragmentMember instanceof PsiMethod)) { + if (!(myCodeFragmentMember instanceof PsiMethod method)) { return; } - final PsiMethod method = (PsiMethod) myCodeFragmentMember; if (!method.isConstructor() || !PsiType.VOID.equals(myReturnType)) { return; } - final PsiCodeBlock body = method.getBody(); + PsiCodeBlock body = method.getBody(); if (body == null) { return; } - final PsiStatement[] psiStatements = body.getStatements(); + PsiStatement[] psiStatements = body.getStatements(); if (psiStatements.length > 0 && myElements[0] == psiStatements[0]) { myCanBeChainedConstructor = true; } } - private void checkLocalClasses(final PsiMethod container) throws PrepareFailedException { + @RequiredReadAction + private void checkLocalClasses(PsiMethod container) throws PrepareFailedException { final List localClasses = new ArrayList<>(); container.accept(new JavaRecursiveElementWalkingVisitor() { @Override - public void visitClass(final PsiClass aClass) { + public void visitClass(@Nonnull PsiClass aClass) { localClasses.add(aClass); } @Override - public void visitAnonymousClass(final PsiAnonymousClass aClass) { + public void visitAnonymousClass(@Nonnull PsiAnonymousClass aClass) { visitElement(aClass); } @Override - public void visitTypeParameter(final PsiTypeParameter classParameter) { + public void visitTypeParameter(@Nonnull PsiTypeParameter classParameter) { visitElement(classParameter); } }); for (PsiClass localClass : localClasses) { - final boolean classExtracted = isExtractedElement(localClass); - final List extractedReferences = Collections.synchronizedList(new ArrayList()); - final List remainingReferences = Collections.synchronizedList(new ArrayList()); + boolean classExtracted = isExtractedElement(localClass); + List extractedReferences = Collections.synchronizedList(new ArrayList()); + List remainingReferences = Collections.synchronizedList(new ArrayList()); ReferencesSearch.search(localClass).forEach(psiReference -> { - final PsiElement element = psiReference.getElement(); - final boolean elementExtracted = isExtractedElement(element); + PsiElement element = psiReference.getElement(); + boolean elementExtracted = isExtractedElement(element); if (elementExtracted && !classExtracted) { extractedReferences.add(element); return false; @@ -545,7 +553,7 @@ public void visitTypeParameter(final PsiTypeParameter classParameter) { } } - private boolean isExtractedElement(final PsiElement element) { + private boolean isExtractedElement(PsiElement element) { boolean isExtracted = false; for (PsiElement psiElement : myElements) { if (PsiTreeUtil.isAncestor(psiElement, element, false)) { @@ -556,18 +564,17 @@ private boolean isExtractedElement(final PsiElement element) { return isExtracted; } - private boolean shouldBeStatic() { for (PsiElement element : myElements) { - final PsiExpressionStatement statement = PsiTreeUtil.getParentOfType(element, PsiExpressionStatement.class); + PsiExpressionStatement statement = PsiTreeUtil.getParentOfType(element, PsiExpressionStatement.class); if (statement != null && JavaHighlightUtil.isSuperOrThisCall(statement, true, true)) { return true; } } PsiElement codeFragmentMember = myCodeFragmentMember; while (codeFragmentMember != null && PsiTreeUtil.isAncestor(myTargetClass, codeFragmentMember, true)) { - if (codeFragmentMember instanceof PsiModifierListOwner && ((PsiModifierListOwner) codeFragmentMember).hasModifierProperty( - PsiModifier.STATIC)) { + if (codeFragmentMember instanceof PsiModifierListOwner modifierListOwner + && modifierListOwner.hasModifierProperty(PsiModifier.STATIC)) { return true; } codeFragmentMember = PsiTreeUtil.getParentOfType(codeFragmentMember, PsiModifierListOwner.class, true); @@ -575,7 +582,8 @@ private boolean shouldBeStatic() { return false; } - public boolean showDialog(final boolean direct) { + @RequiredUIAccess + public boolean showDialog(boolean direct) { AbstractExtractDialog dialog = createExtractMethodDialog(direct); dialog.show(); if (!dialog.isOK()) { @@ -585,21 +593,22 @@ public boolean showDialog(final boolean direct) { return true; } - protected void apply(final AbstractExtractDialog dialog) { + protected void apply(AbstractExtractDialog dialog) { myMethodName = dialog.getChosenMethodName(); myVariableDatum = dialog.getChosenParameters(); myStatic = isStatic() | dialog.isMakeStatic(); myIsChainedConstructor = dialog.isChainedConstructor(); myMethodVisibility = dialog.getVisibility(); - final PsiType returnType = dialog.getReturnType(); + PsiType returnType = dialog.getReturnType(); if (returnType != null) { myReturnType = returnType; } } + @RequiredUIAccess protected AbstractExtractDialog createExtractMethodDialog(final boolean direct) { - final List variables = myInputVariables.getInputVariables(); + List variables = myInputVariables.getInputVariables(); myVariableDatum = variables.toArray(new VariableData[variables.size()]); myNullability = initNullability(); myArtificialOutputVariable = PsiType.VOID.equals(myReturnType) ? getArtificialOutputVariable() : null; @@ -614,7 +623,7 @@ protected AbstractExtractDialog createExtractMethodDialog(final boolean direct) isStatic(), isCanBeStatic(), myCanBeChainedConstructor, - myRefactoringName, + myRefactoringName.get(), myHelpId, myNullability, myElements @@ -625,6 +634,7 @@ protected boolean areTypesDirected() { } @Override + @RequiredReadAction protected String[] suggestMethodNames() { return suggestInitialMethodName(); } @@ -645,26 +655,28 @@ protected boolean isVoidReturn() { } @Override + @RequiredReadAction protected void checkMethodConflicts(MultiMap conflicts) { super.checkMethodConflicts(conflicts); - final VariableData[] parameters = getChosenParameters(); + VariableData[] parameters = getChosenParameters(); final Map vars = new HashMap<>(); for (PsiElement element : myElements) { element.accept(new JavaRecursiveElementWalkingVisitor() { @Override - public void visitLocalVariable(PsiLocalVariable variable) { + @RequiredReadAction + public void visitLocalVariable(@Nonnull PsiLocalVariable variable) { super.visitLocalVariable(variable); vars.put(variable.getName(), variable); } @Override - public void visitClass(PsiClass aClass) { + public void visitClass(@Nonnull PsiClass aClass) { } }); } for (VariableData parameter : parameters) { - final String paramName = parameter.name; - final PsiLocalVariable variable = vars.get(paramName); + String paramName = parameter.name; + PsiLocalVariable variable = vars.get(paramName); if (variable != null) { conflicts.putValue( variable, @@ -681,32 +693,35 @@ public PsiExpression[] findOccurrences() { return new PsiExpression[]{myExpression}; } if (myOutputVariable != null) { - final PsiElement scope = myOutputVariable instanceof PsiLocalVariable localVariable - ? RefactoringUtil.getVariableScope(localVariable) : PsiTreeUtil.findCommonParent(myElements); + PsiElement scope = myOutputVariable instanceof PsiLocalVariable localVariable + ? RefactoringUtil.getVariableScope(localVariable) + : PsiTreeUtil.findCommonParent(myElements); return CodeInsightUtil.findReferenceExpressions(scope, myOutputVariable); } - final List filter = ContainerUtil.filter( + List filter = ContainerUtil.filter( myExitStatements, statement -> statement instanceof PsiReturnStatement returnStatement && returnStatement.getReturnValue() != null ); - final List map = ContainerUtil.map(filter, statement -> ((PsiReturnStatement) statement).getReturnValue()); + List map = ContainerUtil.map(filter, statement -> ((PsiReturnStatement) statement).getReturnValue()); return map.toArray(new PsiExpression[map.size()]); } + @RequiredReadAction private Nullability initNullability() { if (!PsiUtil.isLanguageLevel5OrHigher(myElements[0]) || PsiUtil.resolveClassInType(myReturnType) == null) { return null; } - final NullableNotNullManager manager = NullableNotNullManager.getInstance(myProject); - final PsiClass nullableAnnotationClass = JavaPsiFacade.getInstance(myProject) + NullableNotNullManager manager = NullableNotNullManager.getInstance(myProject); + PsiClass nullableAnnotationClass = JavaPsiFacade.getInstance(myProject) .findClass(manager.getDefaultNullable(), myElements[0].getResolveScope()); + //noinspection RequiredXAction if (nullableAnnotationClass != null) { - final PsiElement elementInCopy = myTargetClass.getContainingFile().copy().findElementAt(myTargetClass.getTextOffset()); - final PsiClass classCopy = PsiTreeUtil.getParentOfType(elementInCopy, PsiClass.class); + PsiElement elementInCopy = myTargetClass.getContainingFile().copy().findElementAt(myTargetClass.getTextOffset()); + PsiClass classCopy = PsiTreeUtil.getParentOfType(elementInCopy, PsiClass.class); if (classCopy == null) { return null; } - final PsiMethod emptyMethod = (PsiMethod) classCopy.addAfter(generateEmptyMethod("name", null), classCopy.getLBrace()); + PsiMethod emptyMethod = (PsiMethod) classCopy.addAfter(generateEmptyMethod("name", null), classCopy.getLBrace()); prepareMethodBody(emptyMethod, false); if (myNotNullConditionalCheck || myNullConditionalCheck) { return Nullability.NULLABLE; @@ -719,18 +734,18 @@ private Nullability initNullability() { @RequiredReadAction protected String[] suggestInitialMethodName() { if (StringUtil.isEmpty(myInitialMethodName)) { - final Set initialMethodNames = new LinkedHashSet<>(); - final JavaCodeStyleManagerImpl codeStyleManager = (JavaCodeStyleManagerImpl) JavaCodeStyleManager.getInstance(myProject); + Set initialMethodNames = new LinkedHashSet<>(); + JavaCodeStyleManagerImpl codeStyleManager = (JavaCodeStyleManagerImpl) JavaCodeStyleManager.getInstance(myProject); if (myExpression != null || !(myReturnType instanceof PsiPrimitiveType)) { - final String[] names = codeStyleManager.suggestVariableName(VariableKind.FIELD, null, myExpression, myReturnType).names; + String[] names = codeStyleManager.suggestVariableName(VariableKind.FIELD, null, myExpression, myReturnType).names; for (String name : names) { initialMethodNames.add(codeStyleManager.variableNameToPropertyName(name, VariableKind.FIELD)); } } if (myOutputVariable != null) { - final VariableKind outKind = codeStyleManager.getVariableKind(myOutputVariable); - final SuggestedNameInfo nameInfo = codeStyleManager.suggestVariableName( + VariableKind outKind = codeStyleManager.getVariableKind(myOutputVariable); + SuggestedNameInfo nameInfo = codeStyleManager.suggestVariableName( VariableKind.FIELD, codeStyleManager.variableNameToPropertyName(myOutputVariable.getName(), outKind), null, @@ -741,28 +756,33 @@ protected String[] suggestInitialMethodName() { } } - final String nameByComment = getNameByComment(); - final PsiField field = JavaPsiFacade.getElementFactory(myProject) - .createField("fieldNameToReplace", myReturnType instanceof PsiEllipsisType ? ((PsiEllipsisType) myReturnType).toArrayType - () : myReturnType); - final List getters = new ArrayList<>(ContainerUtil.map(initialMethodNames, propertyName -> { - if (!PsiNameHelper.getInstance(myProject).isIdentifier(propertyName)) { - LOG.info(propertyName + "; " + myExpression); - return null; + String nameByComment = getNameByComment(); + PsiField field = JavaPsiFacade.getElementFactory(myProject).createField( + "fieldNameToReplace", + myReturnType instanceof PsiEllipsisType ellipsisType ? ellipsisType.toArrayType() : myReturnType + ); + List getters = new ArrayList<>(ContainerUtil.map( + initialMethodNames, + propertyName -> { + if (!PsiNameHelper.getInstance(myProject).isIdentifier(propertyName)) { + LOG.info(propertyName + "; " + myExpression); + return null; + } + field.setName(propertyName); + return PropertyUtil.suggestGetterName(field); } - field.setName(propertyName); - return PropertyUtil.suggestGetterName(field); - })); + )); ContainerUtil.addIfNotNull(getters, nameByComment); return ArrayUtil.toStringArray(getters); } return new String[]{myInitialMethodName}; } + @RequiredReadAction private String getNameByComment() { PsiElement prevSibling = PsiTreeUtil.skipSiblingsBackward(myElements[0], PsiWhiteSpace.class); if (prevSibling instanceof PsiComment comment && comment.getTokenType() == JavaTokenType.END_OF_LINE_COMMENT) { - final String text = StringUtil.decapitalize(StringUtil.capitalizeWords(prevSibling.getText().trim().substring(2), true)) + String text = StringUtil.decapitalize(StringUtil.capitalizeWords(prevSibling.getText().trim().substring(2), true)) .replaceAll(" ", ""); if (PsiNameHelper.getInstance(myProject).isIdentifier(text) && text.length() < 20) { return text; @@ -775,11 +795,13 @@ public boolean isOutputVariable(PsiVariable var) { return ArrayUtil.find(myOutputVariables, var) != -1; } + @RequiredUIAccess public boolean showDialog() { return showDialog(true); } @TestOnly + @RequiredReadAction public void testRun() throws IncorrectOperationException { testPrepare(); testNullness(); @@ -787,6 +809,7 @@ public void testRun() throws IncorrectOperationException { } @TestOnly + @RequiredReadAction public void testNullness() { myNullability = initNullability(); } @@ -832,6 +855,7 @@ public void changeParamName(int i, String param) { /** * Invoked in command and in atomic action */ + @RequiredUIAccess public void doRefactoring() throws IncorrectOperationException { initDuplicates(); @@ -849,16 +873,16 @@ public void doRefactoring() throws IncorrectOperationException { pos1 = null; } - final SearchScope processConflictsScope = myMethodVisibility.equals(PsiModifier.PRIVATE) + SearchScope processConflictsScope = myMethodVisibility.equals(PsiModifier.PRIVATE) ? new LocalSearchScope(myTargetClass) : GlobalSearchScope.projectScope(myProject); - final Map overloadsResolveMap = new HashMap<>(); - final Runnable collectOverloads = () -> myProject.getApplication().runReadAction(() -> { + Map overloadsResolveMap = new HashMap<>(); + Runnable collectOverloads = () -> myProject.getApplication().runReadAction(() -> { Map overloads = ExtractMethodUtil.encodeOverloadTargets(myTargetClass, processConflictsScope, myMethodName, myCodeFragmentMember); overloadsResolveMap.putAll(overloads); }); - final Runnable extract = () -> { + Runnable extract = () -> { doExtract(); ExtractMethodUtil.decodeOverloadTargets(overloadsResolveMap, myExtractedMethod, myCodeFragmentMember); }; @@ -866,13 +890,17 @@ public void doRefactoring() throws IncorrectOperationException { collectOverloads.run(); extract.run(); } - else { - if (!ProgressManager.getInstance() - .runProcessWithProgressSynchronously(collectOverloads, "Collect overloads...", true, myProject)) { - return; - } + else if (ProgressManager.getInstance().runProcessWithProgressSynchronously( + collectOverloads, + LocalizeValue.localizeTODO("Collect overloads..."), + true, + myProject + )) { myProject.getApplication().runWriteAction(extract); } + else { + return; + } if (myEditor != null) { myEditor.getCaretModel().moveToLogicalPosition(pos1); @@ -911,7 +939,7 @@ else if (elements.size() > 0) { return null; } - @RequiredReadAction + @RequiredWriteAction public void doExtract() throws IncorrectOperationException { PsiMethod newMethod = generateEmptyMethod(); @@ -925,7 +953,7 @@ public void doExtract() throws IncorrectOperationException { LOG.assertTrue(myElements[0].isValid()); - final PsiStatement exitStatementCopy = prepareMethodBody(newMethod, true); + PsiStatement exitStatementCopy = prepareMethodBody(newMethod, true); if (myExpression == null) { if (myNeedChangeContext && isNeedToChangeCallContext()) { @@ -935,7 +963,7 @@ public void doExtract() throws IncorrectOperationException { } if (myNullConditionalCheck) { - final String varName = myOutputVariable.getName(); + String varName = myOutputVariable.getName(); if (isDeclaredInside(myOutputVariable)) { declareVariableAtMethodCallLocation(varName); } @@ -953,7 +981,7 @@ public void doExtract() throws IncorrectOperationException { (PsiIfStatement) myElementFactory.createStatementFromText("if (" + varName + "==null) return null;", null); } else if (myGenerateConditionalExit) { - if (myFirstExitStatementCopy instanceof PsiReturnStatement && ((PsiReturnStatement) myFirstExitStatementCopy).getReturnValue() != null) { + if (myFirstExitStatementCopy instanceof PsiReturnStatement returnStmt && returnStmt.getReturnValue() != null) { ifStatement = (PsiIfStatement) myElementFactory.createStatementFromText("if (" + varName + "==null) return null;", null); } @@ -1030,22 +1058,21 @@ else if (!myGenerateConditionalExit && exitStatementCopy != null) { } else { PsiExpression expression2Replace = myExpression; - if (myExpression instanceof PsiAssignmentExpression) { - expression2Replace = ((PsiAssignmentExpression) myExpression).getRExpression(); + if (myExpression instanceof PsiAssignmentExpression assignment) { + expression2Replace = assignment.getRExpression(); } else if (myExpression instanceof PsiPostfixExpression || myExpression instanceof PsiPrefixExpression) { - final IElementType elementType = - myExpression instanceof PsiPostfixExpression ? ((PsiPostfixExpression) myExpression).getOperationTokenType() : ((PsiPrefixExpression) myExpression) - .getOperationTokenType(); + IElementType elementType = myExpression instanceof PsiPostfixExpression postfixExpr + ? postfixExpr.getOperationTokenType() + : ((PsiPrefixExpression) myExpression).getOperationTokenType(); if (elementType == JavaTokenType.PLUSPLUS || elementType == JavaTokenType.MINUSMINUS) { - PsiExpression operand = - myExpression instanceof PsiPostfixExpression ? ((PsiPostfixExpression) myExpression).getOperand() : ((PsiPrefixExpression) myExpression).getOperand(); - expression2Replace = ((PsiBinaryExpression) myExpression.replace(myElementFactory.createExpressionFromText( - operand.getText() + " + x", - operand - ))).getROperand(); + PsiExpression operand = myExpression instanceof PsiPostfixExpression postfixExpr + ? postfixExpr.getOperand() + : ((PsiPrefixExpression) myExpression).getOperand(); + expression2Replace = ((PsiBinaryExpression) myExpression.replace( + myElementFactory.createExpressionFromText(operand.getText() + " + x", operand)) + ).getROperand(); } - } myExpression = (PsiExpression) IntroduceVariableBase.replace(expression2Replace, myMethodCall, myProject); myMethodCall = PsiTreeUtil.getParentOfType( @@ -1055,8 +1082,8 @@ else if (myExpression instanceof PsiPostfixExpression || myExpression instanceof declareNecessaryVariablesAfterCall(myOutputVariable); } - if (myAnchor instanceof PsiField) { - ((PsiField) myAnchor).normalizeDeclaration(); + if (myAnchor instanceof PsiField field) { + field.normalizeDeclaration(); } adjustFinalParameters(newMethod); @@ -1065,18 +1092,14 @@ else if (myExpression instanceof PsiPostfixExpression || myExpression instanceof if (!data.passAsParameter) { continue; } - final PsiParameter psiParameter = newMethod.getParameterList().getParameters()[i++]; - final PsiType paramType = psiParameter.getType(); + PsiParameter psiParameter = newMethod.getParameterList().getParameters()[i++]; + PsiType paramType = psiParameter.getType(); for (PsiReference reference : ReferencesSearch.search(psiParameter, new LocalSearchScope(body))) { - final PsiElement element = reference.getElement(); - if (element != null) { - final PsiElement parent = element.getParent(); - if (parent instanceof PsiTypeCastExpression) { - final PsiTypeCastExpression typeCastExpression = (PsiTypeCastExpression) parent; - final PsiTypeElement castType = typeCastExpression.getCastType(); - if (castType != null && Comparing.equal(castType.getType(), paramType)) { - RedundantCastUtil.removeCast(typeCastExpression); - } + PsiElement element = reference.getElement(); + if (element != null && element.getParent() instanceof PsiTypeCastExpression typeCastExpression) { + PsiTypeElement castType = typeCastExpression.getCastType(); + if (castType != null && Comparing.equal(castType.getType(), paramType)) { + RedundantCastUtil.removeCast(typeCastExpression); } } } @@ -1105,12 +1128,13 @@ else if (myExpression instanceof PsiPostfixExpression || myExpression instanceof RefactoringChangeUtil.createThisExpression(myManager, null) ); if (myMethodCall.resolveMethod() != myExtractedMethod) { - final PsiReferenceExpression methodExpression = myMethodCall.getMethodExpression(); + PsiReferenceExpression methodExpression = myMethodCall.getMethodExpression(); methodExpression.setQualifierExpression(RefactoringChangeUtil.createThisExpression(myManager, myTargetClass)); } } } + @RequiredWriteAction private void updateAnnotations(PsiModifierListOwner owner, List toRemove, String toAdd, List toKeep) { AddAnnotationPsiFix.removePhysicalAnnotations(owner, ArrayUtil.toStringArray(toRemove)); PsiModifierList modifierList = owner.getModifierList(); @@ -1123,14 +1147,14 @@ private void updateAnnotations(PsiModifierListOwner owner, List toRemove } @Nullable - @RequiredReadAction + @RequiredWriteAction private PsiStatement prepareMethodBody(PsiMethod newMethod, boolean doExtract) { PsiCodeBlock body = newMethod.getBody(); if (myExpression != null) { declareNecessaryVariablesInsideBody(body); if (myHasExpressionOutput) { PsiReturnStatement returnStatement = (PsiReturnStatement) myElementFactory.createStatementFromText("return x;", null); - final PsiExpression returnValue = RefactoringUtil.convertInitializerToNormalExpression(myExpression, myForcedReturnType); + PsiExpression returnValue = RefactoringUtil.convertInitializerToNormalExpression(myExpression, myForcedReturnType); returnStatement.getReturnValue().replace(returnValue); body.add(returnStatement); } @@ -1142,7 +1166,7 @@ private PsiStatement prepareMethodBody(PsiMethod newMethod, boolean doExtract) { return null; } - final boolean hasNormalExit = hasNormalExit(); + boolean hasNormalExit = hasNormalExit(); String outVariableName = myOutputVariable != null ? getNewVariableName(myOutputVariable) : null; PsiReturnStatement returnStatement; if (myNullConditionalCheck) { @@ -1174,22 +1198,18 @@ else if (myGenerateConditionalExit) { body.add(myElementFactory.createStatementFromText("return false;", null)); } else if (!myHasReturnStatement && hasNormalExit && myOutputVariable != null) { - final PsiReturnStatement insertedReturnStatement = (PsiReturnStatement) body.add(returnStatement); + PsiReturnStatement insertedReturnStatement = (PsiReturnStatement) body.add(returnStatement); if (myOutputVariables.length == 1) { - final PsiExpression returnValue = insertedReturnStatement.getReturnValue(); - if (returnValue instanceof PsiReferenceExpression returnReferenceExpression) { - final PsiElement resolved = returnReferenceExpression.resolve(); - if (resolved instanceof PsiLocalVariable localVariable && Comparing.strEqual( - localVariable.getName(), - outVariableName - )) { - final PsiStatement statement = PsiTreeUtil.getPrevSiblingOfType(insertedReturnStatement, PsiStatement.class); - if (statement instanceof PsiDeclarationStatement declarationStatement) { - final PsiElement[] declaredElements = declarationStatement.getDeclaredElements(); - if (ArrayUtil.find(declaredElements, resolved) != -1) { - InlineUtil.inlineVariable(localVariable, localVariable.getInitializer(), returnReferenceExpression); - resolved.delete(); - } + PsiExpression returnValue = insertedReturnStatement.getReturnValue(); + if (returnValue instanceof PsiReferenceExpression returnRefExpr + && returnRefExpr.resolve() instanceof PsiLocalVariable localVar + && Comparing.strEqual(localVar.getName(), outVariableName)) { + PsiStatement statement = PsiTreeUtil.getPrevSiblingOfType(insertedReturnStatement, PsiStatement.class); + if (statement instanceof PsiDeclarationStatement declarationStatement) { + PsiElement[] declaredElements = declarationStatement.getDeclaredElements(); + if (ArrayUtil.find(declaredElements, localVar) != -1) { + InlineUtil.inlineVariable(localVar, localVar.getInitializer(), returnRefExpr); + localVar.delete(); } } } @@ -1208,8 +1228,9 @@ private boolean isArtificialOutputUsed() { private boolean hasNormalExit() { boolean hasNormalExit = false; PsiElement lastElement = myElements[myElements.length - 1]; - if (!(lastElement instanceof PsiReturnStatement || lastElement instanceof PsiBreakStatement || - lastElement instanceof PsiContinueStatement)) { + if (!(lastElement instanceof PsiReturnStatement + || lastElement instanceof PsiBreakStatement + || lastElement instanceof PsiContinueStatement)) { hasNormalExit = true; } return hasNormalExit; @@ -1219,10 +1240,12 @@ protected boolean isNeedToChangeCallContext() { return true; } + @RequiredWriteAction private void declareVariableAtMethodCallLocation(String name) { declareVariableAtMethodCallLocation(name, myReturnType); } + @RequiredWriteAction private String declareVariableAtMethodCallLocation(String name, PsiType type) { if (myControlFlowWrapper.getOutputVariables(false).length == 0) { PsiElement lastStatement = PsiTreeUtil.getNextSiblingOfType( @@ -1250,14 +1273,14 @@ private void adjustFinalParameters(final PsiMethod method) throws IncorrectOpera if (parameters.length > 0) { if (CodeStyleSettingsManager.getSettings(myProject).GENERATE_FINAL_PARAMETERS) { method.accept(new JavaRecursiveElementVisitor() { - @Override + @RequiredReadAction public void visitReferenceExpression(PsiReferenceExpression expression) { - final PsiElement resolved = expression.resolve(); + PsiElement resolved = expression.resolve(); if (resolved != null) { - final int index = ArrayUtil.find(parameters, resolved); + int index = ArrayUtil.find(parameters, resolved); if (index >= 0) { - final PsiParameter param = parameters[index]; + PsiParameter param = parameters[index]; if (param.hasModifierProperty(PsiModifier.FINAL) && PsiUtil.isAccessedForWriting(expression)) { try { PsiUtil.setModifierProperty(param, PsiModifier.FINAL, false); @@ -1275,15 +1298,14 @@ public void visitReferenceExpression(PsiReferenceExpression expression) { else { method.accept(new JavaRecursiveElementVisitor() { @Override + @RequiredReadAction public void visitReferenceExpression(PsiReferenceExpression expression) { - final PsiElement resolved = expression.resolve(); - final int index = ArrayUtil.find(parameters, resolved); + PsiElement resolved = expression.resolve(); + int index = ArrayUtil.find(parameters, resolved); if (index >= 0) { - final PsiParameter param = parameters[index]; - if (!param.hasModifierProperty(PsiModifier.FINAL) && RefactoringUtil.isInsideAnonymousOrLocal( - expression, - method - )) { + PsiParameter param = parameters[index]; + if (!param.hasModifierProperty(PsiModifier.FINAL) + && RefactoringUtil.isInsideAnonymousOrLocal(expression, method)) { try { PsiUtil.setModifierProperty(param, PsiModifier.FINAL, true); } @@ -1310,15 +1332,15 @@ public List getDuplicates() { return myDuplicates; } - private static List filterChainedConstructorDuplicates(final List duplicates) { - List result = new ArrayList(); + private static List filterChainedConstructorDuplicates(List duplicates) { + List result = new ArrayList<>(); for (Match duplicate : duplicates) { - final PsiElement matchStart = duplicate.getMatchStart(); - final PsiMethod method = PsiTreeUtil.getParentOfType(matchStart, PsiMethod.class); + PsiElement matchStart = duplicate.getMatchStart(); + PsiMethod method = PsiTreeUtil.getParentOfType(matchStart, PsiMethod.class); if (method != null && method.isConstructor()) { - final PsiCodeBlock body = method.getBody(); + PsiCodeBlock body = method.getBody(); if (body != null) { - final PsiStatement[] psiStatements = body.getStatements(); + PsiStatement[] psiStatements = body.getStatements(); if (psiStatements.length > 0 && matchStart == psiStatements[0]) { result.add(duplicate); } @@ -1329,28 +1351,29 @@ private static List filterChainedConstructorDuplicates(final List } @Override + @RequiredWriteAction public PsiElement processMatch(Match match) throws IncorrectOperationException { MatchUtil.changeSignature(match, myExtractedMethod); if (RefactoringUtil.isInStaticContext(match.getMatchStart(), myExtractedMethod.getContainingClass())) { PsiUtil.setModifierProperty(myExtractedMethod, PsiModifier.STATIC, true); } - final PsiMethodCallExpression methodCallExpression = generateMethodCall(match.getInstanceExpression(), false); + PsiMethodCallExpression methodCallExpression = generateMethodCall(match.getInstanceExpression(), false); - ArrayList datas = new ArrayList(); - for (final VariableData variableData : myVariableDatum) { + List datas = new ArrayList<>(); + for (VariableData variableData : myVariableDatum) { if (variableData.passAsParameter) { datas.add(variableData); } } - final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject); + PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject); for (VariableData data : datas) { - final List parameterValue = match.getParameterValues(data.variable); + List parameterValue = match.getParameterValues(data.variable); if (parameterValue != null) { for (PsiElement val : parameterValue) { - if (val instanceof PsiExpression) { - final PsiType exprType = ((PsiExpression) val).getType(); + if (val instanceof PsiExpression expr) { + PsiType exprType = expr.getType(); if (exprType != null && !TypeConversionUtil.isAssignable(data.type, exprType)) { - final PsiTypeCastExpression cast = (PsiTypeCastExpression) elementFactory.createExpressionFromText("(A)a", val); + PsiTypeCastExpression cast = (PsiTypeCastExpression) elementFactory.createExpressionFromText("(A)a", val); cast.getCastType().replace(elementFactory.createTypeElement(data.type)); cast.getOperand().replace(val.copy()); val = cast; @@ -1367,6 +1390,7 @@ public PsiElement processMatch(Match match) throws IncorrectOperationException { return match.replace(myExtractedMethod, methodCallExpression, myOutputVariable); } + @RequiredWriteAction protected void deleteExtracted() throws IncorrectOperationException { if (myEnclosingBlockStatement == null) { myElements[0].getParent().deleteChildRange(myElements[0], myElements[myElements.length - 1]); @@ -1376,6 +1400,7 @@ protected void deleteExtracted() throws IncorrectOperationException { } } + @RequiredWriteAction protected PsiElement addToMethodCallLocation(PsiStatement statement) throws IncorrectOperationException { if (myEnclosingBlockStatement == null) { PsiElement containingStatement = myElements[0] instanceof PsiComment ? myElements[0] @@ -1392,6 +1417,7 @@ protected PsiElement addToMethodCallLocation(PsiStatement statement) throws Inco } } + @RequiredReadAction private void renameInputVariables() throws IncorrectOperationException { //when multiple input variables should have the same name, unique names are generated //without reverse, the second rename would rename variable without a prefix into second one though it was already renamed @@ -1414,10 +1440,12 @@ public PsiType getReturnType() { return myReturnType; } + @RequiredWriteAction private PsiMethod generateEmptyMethod() throws IncorrectOperationException { return generateEmptyMethod(myMethodName, null); } + @RequiredWriteAction public PsiMethod generateEmptyMethod(String methodName, PsiElement context) throws IncorrectOperationException { PsiMethod newMethod; if (myIsChainedConstructor) { @@ -1439,15 +1467,15 @@ public PsiMethod generateEmptyMethod(String methodName, PsiElement context) thro PsiParameterList list = newMethod.getParameterList(); for (VariableData data : myVariableDatum) { if (data.passAsParameter) { - PsiParameter parm = myElementFactory.createParameter(data.name, data.type); - copyParamAnnotations(parm); + PsiParameter param = myElementFactory.createParameter(data.name, data.type); + copyParamAnnotations(param); if (isFinal) { - PsiUtil.setModifierProperty(parm, PsiModifier.FINAL, true); + PsiUtil.setModifierProperty(param, PsiModifier.FINAL, true); } - list.add(parm); + list.add(param); } else { - @NonNls StringBuilder buffer = new StringBuilder(); + StringBuilder buffer = new StringBuilder(); if (isFinal) { buffer.append("final "); } @@ -1458,7 +1486,7 @@ public PsiMethod generateEmptyMethod(String methodName, PsiElement context) thro PsiDeclarationStatement declaration = (PsiDeclarationStatement) myElementFactory.createStatementFromText(text, null); declaration = (PsiDeclarationStatement) myStyleManager.reformat(declaration); - final PsiTypeElement typeElement = myElementFactory.createTypeElement(data.type); + PsiTypeElement typeElement = myElementFactory.createTypeElement(data.type); ((PsiVariable) declaration.getDeclaredElements()[0]).getTypeElement().replace(typeElement); body.add(declaration); } @@ -1470,7 +1498,7 @@ public PsiMethod generateEmptyMethod(String methodName, PsiElement context) thro } if (myTargetClass.isInterface() && PsiUtil.isLanguageLevel8OrHigher(myTargetClass)) { - final PsiMethod containingMethod = PsiTreeUtil.getParentOfType(myCodeFragmentMember, PsiMethod.class, false); + PsiMethod containingMethod = PsiTreeUtil.getParentOfType(myCodeFragmentMember, PsiMethod.class, false); if (containingMethod != null && containingMethod.hasModifierProperty(PsiModifier.DEFAULT)) { PsiUtil.setModifierProperty(newMethod, PsiModifier.DEFAULT, true); } @@ -1478,29 +1506,30 @@ public PsiMethod generateEmptyMethod(String methodName, PsiElement context) thro return (PsiMethod) myStyleManager.reformat(newMethod); } - private void copyParamAnnotations(PsiParameter parm) { - final PsiVariable variable = PsiResolveHelper.getInstance(myProject).resolveReferencedVariable(parm.getName(), myElements[0]); - if (variable instanceof PsiParameter) { - final PsiModifierList modifierList = variable.getModifierList(); + private void copyParamAnnotations(PsiParameter param) { + PsiVariable variable = PsiResolveHelper.getInstance(myProject).resolveReferencedVariable(param.getName(), myElements[0]); + if (variable instanceof PsiParameter refParam) { + PsiModifierList modifierList = refParam.getModifierList(); if (modifierList != null) { for (PsiAnnotation annotation : modifierList.getAnnotations()) { if (SuppressWarnings.class.getName().equals(annotation.getQualifiedName())) { continue; } - final PsiModifierList parmModifierList = parm.getModifierList(); - LOG.assertTrue(parmModifierList != null, parm); - parmModifierList.add(annotation); + PsiModifierList paramModifierList = param.getModifierList(); + LOG.assertTrue(paramModifierList != null, param); + paramModifierList.add(annotation); } } } } @Nonnull - protected PsiMethodCallExpression generateMethodCall(PsiExpression instanceQualifier, final boolean generateArgs) + @RequiredWriteAction + protected PsiMethodCallExpression generateMethodCall(PsiExpression instanceQualifier, boolean generateArgs) throws IncorrectOperationException { - @NonNls StringBuilder buffer = new StringBuilder(); + StringBuilder buffer = new StringBuilder(); - final boolean skipInstanceQualifier; + boolean skipInstanceQualifier; if (myIsChainedConstructor) { skipInstanceQualifier = true; buffer.append(PsiKeyword.THIS); @@ -1512,12 +1541,9 @@ protected PsiMethodCallExpression generateMethodCall(PsiExpression instanceQuali boolean needsThisQualifier = false; PsiElement parent = myCodeFragmentMember; while (!myTargetClass.equals(parent)) { - if (parent instanceof PsiMethod) { - String methodName = ((PsiMethod) parent).getName(); - if (methodName.equals(myMethodName)) { - needsThisQualifier = true; - break; - } + if (parent instanceof PsiMethod method && method.getName().equals(myMethodName)) { + needsThisQualifier = true; + break; } parent = parent.getParent(); } @@ -1558,24 +1584,20 @@ protected PsiMethodCallExpression generateMethodCall(PsiExpression instanceQuali return (PsiMethodCallExpression) JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(expr); } - private boolean chooseTargetClass( - PsiElement codeFragment, - final Consumer extractPass - ) throws PrepareFailedException { - final List inputVariables = myControlFlowWrapper.getInputVariables(codeFragment, myElements, myOutputVariables); + @RequiredUIAccess + private boolean chooseTargetClass(PsiElement codeFragment, Consumer extractPass) throws PrepareFailedException { + List inputVariables = myControlFlowWrapper.getInputVariables(codeFragment, myElements, myOutputVariables); myNeedChangeContext = false; - myTargetClass = - myCodeFragmentMember instanceof PsiMember ? ((PsiMember) myCodeFragmentMember).getContainingClass() : PsiTreeUtil.getParentOfType( - myCodeFragmentMember, - PsiClass.class - ); + myTargetClass = myCodeFragmentMember instanceof PsiMember member + ? member.getContainingClass() + : PsiTreeUtil.getParentOfType(myCodeFragmentMember, PsiClass.class); if (!shouldAcceptCurrentTarget(extractPass, myTargetClass)) { - - final LinkedHashMap> classes = new LinkedHashMap<>(); - final PsiElementProcessor processor = selectedClass -> { + Map> classes = new LinkedHashMap<>(); + @RequiredUIAccess + PsiElementProcessor processor = selectedClass -> { AnonymousTargetClassPreselectionUtil.rememberSelection(selectedClass, myTargetClass); - final List array = classes.get(selectedClass); + List array = classes.get(selectedClass); myNeedChangeContext = myTargetClass != selectedClass; myTargetClass = selectedClass; if (array != null) { @@ -1612,7 +1634,7 @@ private boolean chooseTargetClass( } if (target instanceof PsiClass psiClass) { boolean success = true; - final List array = new ArrayList<>(); + List array = new ArrayList<>(); for (PsiElement el : myElements) { if (!ControlFlowUtil.collectOuterLocals(array, el, myCodeFragmentMember, targetMember)) { success = false; @@ -1631,8 +1653,8 @@ private boolean chooseTargetClass( } if (classes.size() > 1) { - final PsiClass[] psiClasses = classes.keySet().toArray(new PsiClass[classes.size()]); - final PsiClass preselection = AnonymousTargetClassPreselectionUtil.getPreselection(classes.keySet(), psiClasses[0]); + PsiClass[] psiClasses = classes.keySet().toArray(new PsiClass[classes.size()]); + PsiClass preselection = AnonymousTargetClassPreselectionUtil.getPreselection(classes.keySet(), psiClasses[0]); JBPopup popup = PopupNavigationUtil.getPsiElementPopup( psiClasses, new PsiClassListCellRenderer(), @@ -1670,7 +1692,7 @@ private void declareNecessaryVariablesInsideBody(PsiCodeBlock body) throws Incor } } - @RequiredReadAction + @RequiredWriteAction protected void declareNecessaryVariablesAfterCall(PsiVariable outputVariable) throws IncorrectOperationException { if (myHasExpressionOutput) { return; @@ -1683,7 +1705,7 @@ protected void declareNecessaryVariablesAfterCall(PsiVariable outputVariable) th String name = variable.getName(); PsiDeclarationStatement statement = myElementFactory.createVariableDeclarationStatement(name, variable.getType(), null); if (reassigned.contains(new ControlFlowUtil.VariableInfo(variable, null))) { - final PsiElement[] psiElements = statement.getDeclaredElements(); + PsiElement[] psiElements = statement.getDeclaredElements(); assert psiElements.length > 0; PsiVariable var = (PsiVariable) psiElements[0]; PsiUtil.setModifierProperty(var, PsiModifier.FINAL, false); @@ -1709,7 +1731,7 @@ public boolean isDeclaredInside(PsiVariable variable) { int startOffset; int endOffset; if (myExpression != null) { - final TextRange range = myExpression.getTextRange(); + TextRange range = myExpression.getTextRange(); startOffset = range.getStartOffset(); endOffset = range.getEndOffset(); } @@ -1721,14 +1743,12 @@ public boolean isDeclaredInside(PsiVariable variable) { if (nameIdentifier == null) { return false; } - final TextRange range = nameIdentifier.getTextRange(); - if (range == null) { - return false; - } + TextRange range = nameIdentifier.getTextRange(); int offset = range.getStartOffset(); return startOffset <= offset && offset <= endOffset; } + @RequiredReadAction private String getNewVariableName(PsiVariable variable) { for (VariableData data : myVariableDatum) { if (data.variable.equals(variable)) { @@ -1742,16 +1762,17 @@ private static boolean shouldAcceptCurrentTarget(Consumer inputVariables, @Nullable Consumer extractPass) throws PrepareFailedException { myStatic = shouldBeStatic(); final Set fields = new LinkedHashSet<>(); if (!PsiUtil.isLocalOrAnonymousClass(myTargetClass) - && (myTargetClass.getContainingClass() == null || myTargetClass.hasModifierProperty(PsiModifier.STATIC))) { + && (myTargetClass.getContainingClass() == null || myTargetClass.isStatic())) { boolean canBeStatic = true; if (myTargetClass.isInterface()) { - final PsiMethod containingMethod = PsiTreeUtil.getParentOfType(myCodeFragmentMember, PsiMethod.class, false); - canBeStatic = containingMethod == null || containingMethod.hasModifierProperty(PsiModifier.STATIC); + PsiMethod containingMethod = PsiTreeUtil.getParentOfType(myCodeFragmentMember, PsiMethod.class, false); + canBeStatic = containingMethod == null || containingMethod.isStatic(); } if (canBeStatic) { ElementNeedsThis needsThis = new ElementNeedsThis(myTargetClass) { @@ -1760,8 +1781,8 @@ protected void visitClassMemberReferenceElement( PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference ) { - if (classMember instanceof PsiField && !classMember.hasModifierProperty(PsiModifier.STATIC)) { - final PsiExpression expression = PsiTreeUtil.getParentOfType(classMemberReference, PsiExpression.class, false); + if (classMember instanceof PsiField && !classMember.isStatic()) { + PsiExpression expression = PsiTreeUtil.getParentOfType(classMemberReference, PsiExpression.class, false); if (expression == null || !PsiUtil.isAccessedForWriting(expression)) { fields.add((PsiField) classMember); return; @@ -1810,6 +1831,7 @@ private void chooseAnchor() { } } + @RequiredUIAccess private void showMultipleExitPointsMessage() { if (myShowErrorDialogs) { HighlightManager highlightManager = HighlightManager.getInstance(myProject); @@ -1818,11 +1840,11 @@ private void showMultipleExitPointsMessage() { LocalizeValue message = RefactoringLocalize.cannotPerformRefactoringWithReason( RefactoringLocalize.thereAreMultipleExitPointsInTheSelectedCodeFragment() ); - CommonRefactoringUtil.showErrorHint(myProject, myEditor, message.get(), myRefactoringName, myHelpId); + CommonRefactoringUtil.showErrorHint(myProject, myEditor, message, myRefactoringName, myHelpId); } } - @RequiredReadAction + @RequiredUIAccess private void showMultipleOutputMessage(PsiType expressionType) { if (myShowErrorDialogs) { StringBuilder buffer = new StringBuilder(); @@ -1861,9 +1883,9 @@ private void showMultipleOutputMessage(PsiType expressionType) { } RefactoringMessageDialog dialog = new RefactoringMessageDialog( myRefactoringName, - message, + LocalizeValue.localizeTODO(message), myHelpId, - "OptionPane.errorIcon", + UIUtil.getErrorIcon(), true, myProject ); @@ -1890,7 +1912,7 @@ public Boolean hasDuplicates() { } if (myExtractedMethod != null) { - final ExtractMethodSignatureSuggester suggester = + ExtractMethodSignatureSuggester suggester = new ExtractMethodSignatureSuggester(myProject, myExtractedMethod, myMethodCall, myVariableDatum); duplicates = suggester.getDuplicates(myExtractedMethod, myMethodCall, myInputVariables.getFolding()); if (duplicates != null && !duplicates.isEmpty()) { @@ -1906,14 +1928,14 @@ public Boolean hasDuplicates() { @RequiredReadAction public boolean hasDuplicates(Set files) { - final DuplicatesFinder finder = initDuplicates(); + DuplicatesFinder finder = initDuplicates(); - final Boolean hasDuplicates = hasDuplicates(); + Boolean hasDuplicates = hasDuplicates(); if (hasDuplicates == null || hasDuplicates) { return true; } if (finder != null) { - final PsiManager psiManager = PsiManager.getInstance(myProject); + PsiManager psiManager = PsiManager.getInstance(myProject); for (VirtualFile file : files) { if (!finder.findDuplicates(psiManager.findFile(file)).isEmpty()) { return true; @@ -1926,8 +1948,8 @@ public boolean hasDuplicates(Set files) { @Override @Nullable public String getConfirmDuplicatePrompt(Match match) { - final boolean needToBeStatic = RefactoringUtil.isInStaticContext(match.getMatchStart(), myExtractedMethod.getContainingClass()); - final String changedSignature = MatchUtil.getChangedSignature( + boolean needToBeStatic = RefactoringUtil.isInStaticContext(match.getMatchStart(), myExtractedMethod.getContainingClass()); + String changedSignature = MatchUtil.getChangedSignature( match, myExtractedMethod, needToBeStatic, @@ -1936,7 +1958,7 @@ public String getConfirmDuplicatePrompt(Match match) { if (changedSignature != null) { return RefactoringLocalize.replaceThisCodeFragmentAndChangeSignature(changedSignature).get(); } - if (needToBeStatic && !myExtractedMethod.hasModifierProperty(PsiModifier.STATIC)) { + if (needToBeStatic && !myExtractedMethod.isStatic()) { return RefactoringLocalize.replaceThisCodeFragmentAndMakeMethodStatic().get(); } return null; diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethodObject/ExtractMethodObjectProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethodObject/ExtractMethodObjectProcessor.java index d4478a60d..87f8ee684 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethodObject/ExtractMethodObjectProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethodObject/ExtractMethodObjectProcessor.java @@ -36,7 +36,8 @@ import com.intellij.java.language.psi.util.PropertyUtil; import com.intellij.java.language.psi.util.PsiUtil; import com.intellij.java.language.util.VisibilityUtil; -import consulo.application.ApplicationManager; +import consulo.annotation.access.RequiredReadAction; +import consulo.annotation.access.RequiredWriteAction; import consulo.codeEditor.Editor; import consulo.content.scope.SearchScope; import consulo.language.codeStyle.CodeStyleManager; @@ -61,13 +62,10 @@ import consulo.util.collection.ArrayUtil; import consulo.util.lang.Comparing; import consulo.util.lang.StringUtil; -import org.jetbrains.annotations.NonNls; - import jakarta.annotation.Nonnull; import javax.swing.*; import java.util.*; -import java.util.function.Function; public class ExtractMethodObjectProcessor extends BaseRefactoringProcessor { private static final Logger LOG = Logger.getInstance(ExtractMethodObjectProcessor.class); @@ -89,54 +87,50 @@ public class ExtractMethodObjectProcessor extends BaseRefactoringProcessor { private boolean myChangeReturnType; private Runnable myCopyMethodToInner; - public ExtractMethodObjectProcessor(Project project, Editor editor, PsiElement[] elements, final String innerClassName) { + @RequiredReadAction + public ExtractMethodObjectProcessor(Project project, Editor editor, PsiElement[] elements, String innerClassName) { super(project); myInnerClassName = innerClassName; - myExtractProcessor = new MyExtractMethodProcessor( - project, - editor, - elements, - null, - REFACTORING_NAME.get(), - innerClassName, - HelpID.EXTRACT_METHOD_OBJECT - ); + myExtractProcessor = + new MyExtractMethodProcessor(project, editor, elements, null, REFACTORING_NAME, innerClassName, HelpID.EXTRACT_METHOD_OBJECT); myElementFactory = JavaPsiFacade.getInstance(project).getElementFactory(); } @Nonnull - protected UsageViewDescriptor createUsageViewDescriptor(@Nonnull final UsageInfo[] usages) { + @Override + protected UsageViewDescriptor createUsageViewDescriptor(@Nonnull UsageInfo[] usages) { return new ExtractMethodObjectViewDescriptor(getMethod()); } @Nonnull + @Override + @RequiredReadAction protected UsageInfo[] findUsages() { - final ArrayList result = new ArrayList(); - final PsiClass containingClass = getMethod().getContainingClass(); - final SearchScope scope = - PsiUtilCore.getVirtualFile(containingClass) == null ? new LocalSearchScope(containingClass) : GlobalSearchScope.projectScope( - myProject); + List result = new ArrayList<>(); + PsiClass containingClass = getMethod().getContainingClass(); + SearchScope scope = PsiUtilCore.getVirtualFile(containingClass) == null + ? new LocalSearchScope(containingClass) + : GlobalSearchScope.projectScope(myProject); PsiReference[] refs = ReferencesSearch.search(getMethod(), scope, false).toArray(PsiReference.EMPTY_ARRAY); for (PsiReference ref : refs) { - final PsiElement element = ref.getElement(); + PsiElement element = ref.getElement(); if (element != null && element.isValid()) { result.add(new UsageInfo(element)); } } if (isCreateInnerClass()) { - final Set usedMethods = new LinkedHashSet(); + final Set usedMethods = new LinkedHashSet<>(); getMethod().accept(new JavaRecursiveElementWalkingVisitor() { @Override - public void visitMethodCallExpression(PsiMethodCallExpression expression) { + public void visitMethodCallExpression(@Nonnull PsiMethodCallExpression expression) { super.visitMethodCallExpression(expression); - final PsiMethod method = expression.resolveMethod(); + PsiMethod method = expression.resolveMethod(); if (method != null) { usedMethods.add(method); } } }); - for (PsiMethod usedMethod : usedMethods) { if (usedMethod.getModifierList().hasModifierProperty(PsiModifier.PRIVATE)) { PsiMethod toMove = usedMethod; @@ -156,13 +150,15 @@ public void visitMethodCallExpression(PsiMethodCallExpression expression) { return UsageViewUtil.removeDuplicatedUsages(usageInfos); } - public void performRefactoring(@Nonnull final UsageInfo[] usages) { + @Override + @RequiredWriteAction + public void performRefactoring(@Nonnull UsageInfo[] usages) { try { if (isCreateInnerClass()) { myInnerClass = (PsiClass) getMethod().getContainingClass().add(myElementFactory.createClass(getInnerClassName())); - final boolean isStatic = copyMethodModifiers() && notHasGeneratedFields(); + boolean isStatic = copyMethodModifiers() && notHasGeneratedFields(); for (UsageInfo usage : usages) { - final PsiMethodCallExpression methodCallExpression = + PsiMethodCallExpression methodCallExpression = PsiTreeUtil.getParentOfType(usage.getElement(), PsiMethodCallExpression.class); if (methodCallExpression != null) { replaceMethodCallExpression(inferTypeArguments(methodCallExpression), methodCallExpression); @@ -174,12 +170,12 @@ public void performRefactoring(@Nonnull final UsageInfo[] usages) { myInnerClass.add(myElementFactory.createMethodFromText("boolean is(){return myResult;}", myInnerClass)); } - final PsiParameter[] parameters = getMethod().getParameterList().getParameters(); + PsiParameter[] parameters = getMethod().getParameterList().getParameters(); if (parameters.length > 0) { createInnerClassConstructor(parameters); } else if (isStatic) { - final PsiMethod copy = (PsiMethod) getMethod().copy(); + PsiMethod copy = (PsiMethod) getMethod().copy(); copy.setName("invoke"); myInnerClass.add(copy); if (myMultipleExitPoints) { @@ -190,16 +186,14 @@ else if (isStatic) { if (myMultipleExitPoints) { addOutputVariableFieldsWithGetters(); } - myCopyMethodToInner = new Runnable() { - public void run() { - copyMethodWithoutParameters(); - copyMethodTypeParameters(); - } + myCopyMethodToInner = () -> { + copyMethodWithoutParameters(); + copyMethodTypeParameters(); }; } else { for (UsageInfo usage : usages) { - final PsiMethodCallExpression methodCallExpression = + PsiMethodCallExpression methodCallExpression = PsiTreeUtil.getParentOfType(usage.getElement(), PsiMethodCallExpression.class); if (methodCallExpression != null) { methodCallExpression.replace(processMethodDeclaration(methodCallExpression.getArgumentList())); @@ -212,18 +206,19 @@ public void run() { } } + @RequiredWriteAction void moveUsedMethodsToInner() { if (!myUsages.isEmpty()) { - if (ApplicationManager.getApplication().isUnitTestMode()) { + if (myProject.getApplication().isUnitTestMode()) { for (MethodToMoveUsageInfo usage : myUsages) { - final PsiMember member = (PsiMember) usage.getElement(); + PsiMember member = (PsiMember) usage.getElement(); LOG.assertTrue(member != null); myInnerClass.add(member.copy()); member.delete(); } return; } - final List memberInfos = new ArrayList(); + List memberInfos = new ArrayList<>(); for (MethodToMoveUsageInfo usage : myUsages) { memberInfos.add(new MemberInfo((PsiMethod) usage.getElement())); } @@ -242,13 +237,11 @@ protected JComponent createCenterPanel() { } }; if (dlg.showAndGet()) { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - public void run() { - for (MemberInfoBase memberInfo : panel.getTable().getSelectedMemberInfos()) { - if (memberInfo.isChecked()) { - myInnerClass.add(memberInfo.getMember().copy()); - memberInfo.getMember().delete(); - } + myProject.getApplication().runWriteAction(() -> { + for (MemberInfoBase memberInfo : panel.getTable().getSelectedMemberInfos()) { + if (memberInfo.isChecked()) { + myInnerClass.add(memberInfo.getMember().copy()); + memberInfo.getMember().delete(); } } }); @@ -256,15 +249,16 @@ public void run() { } } + @RequiredWriteAction private void addOutputVariableFieldsWithGetters() throws IncorrectOperationException { - final Map var2FieldNames = new HashMap(); + Map var2FieldNames = new HashMap<>(); final PsiVariable[] outputVariables = myExtractProcessor.getOutputVariables(); for (int i = 0; i < outputVariables.length; i++) { - final PsiVariable var = outputVariables[i]; - final PsiField outputField = myOutputFields[i]; - final String name = getPureName(var); + PsiVariable var = outputVariables[i]; + PsiField outputField = myOutputFields[i]; + String name = getPureName(var); LOG.assertTrue(name != null); - final PsiField field; + PsiField field; if (outputField != null) { var2FieldNames.put(var.getName(), outputField.getName()); myInnerClass.add(outputField); @@ -275,37 +269,37 @@ private void addOutputVariableFieldsWithGetters() throws IncorrectOperationExcep } LOG.assertTrue( field != null, - "i:" + i + "; output variables: " + Arrays.toString(outputVariables) + "; parameters: " + Arrays.toString(getMethod().getParameterList() - .getParameters()) + + "i:" + i + "; output variables: " + Arrays.toString(outputVariables) + + "; parameters: " + Arrays.toString(getMethod().getParameterList().getParameters()) + "; output field: " + outputField ); myInnerClass.add(GenerateMembersUtil.generateGetterPrototype(field)); } - final PsiCodeBlock body = getMethod().getBody(); + PsiCodeBlock body = getMethod().getBody(); LOG.assertTrue(body != null); - final LinkedHashSet vars = new LinkedHashSet(); - final Map replacementMap = new LinkedHashMap(); - final List returnStatements = new ArrayList(); + final LinkedHashSet vars = new LinkedHashSet<>(); + final Map replacementMap = new LinkedHashMap<>(); + final List returnStatements = new ArrayList<>(); body.accept(new JavaRecursiveElementWalkingVisitor() { @Override - public void visitReturnStatement(PsiReturnStatement statement) { + public void visitReturnStatement(@Nonnull PsiReturnStatement statement) { returnStatements.add(statement); } @Override - public void visitClass(PsiClass aClass) { + public void visitClass(@Nonnull PsiClass aClass) { } @Override - public void visitLambdaExpression(PsiLambdaExpression expression) { + public void visitLambdaExpression(@Nonnull PsiLambdaExpression expression) { } }); if (myExtractProcessor.generatesConditionalExit()) { for (int i = 0; i < returnStatements.size() - 1; i++) { - final PsiReturnStatement condition = returnStatements.get(i); - final PsiElement container = condition.getParent(); - final PsiStatement resultStmt = myElementFactory.createStatementFromText("myResult = true;", container); + PsiReturnStatement condition = returnStatements.get(i); + PsiElement container = condition.getParent(); + PsiStatement resultStmt = myElementFactory.createStatementFromText("myResult = true;", container); if (!RefactoringUtil.isLoopOrIf(container)) { container.addBefore(resultStmt, condition); } @@ -315,9 +309,9 @@ public void visitLambdaExpression(PsiLambdaExpression expression) { } LOG.assertTrue(!returnStatements.isEmpty()); - final PsiReturnStatement returnStatement = returnStatements.get(returnStatements.size() - 1); - final PsiElement container = returnStatement.getParent(); - final PsiStatement resultStmt = myElementFactory.createStatementFromText("myResult = false;", container); + PsiReturnStatement returnStatement = returnStatements.get(returnStatements.size() - 1); + PsiElement container = returnStatement.getParent(); + PsiStatement resultStmt = myElementFactory.createStatementFromText("myResult = false;", container); if (!RefactoringUtil.isLoopOrIf(container)) { container.addBefore(resultStmt, returnStatement); } @@ -327,7 +321,7 @@ public void visitLambdaExpression(PsiLambdaExpression expression) { } body.accept(new JavaRecursiveElementWalkingVisitor() { @Override - public void visitReturnStatement(final PsiReturnStatement statement) { + public void visitReturnStatement(@Nonnull PsiReturnStatement statement) { super.visitReturnStatement(statement); try { replacementMap.put(statement, myElementFactory.createStatementFromText("return this;", statement)); @@ -338,23 +332,22 @@ public void visitReturnStatement(final PsiReturnStatement statement) { } @Override - public void visitClass(PsiClass aClass) { + public void visitClass(@Nonnull PsiClass aClass) { } @Override - public void visitLambdaExpression(PsiLambdaExpression expression) { + public void visitLambdaExpression(@Nonnull PsiLambdaExpression expression) { } @Override - public void visitDeclarationStatement(final PsiDeclarationStatement statement) { + public void visitDeclarationStatement(@Nonnull PsiDeclarationStatement statement) { super.visitDeclarationStatement(statement); - final PsiElement[] declaredElements = statement.getDeclaredElements();//todo + PsiElement[] declaredElements = statement.getDeclaredElements();//todo for (PsiElement declaredElement : declaredElements) { - if (declaredElement instanceof PsiVariable) { + if (declaredElement instanceof PsiVariable var) { for (PsiVariable variable : outputVariables) { - PsiVariable var = (PsiVariable) declaredElement; if (Comparing.strEqual(var.getName(), variable.getName())) { - final PsiExpression initializer = var.getInitializer(); + PsiExpression initializer = var.getInitializer(); if (initializer == null) { replacementMap.put(statement, null); } @@ -368,14 +361,14 @@ public void visitDeclarationStatement(final PsiDeclarationStatement statement) { } @Override - public void visitReferenceExpression(final PsiReferenceExpression expression) { + @RequiredReadAction + public void visitReferenceExpression(PsiReferenceExpression expression) { super.visitReferenceExpression(expression); - final PsiElement resolved = expression.resolve(); - if (resolved instanceof PsiLocalVariable) { - final String var = ((PsiLocalVariable) resolved).getName(); + if (expression.resolve() instanceof PsiLocalVariable localVar) { + String localVarName = localVar.getName(); for (PsiVariable variable : outputVariables) { - if (Comparing.strEqual(variable.getName(), var)) { - vars.add((PsiLocalVariable) resolved); + if (Objects.equals(variable.getName(), localVarName)) { + vars.add(localVar); break; } } @@ -384,33 +377,34 @@ public void visitReferenceExpression(final PsiReferenceExpression expression) { }); for (PsiLocalVariable var : vars) { - final String fieldName = var2FieldNames.get(var.getName()); + String fieldName = var2FieldNames.get(var.getName()); for (PsiReference reference : ReferencesSearch.search(var)) { reference.handleElementRename(fieldName); } } for (PsiElement statement : replacementMap.keySet()) { - final PsiElement replacement = replacementMap.get(statement); + PsiElement replacement = replacementMap.get(statement); if (replacement != null) { - if (statement instanceof PsiLocalVariable) { - final PsiLocalVariable variable = (PsiLocalVariable) statement; + if (statement instanceof PsiLocalVariable variable) { variable.normalizeDeclaration(); - final PsiExpression initializer = variable.getInitializer(); + PsiExpression initializer = variable.getInitializer(); LOG.assertTrue(initializer != null); - final PsiStatement assignmentStatement = myElementFactory.createStatementFromText( + PsiStatement assignmentStatement = myElementFactory.createStatementFromText( var2FieldNames.get(variable.getName()) + " = " + initializer.getText() + ";", statement ); - final PsiDeclarationStatement declaration = PsiTreeUtil.getParentOfType(statement, PsiDeclarationStatement.class); + PsiDeclarationStatement declaration = PsiTreeUtil.getParentOfType(statement, PsiDeclarationStatement.class); LOG.assertTrue(declaration != null); declaration.replace(assignmentStatement); } else { - if (statement instanceof PsiReturnStatement) { - final PsiExpression returnValue = ((PsiReturnStatement) statement).getReturnValue(); - if (!(returnValue instanceof PsiReferenceExpression || returnValue == null || returnValue instanceof PsiLiteralExpression)) { - statement.getParent() + if (statement instanceof PsiReturnStatement returnStmt) { + PsiExpression returnValue = returnStmt.getReturnValue(); + if (!(returnValue instanceof PsiReferenceExpression + || returnValue == null + || returnValue instanceof PsiLiteralExpression)) { + returnStmt.getParent() .addBefore(myElementFactory.createStatementFromText(returnValue.getText() + ";", returnValue), statement); } } @@ -425,80 +419,83 @@ public void visitReferenceExpression(final PsiReferenceExpression expression) { myChangeReturnType = true; } + @RequiredWriteAction void runChangeSignature() { if (myCopyMethodToInner != null) { myCopyMethodToInner.run(); } if (myChangeReturnType) { - final PsiTypeElement typeElement = + PsiTypeElement typeElement = ((PsiLocalVariable) ((PsiDeclarationStatement) JavaPsiFacade.getElementFactory(myProject).createStatementFromText( myInnerClassName + " l =null;", myInnerClass )).getDeclaredElements()[0]).getTypeElement(); - final PsiTypeElement innerMethodReturnTypeElement = myInnerMethod.getReturnTypeElement(); + PsiTypeElement innerMethodReturnTypeElement = myInnerMethod.getReturnTypeElement(); LOG.assertTrue(innerMethodReturnTypeElement != null); innerMethodReturnTypeElement.replace(typeElement); } } private String getPureName(PsiVariable var) { - final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(myProject); + JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(myProject); return styleManager.variableNameToPropertyName(var.getName(), styleManager.getVariableKind(var)); } + @RequiredWriteAction public PsiExpression processMethodDeclaration(PsiExpressionList expressionList) throws IncorrectOperationException { if (isCreateInnerClass()) { - final String typeArguments = + String typeArguments = getMethod().hasTypeParameters() ? "<" + StringUtil.join( Arrays.asList(getMethod().getTypeParameters()), - new Function() { - public String apply(final PsiTypeParameter typeParameter) { - final String typeParameterName = typeParameter.getName(); - LOG.assertTrue(typeParameterName != null); - return typeParameterName; - } + typeParameter -> { + String typeParameterName = typeParameter.getName(); + LOG.assertTrue(typeParameterName != null); + return typeParameterName; }, ", " ) + ">" : ""; - final PsiMethodCallExpression methodCallExpression = + PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) myElementFactory.createExpressionFromText("invoke" + expressionList.getText(), null); return replaceMethodCallExpression(typeArguments, methodCallExpression); } else { - final String paramsDeclaration = getMethod().getParameterList().getText(); - final PsiType returnType = getMethod().getReturnType(); + String paramsDeclaration = getMethod().getParameterList().getText(); + PsiType returnType = getMethod().getReturnType(); LOG.assertTrue(returnType != null); - final PsiCodeBlock methodBody = getMethod().getBody(); + PsiCodeBlock methodBody = getMethod().getBody(); LOG.assertTrue(methodBody != null); - return myElementFactory.createExpressionFromText("new Object(){ \n" + - "private " + - returnType.getPresentableText() + - " " + myInnerClassName + - paramsDeclaration + - methodBody.getText() + - "}." + myInnerClassName + - expressionList.getText(), null); + return myElementFactory.createExpressionFromText( + "new Object(){ \n" + + "private " + + returnType.getPresentableText() + + " " + myInnerClassName + + paramsDeclaration + + methodBody.getText() + + "}." + myInnerClassName + + expressionList.getText(), + null + ); } } - + @RequiredWriteAction private PsiMethodCallExpression replaceMethodCallExpression( - final String inferredTypeArguments, - final PsiMethodCallExpression methodCallExpression + String inferredTypeArguments, + PsiMethodCallExpression methodCallExpression ) throws IncorrectOperationException { - @NonNls final String staticqualifier = - getMethod().hasModifierProperty(PsiModifier.STATIC) && notHasGeneratedFields() ? getInnerClassName() : null; - @NonNls String newReplacement; - final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression(); - final PsiExpressionList argumentList = methodCallExpression.getArgumentList(); - if (staticqualifier != null) { - newReplacement = - argumentList.getExpressions().length > 0 ? "new " + staticqualifier + inferredTypeArguments + argumentList.getText() + "." : staticqualifier + "."; + String staticQualifier = getMethod().isStatic() && notHasGeneratedFields() ? getInnerClassName() : null; + String newReplacement; + PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression(); + PsiExpressionList argumentList = methodCallExpression.getArgumentList(); + if (staticQualifier != null) { + newReplacement = argumentList.getExpressions().length > 0 + ? "new " + staticQualifier + inferredTypeArguments + argumentList.getText() + "." + : staticQualifier + "."; } else { - final PsiExpression qualifierExpression = methodExpression.getQualifierExpression(); - final String qualifier = qualifierExpression != null ? qualifierExpression.getText() + "." : ""; + PsiExpression qualifierExpression = methodExpression.getQualifierExpression(); + String qualifier = qualifierExpression != null ? qualifierExpression.getText() + "." : ""; newReplacement = qualifier + "new " + getInnerClassName() + inferredTypeArguments + argumentList.getText() + "."; } return (PsiMethodCallExpression) methodCallExpression.replace(myElementFactory.createExpressionFromText( @@ -508,18 +505,19 @@ private PsiMethodCallExpression replaceMethodCallExpression( } @Nonnull - private String inferTypeArguments(final PsiMethodCallExpression methodCallExpression) { - final PsiReferenceParameterList list = methodCallExpression.getMethodExpression().getParameterList(); + @RequiredReadAction + private String inferTypeArguments(PsiMethodCallExpression methodCallExpression) { + PsiReferenceParameterList list = methodCallExpression.getMethodExpression().getParameterList(); if (list != null && list.getTypeArguments().length > 0) { return list.getText(); } - final PsiTypeParameter[] methodTypeParameters = getMethod().getTypeParameters(); + PsiTypeParameter[] methodTypeParameters = getMethod().getTypeParameters(); if (methodTypeParameters.length > 0) { - List typeSignature = new ArrayList(); - final PsiSubstitutor substitutor = methodCallExpression.resolveMethodGenerics().getSubstitutor(); - for (final PsiTypeParameter typeParameter : methodTypeParameters) { - final PsiType type = substitutor.substitute(typeParameter); + List typeSignature = new ArrayList<>(); + PsiSubstitutor substitutor = methodCallExpression.resolveMethodGenerics().getSubstitutor(); + for (PsiTypeParameter typeParameter : methodTypeParameters) { + PsiType type = substitutor.substitute(typeParameter); if (type == null || PsiType.NULL.equals(type)) { return ""; } @@ -531,23 +529,26 @@ private String inferTypeArguments(final PsiMethodCallExpression methodCallExpres return ""; } + @Nonnull + @Override protected String getCommandName() { return REFACTORING_NAME.get(); } + @RequiredReadAction private boolean copyMethodModifiers() throws IncorrectOperationException { - final PsiModifierList methodModifierList = getMethod().getModifierList(); + PsiModifierList methodModifierList = getMethod().getModifierList(); - final PsiModifierList innerClassModifierList = myInnerClass.getModifierList(); + PsiModifierList innerClassModifierList = myInnerClass.getModifierList(); LOG.assertTrue(innerClassModifierList != null); innerClassModifierList.setModifierProperty(VisibilityUtil.getVisibilityModifier(methodModifierList), true); - final boolean isStatic = methodModifierList.hasModifierProperty(PsiModifier.STATIC); + boolean isStatic = methodModifierList.hasModifierProperty(PsiModifier.STATIC); innerClassModifierList.setModifierProperty(PsiModifier.STATIC, isStatic); return isStatic; } private void copyMethodTypeParameters() throws IncorrectOperationException { - final PsiTypeParameterList typeParameterList = myInnerClass.getTypeParameterList(); + PsiTypeParameterList typeParameterList = myInnerClass.getTypeParameterList(); LOG.assertTrue(typeParameterList != null); for (PsiTypeParameter parameter : getMethod().getTypeParameters()) { @@ -555,19 +556,20 @@ private void copyMethodTypeParameters() throws IncorrectOperationException { } } + @RequiredWriteAction private void copyMethodWithoutParameters() throws IncorrectOperationException { - final PsiMethod newMethod = myElementFactory.createMethod("invoke", getMethod().getReturnType()); + PsiMethod newMethod = myElementFactory.createMethod("invoke", getMethod().getReturnType()); newMethod.getThrowsList().replace(getMethod().getThrowsList()); - final PsiCodeBlock replacedMethodBody = newMethod.getBody(); + PsiCodeBlock replacedMethodBody = newMethod.getBody(); LOG.assertTrue(replacedMethodBody != null); - final PsiCodeBlock methodBody = getMethod().getBody(); + PsiCodeBlock methodBody = getMethod().getBody(); LOG.assertTrue(methodBody != null); replacedMethodBody.replace(methodBody); PsiUtil.setModifierProperty( newMethod, PsiModifier.STATIC, - myInnerClass.hasModifierProperty(PsiModifier.STATIC) && notHasGeneratedFields() + myInnerClass.isStatic() && notHasGeneratedFields() ); myInnerMethod = (PsiMethod) myInnerClass.add(newMethod); } @@ -576,23 +578,22 @@ private boolean notHasGeneratedFields() { return !myMultipleExitPoints && getMethod().getParameterList().getParametersCount() == 0; } - private void createInnerClassConstructor(final PsiParameter[] parameters) throws IncorrectOperationException { - final PsiMethod constructor = myElementFactory.createConstructor(); - final PsiParameterList parameterList = constructor.getParameterList(); + @RequiredWriteAction + private void createInnerClassConstructor(PsiParameter[] parameters) throws IncorrectOperationException { + PsiMethod constructor = myElementFactory.createConstructor(); + PsiParameterList parameterList = constructor.getParameterList(); for (PsiParameter parameter : parameters) { - final PsiModifierList parameterModifierList = parameter.getModifierList(); + PsiModifierList parameterModifierList = parameter.getModifierList(); LOG.assertTrue(parameterModifierList != null); - final String parameterName = parameter.getName(); - LOG.assertTrue(parameterName != null); - PsiParameter parm = myElementFactory.createParameter(parameterName, parameter.getType()); + PsiParameter param = myElementFactory.createParameter(parameter.getName(), parameter.getType()); if (CodeStyleSettingsManager.getSettings(myProject).GENERATE_FINAL_PARAMETERS) { - final PsiModifierList modifierList = parm.getModifierList(); + PsiModifierList modifierList = param.getModifierList(); LOG.assertTrue(modifierList != null); modifierList.setModifierProperty(PsiModifier.FINAL, true); } - parameterList.add(parm); + parameterList.add(param); - final PsiField field = createField(parm, constructor, parameterModifierList.hasModifierProperty(PsiModifier.FINAL)); + PsiField field = createField(param, constructor, parameterModifierList.hasModifierProperty(PsiModifier.FINAL)); for (PsiReference reference : ReferencesSearch.search(parameter)) { reference.handleElementRename(field.getName()); } @@ -600,35 +601,32 @@ private void createInnerClassConstructor(final PsiParameter[] parameters) throws myInnerClass.add(constructor); } + @RequiredWriteAction private PsiField createField(PsiParameter parameter, PsiMethod constructor, boolean isFinal) { - final String parameterName = parameter.getName(); + String parameterName = parameter.getName(); PsiType type = parameter.getType(); - if (type instanceof PsiEllipsisType) { - type = ((PsiEllipsisType) type).toArrayType(); + if (type instanceof PsiEllipsisType ellipsisType) { + type = ellipsisType.toArrayType(); } try { - final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(getMethod().getProject()); - final String fieldName = styleManager.suggestVariableName( - VariableKind.FIELD, - styleManager.variableNameToPropertyName(parameterName, VariableKind.PARAMETER), - null, - type - ).names[0]; + JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(getMethod().getProject()); + String propertyName = styleManager.variableNameToPropertyName(parameterName, VariableKind.PARAMETER); + String fieldName = styleManager.suggestVariableName(VariableKind.FIELD, propertyName, null, type).names[0]; PsiField field = myElementFactory.createField(fieldName, type); - final PsiModifierList modifierList = field.getModifierList(); + PsiModifierList modifierList = field.getModifierList(); LOG.assertTrue(modifierList != null); - final NullableNotNullManager manager = NullableNotNullManager.getInstance(myProject); + NullableNotNullManager manager = NullableNotNullManager.getInstance(myProject); if (manager.isNullable(parameter, false)) { modifierList.addAfter(myElementFactory.createAnnotationFromText("@" + manager.getDefaultNullable(), field), null); } modifierList.setModifierProperty(PsiModifier.FINAL, isFinal); - final PsiCodeBlock methodBody = constructor.getBody(); + PsiCodeBlock methodBody = constructor.getBody(); LOG.assertTrue(methodBody != null); - @NonNls final String stmtText; + String stmtText; if (Comparing.strEqual(parameterName, fieldName)) { stmtText = "this." + fieldName + " = " + parameterName + ";"; } @@ -648,13 +646,14 @@ private PsiField createField(PsiParameter parameter, PsiMethod constructor, bool return null; } - protected void changeInstanceAccess(final Project project) throws IncorrectOperationException { + @RequiredWriteAction + protected void changeInstanceAccess(Project project) throws IncorrectOperationException { if (myMadeStatic) { PsiReference[] refs = ReferencesSearch.search(myInnerMethod, GlobalSearchScope.projectScope(project), false).toArray(PsiReference.EMPTY_ARRAY); for (PsiReference ref : refs) { - final PsiElement element = ref.getElement(); - final PsiMethodCallExpression callExpression = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class); + PsiElement element = ref.getElement(); + PsiMethodCallExpression callExpression = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class); if (callExpression != null) { replaceMethodCallExpression(inferTypeArguments(callExpression), callExpression); } @@ -670,7 +669,7 @@ public String getInnerClassName() { return myInnerClassName; } - public void setCreateInnerClass(final boolean createInnerClass) { + public void setCreateInnerClass(boolean createInnerClass) { myCreateInnerClass = createInnerClass; } @@ -711,17 +710,17 @@ protected boolean isFoldingApplicable() { } public class MyExtractMethodProcessor extends ExtractMethodProcessor { + @RequiredReadAction public MyExtractMethodProcessor( Project project, Editor editor, PsiElement[] elements, PsiType forcedReturnType, - String refactoringName, + LocalizeValue refactoringName, String initialMethodName, String helpId ) { super(project, editor, elements, forcedReturnType, refactoringName, initialMethodName, helpId); - } @Override @@ -735,14 +734,15 @@ protected boolean isNeedToChangeCallContext() { } @Override - protected void apply(final AbstractExtractDialog dialog) { + protected void apply(AbstractExtractDialog dialog) { super.apply(dialog); myCreateInnerClass = !(dialog instanceof ExtractMethodObjectDialog) || ((ExtractMethodObjectDialog) dialog).createInnerClass(); myInnerClassName = myCreateInnerClass ? StringUtil.capitalize(dialog.getChosenMethodName()) : dialog.getChosenMethodName(); } @Override - protected AbstractExtractDialog createExtractMethodDialog(final boolean direct) { + @RequiredReadAction + protected AbstractExtractDialog createExtractMethodDialog(boolean direct) { return createExtractMethodObjectDialog(this); } @@ -753,8 +753,8 @@ protected boolean checkOutputVariablesCount() { for (int i = 0; i < myOutputVariables.length; i++) { PsiVariable variable = myOutputVariables[i]; if (!myInputVariables.contains(variable)) { //one field creation - final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(myProject); - final String fieldName = + JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(myProject); + String fieldName = styleManager.suggestVariableName(VariableKind.FIELD, getPureName(variable), null, variable.getType()).names[0]; try { myOutputFields[i] = myElementFactory.createField(fieldName, variable.getType()); @@ -768,43 +768,40 @@ protected boolean checkOutputVariablesCount() { } @Override - public PsiElement processMatch(final Match match) throws IncorrectOperationException { - final boolean makeStatic = myInnerMethod != null && - RefactoringUtil.isInStaticContext(match.getMatchStart(), getExtractedMethod().getContainingClass()) && - !myInnerMethod.getContainingClass().hasModifierProperty(PsiModifier.STATIC); - final PsiElement element = super.processMatch(match); + @RequiredWriteAction + public PsiElement processMatch(Match match) throws IncorrectOperationException { + boolean makeStatic = myInnerMethod != null + && RefactoringUtil.isInStaticContext(match.getMatchStart(), getExtractedMethod().getContainingClass()) + && !myInnerMethod.getContainingClass().isStatic(); + PsiElement element = super.processMatch(match); if (makeStatic) { myMadeStatic = true; - final PsiModifierList modifierList = myInnerMethod.getContainingClass().getModifierList(); + PsiModifierList modifierList = myInnerMethod.getContainingClass().getModifierList(); LOG.assertTrue(modifierList != null); modifierList.setModifierProperty(PsiModifier.STATIC, true); PsiUtil.setModifierProperty(myInnerMethod, PsiModifier.STATIC, true); } PsiMethodCallExpression methodCallExpression = null; - if (element instanceof PsiMethodCallExpression) { - methodCallExpression = (PsiMethodCallExpression) element; - } - else if (element instanceof PsiExpressionStatement) { - final PsiExpression expression = ((PsiExpressionStatement) element).getExpression(); - if (expression instanceof PsiMethodCallExpression) { - methodCallExpression = (PsiMethodCallExpression) expression; - } - else if (expression instanceof PsiAssignmentExpression) { - final PsiExpression psiExpression = ((PsiAssignmentExpression) expression).getRExpression(); - if (psiExpression instanceof PsiMethodCallExpression) { - methodCallExpression = (PsiMethodCallExpression) psiExpression; - } + if (element instanceof PsiMethodCallExpression call) { + methodCallExpression = call; + } + else if (element instanceof PsiExpressionStatement exprStmt) { + PsiExpression expression = exprStmt.getExpression(); + if (expression instanceof PsiMethodCallExpression call) { + methodCallExpression = call; + } + else if (expression instanceof PsiAssignmentExpression assignment + && assignment.getRExpression() instanceof PsiMethodCallExpression call) { + methodCallExpression = call; } } - else if (element instanceof PsiDeclarationStatement) { - final PsiElement[] declaredElements = ((PsiDeclarationStatement) element).getDeclaredElements(); + else if (element instanceof PsiDeclarationStatement declaration) { + PsiElement[] declaredElements = declaration.getDeclaredElements(); for (PsiElement declaredElement : declaredElements) { - if (declaredElement instanceof PsiLocalVariable) { - final PsiExpression initializer = ((PsiLocalVariable) declaredElement).getInitializer(); - if (initializer instanceof PsiMethodCallExpression) { - methodCallExpression = (PsiMethodCallExpression) initializer; - break; - } + if (declaredElement instanceof PsiLocalVariable localVar + && localVar.getInitializer() instanceof PsiMethodCallExpression call) { + methodCallExpression = call; + break; } } } @@ -817,72 +814,73 @@ else if (element instanceof PsiDeclarationStatement) { return methodCallExpression.replace(expression); } + @Override public PsiVariable[] getOutputVariables() { return myOutputVariables; } @Override - protected void declareNecessaryVariablesAfterCall(final PsiVariable outputVariable) throws IncorrectOperationException { + @RequiredWriteAction + protected void declareNecessaryVariablesAfterCall(PsiVariable outputVariable) throws IncorrectOperationException { if (myMultipleExitPoints) { - final String object = JavaCodeStyleManager.getInstance(myProject) + String object = JavaCodeStyleManager.getInstance(myProject) .suggestUniqueVariableName(StringUtil.decapitalize(myInnerClassName), outputVariable, true); - final PsiStatement methodCallStatement = PsiTreeUtil.getParentOfType(getMethodCall(), PsiStatement.class); + PsiStatement methodCallStatement = PsiTreeUtil.getParentOfType(getMethodCall(), PsiStatement.class); LOG.assertTrue(methodCallStatement != null); - final PsiStatement declarationStatement = myElementFactory.createStatementFromText( + PsiStatement declarationStatement = myElementFactory.createStatementFromText( myInnerClassName + " " + object + " = " + getMethodCall().getText() + ";", myInnerMethod ); - if (methodCallStatement instanceof PsiIfStatement) { - methodCallStatement.getParent().addBefore(declarationStatement, methodCallStatement); - final PsiExpression conditionExpression = ((PsiIfStatement) methodCallStatement).getCondition(); - setMethodCall((PsiMethodCallExpression) conditionExpression.replace(myElementFactory.createExpressionFromText( - object + ".is()", - myInnerMethod - ))); + if (methodCallStatement instanceof PsiIfStatement ifStatement) { + ifStatement.getParent().addBefore(declarationStatement, ifStatement); + setMethodCall( + (PsiMethodCallExpression) ifStatement.getCondition() + .replace(myElementFactory.createExpressionFromText(object + ".is()", myInnerMethod)) + ); } else if (myElements[0] instanceof PsiExpression) { methodCallStatement.getParent().addBefore(declarationStatement, methodCallStatement); } else { - final PsiDeclarationStatement replace = (PsiDeclarationStatement) methodCallStatement.replace(declarationStatement); + PsiDeclarationStatement replace = (PsiDeclarationStatement) methodCallStatement.replace(declarationStatement); setMethodCall((PsiMethodCallExpression) ((PsiLocalVariable) replace.getDeclaredElements()[0]).getInitializer()); } - final List usedVariables = myControlFlowWrapper.getUsedVariables(); + List usedVariables = myControlFlowWrapper.getUsedVariables(); Collection reassigned = myControlFlowWrapper.getInitializedTwice(); for (PsiVariable variable : usedVariables) { String name = variable.getName(); LOG.assertTrue(name != null); PsiStatement st = null; - final String pureName = getPureName(variable); - final int varIdxInOutput = ArrayUtil.find(myOutputVariables, variable); - final String getterName = - varIdxInOutput > -1 && myOutputFields[varIdxInOutput] != null ? GenerateMembersUtil.suggestGetterName(myOutputFields[varIdxInOutput]) : - GenerateMembersUtil.suggestGetterName(pureName, variable.getType(), myProject); + String pureName = getPureName(variable); + int varIdxInOutput = ArrayUtil.find(myOutputVariables, variable); + String getterName = varIdxInOutput > -1 && myOutputFields[varIdxInOutput] != null + ? GenerateMembersUtil.suggestGetterName(myOutputFields[varIdxInOutput]) + : GenerateMembersUtil.suggestGetterName(pureName, variable.getType(), myProject); if (isDeclaredInside(variable)) { st = myElementFactory.createStatementFromText(variable.getType() .getCanonicalText() + " " + name + " = " + object + "." + getterName + "();", myInnerMethod); if (reassigned.contains(new ControlFlowUtil.VariableInfo(variable, null))) { - final PsiElement[] psiElements = ((PsiDeclarationStatement) st).getDeclaredElements(); + PsiElement[] psiElements = ((PsiDeclarationStatement) st).getDeclaredElements(); assert psiElements.length > 0; PsiVariable var = (PsiVariable) psiElements[0]; PsiUtil.setModifierProperty(var, PsiModifier.FINAL, false); } } - else { - if (varIdxInOutput != -1) { - st = myElementFactory.createStatementFromText(name + " = " + object + "." + getterName + "();", myInnerMethod); - } + else if (varIdxInOutput != -1) { + st = myElementFactory.createStatementFromText(name + " = " + object + "." + getterName + "();", myInnerMethod); } if (st != null) { addToMethodCallLocation(st); } } if (myElements[0] instanceof PsiAssignmentExpression) { - getMethodCall().getParent().replace(((PsiAssignmentExpression) getMethodCall().getParent()).getLExpression()); + PsiAssignmentExpression parentAssignment = (PsiAssignmentExpression) getMethodCall().getParent(); + parentAssignment.replace(parentAssignment.getLExpression()); } else if (myElements[0] instanceof PsiPostfixExpression || myElements[0] instanceof PsiPrefixExpression) { - getMethodCall().getParent().replace(((PsiBinaryExpression) getMethodCall().getParent()).getLOperand()); + PsiBinaryExpression parentBinary = (PsiBinaryExpression) getMethodCall().getParent(); + parentBinary.replace(parentBinary.getLOperand()); } rebindExitStatement(object); @@ -897,28 +895,29 @@ protected boolean isFoldingApplicable() { return ExtractMethodObjectProcessor.this.isFoldingApplicable(); } + @RequiredWriteAction private void rebindExitStatement(final String objectName) { - final PsiStatement exitStatementCopy = myExtractProcessor.myFirstExitStatementCopy; + PsiStatement exitStatementCopy = myExtractProcessor.myFirstExitStatementCopy; if (exitStatementCopy != null) { myExtractProcessor.getDuplicates().clear(); - final Map outVarsNames = new HashMap(); + final Map outVarsNames = new HashMap<>(); for (PsiVariable variable : myOutputVariables) { outVarsNames.put(variable.getName(), variable); } - final Map replaceMap = new HashMap(); + final Map replaceMap = new HashMap<>(); exitStatementCopy.accept(new JavaRecursiveElementWalkingVisitor() { @Override public void visitReferenceExpression(PsiReferenceExpression expression) { super.visitReferenceExpression(expression); if (expression.resolve() == null) { - final PsiVariable variable = outVarsNames.get(expression.getReferenceName()); + PsiVariable variable = outVarsNames.get(expression.getReferenceName()); if (variable != null) { - final String call2Getter = objectName + "." + GenerateMembersUtil.suggestGetterName( + String call2Getter = objectName + "." + GenerateMembersUtil.suggestGetterName( getPureName(variable), variable.getType(), myProject ) + "()"; - final PsiExpression callToGetter = myElementFactory.createExpressionFromText(call2Getter, variable); + PsiExpression callToGetter = myElementFactory.createExpressionFromText(call2Getter, variable); replaceMap.put(expression, callToGetter); } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/tempWithQuery/TempWithQueryHandler.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/tempWithQuery/TempWithQueryHandler.java index 3587955ec..5a686451b 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/tempWithQuery/TempWithQueryHandler.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/tempWithQuery/TempWithQueryHandler.java @@ -124,7 +124,7 @@ private static void invokeOnVariable(PsiFile file, Project project, PsiLocalVari editor, new PsiElement[]{initializer}, local.getType(), - REFACTORING_NAME.get(), + REFACTORING_NAME, localName, HelpID.REPLACE_TEMP_WITH_QUERY ); @@ -153,38 +153,36 @@ private static void invokeOnVariable(PsiFile file, Project project, PsiLocalVari } if (processor.showDialog()) { + Runnable action = () -> { + try { + processor.doRefactoring(); + + local.normalizeDeclaration(); + + PsiExpression initializer1 = local.getInitializer(); + + PsiExpression[] exprs = new PsiExpression[refs.length]; + for (int idx = 0; idx < refs.length; idx++) { + PsiElement ref = refs[idx].getElement(); + exprs[idx] = (PsiExpression) ref.replace(initializer1); + } + PsiDeclarationStatement declaration = (PsiDeclarationStatement) local.getParent(); + declaration.delete(); + + highlightManager.addOccurrenceHighlights(editor, exprs, EditorColors.SEARCH_RESULT_ATTRIBUTES, true, null); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + }; + CommandProcessor.getInstance().newCommand() .project(project) .name(REFACTORING_NAME) - .run(() -> { - Runnable action = () -> { - try { - processor.doRefactoring(); - - local.normalizeDeclaration(); - - PsiExpression initializer1 = local.getInitializer(); - - PsiExpression[] exprs = new PsiExpression[refs.length]; - for (int idx = 0; idx < refs.length; idx++) { - PsiElement ref = refs[idx].getElement(); - exprs[idx] = (PsiExpression) ref.replace(initializer1); - } - PsiDeclarationStatement declaration = (PsiDeclarationStatement) local.getParent(); - declaration.delete(); - - highlightManager.addOccurrenceHighlights(editor, exprs, EditorColors.SEARCH_RESULT_ATTRIBUTES, true, null); - } - catch (IncorrectOperationException e) { - LOG.error(e); - } - }; - - PostprocessReformattingAspect.getInstance(project).postponeFormattingInside(() -> { - project.getApplication().runWriteAction(action); - DuplicatesImpl.processDuplicates(processor, project, editor); - }); - }); + .run(() -> PostprocessReformattingAspect.getInstance(project).postponeFormattingInside(() -> { + project.getApplication().runWriteAction(action); + DuplicatesImpl.processDuplicates(processor, project, editor); + })); } }