diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethodObject/ExtractMethodObjectDialog.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethodObject/ExtractMethodObjectDialog.java index 796a16b59..b961e214b 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethodObject/ExtractMethodObjectDialog.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethodObject/ExtractMethodObjectDialog.java @@ -32,20 +32,17 @@ import consulo.language.psi.PsiElement; import consulo.localize.LocalizeValue; import consulo.project.Project; +import consulo.ui.annotation.RequiredUIAccess; import consulo.ui.ex.awt.DialogWrapper; import consulo.ui.ex.awt.UIUtil; import consulo.util.collection.MultiMap; import consulo.util.lang.StringUtil; -import org.jetbrains.annotations.NonNls; - import jakarta.annotation.Nonnull; import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Enumeration; -import java.util.function.Function; public class ExtractMethodObjectDialog extends DialogWrapper implements AbstractExtractDialog { private final Project myProject; @@ -122,7 +119,6 @@ public ExtractMethodObjectDialog( // Create UI components - myCbMakeVarargs.setVisible(canBeVarargs); myCbMakeVarargsAnonymous.setVisible(canBeVarargs); @@ -131,6 +127,7 @@ public ExtractMethodObjectDialog( } + @Override public boolean isMakeStatic() { if (myStaticFlag) { return true; @@ -141,6 +138,7 @@ public boolean isMakeStatic() { return myCbMakeStatic.isSelected(); } + @Override public boolean isChainedConstructor() { return false; } @@ -151,6 +149,7 @@ public PsiType getReturnType() { } @Nonnull + @Override protected Action[] createActions() { return new Action[]{ getOKAction(), @@ -159,22 +158,30 @@ protected Action[] createActions() { }; } + @Override public String getChosenMethodName() { return myCreateInnerClassRb.isSelected() ? myInnerClassName.getText() : myMethodName.getText(); } + @Override public VariableData[] getChosenParameters() { return myInputVariables; } + @Override + @RequiredUIAccess public JComponent getPreferredFocusedComponent() { return myInnerClassName; } + @Override + @RequiredUIAccess protected void doHelpAction() { HelpManager.getInstance().invokeHelp(HelpID.EXTRACT_METHOD_OBJECT); } + @Override + @RequiredUIAccess protected void doOKAction() { MultiMap conflicts = new MultiMap<>(); if (myCreateInnerClassRb.isSelected()) { @@ -201,8 +208,8 @@ protected void doOKAction() { JCheckBox makeVarargsCb = myCreateInnerClassRb.isSelected() ? myCbMakeVarargs : myCbMakeVarargsAnonymous; if (makeVarargsCb != null && makeVarargsCb.isSelected()) { VariableData data = myInputVariables[myInputVariables.length - 1]; - if (data.type instanceof PsiArrayType) { - data.type = new PsiEllipsisType(((PsiArrayType) data.type).getComponentType()); + if (data.type instanceof PsiArrayType arrayType) { + data.type = new PsiEllipsisType(arrayType.getComponentType()); } } super.doOKAction(); @@ -222,11 +229,13 @@ private void update() { myCbMakeStatic.setEnabled(myCreateInnerClassRb.isSelected() && myCanBeStatic && !myStaticFlag); updateSignature(); PsiNameHelper helper = PsiNameHelper.getInstance(myProject); - setOKActionEnabled((myCreateInnerClassRb.isSelected() && helper.isIdentifier(myInnerClassName.getText())) || (!myCreateInnerClassRb.isSelected() && helper.isIdentifier( - myMethodName.getText() - ))); + setOKActionEnabled( + (myCreateInnerClassRb.isSelected() && helper.isIdentifier(myInnerClassName.getText())) + || (!myCreateInnerClassRb.isSelected() && helper.isIdentifier(myMethodName.getText())) + ); } + @Override public String getVisibility() { if (myPublicRadioButton.isSelected()) { return PsiModifier.PUBLIC; @@ -243,16 +252,12 @@ public String getVisibility() { return null; } - + @Override protected JComponent createCenterPanel() { mySignatureArea.setEditable(false); myCreateInnerClassRb.setSelected(true); - ActionListener enableDisableListener = new ActionListener() { - public void actionPerformed(ActionEvent e) { - enable(myCreateInnerClassRb.isSelected()); - } - }; + ActionListener enableDisableListener = e -> enable(myCreateInnerClassRb.isSelected()); myCreateInnerClassRb.addActionListener(enableDisableListener); myCreateAnonymousClassWrapperRb.addActionListener(enableDisableListener); myCreateAnonymousClassWrapperRb.setEnabled(!myMultipleExitPoints); @@ -261,33 +266,29 @@ public void actionPerformed(ActionEvent e) { myFoldCb.setVisible(myVariableData.isFoldable()); myVariableData.setFoldingAvailable(myFoldCb.isSelected()); myInputVariables = myVariableData.getInputVariables().toArray(new VariableData[myVariableData.getInputVariables().size()]); - myFoldCb.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - myVariableData.setFoldingAvailable(myFoldCb.isSelected()); - myInputVariables = myVariableData.getInputVariables().toArray(new VariableData[myVariableData.getInputVariables().size()]); - myParametersTableContainer.removeAll(); - myParametersTableContainer.add(createParametersPanel(), BorderLayout.CENTER); - myParametersTableContainer.revalidate(); - updateSignature(); - updateVarargsEnabled(); - } + myFoldCb.addActionListener(e -> { + myVariableData.setFoldingAvailable(myFoldCb.isSelected()); + myInputVariables = myVariableData.getInputVariables().toArray(new VariableData[myVariableData.getInputVariables().size()]); + myParametersTableContainer.removeAll(); + myParametersTableContainer.add(createParametersPanel(), BorderLayout.CENTER); + myParametersTableContainer.revalidate(); + updateSignature(); + updateVarargsEnabled(); }); myParametersTableContainer.add(createParametersPanel(), BorderLayout.CENTER); - ActionListener updateSugnatureListener = new ActionListener() { - public void actionPerformed(ActionEvent e) { - updateSignature(); - ApplicationIdeFocusManager.getInstance() - .getInstanceForProject(myProject) - .requestFocus(myCreateInnerClassRb.isSelected() ? myInnerClassName : myMethodName, false); - } + ActionListener updateSignatureListener = e -> { + updateSignature(); + ApplicationIdeFocusManager.getInstance() + .getInstanceForProject(myProject) + .requestFocus(myCreateInnerClassRb.isSelected() ? myInnerClassName : myMethodName, false); }; if (myStaticFlag || myCanBeStatic) { myCbMakeStatic.setEnabled(!myStaticFlag); myCbMakeStatic.setSelected(myStaticFlag); - myCbMakeStatic.addActionListener(updateSugnatureListener); + myCbMakeStatic.addActionListener(updateSignatureListener); } else { myCbMakeStatic.setSelected(false); @@ -297,10 +298,10 @@ public void actionPerformed(ActionEvent e) { updateVarargsEnabled(); myCbMakeVarargs.setSelected(myWasStatic); - myCbMakeVarargs.addActionListener(updateSugnatureListener); + myCbMakeVarargs.addActionListener(updateSignatureListener); myCbMakeVarargsAnonymous.setSelected(myWasStatic); - myCbMakeVarargsAnonymous.addActionListener(updateSugnatureListener); + myCbMakeVarargsAnonymous.addActionListener(updateSignatureListener); DocumentAdapter nameListener = new DocumentAdapter() { @Override @@ -313,12 +314,12 @@ public void documentChanged(DocumentEvent e) { myPrivateRadioButton.setSelected(true); - myCreateInnerClassRb.addActionListener(updateSugnatureListener); - myCreateAnonymousClassWrapperRb.addActionListener(updateSugnatureListener); + myCreateInnerClassRb.addActionListener(updateSignatureListener); + myCreateAnonymousClassWrapperRb.addActionListener(updateSignatureListener); Enumeration visibilities = myVisibilityGroup.getElements(); while (visibilities.hasMoreElements()) { - visibilities.nextElement().addActionListener(updateSugnatureListener); + visibilities.nextElement().addActionListener(updateSignatureListener); } enable(true); @@ -333,15 +334,18 @@ private void enable(boolean innerClassSelected) { private JComponent createParametersPanel() { return new ParameterTablePanel(myProject, myInputVariables, myElementsToExtract) { + @Override protected void updateSignature() { updateVarargsEnabled(); ExtractMethodObjectDialog.this.updateSignature(); } + @Override protected void doEnterAction() { clickDefaultButton(); } + @Override protected void doCancelAction() { ExtractMethodObjectDialog.this.doCancelAction(); } @@ -361,13 +365,13 @@ protected void updateSignature() { if (mySignatureArea == null) { return; } - @NonNls StringBuffer buffer = getSignature(); + StringBuilder buffer = getSignature(); mySignatureArea.setText(buffer.toString()); } - protected StringBuffer getSignature() { - String INDENT = " "; - @NonNls StringBuffer buffer = new StringBuffer(); + protected StringBuilder getSignature() { + String indent = " "; + StringBuilder buffer = new StringBuilder(); String visibilityString = VisibilityUtil.getVisibilityString(getVisibility()); if (myCreateInnerClassRb.isSelected()) { buffer.append(visibilityString); @@ -384,67 +388,63 @@ protected StringBuffer getSignature() { buffer.append(" "); } buffer.append("{\n"); - buffer.append(INDENT); + buffer.append(indent); buffer.append("public "); buffer.append(myInnerClassName.getText()); - methodSignature(INDENT, buffer); + methodSignature(indent, buffer); buffer.append("\n}"); } else { buffer.append("new Object(){\n"); - buffer.append(INDENT); + buffer.append(indent); buffer.append("private "); buffer.append(PsiFormatUtil.formatType(myReturnType, 0, PsiSubstitutor.EMPTY)); buffer.append(" "); buffer.append(myMethodName.getText()); - methodSignature(INDENT, buffer); + methodSignature(indent, buffer); buffer.append("\n}."); buffer.append(myMethodName.getText()); buffer.append("("); - buffer.append(StringUtil.join(myInputVariables, new Function() { - public String apply(VariableData variableData) { - return variableData.name; - } - }, ", ")); + buffer.append(StringUtil.join(myInputVariables, variableData -> variableData.name, ", ")); buffer.append(")"); } return buffer; } - private void methodSignature(String INDENT, StringBuffer buffer) { + private void methodSignature(String indent, StringBuilder buffer) { buffer.append("("); int count = 0; - String indent = " "; for (int i = 0; i < myInputVariables.length; i++) { VariableData data = myInputVariables[i]; - if (data.passAsParameter) { - //String typeAndModifiers = PsiFormatUtil.formatVariable(data.variable, - // PsiFormatUtil.SHOW_MODIFIERS | PsiFormatUtil.SHOW_TYPE); - PsiType type = data.type; - if (i == myInputVariables.length - 1 && type instanceof PsiArrayType && ((myCreateInnerClassRb.isSelected() && myCbMakeVarargs.isSelected()) || (myCreateAnonymousClassWrapperRb - .isSelected() && myCbMakeVarargsAnonymous.isSelected()))) { - type = new PsiEllipsisType(((PsiArrayType) type).getComponentType()); - } + if (!data.passAsParameter) { + continue; + } - String typeText = type.getPresentableText(); - if (count > 0) { - buffer.append(", "); - } - buffer.append("\n"); - buffer.append(indent); - buffer.append(typeText); - buffer.append(" "); - buffer.append(data.name); - count++; + PsiType type = data.type; + if (i == myInputVariables.length - 1 && type instanceof PsiArrayType arrayType + && ((myCreateInnerClassRb.isSelected() && myCbMakeVarargs.isSelected()) + || (myCreateAnonymousClassWrapperRb.isSelected() && myCbMakeVarargsAnonymous.isSelected()))) { + type = new PsiEllipsisType(arrayType.getComponentType()); + } + + String typeText = type.getPresentableText(); + if (count > 0) { + buffer.append(", "); } + buffer.append("\n"); + buffer.append(indent); + buffer.append(typeText); + buffer.append(" "); + buffer.append(data.name); + count++; } buffer.append(")"); if (myExceptions.length > 0) { 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"); } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethodObject/ExtractMethodObjectHandler.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethodObject/ExtractMethodObjectHandler.java index 45e1f8e3a..9ae205f43 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethodObject/ExtractMethodObjectHandler.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractMethodObject/ExtractMethodObjectHandler.java @@ -24,6 +24,7 @@ import com.intellij.java.impl.refactoring.extractMethod.ExtractMethodHandler; import com.intellij.java.impl.refactoring.extractMethod.PrepareFailedException; import com.intellij.java.impl.refactoring.util.duplicates.DuplicatesImpl; +import consulo.application.Application; import consulo.codeEditor.Editor; import consulo.codeEditor.ScrollType; import consulo.dataContext.DataContext; @@ -44,51 +45,44 @@ import consulo.undoRedo.CommandProcessor; import jakarta.annotation.Nonnull; -import java.util.function.Consumer; - public class ExtractMethodObjectHandler implements RefactoringActionHandler { private static final Logger LOG = Logger.getInstance(ExtractMethodObjectHandler.class); - public void invoke(@Nonnull final Project project, final Editor editor, final PsiFile file, final DataContext dataContext) { - ExtractMethodHandler.selectAndPass(project, editor, file, new Consumer() { - public void accept(final PsiElement[] selectedValue) { - invokeOnElements(project, editor, file, selectedValue); - } - }); + @Override + @RequiredUIAccess + public void invoke(@Nonnull Project project, Editor editor, PsiFile file, DataContext dataContext) { + ExtractMethodHandler.selectAndPass(project, editor, file, selectedValue -> invokeOnElements(project, editor, file, selectedValue)); } @RequiredUIAccess private void invokeOnElements( - @Nonnull final Project project, - @Nonnull final Editor editor, + @Nonnull Project project, + @Nonnull Editor editor, @Nonnull PsiFile file, @Nonnull PsiElement[] elements ) { if (elements.length == 0) { - LocalizeValue message = RefactoringLocalize.cannotPerformRefactoringWithReason( - RefactoringLocalize.selectedBlockShouldRepresentASetOfStatementsOrAnExpression() - ); CommonRefactoringUtil.showErrorHint( project, editor, - message, + RefactoringLocalize.cannotPerformRefactoringWithReason( + RefactoringLocalize.selectedBlockShouldRepresentASetOfStatementsOrAnExpression() + ), ExtractMethodObjectProcessor.REFACTORING_NAME, HelpID.EXTRACT_METHOD_OBJECT ); return; } - final ExtractMethodObjectProcessor processor = new ExtractMethodObjectProcessor(project, editor, elements, ""); - final ExtractMethodObjectProcessor.MyExtractMethodProcessor extractProcessor = processor.getExtractProcessor(); + ExtractMethodObjectProcessor processor = new ExtractMethodObjectProcessor(project, editor, elements, ""); + ExtractMethodObjectProcessor.MyExtractMethodProcessor extractProcessor = processor.getExtractProcessor(); try { if (!extractProcessor.prepare()) { return; } } catch (PrepareFailedException e) { - CommonRefactoringUtil.showErrorHint( - project, - editor, + CommonRefactoringUtil.showErrorHint(project, editor, LocalizeValue.ofNullable(e.getMessage()), ExtractMethodObjectProcessor.REFACTORING_NAME, HelpID.EXTRACT_METHOD_OBJECT @@ -105,14 +99,15 @@ private void invokeOnElements( } } + @RequiredUIAccess public static void run( - @Nonnull final Project project, - @Nonnull final Editor editor, - @Nonnull final ExtractMethodObjectProcessor processor, - @Nonnull final ExtractMethodObjectProcessor.MyExtractMethodProcessor extractProcessor + @Nonnull Project project, + @Nonnull Editor editor, + @Nonnull ExtractMethodObjectProcessor processor, + @Nonnull ExtractMethodObjectProcessor.MyExtractMethodProcessor extractProcessor ) { - final int offset = editor.getCaretModel().getOffset(); - final RangeMarker marker = editor.getDocument().createRangeMarker(new TextRange(offset, offset)); + int offset = editor.getCaretModel().getOffset(); + RangeMarker marker = editor.getDocument().createRangeMarker(new TextRange(offset, offset)); CommandProcessor.getInstance().newCommand() .project(project) .name(ExtractMethodObjectProcessor.REFACTORING_NAME) @@ -149,7 +144,9 @@ public static void run( editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); } - public void invoke(@Nonnull final Project project, @Nonnull final PsiElement[] elements, final DataContext dataContext) { + @Override + @RequiredUIAccess + public void invoke(@Nonnull Project project, @Nonnull PsiElement[] elements, DataContext dataContext) { throw new UnsupportedOperationException(); } } \ No newline at end of file diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractSuperclass/ExtractSuperClassUtil.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractSuperclass/ExtractSuperClassUtil.java index 14216bb12..a12908cc0 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractSuperclass/ExtractSuperClassUtil.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractSuperclass/ExtractSuperClassUtil.java @@ -23,7 +23,8 @@ import com.intellij.java.language.psi.util.MethodSignature; import com.intellij.java.language.psi.util.PsiUtil; import com.intellij.java.language.psi.util.TypeConversionUtil; -import consulo.ide.impl.idea.openapi.module.ModuleUtil; +import consulo.annotation.access.RequiredReadAction; +import consulo.annotation.access.RequiredWriteAction; import consulo.language.codeStyle.CodeStyleManager; import consulo.language.editor.refactoring.ui.ConflictsDialog; import consulo.language.editor.ui.util.DocCommentPolicy; @@ -37,14 +38,13 @@ import consulo.logging.Logger; import consulo.module.Module; import consulo.module.content.ProjectRootManager; +import consulo.module.content.util.ModuleContentUtil; import consulo.project.Project; import consulo.ui.annotation.RequiredUIAccess; import consulo.ui.ex.awt.DialogWrapper; import consulo.util.collection.MultiMap; -import consulo.util.lang.function.Condition; import consulo.virtualFileSystem.VirtualFile; import jakarta.annotation.Nullable; -import org.jetbrains.annotations.NonNls; import java.util.*; @@ -57,6 +57,7 @@ public class ExtractSuperClassUtil { private ExtractSuperClassUtil() { } + @RequiredWriteAction public static PsiClass extractSuperClass( Project project, PsiDirectory targetDirectory, @@ -64,8 +65,7 @@ public static PsiClass extractSuperClass( PsiClass subclass, MemberInfo[] selectedMemberInfos, DocCommentPolicy javaDocPolicy - ) - throws IncorrectOperationException { + ) throws IncorrectOperationException { PsiClass superclass = JavaDirectoryService.getInstance().createClass(targetDirectory, superclassName); PsiModifierList superClassModifierList = superclass.getModifierList(); assert superClassModifierList != null; @@ -101,18 +101,16 @@ public static PsiClass extractSuperClass( return superclass; } - private static void createConstructorsByPattern( - Project project, - PsiClass superclass, - PsiMethod[] patternConstructors - ) throws IncorrectOperationException { + @RequiredWriteAction + private static void createConstructorsByPattern(Project project, PsiClass superclass, PsiMethod[] patternConstructors) + throws IncorrectOperationException { PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory(); CodeStyleManager styleManager = CodeStyleManager.getInstance(project); for (PsiMethod baseConstructor : patternConstructors) { PsiMethod constructor = (PsiMethod) superclass.add(factory.createConstructor()); PsiParameterList paramList = constructor.getParameterList(); PsiParameter[] baseParams = baseConstructor.getParameterList().getParameters(); - @NonNls StringBuilder superCallText = new StringBuilder(); + StringBuilder superCallText = new StringBuilder(); superCallText.append("super("); PsiClass baseClass = baseConstructor.getContainingClass(); LOG.assertTrue(baseClass != null); @@ -139,8 +137,9 @@ private static void createConstructorsByPattern( } } + @RequiredReadAction private static PsiMethod[] getCalledBaseConstructors(PsiClass subclass) { - Set baseConstructors = new HashSet(); + Set baseConstructors = new HashSet<>(); PsiMethod[] constructors = subclass.getConstructors(); for (PsiMethod constructor : constructors) { PsiCodeBlock body = constructor.getBody(); @@ -148,19 +147,15 @@ private static PsiMethod[] getCalledBaseConstructors(PsiClass subclass) { continue; } PsiStatement[] statements = body.getStatements(); - if (statements.length > 0) { - PsiStatement first = statements[0]; - if (first instanceof PsiExpressionStatement) { - PsiExpression expression = ((PsiExpressionStatement) first).getExpression(); - if (expression instanceof PsiMethodCallExpression) { - PsiReferenceExpression calledMethod = ((PsiMethodCallExpression) expression).getMethodExpression(); - @NonNls String text = calledMethod.getText(); - if ("super".equals(text)) { - PsiMethod baseConstructor = (PsiMethod) calledMethod.resolve(); - if (baseConstructor != null) { - baseConstructors.add(baseConstructor); - } - } + if (statements.length > 0 + && statements[0] instanceof PsiExpressionStatement firstExpr + && firstExpr.getExpression() instanceof PsiMethodCallExpression call) { + PsiReferenceExpression calledMethod = call.getMethodExpression(); + String text = calledMethod.getText(); + if ("super".equals(text)) { + PsiMethod baseConstructor = (PsiMethod) calledMethod.resolve(); + if (baseConstructor != null) { + baseConstructors.add(baseConstructor); } } } @@ -168,6 +163,7 @@ private static PsiMethod[] getCalledBaseConstructors(PsiClass subclass) { return baseConstructors.toArray(new PsiMethod[baseConstructors.size()]); } + @RequiredWriteAction private static void clearPsiReferenceList(PsiReferenceList refList) throws IncorrectOperationException { PsiJavaCodeReferenceElement[] refs = refList.getReferenceElements(); for (PsiJavaCodeReferenceElement ref : refs) { @@ -175,10 +171,9 @@ private static void clearPsiReferenceList(PsiReferenceList refList) throws Incor } } - private static void copyPsiReferenceList( - PsiReferenceList sourceList, - PsiReferenceList destinationList - ) throws IncorrectOperationException { + @RequiredWriteAction + private static void copyPsiReferenceList(PsiReferenceList sourceList, PsiReferenceList destinationList) + throws IncorrectOperationException { clearPsiReferenceList(destinationList); PsiJavaCodeReferenceElement[] refs = sourceList.getReferenceElements(); for (PsiJavaCodeReferenceElement ref : refs) { @@ -186,39 +181,32 @@ private static void copyPsiReferenceList( } } + @RequiredWriteAction public static PsiJavaCodeReferenceElement createExtendingReference( PsiClass superClass, - final PsiClass derivedClass, + PsiClass derivedClass, MemberInfo[] selectedMembers ) throws IncorrectOperationException { PsiManager manager = derivedClass.getManager(); - Set movedElements = new HashSet(); + Set movedElements = new HashSet<>(); for (MemberInfo info : selectedMembers) { movedElements.add(info.getMember()); } - PsiTypeParameterList typeParameterList = RefactoringUtil.createTypeParameterListWithUsedTypeParameters(null, - new Condition() { - @Override - public boolean value( - PsiTypeParameter parameter - ) { - return - findTypeParameterInDerived( - derivedClass, - parameter - .getName() - ) != - null; - } - }, PsiUtilBase - .toPsiElementArray(movedElements) + PsiTypeParameterList typeParameterList = RefactoringUtil.createTypeParameterListWithUsedTypeParameters( + null, + parameter -> findTypeParameterInDerived( + derivedClass, + parameter.getName() + ) != null, + PsiUtilBase.toPsiElementArray(movedElements) ); PsiTypeParameterList originalTypeParameterList = superClass.getTypeParameterList(); assert originalTypeParameterList != null; - PsiTypeParameterList newList = - typeParameterList != null ? (PsiTypeParameterList) originalTypeParameterList.replace(typeParameterList) : originalTypeParameterList; + PsiTypeParameterList newList = typeParameterList != null + ? (PsiTypeParameterList) originalTypeParameterList.replace(typeParameterList) + : originalTypeParameterList; PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); - Map substitutionMap = new HashMap(); + Map substitutionMap = new HashMap<>(); for (PsiTypeParameter parameter : newList.getTypeParameters()) { PsiTypeParameter parameterInDerived = findTypeParameterInDerived(derivedClass, parameter.getName()); if (parameterInDerived != null) { @@ -231,6 +219,7 @@ public boolean value( } @Nullable + @RequiredReadAction public static PsiTypeParameter findTypeParameterInDerived(PsiClass aClass, String name) { for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(aClass)) { if (name.equals(typeParameter.getName())) { @@ -241,16 +230,20 @@ public static PsiTypeParameter findTypeParameterInDerived(PsiClass aClass, Strin return null; } - public static void checkSuperAccessible(PsiDirectory targetDirectory, MultiMap conflicts, PsiClass subclass) { + public static void checkSuperAccessible( + PsiDirectory targetDirectory, + MultiMap conflicts, + PsiClass subclass + ) { VirtualFile virtualFile = subclass.getContainingFile().getVirtualFile(); if (virtualFile != null) { boolean inTestSourceContent = ProjectRootManager.getInstance(subclass.getProject()).getFileIndex().isInTestSourceContent(virtualFile); - Module module = ModuleUtil.findModuleForFile(virtualFile, subclass.getProject()); - if (targetDirectory != null && - module != null && - !GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module, inTestSourceContent) - .contains(targetDirectory.getVirtualFile())) { + Module module = ModuleContentUtil.findModuleForFile(virtualFile, subclass.getProject()); + if (targetDirectory != null + && module != null + && !GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module, inTestSourceContent) + .contains(targetDirectory.getVirtualFile())) { conflicts.putValue(subclass, LocalizeValue.localizeTODO("Superclass won't be accessible in subclass")); } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/inlineSuperClass/usageInfo/InlineSuperCallUsageInfo.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/inlineSuperClass/usageInfo/InlineSuperCallUsageInfo.java index 377b0cbdd..29c960e7a 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/inlineSuperClass/usageInfo/InlineSuperCallUsageInfo.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/inlineSuperClass/usageInfo/InlineSuperCallUsageInfo.java @@ -13,11 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/* - * User: anna - * Date: 10-Oct-2009 - */ package com.intellij.java.impl.refactoring.inlineSuperClass.usageInfo; import com.intellij.java.impl.refactoring.inline.InlineMethodProcessor; @@ -25,38 +20,47 @@ import com.intellij.java.impl.refactoring.util.FixableUsageInfo; import com.intellij.java.impl.refactoring.util.InlineUtil; import com.intellij.java.language.psi.*; +import consulo.annotation.access.RequiredReadAction; +import consulo.annotation.access.RequiredWriteAction; import consulo.language.editor.refactoring.localize.RefactoringLocalize; -import consulo.language.editor.refactoring.util.CommonRefactoringUtil; import consulo.language.psi.PsiElement; import consulo.language.psi.util.PsiTreeUtil; import consulo.language.util.IncorrectOperationException; import consulo.localize.LocalizeValue; import consulo.usage.UsageInfo; import consulo.util.collection.MultiMap; +import consulo.util.lang.StringUtil; import jakarta.annotation.Nonnull; +/** + * @author anna + * @since 2009-10-10 + */ public class InlineSuperCallUsageInfo extends FixableUsageInfo { - private PsiCodeBlock myConstrBody; + private PsiCodeBlock myConstructorBody; + @RequiredReadAction public InlineSuperCallUsageInfo(PsiMethodCallExpression methodCallExpression) { super(methodCallExpression); } - public InlineSuperCallUsageInfo(PsiMethodCallExpression methodCallExpression, PsiCodeBlock constrBody) { + @RequiredReadAction + public InlineSuperCallUsageInfo(PsiMethodCallExpression methodCallExpression, PsiCodeBlock constructorBody) { super(methodCallExpression); - myConstrBody = constrBody; + myConstructorBody = constructorBody; } @Override + @RequiredWriteAction public void fixUsage() throws IncorrectOperationException { PsiElement element = getElement(); - if (element != null && myConstrBody != null) { + if (element != null && myConstructorBody != null) { assert !element.isPhysical(); - PsiStatement statement = JavaPsiFacade.getElementFactory(getProject()).createStatementFromText("super();", myConstrBody); - element = ((PsiExpressionStatement) myConstrBody.addBefore(statement, myConstrBody.getFirstBodyElement())).getExpression(); + PsiStatement statement = JavaPsiFacade.getElementFactory(getProject()).createStatementFromText("super();", myConstructorBody); + element = ((PsiExpressionStatement) myConstructorBody.addBefore(statement, myConstructorBody.getFirstBodyElement())).getExpression(); } - if (element instanceof PsiMethodCallExpression) { - PsiReferenceExpression methodExpression = ((PsiMethodCallExpression) element).getMethodExpression(); + if (element instanceof PsiMethodCallExpression call) { + PsiReferenceExpression methodExpression = call.getMethodExpression(); PsiMethod superConstructor = (PsiMethod) methodExpression.resolve(); if (superConstructor != null) { PsiMethod methodCopy = JavaPsiFacade.getElementFactory(getProject()).createMethod("toInline", PsiType.VOID); @@ -84,11 +88,10 @@ public void fixUsage() throws IncorrectOperationException { } @Override + @RequiredReadAction public LocalizeValue getConflictMessage() { MultiMap conflicts = new MultiMap<>(); - PsiElement element = getElement(); - if (element instanceof PsiMethodCallExpression) { - PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) element; + if (getElement() instanceof PsiMethodCallExpression methodCallExpression) { final PsiMethod superConstructor = methodCallExpression.resolveMethod(); if (superConstructor != null) { InlineMethodProcessor.addInaccessibleMemberConflicts( @@ -107,7 +110,7 @@ protected void checkAddMember(@Nonnull PsiMember member) { if (InlineMethodProcessor.checkBadReturns(superConstructor) && !InlineUtil.allUsagesAreTailCalls(superConstructor)) { conflicts.putValue( superConstructor, - LocalizeValue.localizeTODO(CommonRefactoringUtil.capitalize( + LocalizeValue.localizeTODO(StringUtil.capitalize( RefactoringLocalize.refactoringIsNotSupportedWhenReturnStatementInterruptsTheExecutionFlow("") + " of super constructor" )) diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/introduceField/BaseExpressionToFieldHandler.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/introduceField/BaseExpressionToFieldHandler.java index 52435cd4f..b574a06b1 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/introduceField/BaseExpressionToFieldHandler.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/introduceField/BaseExpressionToFieldHandler.java @@ -32,7 +32,8 @@ import com.intellij.java.language.psi.codeStyle.JavaCodeStyleManager; 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.application.Result; import consulo.codeEditor.Editor; import consulo.codeEditor.EditorColors; @@ -50,7 +51,6 @@ import consulo.language.editor.util.PsiUtilBase; import consulo.language.impl.psi.CodeEditUtil; import consulo.language.psi.*; -import consulo.language.psi.resolve.PsiElementProcessor; import consulo.language.psi.scope.GlobalSearchScope; import consulo.language.psi.util.PsiTreeUtil; import consulo.language.util.IncorrectOperationException; @@ -63,7 +63,6 @@ import consulo.util.lang.StringUtil; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; -import org.jetbrains.annotations.NonNls; import java.util.ArrayList; import java.util.HashMap; @@ -90,18 +89,19 @@ protected BaseExpressionToFieldHandler(boolean isConstant) { myIsConstant = isConstant; } + @Override @RequiredUIAccess - protected boolean invokeImpl(final Project project, @Nonnull final PsiExpression selectedExpr, final Editor editor) { + protected boolean invokeImpl(@Nonnull Project project, @Nonnull PsiExpression selectedExpr, Editor editor) { PsiElement element = getPhysicalElement(selectedExpr); - final PsiFile file = element.getContainingFile(); + PsiFile file = element.getContainingFile(); LOG.assertTrue(file != null, "expr.getContainingFile() == null"); if (LOG.isDebugEnabled()) { LOG.debug("expression:" + selectedExpr); } - final PsiType tempType = getTypeByExpression(selectedExpr); + PsiType tempType = getTypeByExpression(selectedExpr); if (tempType == null || LambdaUtil.notInferredType(tempType)) { LocalizeValue message = RefactoringLocalize.cannotPerformRefactoringWithReason(RefactoringLocalize.unknownExpressionType()); CommonRefactoringUtil.showErrorHint(project, editor, message, getRefactoringName(), getHelpID()); @@ -116,7 +116,7 @@ protected boolean invokeImpl(final Project project, @Nonnull final PsiExpression } myParentClass = getParentClass(selectedExpr); - List classes = new ArrayList(); + List classes = new ArrayList<>(); PsiClass aClass = myParentClass; while (aClass != null) { classes.add(aClass); @@ -127,9 +127,9 @@ protected boolean invokeImpl(final Project project, @Nonnull final PsiExpression aClass = PsiTreeUtil.getParentOfType(aClass, PsiClass.class, true); } AbstractInplaceIntroducer activeIntroducer = AbstractInplaceIntroducer.getActiveIntroducer(editor); - boolean shouldSuggestDialog = activeIntroducer instanceof InplaceIntroduceConstantPopup && - activeIntroducer.startsOnTheSameElement(selectedExpr, null); - if (classes.size() == 1 || editor == null || ApplicationManager.getApplication().isUnitTestMode() || shouldSuggestDialog) { + boolean shouldSuggestDialog = activeIntroducer instanceof InplaceIntroduceConstantPopup + && activeIntroducer.startsOnTheSameElement(selectedExpr, null); + if (classes.size() == 1 || editor == null || project.getApplication().isUnitTestMode() || shouldSuggestDialog) { return !convertExpressionToField(selectedExpr, editor, file, project, tempType); } else { @@ -140,23 +140,23 @@ protected boolean invokeImpl(final Project project, @Nonnull final PsiExpression break; } } - JBPopup popup = - PopupNavigationUtil.getPsiElementPopup(classes.toArray(new PsiClass[classes.size()]), new PsiClassListCellRenderer(), - "Choose class to introduce " + (myIsConstant ? "constant" : "field"), - new PsiElementProcessor() { - @Override - public boolean execute(@Nonnull PsiClass aClass) { - myParentClass = aClass; - convertExpressionToField(selectedExpr, editor, file, project, tempType); - return false; - } - }, selection - ); + JBPopup popup = PopupNavigationUtil.getPsiElementPopup( + classes.toArray(new PsiClass[classes.size()]), + new PsiClassListCellRenderer(), + "Choose class to introduce " + (myIsConstant ? "constant" : "field"), + thisClass -> { + myParentClass = thisClass; + convertExpressionToField(selectedExpr, editor, file, project, tempType); + return false; + }, + selection + ); EditorPopupHelper.getInstance().showPopupInBestPositionFor(editor, popup); } return true; } + @RequiredUIAccess private boolean convertExpressionToField( PsiExpression selectedExpr, @Nullable Editor editor, @@ -164,17 +164,24 @@ private boolean convertExpressionToField( final Project project, PsiType tempType ) { - /*if (myParentClass == null) { - if (JspPsiUtil.isInJspFile(file)) { - CommonRefactoringUtil.showErrorHint(project, editor, RefactoringBundle.message("error.not.supported.for.jsp", getRefactoringName()), - getRefactoringName(), getHelpID()); - return true; - } - else { - LOG.assertTrue(false); - return true; - } - } */ + /* + if (myParentClass == null) { + if (JspPsiUtil.isInJspFile(file)) { + CommonRefactoringUtil.showErrorHint( + project, + editor, + RefactoringBundle.message("error.not.supported.for.jsp", getRefactoringName()), + getRefactoringName(), + getHelpID() + ); + return true; + } + else { + LOG.assertTrue(false); + return true; + } + } + */ if (!validClass(myParentClass, editor)) { return true; @@ -195,14 +202,20 @@ private boolean convertExpressionToField( PsiElement tempAnchorElement = RefactoringUtil.getParentExpressionAnchorElement(selectedExpr); if (!IntroduceConstantHandlerImpl.REFACTORING_NAME.equals(getRefactoringName()) - && IntroduceVariableBase.checkAnchorBeforeThisOrSuper(project, editor, tempAnchorElement, getRefactoringName().get(), getHelpID())) { + && IntroduceVariableBase.checkAnchorBeforeThisOrSuper(project, editor, tempAnchorElement, getRefactoringName(), getHelpID())) { return true; } - Settings settings = - showRefactoringDialog(project, editor, myParentClass, selectedExpr, tempType, - occurrences, tempAnchorElement, anchorStatementIfAll - ); + Settings settings = showRefactoringDialog( + project, + editor, + myParentClass, + selectedExpr, + tempType, + occurrences, + tempAnchorElement, + anchorStatementIfAll + ); if (settings == null) { return true; @@ -220,12 +233,17 @@ private boolean convertExpressionToField( } } - - final Runnable runnable = - new ConvertToFieldRunnable(settings.getSelectedExpr(), settings, type, settings.getOccurrences(), occurrenceManager, - anchorStatementIfAll, tempAnchorElement, editor, - myParentClass - ); + final Runnable runnable = new ConvertToFieldRunnable( + settings.getSelectedExpr(), + settings, + type, + settings.getOccurrences(), + occurrenceManager, + anchorStatementIfAll, + tempAnchorElement, + editor, + myParentClass + ); new WriteCommandAction(project, getRefactoringName().get()) { @Override @@ -236,6 +254,7 @@ protected void run(Result result) throws Throwable { return false; } + @RequiredWriteAction public static void setModifiers(PsiField field, Settings settings) { if (!settings.isIntroduceEnumConstant()) { if (settings.isDeclareStatic()) { @@ -271,6 +290,7 @@ protected final PsiClass getParentClass() { protected abstract boolean validClass(PsiClass parentClass, Editor editor); + @RequiredReadAction private static PsiElement getNormalizedAnchor(PsiElement anchorElement) { PsiElement child = anchorElement; while (child != null) { @@ -278,7 +298,7 @@ private static PsiElement getNormalizedAnchor(PsiElement anchorElement) { if (RefactoringUtil.isExpressionAnchorElement(prev)) { break; } - if (prev instanceof PsiJavaToken && ((PsiJavaToken) prev).getTokenType() == JavaTokenType.LBRACE) { + if (prev instanceof PsiJavaToken token && token.getTokenType() == JavaTokenType.LBRACE) { break; } child = prev; @@ -315,8 +335,8 @@ public PsiClass getParentClass(@Nonnull PsiExpression initializerExpression) { } PsiElement parent = element; while (parent != null) { - if (parent instanceof PsiClass && !(parent instanceof PsiAnonymousClass && myIsConstant)) { - return (PsiClass) parent; + if (parent instanceof PsiClass psiClass && !(parent instanceof PsiAnonymousClass && myIsConstant)) { + return psiClass; } parent = parent.getParent(); } @@ -339,6 +359,7 @@ public static PsiMethod getEnclosingConstructor(PsiClass parentClass, PsiElement return null; } + @RequiredWriteAction private static void addInitializationToSetUp( PsiExpression initializer, PsiField field, @@ -370,10 +391,12 @@ private static void addInitializationToSetUp( body.addBefore(expressionStatement, anchor); } + @RequiredWriteAction private static void addInitializationToConstructors( PsiExpression initializerExpression, PsiField field, - PsiMethod enclosingConstructor, PsiClass parentClass + PsiMethod enclosingConstructor, + PsiClass parentClass ) { try { PsiClass aClass = field.getContainingClass(); @@ -389,21 +412,19 @@ private static void addInitializationToConstructors( continue; } PsiStatement[] statements = body.getStatements(); - if (statements.length > 0) { - PsiStatement first = statements[0]; - if (first instanceof PsiExpressionStatement) { - PsiExpression expression = ((PsiExpressionStatement) first).getExpression(); - if (expression instanceof PsiMethodCallExpression) { - @NonNls String text = ((PsiMethodCallExpression) expression).getMethodExpression().getText(); - if ("this".equals(text)) { - continue; - } - } + if (statements.length > 0 + && statements[0] instanceof PsiExpressionStatement firstExpr + && firstExpr.getExpression() instanceof PsiMethodCallExpression call) { + String text = call.getMethodExpression().getText(); + if ("this".equals(text)) { + continue; } } PsiStatement assignment = createAssignment(field, initializerExpression, body.getLastChild(), parentClass); assignment = (PsiStatement) body.add(assignment); - ChangeContextUtil.decodeContextInfo(assignment, field.getContainingClass(), + ChangeContextUtil.decodeContextInfo( + assignment, + field.getContainingClass(), RefactoringChangeUtil.createThisExpression(field.getManager(), null) ); added = true; @@ -424,13 +445,15 @@ private static void addInitializationToConstructors( } } + @RequiredWriteAction private static PsiField createField( String fieldName, PsiType type, PsiExpression initializerExpr, - boolean includeInitializer, PsiClass parentClass + boolean includeInitializer, + PsiClass parentClass ) { - @NonNls StringBuilder pattern = new StringBuilder(); + StringBuilder pattern = new StringBuilder(); pattern.append("private int "); pattern.append(fieldName); if (includeInitializer) { @@ -454,6 +477,7 @@ private static PsiField createField( } } + @RequiredWriteAction private static PsiStatement createAssignment( PsiField field, PsiExpression initializerExpr, @@ -461,7 +485,7 @@ private static PsiStatement createAssignment( PsiClass parentClass ) { try { - @NonNls String pattern = "x=0;"; + String pattern = "x=0;"; PsiManager psiManager = parentClass.getManager(); PsiElementFactory factory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory(); PsiExpressionStatement statement = (PsiExpressionStatement) factory.createStatementFromText(pattern, null); @@ -484,14 +508,15 @@ private static PsiStatement createAssignment( protected abstract boolean accept(ElementToWorkOn elementToWorkOn); - protected ElementToWorkOn.ElementsProcessor getElementProcessor(final Project project, final Editor editor) { - return new ElementToWorkOn.ElementsProcessor() { + protected ElementToWorkOn.ElementsProcessor getElementProcessor(@Nonnull Project project, final Editor editor) { + return new ElementToWorkOn.ElementsProcessor<>() { @Override public boolean accept(ElementToWorkOn el) { return BaseExpressionToFieldHandler.this.accept(el); } @Override + @RequiredUIAccess public void pass(ElementToWorkOn elementToWorkOn) { if (elementToWorkOn == null) { return; @@ -505,15 +530,14 @@ public void pass(ElementToWorkOn elementToWorkOn) { editor.getSelectionModel().removeSelection(); } } - else { - if (invokeImpl(project, elementToWorkOn.getExpression(), editor) && hasRunTemplate) { - editor.getSelectionModel().removeSelection(); - } + else if (invokeImpl(project, elementToWorkOn.getExpression(), editor) && hasRunTemplate) { + editor.getSelectionModel().removeSelection(); } } }; } + @Nonnull protected abstract LocalizeValue getRefactoringName(); public static class Settings { @@ -595,7 +619,6 @@ public Settings( boolean annotateAsNonNls, boolean introduceEnumConstant ) { - myFieldName = fieldName; myOccurrences = occurrences; mySelectedExpr = selectedExpr; @@ -624,7 +647,6 @@ public Settings( boolean annotateAsNonNls, boolean introduceEnumConstant ) { - this( fieldName, selectedExpression, @@ -694,7 +716,7 @@ public PsiClass getTargetClass() { directories, null, myProject, - new HashMap() + new HashMap<>() ) : directories[0]; } else { @@ -714,6 +736,7 @@ public static class ConvertToFieldRunnable implements Runnable { private PsiExpression mySelectedExpr; private final Settings mySettings; private final PsiElement myAnchorElement; + @Nonnull private final Project myProject; private final String myFieldName; private final PsiType myType; @@ -730,6 +753,7 @@ public static class ConvertToFieldRunnable implements Runnable { private PsiField myField; + @RequiredReadAction public ConvertToFieldRunnable( PsiExpression selectedExpr, Settings settings, @@ -755,7 +779,9 @@ public ConvertToFieldRunnable( myOutOfCodeBlockExtraction = selectedExpr.getUserData(ElementToWorkOn.OUT_OF_CODE_BLOCK); myDeleteSelf = myOutOfCodeBlockExtraction != null; myElement = getPhysicalElement(selectedExpr); - if (myElement.getParent() instanceof PsiExpressionStatement && getNormalizedAnchor(myAnchorElement).equals(myAnchorElement) && selectedExpr.isPhysical()) { + if (myElement.getParent() instanceof PsiExpressionStatement + && getNormalizedAnchor(myAnchorElement).equals(myAnchorElement) + && selectedExpr.isPhysical()) { PsiStatement statement = (PsiStatement) myElement.getParent(); if (statement.getParent() instanceof PsiCodeBlock) { myDeleteSelf = true; @@ -766,6 +792,8 @@ public ConvertToFieldRunnable( myParentClass = parentClass; } + @Override + @RequiredWriteAction public void run() { try { InitializationPlace initializerPlace = mySettings.getInitializerPlace(); @@ -775,7 +803,7 @@ public void run() { if (localVariable != null) { initializer = localVariable.getInitializer(); } - else if (!(mySelectedExpr instanceof PsiReferenceExpression && ((PsiReferenceExpression) mySelectedExpr).resolve() == null)) { + else if (!(mySelectedExpr instanceof PsiReferenceExpression refExpr && refExpr.resolve() == null)) { initializer = mySelectedExpr; } @@ -803,14 +831,18 @@ else if (!(mySelectedExpr instanceof PsiReferenceExpression && ((PsiReferenceExp setModifiers(myField, mySettings); PsiElement finalAnchorElement = null; if (destClass == myParentClass) { - for (finalAnchorElement = myAnchorElement; - finalAnchorElement != null && finalAnchorElement.getParent() != destClass; - finalAnchorElement = finalAnchorElement.getParent()) { + finalAnchorElement = myAnchorElement; + while (finalAnchorElement != null) { + PsiElement parent = finalAnchorElement.getParent(); + if (parent == destClass) { + break; + } + finalAnchorElement = parent; } } - PsiMember anchorMember = finalAnchorElement instanceof PsiMember ? (PsiMember) finalAnchorElement : null; + PsiMember anchorMember = finalAnchorElement instanceof PsiMember member ? member : null; - if (anchorMember instanceof PsiEnumConstant && destClass == anchorMember.getContainingClass()) { + if (anchorMember instanceof PsiEnumConstant enumConst && destClass == enumConst.getContainingClass()) { String initialName = "Constants"; String constantsClassName = initialName; @@ -889,7 +921,7 @@ else if (myDeleteSelf) { } if (myReplaceAll) { - List array = new ArrayList(); + List array = new ArrayList<>(); for (PsiExpression occurrence : myOccurrences) { if (occurrence instanceof PsiExpression) { occurrence = RefactoringUtil.outermostParenthesizedExpression(occurrence); @@ -903,25 +935,21 @@ else if (myDeleteSelf) { } } - if (myEditor != null) { - if (!ApplicationManager.getApplication().isUnitTestMode()) { - PsiElement[] exprsToHighlight = PsiUtilBase.toPsiElementArray(array); - HighlightManager highlightManager = HighlightManager.getInstance(myProject); - highlightManager.addOccurrenceHighlights( - myEditor, - exprsToHighlight, - EditorColors.SEARCH_RESULT_ATTRIBUTES, - true, - null - ); - } + if (myEditor != null && !myProject.getApplication().isUnitTestMode()) { + PsiElement[] exprsToHighlight = PsiUtilBase.toPsiElementArray(array); + HighlightManager highlightManager = HighlightManager.getInstance(myProject); + highlightManager.addOccurrenceHighlights( + myEditor, + exprsToHighlight, + EditorColors.SEARCH_RESULT_ATTRIBUTES, + true, + null + ); } } - else { - if (!myDeleteSelf) { - mySelectedExpr = RefactoringUtil.outermostParenthesizedExpression(mySelectedExpr); - RefactoringUtil.replaceOccurenceWithFieldRef(mySelectedExpr, myField, destClass); - } + else if (!myDeleteSelf) { + mySelectedExpr = RefactoringUtil.outermostParenthesizedExpression(mySelectedExpr); + RefactoringUtil.replaceOccurenceWithFieldRef(mySelectedExpr, myField, destClass); } if (anchorElementHere != null && RefactoringUtil.isLoopOrIf(anchorElementHere.getParent())) { @@ -950,24 +978,31 @@ static boolean isConstantsClass(PsiClass innerClass) { return false; } for (PsiField field : innerClass.getFields()) { - if (!field.hasModifierProperty(PsiModifier.STATIC) || !field.hasModifierProperty(PsiModifier.FINAL)) { + if (!field.isStatic() || !field.isFinal()) { return false; } } return true; } + @RequiredWriteAction static PsiField appendField( PsiExpression initializer, - InitializationPlace initializerPlace, PsiClass destClass, + InitializationPlace initializerPlace, + PsiClass destClass, PsiClass parentClass, PsiField psiField, PsiMember anchorMember ) { - return appendField(destClass, psiField, anchorMember, initializerPlace == InitializationPlace.IN_FIELD_DECLARATION - ? checkForwardRefs(initializer, parentClass) : null); + return appendField( + destClass, + psiField, + anchorMember, + initializerPlace == InitializationPlace.IN_FIELD_DECLARATION ? checkForwardRefs(initializer, parentClass) : null + ); } + @RequiredWriteAction public static PsiField appendField( PsiClass destClass, PsiField psiField, @@ -976,28 +1011,26 @@ public static PsiField appendField( ) { PsiClass parentClass = PsiTreeUtil.getParentOfType(anchorMember, PsiClass.class); - if (anchorMember instanceof PsiField && - anchorMember.getParent() == parentClass && - destClass == parentClass && - ((PsiField) anchorMember).hasModifierProperty(PsiModifier.STATIC) == psiField.hasModifierProperty(PsiModifier.STATIC)) { + if (anchorMember instanceof PsiField field + && anchorMember.getParent() == parentClass + && destClass == parentClass + && field.isStatic() == psiField.isStatic()) { return (PsiField) destClass.addBefore(psiField, anchorMember); } - else if (anchorMember instanceof PsiClassInitializer && - anchorMember.getParent() == parentClass && - destClass == parentClass) { + else if (anchorMember instanceof PsiClassInitializer + && anchorMember.getParent() == parentClass + && destClass == parentClass) { PsiField field = (PsiField) destClass.addBefore(psiField, anchorMember); destClass.addBefore(CodeEditUtil.createLineFeed(field.getManager()), anchorMember); return field; } + else if (forwardReference != null) { + return forwardReference.getParent() == destClass + ? (PsiField) destClass.addAfter(psiField, forwardReference) + : (PsiField) forwardReference.getParent().addAfter(psiField, forwardReference); + } else { - if (forwardReference != null) { - return forwardReference.getParent() == destClass ? - (PsiField) destClass.addAfter(psiField, forwardReference) : - (PsiField) forwardReference.getParent().addAfter(psiField, forwardReference); - } - else { - return (PsiField) destClass.add(psiField); - } + return (PsiField) destClass.add(psiField); } } @@ -1009,14 +1042,16 @@ private static PsiField checkForwardRefs(@Nullable final PsiExpression initializ final PsiField[] refConstantFields = new PsiField[1]; initializer.accept(new JavaRecursiveElementWalkingVisitor() { @Override + @RequiredReadAction public void visitReferenceExpression(PsiReferenceExpression expression) { super.visitReferenceExpression(expression); PsiElement resolve = expression.resolve(); - if (resolve instanceof PsiField && - PsiTreeUtil.isAncestor(parentClass, resolve, false) && ((PsiField) resolve).hasInitializer() && - !PsiTreeUtil.isAncestor(initializer, resolve, false)) { - if (refConstantFields[0] == null || refConstantFields[0].getTextOffset() < resolve.getTextOffset()) { - refConstantFields[0] = (PsiField) resolve; + if (resolve instanceof PsiField field + && PsiTreeUtil.isAncestor(parentClass, field, false) + && field.hasInitializer() + && !PsiTreeUtil.isAncestor(initializer, field, false)) { + if (refConstantFields[0] == null || refConstantFields[0].getTextOffset() < field.getTextOffset()) { + refConstantFields[0] = field; } } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/introduceField/IntroduceConstantHandlerImpl.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/introduceField/IntroduceConstantHandlerImpl.java index 5f95c9892..2a0484b50 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/introduceField/IntroduceConstantHandlerImpl.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/introduceField/IntroduceConstantHandlerImpl.java @@ -25,9 +25,9 @@ import com.intellij.java.language.impl.codeInsight.ExceptionUtil; import com.intellij.java.language.psi.*; import com.intellij.java.language.psi.util.PsiUtil; +import consulo.annotation.access.RequiredReadAction; import consulo.codeEditor.Editor; import consulo.codeEditor.EditorColors; -import consulo.codeEditor.markup.RangeHighlighter; import consulo.dataContext.DataContext; import consulo.document.util.TextRange; import consulo.language.editor.highlight.HighlightManager; @@ -55,10 +55,13 @@ public IntroduceConstantHandlerImpl() { super(true); } + @Override protected String getHelpID() { return HelpID.INTRODUCE_CONSTANT; } + @Override + @RequiredUIAccess public void invoke(Project project, PsiExpression[] expressions) { for (PsiExpression expression : expressions) { PsiFile file = expression.getContainingFile(); @@ -70,6 +73,8 @@ public void invoke(Project project, PsiExpression[] expressions) { super.invoke(project, expressions, null); } + @Override + @RequiredUIAccess public void invoke(@Nonnull Project project, Editor editor, PsiFile file, DataContext dataContext) { if (!CommonRefactoringUtil.checkReadOnlyStatus(project, file)) { return; @@ -86,7 +91,9 @@ public void invoke(@Nonnull Project project, Editor editor, PsiFile file, DataCo ); } - protected boolean invokeImpl(final Project project, PsiLocalVariable localVariable, final Editor editor) { + @Override + @RequiredUIAccess + protected boolean invokeImpl(@Nonnull Project project, PsiLocalVariable localVariable, final Editor editor) { PsiElement parent = localVariable.getParent(); if (!(parent instanceof PsiDeclarationStatement)) { LocalizeValue message = @@ -96,10 +103,11 @@ protected boolean invokeImpl(final Project project, PsiLocalVariable localVariab } LocalToFieldHandler localToFieldHandler = new LocalToFieldHandler(project, true) { @Override + @RequiredUIAccess protected Settings showRefactoringDialog( PsiClass aClass, PsiLocalVariable local, - PsiExpression[] occurences, + PsiExpression[] occurrences, boolean isStatic ) { return IntroduceConstantHandlerImpl.this.showRefactoringDialog( @@ -108,7 +116,7 @@ protected Settings showRefactoringDialog( aClass, local.getInitializer(), local.getType(), - occurences, + occurrences, local, null ); @@ -117,6 +125,7 @@ protected Settings showRefactoringDialog( return localToFieldHandler.convertLocalToField(localVariable, editor); } + @Override @RequiredUIAccess protected Settings showRefactoringDialog( Project project, @@ -131,14 +140,13 @@ protected Settings showRefactoringDialog( PsiMethod containingMethod = PsiTreeUtil.getParentOfType(expr != null ? expr : anchorElement, PsiMethod.class); PsiLocalVariable localVariable = null; - if (expr instanceof PsiReferenceExpression) { - PsiElement ref = ((PsiReferenceExpression) expr).resolve(); - if (ref instanceof PsiLocalVariable) { - localVariable = (PsiLocalVariable) ref; + if (expr instanceof PsiReferenceExpression refExpr) { + if (refExpr.resolve() instanceof PsiLocalVariable localVar) { + localVariable = localVar; } } - else if (anchorElement instanceof PsiLocalVariable) { - localVariable = (PsiLocalVariable) anchorElement; + else if (anchorElement instanceof PsiLocalVariable localVar) { + localVariable = localVar; } String enteredName = null; @@ -198,22 +206,34 @@ else if (anchorElement instanceof PsiLocalVariable) { TypeSelectorManagerImpl typeSelectorManager = new TypeSelectorManagerImpl(project, type, containingMethod, expr, occurrences); if (editor != null && editor.getSettings().isVariableInplaceRenameEnabled() && (expr == null || expr.isPhysical()) && activeIntroducer == null) { - myInplaceIntroduceConstantPopup = - new InplaceIntroduceConstantPopup(project, editor, parentClass, expr, localVariable, occurrences, - typeSelectorManager, - anchorElement, anchorElementIfAll, - expr != null ? createOccurrenceManager(expr, parentClass) : null - ); + myInplaceIntroduceConstantPopup = new InplaceIntroduceConstantPopup( + project, + editor, + parentClass, + expr, + localVariable, + occurrences, + typeSelectorManager, + anchorElement, + anchorElementIfAll, + expr != null ? createOccurrenceManager(expr, parentClass) : null + ); if (myInplaceIntroduceConstantPopup.startInplaceIntroduceTemplate()) { return null; } } - - IntroduceConstantDialog dialog = - new IntroduceConstantDialog(project, parentClass, expr, localVariable, localVariable != null, occurrences, getParentClass(), - typeSelectorManager, enteredName - ); + IntroduceConstantDialog dialog = new IntroduceConstantDialog( + project, + parentClass, + expr, + localVariable, + localVariable != null, + occurrences, + getParentClass(), + typeSelectorManager, + enteredName + ); dialog.setReplaceAllOccurrences(replaceAllOccurrences); dialog.show(); if (!dialog.isOK()) { @@ -227,21 +247,23 @@ else if (anchorElement instanceof PsiLocalVariable) { ); } + @RequiredReadAction private static void highlightError(Project project, Editor editor, PsiElement errorElement) { if (editor != null) { TextRange textRange = errorElement.getTextRange(); - HighlightManager.getInstance(project) - .addRangeHighlight( - editor, - textRange.getStartOffset(), - textRange.getEndOffset(), - EditorColors.SEARCH_RESULT_ATTRIBUTES, - true, - new ArrayList() - ); + HighlightManager.getInstance(project).addRangeHighlight( + editor, + textRange.getStartOffset(), + textRange.getEndOffset(), + EditorColors.SEARCH_RESULT_ATTRIBUTES, + true, + new ArrayList<>() + ); } } + @Nonnull + @Override protected LocalizeValue getRefactoringName() { return REFACTORING_NAME; } @@ -262,6 +284,7 @@ private PsiElement isStaticFinalInitializer(PsiExpression expr) { return visitor.getElementReference(); } + @Override protected OccurrenceManager createOccurrenceManager(PsiExpression selectedExpr, PsiClass parentClass) { return new ExpressionOccurrenceManager(selectedExpr, parentClass, null); } @@ -276,10 +299,11 @@ public IsStaticFinalInitializerExpression(PsiClass aClass, PsiExpression initial } @Override + @RequiredReadAction public void visitReferenceExpression(PsiReferenceExpression expression) { PsiElement psiElement = expression.resolve(); - if ((psiElement instanceof PsiLocalVariable || psiElement instanceof PsiParameter) && - !PsiTreeUtil.isAncestor(myInitializer, psiElement, false)) { + if ((psiElement instanceof PsiLocalVariable || psiElement instanceof PsiParameter) + && !PsiTreeUtil.isAncestor(myInitializer, psiElement, false)) { myElementReference = expression; } else { @@ -288,16 +312,17 @@ public void visitReferenceExpression(PsiReferenceExpression expression) { } @Override - public void visitCallExpression(PsiCallExpression callExpression) { + public void visitCallExpression(@Nonnull PsiCallExpression callExpression) { super.visitCallExpression(callExpression); - List checkedExceptions = ExceptionUtil.getThrownCheckedExceptions(new PsiElement[]{callExpression}); + List checkedExceptions = ExceptionUtil.getThrownCheckedExceptions(callExpression); if (!checkedExceptions.isEmpty()) { myElementReference = callExpression; } } + @Override protected void visitClassMemberReferenceElement(PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference) { - if (!classMember.hasModifierProperty(PsiModifier.STATIC)) { + if (!classMember.isStatic()) { myElementReference = classMemberReference; } } @@ -316,12 +341,13 @@ public PsiElement getElementReference() { } } + @Override public PsiClass getParentClass(@Nonnull PsiExpression initializerExpression) { PsiType type = initializerExpression.getType(); if (type != null && PsiUtil.isConstantExpression(initializerExpression)) { - if (type instanceof PsiPrimitiveType || - PsiType.getJavaLangString(initializerExpression.getManager(), initializerExpression.getResolveScope()).equals(type)) { + if (type instanceof PsiPrimitiveType + || PsiType.getJavaLangString(initializerExpression.getManager(), initializerExpression.getResolveScope()).equals(type)) { return super.getParentClass(initializerExpression); } } @@ -332,7 +358,7 @@ public PsiClass getParentClass(@Nonnull PsiExpression initializerExpression) { } PsiClass aClass = PsiTreeUtil.getParentOfType(parent, PsiClass.class); while (aClass != null) { - if (aClass.hasModifierProperty(PsiModifier.STATIC)) { + if (aClass.isStatic()) { return aClass; } if (aClass.getParent() instanceof PsiJavaFile) { @@ -354,8 +380,8 @@ protected boolean accept(ElementToWorkOn elementToWorkOn) { return initializer != null && isStaticFinalInitializer(initializer) == null; } + @Override protected boolean validClass(PsiClass parentClass, Editor editor) { return true; } - } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/introduceField/IntroduceFieldHandler.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/introduceField/IntroduceFieldHandler.java index b99d92366..24dbed98c 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/introduceField/IntroduceFieldHandler.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/introduceField/IntroduceFieldHandler.java @@ -222,7 +222,7 @@ protected OccurrenceManager createOccurrenceManager(PsiExpression selectedExpr, @Override @RequiredUIAccess - protected boolean invokeImpl(final Project project, PsiLocalVariable localVariable, final Editor editor) { + protected boolean invokeImpl(@Nonnull Project project, PsiLocalVariable localVariable, final Editor editor) { PsiElement parent = localVariable.getParent(); if (!(parent instanceof PsiDeclarationStatement)) { LocalizeValue message = diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/introduceVariable/IntroduceVariableBase.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/introduceVariable/IntroduceVariableBase.java index c5d41a233..e4b9e187f 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/introduceVariable/IntroduceVariableBase.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/introduceVariable/IntroduceVariableBase.java @@ -38,7 +38,8 @@ import com.intellij.java.language.psi.util.PsiExpressionTrimRenderer; import com.intellij.java.language.psi.util.PsiUtil; import com.intellij.java.language.psi.util.TypeConversionUtil; -import consulo.application.ApplicationManager; +import consulo.annotation.access.RequiredReadAction; +import consulo.annotation.access.RequiredWriteAction; import consulo.application.ApplicationPropertiesComponent; import consulo.codeEditor.*; import consulo.dataContext.DataContext; @@ -69,15 +70,15 @@ import consulo.localize.LocalizeValue; import consulo.logging.Logger; import consulo.project.Project; +import consulo.ui.annotation.RequiredUIAccess; import consulo.undoRedo.CommandProcessor; import consulo.util.collection.ArrayUtil; import consulo.util.collection.MultiMap; import consulo.util.dataholder.Key; import consulo.util.lang.StringUtil; -import consulo.util.lang.ref.Ref; +import consulo.util.lang.ref.SimpleReference; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; -import org.jetbrains.annotations.NonNls; import java.util.*; import java.util.function.Consumer; @@ -88,7 +89,6 @@ */ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { private static final Logger LOG = Logger.getInstance(IntroduceVariableBase.class); - @NonNls private static final String PREFER_STATEMENTS_OPTION = "introduce.variable.prefer.statements"; protected static final LocalizeValue REFACTORING_NAME = RefactoringLocalize.introduceVariableTitle(); @@ -98,11 +98,7 @@ public static SuggestedNameInfo getSuggestedName(@Nullable PsiType type, @Nonnul return getSuggestedName(type, expression, expression); } - public static SuggestedNameInfo getSuggestedName( - @Nullable PsiType type, - @Nonnull PsiExpression expression, - PsiElement anchor - ) { + public static SuggestedNameInfo getSuggestedName(@Nullable PsiType type, @Nonnull PsiExpression expression, PsiElement anchor) { JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(expression.getProject()); SuggestedNameInfo nameInfo = codeStyleManager.suggestVariableName(VariableKind.LOCAL_VARIABLE, null, expression, type); String[] strings = @@ -111,7 +107,9 @@ public static SuggestedNameInfo getSuggestedName( return codeStyleManager.suggestUniqueVariableName(delegate, anchor, true); } - public void invoke(@Nonnull final Project project, final Editor editor, final PsiFile file, DataContext dataContext) { + @Override + @RequiredUIAccess + public void invoke(@Nonnull Project project, Editor editor, PsiFile file, DataContext dataContext) { SelectionModel selectionModel = editor.getSelectionModel(); if (!selectionModel.hasSelection()) { int offset = editor.getCaretModel().getOffset(); @@ -123,9 +121,8 @@ public void invoke(@Nonnull final Project project, final Editor editor, final Ps statementsInRange[0].getTextRange().getEndOffset() < offset || isPreferStatements())) { selectionModel.selectLineAtCaret(); - PsiExpression expressionInRange = findExpressionInRange(project, file, selectionModel.getSelectionStart(), - selectionModel.getSelectionEnd() - ); + PsiExpression expressionInRange = + findExpressionInRange(project, file, selectionModel.getSelectionStart(), selectionModel.getSelectionEnd()); if (expressionInRange == null || getErrorMessage(expressionInRange) != null) { selectionModel.removeSelection(); } @@ -142,45 +139,39 @@ else if (expressions.size() == 1) { } else { int selection; - if (statementsInRange.length == 1 && - statementsInRange[0] instanceof PsiExpressionStatement && - PsiUtilCore.hasErrorElementChild(statementsInRange[0])) { - selection = expressions.indexOf(((PsiExpressionStatement) statementsInRange[0]).getExpression()); + if (statementsInRange.length == 1 + && statementsInRange[0] instanceof PsiExpressionStatement exprStmt + && PsiUtilCore.hasErrorElementChild(exprStmt)) { + selection = expressions.indexOf(exprStmt.getExpression()); + } + else if (expressions.get(0) instanceof PsiReferenceExpression refExpr + && refExpr.resolve() instanceof PsiLocalVariable) { + selection = 1; } else { - PsiExpression expression = expressions.get(0); - if (expression instanceof PsiReferenceExpression && ((PsiReferenceExpression) expression).resolve() instanceof - PsiLocalVariable) { - selection = 1; - } - else { - selection = -1; - } + selection = -1; } - IntroduceTargetChooser.showChooser(editor, expressions, new Consumer() { - public void accept(PsiExpression selectedValue) { - invoke( - project, - editor, - file, - selectedValue.getTextRange().getStartOffset(), - selectedValue.getTextRange().getEndOffset - () - ); - } - }, new PsiExpressionTrimRenderer.RenderFunction(), "Expressions", selection, ScopeHighlighter.NATURAL_RANGER); + IntroduceTargetChooser.showChooser( + editor, + expressions, + selectedValue -> invoke( + project, + editor, + file, + selectedValue.getTextRange().getStartOffset(), + selectedValue.getTextRange().getEndOffset() + ), + new PsiExpressionTrimRenderer.RenderFunction(), + "Expressions", + selection, + ScopeHighlighter.NATURAL_RANGER + ); return; } } } - if (invoke( - project, - editor, - file, - selectionModel.getSelectionStart(), - selectionModel.getSelectionEnd() - ) && LookupManager.getActiveLookup - (editor) == null) { + if (invoke(project, editor, file, selectionModel.getSelectionStart(), selectionModel.getSelectionEnd()) + && LookupManager.getActiveLookup(editor) == null) { selectionModel.removeSelection(); } } @@ -189,20 +180,18 @@ public static boolean isPreferStatements() { return ApplicationPropertiesComponent.getInstance().getBoolean(PREFER_STATEMENTS_OPTION, false); } + @RequiredReadAction public static List collectExpressions(PsiFile file, Editor editor, int offset) { return collectExpressions(file, editor, offset, false); } + @RequiredReadAction public static List collectExpressions(PsiFile file, Editor editor, int offset, boolean acceptVoid) { return collectExpressions(file, editor.getDocument(), offset, acceptVoid); } - public static List collectExpressions( - PsiFile file, - Document document, - int offset, - boolean acceptVoid - ) { + @RequiredReadAction + public static List collectExpressions(PsiFile file, Document document, int offset, boolean acceptVoid) { CharSequence text = document.getCharsSequence(); int correctedOffset = offset; int textLength = document.getTextLength(); @@ -224,35 +213,37 @@ else if (!Character.isJavaIdentifierPart(text.charAt(correctedOffset))) { } } PsiElement elementAtCaret = file.findElementAt(correctedOffset); - List expressions = new ArrayList(); - /*for (PsiElement element : statementsInRange) { - if (element instanceof PsiExpressionStatement) { - final PsiExpression expression = ((PsiExpressionStatement)element).getExpression(); - if (expression.getType() != PsiType.VOID) { - expressions.add(expression); - } - } - }*/ + List expressions = new ArrayList<>(); + /* + for (PsiElement element : statementsInRange) { + if (element instanceof PsiExpressionStatement) { + final PsiExpression expression = ((PsiExpressionStatement)element).getExpression(); + if (expression.getType() != PsiType.VOID) { + expressions.add(expression); + } + } + }*/ PsiExpression expression = PsiTreeUtil.getParentOfType(elementAtCaret, PsiExpression.class); while (expression != null) { - if (!expressions.contains(expression) && !(expression instanceof PsiParenthesizedExpression) && !(expression instanceof - PsiSuperExpression) && - (acceptVoid || !PsiType.VOID.equals(expression.getType()))) { + if (!expressions.contains(expression) + && !(expression instanceof PsiParenthesizedExpression) + && !(expression instanceof PsiSuperExpression) + && (acceptVoid || !PsiType.VOID.equals(expression.getType()))) { if (expression instanceof PsiMethodReferenceExpression) { expressions.add(expression); } else if (!(expression instanceof PsiAssignmentExpression)) { - if (!(expression instanceof PsiReferenceExpression)) { - expressions.add(expression); - } - else { - if (!(expression.getParent() instanceof PsiMethodCallExpression)) { - PsiElement resolve = ((PsiReferenceExpression) expression).resolve(); + if (expression instanceof PsiReferenceExpression refExpr) { + if (!(expression.getParent() instanceof PsiMethodCallExpression call)) { + PsiElement resolve = refExpr.resolve(); if (!(resolve instanceof PsiClass) && !(resolve instanceof PsiPackage)) { expressions.add(expression); } } } + else { + expressions.add(expression); + } } } expression = PsiTreeUtil.getParentOfType(expression, PsiExpression.class); @@ -269,24 +260,25 @@ public static PsiElement[] findStatementsAtOffset(Editor editor, PsiFile file, i return CodeInsightUtil.findStatementsInRange(file, lineStart, lineEnd); } + @RequiredUIAccess private boolean invoke(Project project, Editor editor, PsiFile file, int startOffset, int endOffset) { FeatureUsageTracker.getInstance().triggerFeatureUsed(ProductivityFeatureNames.REFACTORING_INTRODUCE_VARIABLE); PsiDocumentManager.getInstance(project).commitAllDocuments(); - return invokeImpl(project, findExpressionInRange(project, file, startOffset, endOffset), editor); } + @RequiredReadAction private static PsiExpression findExpressionInRange(Project project, PsiFile file, int startOffset, int endOffset) { PsiExpression tempExpr = CodeInsightUtil.findExpressionInRange(file, startOffset, endOffset); if (tempExpr == null) { PsiElement[] statements = CodeInsightUtil.findStatementsInRange(file, startOffset, endOffset); if (statements.length == 1) { - if (statements[0] instanceof PsiExpressionStatement) { - tempExpr = ((PsiExpressionStatement) statements[0]).getExpression(); + if (statements[0] instanceof PsiExpressionStatement exprStmt) { + tempExpr = exprStmt.getExpression(); } - else if (statements[0] instanceof PsiReturnStatement) { - tempExpr = ((PsiReturnStatement) statements[0]).getReturnValue(); + else if (statements[0] instanceof PsiReturnStatement returnStmt) { + tempExpr = returnStmt.getReturnValue(); } } } @@ -300,6 +292,7 @@ else if (statements[0] instanceof PsiReturnStatement) { /** * @return can return NotNull value although extraction will fail: reason could be retrieved from {@link #getErrorMessage(PsiExpression)} */ + @RequiredReadAction public static PsiExpression getSelectedExpression(Project project, PsiFile file, int startOffset, int endOffset) { InjectedLanguageManager injectedLanguageManager = InjectedLanguageManager.getInstance(project); PsiElement elementAtStart = file.findElementAt(startOffset); @@ -429,18 +422,17 @@ public void visitErrorElement(PsiErrorElement element) { tempExpr.putUserData(ElementToWorkOn.PREFIX, prefix); tempExpr.putUserData(ElementToWorkOn.SUFFIX, suffix); - RangeMarker rangeMarker = FileDocumentManager.getInstance().getDocument(file.getVirtualFile()).createRangeMarker( - startOffset, - endOffset - ); + RangeMarker rangeMarker = FileDocumentManager.getInstance().getDocument(file.getVirtualFile()) + .createRangeMarker(startOffset, endOffset); tempExpr.putUserData(ElementToWorkOn.TEXT_RANGE, rangeMarker); if (parent != null) { tempExpr.putUserData(ElementToWorkOn.PARENT, parent); } else { - PsiErrorElement errorElement = elementAtStart instanceof PsiErrorElement ? (PsiErrorElement) elementAtStart : PsiTreeUtil - .getNextSiblingOfType(elementAtStart, PsiErrorElement.class); + PsiErrorElement errorElement = elementAtStart instanceof PsiErrorElement errorElem + ? errorElem + : PsiTreeUtil.getNextSiblingOfType(elementAtStart, PsiErrorElement.class); if (errorElement == null) { errorElement = PsiTreeUtil.getParentOfType(elementAtStart, PsiErrorElement.class); } @@ -484,24 +476,26 @@ public void visitErrorElement(PsiErrorElement element) { } } catch (IncorrectOperationException e) { - if (elementAt instanceof PsiExpressionList) { - PsiElement parent = elementAt.getParent(); - return parent instanceof PsiCallExpression ? createArrayCreationExpression(text, startOffset, endOffset, - (PsiCallExpression) parent - ) : null; - } - return null; + return elementAt instanceof PsiExpressionList exprList && exprList.getParent() instanceof PsiCallExpression call + ? createArrayCreationExpression(text, startOffset, endOffset, call) : null; } return tempExpr; } + @RequiredReadAction private static PsiExpression getSelectionFromInjectedHost( - Project project, PsiFile file, InjectedLanguageManager injectedLanguageManager, - int startOffset, int endOffset + Project project, + PsiFile file, + InjectedLanguageManager injectedLanguageManager, + int startOffset, + int endOffset ) { PsiLanguageInjectionHost injectionHost = injectedLanguageManager.getInjectionHost(file); - return getSelectedExpression(project, injectionHost.getContainingFile(), injectedLanguageManager.injectedToHost(file, startOffset), + return getSelectedExpression( + project, + injectionHost.getContainingFile(), + injectedLanguageManager.injectedToHost(file, startOffset), injectedLanguageManager.injectedToHost(file, endOffset) ); } @@ -509,12 +503,13 @@ private static PsiExpression getSelectionFromInjectedHost( @Nullable public static String getErrorMessage(PsiExpression expr) { Boolean needParenthesis = expr.getCopyableUserData(NEED_PARENTHESIS); - if (needParenthesis != null && needParenthesis.booleanValue()) { + if (needParenthesis != null && needParenthesis) { return "Extracting selected expression would change the semantic of the whole expression."; } return null; } + @RequiredReadAction private static PsiExpression createArrayCreationExpression(String text, int startOffset, int endOffset, PsiCallExpression parent) { if (text == null || parent == null) { return null; @@ -559,12 +554,12 @@ private static PsiExpression createArrayCreationExpression(String text, int star PsiType componentType = TypeConversionUtil.erasure(psiSubstitutor.substitute(psiType.getComponentType())); try { - PsiExpression expressionFromText = - elementFactory.createExpressionFromText("new " + componentType.getCanonicalText() + "[]{" + - text + "}", parent); - RangeMarker rangeMarker = - FileDocumentManager.getInstance().getDocument(containingFile.getVirtualFile()).createRangeMarker - (startOffset, endOffset); + PsiExpression expressionFromText = elementFactory.createExpressionFromText( + "new " + componentType.getCanonicalText() + "[]{" + text + "}", + parent + ); + RangeMarker rangeMarker = FileDocumentManager.getInstance().getDocument(containingFile.getVirtualFile()) + .createRangeMarker(startOffset, endOffset); expressionFromText.putUserData(ElementToWorkOn.TEXT_RANGE, rangeMarker); expressionFromText.putUserData(ElementToWorkOn.PARENT, parent); return expressionFromText; @@ -576,7 +571,9 @@ private static PsiExpression createArrayCreationExpression(String text, int star return null; } - protected boolean invokeImpl(@Nonnull Project project, final PsiExpression expr, final Editor editor) { + @Override + @RequiredUIAccess + protected boolean invokeImpl(@Nonnull Project project, PsiExpression expr, Editor editor) { if (expr != null) { String errorMessage = getErrorMessage(expr); if (errorMessage != null) { @@ -604,7 +601,6 @@ protected boolean invokeImpl(@Nonnull Project project, final PsiExpression expr, } } - PsiType originalType = RefactoringUtil.getTypeByExpressionWithExpectedType(expr); if (originalType == null || LambdaUtil.notInferredType(originalType)) { LocalizeValue message = RefactoringLocalize.cannotPerformRefactoringWithReason(RefactoringLocalize.unknownExpressionType()); @@ -619,22 +615,22 @@ protected boolean invokeImpl(@Nonnull Project project, final PsiExpression expr, return false; } - PsiElement physicalElement = expr.getUserData(ElementToWorkOn.PARENT); - final PsiElement anchorStatement = RefactoringUtil.getParentStatement(physicalElement != null ? physicalElement : expr, false); + PsiElement anchorStatement = RefactoringUtil.getParentStatement(physicalElement != null ? physicalElement : expr, false); if (anchorStatement == null) { return parentStatementNotFound(project, editor); } - if (checkAnchorBeforeThisOrSuper(project, editor, anchorStatement, REFACTORING_NAME.get(), HelpID.INTRODUCE_VARIABLE)) { + if (checkAnchorBeforeThisOrSuper(project, editor, anchorStatement, REFACTORING_NAME, HelpID.INTRODUCE_VARIABLE)) { return false; } PsiElement tempContainer = anchorStatement.getParent(); - if (!(tempContainer instanceof PsiCodeBlock) && !RefactoringUtil.isLoopOrIf(tempContainer) && (tempContainer.getParent() instanceof - PsiLambdaExpression)) { + if (!(tempContainer instanceof PsiCodeBlock) + && !RefactoringUtil.isLoopOrIf(tempContainer) + && (tempContainer.getParent() instanceof PsiLambdaExpression)) { LocalizeValue message = RefactoringLocalize.refactoringIsNotSupportedInTheCurrentContext(REFACTORING_NAME); showErrorMessage(project, editor, message); return false; @@ -651,11 +647,10 @@ protected boolean invokeImpl(@Nonnull Project project, final PsiExpression expr, LOG.assertTrue(file != null, "expr.getContainingFile() == null"); PsiElement nameSuggestionContext = editor == null ? null : file.findElementAt(editor.getCaretModel().getOffset()); RefactoringSupportProvider supportProvider = RefactoringSupportProvider.forLanguage(expr.getLanguage()); - final boolean isInplaceAvailableOnDataContext = supportProvider != null && - editor.getSettings().isVariableInplaceRenameEnabled() && - supportProvider.isInplaceIntroduceAvailable(expr, nameSuggestionContext) && - (!ApplicationManager.getApplication().isUnitTestMode() || isInplaceAvailableInTestMode()) && - !isInJspHolderMethod(expr); + boolean isInplaceAvailableOnDataContext = editor.getSettings().isVariableInplaceRenameEnabled() + && supportProvider.isInplaceIntroduceAvailable(expr, nameSuggestionContext) + && (!project.getApplication().isUnitTestMode() || isInplaceAvailableInTestMode()) + && !isInJspHolderMethod(expr); if (isInplaceAvailableOnDataContext) { MultiMap conflicts = new MultiMap<>(); @@ -667,11 +662,10 @@ protected boolean invokeImpl(@Nonnull Project project, final PsiExpression expr, } ExpressionOccurrenceManager occurrenceManager = createOccurrenceManager(expr, tempContainer); - final PsiExpression[] occurrences = occurrenceManager.getOccurrences(); - final PsiElement anchorStatementIfAll = occurrenceManager.getAnchorStatementForAll(); - + PsiExpression[] occurrences = occurrenceManager.getOccurrences(); + PsiElement anchorStatementIfAll = occurrenceManager.getAnchorStatementForAll(); - final List nonWrite = new ArrayList(); + List nonWrite = new ArrayList<>(); boolean cantReplaceAll = false; boolean cantReplaceAllButWrite = false; for (PsiExpression occurrence : occurrences) { @@ -690,9 +684,9 @@ else if (!nonWrite.isEmpty()) { return false; } - LinkedHashMap> occurrencesMap = new LinkedHashMap<>(); + Map> occurrencesMap = new LinkedHashMap<>(); occurrencesMap.put(OccurrencesChooser.ReplaceChoice.NO, Collections.singletonList(expr)); - final boolean hasWriteAccess = occurrences.length > nonWrite.size() && occurrences.length > 1; + boolean hasWriteAccess = occurrences.length > nonWrite.size() && occurrences.length > 1; if (hasWriteAccess && !cantReplaceAllButWrite) { occurrencesMap.put(OccurrencesChooser.ReplaceChoice.NO_WRITE, nonWrite); } @@ -701,91 +695,112 @@ else if (!nonWrite.isEmpty()) { occurrencesMap.put(OccurrencesChooser.ReplaceChoice.ALL, Arrays.asList(occurrences)); } - final boolean inFinalContext = occurrenceManager.isInFinalContext(); - final InputValidator validator = new InputValidator(this, project, anchorStatementIfAll, anchorStatement, occurrenceManager); - final TypeSelectorManagerImpl typeSelectorManager = new TypeSelectorManagerImpl(project, originalType, expr, occurrences); - final boolean[] wasSucceed = new boolean[]{true}; - Consumer callback = new Consumer() { - @Override - public void accept(OccurrencesChooser.ReplaceChoice choice) { - boolean allOccurences = - choice == OccurrencesChooser.ReplaceChoice.ALL || choice == OccurrencesChooser.ReplaceChoice.NO_WRITE; - Ref> variable = new Ref>(); - - Editor topLevelEditor; - if (!InjectedLanguageManager.getInstance(project).isInjectedFragment(anchorStatement.getContainingFile())) { - topLevelEditor = EditorWindow.getTopLevelEditor(editor); - } - else { - topLevelEditor = editor; - } + boolean inFinalContext = occurrenceManager.isInFinalContext(); + InputValidator validator = new InputValidator(this, project, anchorStatementIfAll, anchorStatement, occurrenceManager); + TypeSelectorManagerImpl typeSelectorManager = new TypeSelectorManagerImpl(project, originalType, expr, occurrences); + boolean[] wasSucceed = new boolean[]{true}; + @RequiredWriteAction + Consumer callback = choice -> { + boolean allOccurrences = + choice == OccurrencesChooser.ReplaceChoice.ALL || choice == OccurrencesChooser.ReplaceChoice.NO_WRITE; + SimpleReference> variable = new SimpleReference<>(); - IntroduceVariableSettings settings; - PsiElement chosenAnchor; - if (choice != null) { - chosenAnchor = - chooseAnchor(allOccurences, choice == OccurrencesChooser.ReplaceChoice.NO_WRITE, nonWrite, anchorStatementIfAll, - anchorStatement - ); - settings = getSettings(project, topLevelEditor, expr, occurrences, typeSelectorManager, inFinalContext, hasWriteAccess, - validator, chosenAnchor, choice - ); - } - else { - settings = getSettings(project, topLevelEditor, expr, occurrences, typeSelectorManager, inFinalContext, hasWriteAccess, - validator, anchorStatement, choice - ); - chosenAnchor = - chooseAnchor(settings.isReplaceAllOccurrences(), hasWriteAccess, nonWrite, anchorStatementIfAll, anchorStatement); - } - if (!settings.isOK()) { - wasSucceed[0] = false; - return; - } - typeSelectorManager.setAllOccurrences(allOccurences); - TypeExpression expression = new TypeExpression(project, allOccurences ? typeSelectorManager.getTypesForAll() : - typeSelectorManager.getTypesForOne()); - RangeMarker exprMarker = topLevelEditor.getDocument().createRangeMarker(expr.getTextRange()); - SuggestedNameInfo suggestedName = getSuggestedName(settings.getSelectedType(), expr, chosenAnchor); - List occurrenceMarkers = new ArrayList(); - boolean noWrite = choice == OccurrencesChooser.ReplaceChoice.NO_WRITE; - for (PsiExpression occurrence : occurrences) { - if (allOccurences || (noWrite && !PsiUtil.isAccessedForWriting(occurrence))) { - occurrenceMarkers.add(topLevelEditor.getDocument().createRangeMarker(occurrence.getTextRange())); - } + Editor topLevelEditor; + if (!InjectedLanguageManager.getInstance(project).isInjectedFragment(anchorStatement.getContainingFile())) { + topLevelEditor = EditorWindow.getTopLevelEditor(editor); + } + else { + topLevelEditor = editor; + } + + IntroduceVariableSettings settings; + PsiElement chosenAnchor; + if (choice != null) { + chosenAnchor = chooseAnchor( + allOccurrences, + choice == OccurrencesChooser.ReplaceChoice.NO_WRITE, + nonWrite, + anchorStatementIfAll, + anchorStatement + ); + settings = getSettings( + project, + topLevelEditor, + expr, + occurrences, + typeSelectorManager, + inFinalContext, + hasWriteAccess, + validator, + chosenAnchor, + choice + ); + } + else { + settings = getSettings( + project, + topLevelEditor, + expr, + occurrences, + typeSelectorManager, + inFinalContext, + hasWriteAccess, + validator, + anchorStatement, + choice + ); + chosenAnchor = + chooseAnchor(settings.isReplaceAllOccurrences(), hasWriteAccess, nonWrite, anchorStatementIfAll, anchorStatement); + } + if (!settings.isOK()) { + wasSucceed[0] = false; + return; + } + typeSelectorManager.setAllOccurrences(allOccurrences); + TypeExpression expression = new TypeExpression( + project, + allOccurrences ? typeSelectorManager.getTypesForAll() : typeSelectorManager.getTypesForOne() + ); + RangeMarker exprMarker = topLevelEditor.getDocument().createRangeMarker(expr.getTextRange()); + SuggestedNameInfo suggestedName = getSuggestedName(settings.getSelectedType(), expr, chosenAnchor); + List occurrenceMarkers = new ArrayList<>(); + boolean noWrite = choice == OccurrencesChooser.ReplaceChoice.NO_WRITE; + for (PsiExpression occurrence : occurrences) { + if (allOccurrences || (noWrite && !PsiUtil.isAccessedForWriting(occurrence))) { + occurrenceMarkers.add(topLevelEditor.getDocument().createRangeMarker(occurrence.getTextRange())); } - String expressionText = expr.getText(); - Runnable runnable = introduce(project, expr, topLevelEditor, chosenAnchor, occurrences, settings, variable); - CommandProcessor.getInstance().newCommand() - .project(project) - .name(REFACTORING_NAME) - .run(() -> { - project.getApplication().runWriteAction(runnable); - if (isInplaceAvailableOnDataContext) { - PsiVariable elementToRename = variable.get().getElement(); - if (elementToRename != null) { - topLevelEditor.getCaretModel().moveToOffset(elementToRename.getTextOffset()); - boolean cantChangeFinalModifier = (hasWriteAccess || inFinalContext) - && choice == OccurrencesChooser.ReplaceChoice.ALL; - JavaVariableInplaceIntroducer renamer = new JavaVariableInplaceIntroducer( - project, - expression, - topLevelEditor, - elementToRename, - cantChangeFinalModifier, - typeSelectorManager.getTypesForAll().length > 1, - exprMarker, - occurrenceMarkers, - REFACTORING_NAME.get() - ); - renamer.initInitialText(expressionText); - PsiDocumentManager.getInstance(project) - .doPostponedOperationsAndUnblockDocument(topLevelEditor.getDocument()); - renamer.performInplaceRefactoring(new LinkedHashSet<>(Arrays.asList(suggestedName.names))); - } - } - }); } + String expressionText = expr.getText(); + Runnable runnable = introduce(project, expr, topLevelEditor, chosenAnchor, occurrences, settings, variable); + CommandProcessor.getInstance().newCommand() + .project(project) + .name(REFACTORING_NAME) + .run(() -> { + project.getApplication().runWriteAction(runnable); + if (isInplaceAvailableOnDataContext) { + PsiVariable elementToRename = variable.get().getElement(); + if (elementToRename != null) { + topLevelEditor.getCaretModel().moveToOffset(elementToRename.getTextOffset()); + boolean cantChangeFinalModifier = (hasWriteAccess || inFinalContext) + && choice == OccurrencesChooser.ReplaceChoice.ALL; + JavaVariableInplaceIntroducer renamer = new JavaVariableInplaceIntroducer( + project, + expression, + topLevelEditor, + elementToRename, + cantChangeFinalModifier, + typeSelectorManager.getTypesForAll().length > 1, + exprMarker, + occurrenceMarkers, + REFACTORING_NAME.get() + ); + renamer.initInitialText(expressionText); + PsiDocumentManager.getInstance(project) + .doPostponedOperationsAndUnblockDocument(topLevelEditor.getDocument()); + renamer.performInplaceRefactoring(new LinkedHashSet<>(Arrays.asList(suggestedName.names))); + } + } + }); }; if (!isInplaceAvailableOnDataContext) { @@ -798,19 +813,20 @@ public void accept(OccurrencesChooser.ReplaceChoice choice) { } protected PsiElement chooseAnchor( - boolean allOccurences, boolean hasWriteAccess, List nonWrite, PsiElement anchorStatementIfAll, + boolean allOccurrences, + boolean hasWriteAccess, + List nonWrite, + PsiElement anchorStatementIfAll, PsiElement anchorStatement ) { - if (allOccurences) { - if (hasWriteAccess) { - return RefactoringUtil.getAnchorElementForMultipleExpressions(nonWrite.toArray(new PsiExpression[nonWrite.size()]), null); - } - else { - return anchorStatementIfAll; - } + if (!allOccurrences) { + return anchorStatement; + } + else if (hasWriteAccess) { + return RefactoringUtil.getAnchorElementForMultipleExpressions(nonWrite.toArray(new PsiExpression[nonWrite.size()]), null); } else { - return anchorStatement; + return anchorStatementIfAll; } } @@ -864,16 +880,22 @@ private static boolean isInJspHolderMethod(PsiExpression expr) { } /*final PsiElement parent2 = parent1.getParent(); if(!(parent2 instanceof JspCodeBlock)) - { - return false; - } */ + { + return false; + } */ /*final PsiElement parent3 = parent2.getParent(); return parent3 instanceof JspHolderMethod; */ } + @RequiredWriteAction private static Runnable introduce( - final Project project, final PsiExpression expr, final Editor editor, final PsiElement anchorStatement, - final PsiExpression[] occurrences, final IntroduceVariableSettings settings, final Ref> variable + final Project project, + final PsiExpression expr, + final Editor editor, + final PsiElement anchorStatement, + final PsiExpression[] occurrences, + final IntroduceVariableSettings settings, + final SimpleReference> variable ) { final PsiElement container = anchorStatement.getParent(); PsiElement child = anchorStatement; @@ -888,12 +910,11 @@ private static Runnable introduce( boolean tempDeleteSelf = false; final boolean replaceSelf = settings.isReplaceLValues() || !RefactoringUtil.isAssignmentLHS(expr); if (!RefactoringUtil.isLoopOrIf(container)) { - if (expr.getParent() instanceof PsiExpressionStatement && anchor.equals(anchorStatement)) { - PsiStatement statement = (PsiStatement) expr.getParent(); + if (expr.getParent() instanceof PsiExpressionStatement statement && anchor.equals(anchorStatement)) { PsiElement parent = statement.getParent(); - if (parent instanceof PsiCodeBlock || + if (parent instanceof PsiCodeBlock //fabrique - parent instanceof PsiCodeFragment) { + || parent instanceof PsiCodeFragment) { tempDeleteSelf = true; } } @@ -914,6 +935,8 @@ private static Runnable introduce( PsiCodeBlock newDeclarationScope = PsiTreeUtil.getParentOfType(container, PsiCodeBlock.class, false); final FieldConflictsResolver fieldConflictsResolver = new FieldConflictsResolver(settings.getEnteredName(), newDeclarationScope); return new Runnable() { + @Override + @RequiredWriteAction public void run() { try { PsiStatement statement = null; @@ -924,26 +947,24 @@ public void run() { PsiExpression expr1 = fieldConflictsResolver.fixInitializer(expr); PsiExpression initializer = RefactoringUtil.unparenthesizeExpression(expr1); - SmartTypePointer selectedType = SmartTypePointerManager.getInstance(project).createSmartTypePointer(settings - .getSelectedType()); - if (expr1 instanceof PsiNewExpression) { - PsiNewExpression newExpression = (PsiNewExpression) expr1; + SmartTypePointer selectedType = SmartTypePointerManager.getInstance(project) + .createSmartTypePointer(settings.getSelectedType()); + if (expr1 instanceof PsiNewExpression newExpression) { if (newExpression.getArrayInitializer() != null) { initializer = newExpression.getArrayInitializer(); } initializer = replaceExplicitWithDiamondWhenApplicable(initializer, selectedType.getType()); } - PsiDeclarationStatement declaration = - JavaPsiFacade.getInstance(project).getElementFactory().createVariableDeclarationStatement - (settings.getEnteredName(), selectedType.getType(), initializer); + PsiDeclarationStatement declaration = JavaPsiFacade.getInstance(project).getElementFactory() + .createVariableDeclarationStatement(settings.getEnteredName(), selectedType.getType(), initializer); if (!isInsideLoop) { declaration = addDeclaration(declaration, initializer); LOG.assertTrue(expr1.isValid()); if (deleteSelf) { // never true - PsiElement lastChild = statement.getLastChild(); - if (lastChild instanceof PsiComment) { // keep trailing comment - declaration.addBefore(lastChild, null); + // keep trailing comment + if (statement.getLastChild() instanceof PsiComment comment) { + declaration.addBefore(comment, null); } statement.delete(); if (editor != null) { @@ -961,7 +982,7 @@ public void run() { null ); if (settings.isReplaceAllOccurrences()) { - ArrayList array = new ArrayList(); + List array = new ArrayList<>(); for (PsiExpression occurrence : occurrences) { if (deleteSelf && occurrence.equals(expr)) { continue; @@ -982,8 +1003,8 @@ public void run() { } if (editor != null) { - PsiElement[] replacedOccurences = PsiUtilCore.toPsiElementArray(array); - highlightReplacedOccurences(project, editor, replacedOccurences); + PsiElement[] replacedOccurrences = PsiUtilCore.toPsiElementArray(array); + highlightReplacedOccurences(project, editor, replacedOccurrences); } } else { @@ -1004,13 +1025,15 @@ public void run() { } } + @RequiredWriteAction private PsiDeclarationStatement addDeclaration(PsiDeclarationStatement declaration, PsiExpression initializer) { - if (anchor instanceof PsiDeclarationStatement) { - final PsiElement[] declaredElements = ((PsiDeclarationStatement) anchor).getDeclaredElements(); + if (anchor instanceof PsiDeclarationStatement anchorDecl) { + final PsiElement[] declaredElements = anchorDecl.getDeclaredElements(); if (declaredElements.length > 1) { final int[] usedFirstVar = new int[]{-1}; initializer.accept(new JavaRecursiveElementWalkingVisitor() { @Override + @RequiredReadAction public void visitReferenceExpression(PsiReferenceExpression expression) { int i = ArrayUtil.find(declaredElements, expression.resolve()); if (i > -1) { @@ -1022,10 +1045,8 @@ public void visitReferenceExpression(PsiReferenceExpression expression) { if (usedFirstVar[0] > -1) { PsiVariable psiVariable = (PsiVariable) declaredElements[usedFirstVar[0]]; psiVariable.normalizeDeclaration(); - PsiDeclarationStatement parDeclarationStatement = PsiTreeUtil.getParentOfType( - psiVariable, - PsiDeclarationStatement.class - ); + PsiDeclarationStatement parDeclarationStatement = + PsiTreeUtil.getParentOfType(psiVariable, PsiDeclarationStatement.class); return (PsiDeclarationStatement) container.addAfter(declaration, parDeclarationStatement); } } @@ -1035,39 +1056,35 @@ public void visitReferenceExpression(PsiReferenceExpression expression) { }; } + @RequiredReadAction private static boolean isFinalVariableOnLHS(PsiExpression expr) { - if (expr instanceof PsiReferenceExpression && RefactoringUtil.isAssignmentLHS(expr)) { - PsiElement resolve = ((PsiReferenceExpression) expr).resolve(); - if (resolve instanceof PsiVariable && ((PsiVariable) resolve).hasModifierProperty(PsiModifier.FINAL)) { //should be inserted after assignment - return true; - } - } - return false; + //should be inserted after assignment + return expr instanceof PsiReferenceExpression refExpr + && RefactoringUtil.isAssignmentLHS(expr) + && refExpr.resolve() instanceof PsiVariable variable + && variable.hasModifierProperty(PsiModifier.FINAL); } public static PsiExpression replaceExplicitWithDiamondWhenApplicable(PsiExpression initializer, PsiType expectedType) { - if (initializer instanceof PsiNewExpression) { - PsiNewExpression newExpression = (PsiNewExpression) initializer; + if (initializer instanceof PsiNewExpression newExpression) { PsiExpression tryToDetectDiamondNewExpr = ((PsiVariable) JavaPsiFacade.getElementFactory(initializer.getProject()) .createVariableDeclarationStatement("x", expectedType, initializer).getDeclaredElements()[0]).getInitializer(); - if (tryToDetectDiamondNewExpr instanceof PsiNewExpression && PsiDiamondTypeUtil.canCollapseToDiamond((PsiNewExpression) - tryToDetectDiamondNewExpr, (PsiNewExpression) tryToDetectDiamondNewExpr, expectedType)) { - PsiElement paramList = PsiDiamondTypeUtil.replaceExplicitWithDiamond(newExpression.getClassOrAnonymousClassReference() - .getParameterList()); + if (tryToDetectDiamondNewExpr instanceof PsiNewExpression newExpr + && PsiDiamondTypeUtil.canCollapseToDiamond(newExpr, newExpr, expectedType)) { + PsiElement paramList = PsiDiamondTypeUtil.replaceExplicitWithDiamond( + newExpression.getClassOrAnonymousClassReference().getParameterList() + ); return PsiTreeUtil.getParentOfType(paramList, PsiNewExpression.class); } } return initializer; } - public static PsiElement replace( - PsiExpression expr1, - PsiExpression ref, - Project project - ) throws IncorrectOperationException { + @RequiredWriteAction + public static PsiElement replace(PsiExpression expr1, PsiExpression ref, Project project) throws IncorrectOperationException { PsiExpression expr2; - if (expr1 instanceof PsiArrayInitializerExpression && expr1.getParent() instanceof PsiNewExpression) { - expr2 = (PsiNewExpression) expr1.getParent(); + if (expr1 instanceof PsiArrayInitializerExpression arrayInit && arrayInit.getParent() instanceof PsiNewExpression arrayNew) { + expr2 = arrayNew; } else { expr2 = RefactoringUtil.outermostParenthesizedExpression(expr1); @@ -1086,9 +1103,15 @@ public static PsiElement replace( } } + @RequiredReadAction private static PsiExpression createReplacement( - String refText, Project project, String prefix, String suffix, - PsiElement parent, RangeMarker rangeMarker, int[] refIdx + String refText, + Project project, + String prefix, + String suffix, + PsiElement parent, + RangeMarker rangeMarker, + int[] refIdx ) { String text = refText; if (parent != null) { @@ -1117,23 +1140,27 @@ private static PsiExpression createReplacement( return JavaPsiFacade.getInstance(project).getElementFactory().createExpressionFromText(text, parent); } + @RequiredUIAccess private boolean parentStatementNotFound(Project project, Editor editor) { LocalizeValue message = RefactoringLocalize.refactoringIsNotSupportedInTheCurrentContext(REFACTORING_NAME); showErrorMessage(project, editor, message); return false; } - protected boolean invokeImpl(Project project, PsiLocalVariable localVariable, Editor editor) { + @Override + @RequiredUIAccess + protected boolean invokeImpl(@Nonnull Project project, PsiLocalVariable localVariable, Editor editor) { throw new UnsupportedOperationException(); } + @RequiredReadAction private static PsiElement locateAnchor(PsiElement child) { while (child != null) { PsiElement prev = child.getPrevSibling(); if (prev instanceof PsiStatement) { break; } - if (prev instanceof PsiJavaToken && ((PsiJavaToken) prev).getTokenType() == JavaTokenType.LBRACE) { + if (prev instanceof PsiJavaToken token && token.getTokenType() == JavaTokenType.LBRACE) { break; } child = prev; @@ -1145,18 +1172,20 @@ private static PsiElement locateAnchor(PsiElement child) { return child; } - protected static void highlightReplacedOccurences(Project project, Editor editor, PsiElement[] replacedOccurences) { + @RequiredReadAction + protected static void highlightReplacedOccurences(Project project, Editor editor, PsiElement[] replacedOccurrences) { if (editor == null) { return; } - if (ApplicationManager.getApplication().isUnitTestMode()) { + if (project.getApplication().isUnitTestMode()) { return; } HighlightManager highlightManager = HighlightManager.getInstance(project); - highlightManager.addOccurrenceHighlights(editor, replacedOccurences, EditorColors.SEARCH_RESULT_ATTRIBUTES, true, null); + highlightManager.addOccurrenceHighlights(editor, replacedOccurrences, EditorColors.SEARCH_RESULT_ATTRIBUTES, true, null); } - protected abstract void showErrorMessage(Project project, Editor editor, LocalizeValue message); + @RequiredUIAccess + protected abstract void showErrorMessage(Project project, Editor editor, @Nonnull LocalizeValue message); protected boolean reportConflicts(MultiMap conflicts, Project project, IntroduceVariableSettings settings) { return false; @@ -1175,8 +1204,7 @@ public IntroduceVariableSettings getSettings( OccurrencesChooser.ReplaceChoice replaceChoice ) { final boolean replaceAll = - replaceChoice == OccurrencesChooser.ReplaceChoice.ALL || replaceChoice == OccurrencesChooser.ReplaceChoice - .NO_WRITE; + replaceChoice == OccurrencesChooser.ReplaceChoice.ALL || replaceChoice == OccurrencesChooser.ReplaceChoice.NO_WRITE; SuggestedNameInfo suggestedName = getSuggestedName(typeSelectorManager.getDefaultType(), expr, anchor); final String variableName = suggestedName.names.length > 0 ? suggestedName.names[0] : ""; final boolean declareFinal = replaceAll && declareFinalIfAll || !anyAssignmentLHS && createFinals(project); @@ -1217,24 +1245,26 @@ public boolean isOK() { public static boolean createFinals(Project project) { Boolean createFinals = JavaRefactoringSettings.getInstance().INTRODUCE_LOCAL_CREATE_FINALS; - return createFinals == null ? CodeStyleSettingsManager.getSettings(project).GENERATE_FINAL_LOCALS : createFinals.booleanValue(); + return createFinals == null ? CodeStyleSettingsManager.getSettings(project).GENERATE_FINAL_LOCALS : createFinals; } + @RequiredUIAccess public static boolean checkAnchorBeforeThisOrSuper( - Project project, Editor editor, PsiElement tempAnchorElement, - String refactoringName, String helpID + Project project, + Editor editor, + PsiElement tempAnchorElement, + @Nonnull LocalizeValue refactoringName, + String helpID ) { - if (tempAnchorElement instanceof PsiExpressionStatement) { - PsiExpression enclosingExpr = ((PsiExpressionStatement) tempAnchorElement).getExpression(); - if (enclosingExpr instanceof PsiMethodCallExpression) { - PsiMethod method = ((PsiMethodCallExpression) enclosingExpr).resolveMethod(); - if (method != null && method.isConstructor()) { - //This is either 'this' or 'super', both must be the first in the respective contructor - LocalizeValue message = - RefactoringLocalize.cannotPerformRefactoringWithReason(RefactoringLocalize.invalidExpressionContext()); - CommonRefactoringUtil.showErrorHint(project, editor, message.get(), refactoringName, helpID); - return true; - } + if (tempAnchorElement instanceof PsiExpressionStatement exprStmt + && exprStmt.getExpression() instanceof PsiMethodCallExpression call) { + PsiMethod method = call.resolveMethod(); + if (method != null && method.isConstructor()) { + //This is either 'this' or 'super', both must be the first in the respective constructor + LocalizeValue message = + RefactoringLocalize.cannotPerformRefactoringWithReason(RefactoringLocalize.invalidExpressionContext()); + CommonRefactoringUtil.showErrorHint(project, editor, message, refactoringName, helpID); + return true; } } return false; @@ -1244,13 +1274,13 @@ public interface Validator { boolean isOK(IntroduceVariableSettings dialog); } - public static void checkInLoopCondition(PsiExpression occurence, MultiMap conflicts) { - PsiElement loopForLoopCondition = RefactoringUtil.getLoopForLoopCondition(occurence); + public static void checkInLoopCondition(PsiExpression occurrence, MultiMap conflicts) { + PsiElement loopForLoopCondition = RefactoringUtil.getLoopForLoopCondition(occurrence); if (loopForLoopCondition == null) { return; } - List referencedVariables = RefactoringUtil.collectReferencedVariables(occurence); - List modifiedInBody = new ArrayList(); + List referencedVariables = RefactoringUtil.collectReferencedVariables(occurrence); + List modifiedInBody = new ArrayList<>(); for (PsiVariable psiVariable : referencedVariables) { if (RefactoringUtil.isModifiedInScope(psiVariable, loopForLoopCondition)) { modifiedInBody.add(psiVariable); @@ -1262,7 +1292,7 @@ public static void checkInLoopCondition(PsiExpression occurence, MultiMap