From 59fb2ddf669ae862db7a2c6ee71aee10328c7140 Mon Sep 17 00:00:00 2001 From: UNV Date: Wed, 9 Apr 2025 13:26:09 +0300 Subject: [PATCH 1/2] Reformatting descendants of FixableUsagesRefactoringProcessor. --- .../CopyPasteReferenceProcessor.java | 320 +-- .../ChangeClassSignatureProcessor.java | 339 ++-- .../ChangeSignatureProcessor.java | 533 ++--- .../changeSignature/ChangeSignatureUtil.java | 155 +- .../JavaChangeSignatureUsageProcessor.java | 1803 +++++++++-------- .../extractclass/ExtractClassProcessor.java | 14 +- .../extractclass/ExtractEnumProcessor.java | 391 ++-- .../inline/InlineConstantFieldProcessor.java | 641 +++--- .../InlineParameterExpressionProcessor.java | 679 ++++--- .../InlineSuperClassRefactoringProcessor.java | 650 +++--- .../invertBoolean/InvertBooleanProcessor.java | 379 ++-- .../migration/MigrationProcessor.java | 341 ++-- .../MoveDirectoryWithClassesProcessor.java | 416 ++-- ...eplaceConstructorWithBuilderProcessor.java | 509 ++--- .../typeMigration/TypeMigrationProcessor.java | 455 +++-- .../FixableUsagesRefactoringProcessor.java | 63 +- .../WrapReturnValueProcessor.java | 1 - 17 files changed, 3966 insertions(+), 3723 deletions(-) diff --git a/plugin/src/main/java/com/intellij/java/impl/codeInsight/editorActions/CopyPasteReferenceProcessor.java b/plugin/src/main/java/com/intellij/java/impl/codeInsight/editorActions/CopyPasteReferenceProcessor.java index d735f74d0..345d87571 100644 --- a/plugin/src/main/java/com/intellij/java/impl/codeInsight/editorActions/CopyPasteReferenceProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/codeInsight/editorActions/CopyPasteReferenceProcessor.java @@ -44,177 +44,199 @@ import java.util.*; public abstract class CopyPasteReferenceProcessor extends CopyPastePostProcessor { - private static final Logger LOG = Logger.getInstance(CopyPasteReferenceProcessor.class); - - @Nonnull - @Override - public List collectTransferableData(PsiFile file, final Editor editor, final int[] startOffsets, - final int[] endOffsets) { - if (CodeInsightSettings.getInstance().ADD_IMPORTS_ON_PASTE == CodeInsightSettings.NO) { - return Collections.emptyList(); - } + private static final Logger LOG = Logger.getInstance(CopyPasteReferenceProcessor.class); + + @Nonnull + @Override + public List collectTransferableData( + PsiFile file, + final Editor editor, + final int[] startOffsets, + final int[] endOffsets + ) { + if (CodeInsightSettings.getInstance().ADD_IMPORTS_ON_PASTE == CodeInsightSettings.NO) { + return Collections.emptyList(); + } - if (file instanceof PsiCompiledFile) { - file = ((PsiCompiledFile) file).getDecompiledPsiFile(); - } - if (!(file instanceof PsiClassOwner)) { - return Collections.emptyList(); - } + if (file instanceof PsiCompiledFile) { + file = ((PsiCompiledFile)file).getDecompiledPsiFile(); + } + if (!(file instanceof PsiClassOwner)) { + return Collections.emptyList(); + } - final ArrayList array = new ArrayList(); - for (int j = 0; j < startOffsets.length; j++) { - final int startOffset = startOffsets[j]; - for (final PsiElement element : CollectHighlightsUtil.getElementsInRange(file, startOffset, endOffsets[j])) { - addReferenceData(file, startOffset, element, array); - } - } + final ArrayList array = new ArrayList(); + for (int j = 0; j < startOffsets.length; j++) { + final int startOffset = startOffsets[j]; + for (final PsiElement element : CollectHighlightsUtil.getElementsInRange(file, startOffset, endOffsets[j])) { + addReferenceData(file, startOffset, element, array); + } + } - if (array.isEmpty()) { - return Collections.emptyList(); - } + if (array.isEmpty()) { + return Collections.emptyList(); + } - return Collections.singletonList(new ReferenceTransferableData(array.toArray(new ReferenceData[array.size()]))); - } + return Collections.singletonList(new ReferenceTransferableData(array.toArray(new ReferenceData[array.size()]))); + } - protected abstract void addReferenceData(PsiFile file, int startOffset, PsiElement element, ArrayList to); + protected abstract void addReferenceData(PsiFile file, int startOffset, PsiElement element, ArrayList to); + + @Nonnull + @Override + public List extractTransferableData(final Transferable content) { + ReferenceTransferableData referenceData = null; + if (CodeInsightSettings.getInstance().ADD_IMPORTS_ON_PASTE != CodeInsightSettings.NO) { + try { + final DataFlavor flavor = ReferenceData.getDataFlavor(); + if (flavor != null) { + referenceData = (ReferenceTransferableData)content.getTransferData(flavor); + } + } + catch (UnsupportedFlavorException ignored) { + } + catch (IOException ignored) { + } + } - @Nonnull - @Override - public List extractTransferableData(final Transferable content) { - ReferenceTransferableData referenceData = null; - if (CodeInsightSettings.getInstance().ADD_IMPORTS_ON_PASTE != CodeInsightSettings.NO) { - try { - final DataFlavor flavor = ReferenceData.getDataFlavor(); - if (flavor != null) { - referenceData = (ReferenceTransferableData) content.getTransferData(flavor); + if (referenceData != null) { // copy to prevent changing of original by convertLineSeparators + return Collections.singletonList(referenceData.clone()); } - } catch (UnsupportedFlavorException ignored) { - } catch (IOException ignored) { - } - } - if (referenceData != null) { // copy to prevent changing of original by convertLineSeparators - return Collections.singletonList(referenceData.clone()); + return Collections.emptyList(); } - return Collections.emptyList(); - } + @Override + public void processTransferableData( + final Project project, + final Editor editor, + final RangeMarker bounds, + int caretOffset, + Ref indented, + final List values + ) { + if (DumbService.getInstance(project).isDumb()) { + return; + } + final Document document = editor.getDocument(); + final PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document); - @Override - public void processTransferableData(final Project project, final Editor editor, final RangeMarker bounds, int caretOffset, - Ref indented, final List values) { - if (DumbService.getInstance(project).isDumb()) { - return; - } - final Document document = editor.getDocument(); - final PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document); + if (!(file instanceof PsiClassOwner)) { + return; + } - if (!(file instanceof PsiClassOwner)) { - return; + PsiDocumentManager.getInstance(project).commitAllDocuments(); + assert values.size() == 1; + final ReferenceData[] referenceData = values.get(0).getData(); + final TRef[] refs = findReferencesToRestore(file, bounds, referenceData); + if (CodeInsightSettings.getInstance().ADD_IMPORTS_ON_PASTE == CodeInsightSettings.ASK) { + askReferencesToRestore(project, refs, referenceData); + } + PsiDocumentManager.getInstance(project).commitAllDocuments(); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + restoreReferences(referenceData, refs); + } + }); } - PsiDocumentManager.getInstance(project).commitAllDocuments(); - assert values.size() == 1; - final ReferenceData[] referenceData = values.get(0).getData(); - final TRef[] refs = findReferencesToRestore(file, bounds, referenceData); - if (CodeInsightSettings.getInstance().ADD_IMPORTS_ON_PASTE == CodeInsightSettings.ASK) { - askReferencesToRestore(project, refs, referenceData); - } - PsiDocumentManager.getInstance(project).commitAllDocuments(); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - restoreReferences(referenceData, refs); - } - }); - } - - protected static void addReferenceData(final PsiElement element, final ArrayList array, final int startOffset, - final String qClassName, @Nullable final String staticMemberName) { - final TextRange range = element.getTextRange(); - array.add(new ReferenceData(range.getStartOffset() - startOffset, range.getEndOffset() - startOffset, qClassName, staticMemberName)); - } - - protected abstract TRef[] findReferencesToRestore(PsiFile file, RangeMarker bounds, ReferenceData[] referenceData); - - protected PsiElement resolveReferenceIgnoreOverriding(PsiPolyVariantReference reference) { - PsiElement referent = reference.resolve(); - if (referent == null) { - final ResolveResult[] results = reference.multiResolve(true); - if (results.length > 0) { - referent = results[0].getElement(); - } + protected static void addReferenceData( + final PsiElement element, + final ArrayList array, + final int startOffset, + final String qClassName, + @Nullable final String staticMemberName + ) { + final TextRange range = element.getTextRange(); + array.add(new ReferenceData( + range.getStartOffset() - startOffset, + range.getEndOffset() - startOffset, + qClassName, + staticMemberName + )); } - return referent; - } - - protected abstract void restoreReferences(ReferenceData[] referenceData, TRef[] refs); - - private static void askReferencesToRestore(Project project, PsiElement[] refs, ReferenceData[] referenceData) { - PsiManager manager = PsiManager.getInstance(project); - - ArrayList array = new ArrayList(); - Object[] refObjects = new Object[refs.length]; - for (int i = 0; i < referenceData.length; i++) { - PsiElement ref = refs[i]; - if (ref != null) { - LOG.assertTrue(ref.isValid()); - ReferenceData data = referenceData[i]; - PsiClass refClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(data.qClassName, ref.getResolveScope()); - if (refClass == null) { - continue; - } - Object refObject = refClass; - if (data.staticMemberName != null) { - //Show static members as Strings - refObject = refClass.getQualifiedName() + "." + data.staticMemberName; - } - refObjects[i] = refObject; + protected abstract TRef[] findReferencesToRestore(PsiFile file, RangeMarker bounds, ReferenceData[] referenceData); - if (!array.contains(refObject)) { - array.add(refObject); + protected PsiElement resolveReferenceIgnoreOverriding(PsiPolyVariantReference reference) { + PsiElement referent = reference.resolve(); + if (referent == null) { + final ResolveResult[] results = reference.multiResolve(true); + if (results.length > 0) { + referent = results[0].getElement(); + } } - } - } - if (array.isEmpty()) { - return; + return referent; } - Object[] selectedObjects = ArrayUtil.toObjectArray(array); - Arrays.sort(selectedObjects, new Comparator() { - @Override - public int compare(Object o1, Object o2) { - String fqName1 = getFQName(o1); - String fqName2 = getFQName(o2); - return fqName1.compareToIgnoreCase(fqName2); - } - }); - - RestoreReferencesDialog dialog = new RestoreReferencesDialog(project, selectedObjects); - dialog.show(); - selectedObjects = dialog.getSelectedElements(); - - for (int i = 0; i < referenceData.length; i++) { - PsiElement ref = refs[i]; - if (ref != null) { - LOG.assertTrue(ref.isValid()); - Object refObject = refObjects[i]; - boolean found = false; - for (Object selected : selectedObjects) { - if (Comparing.equal(refObject, selected)) { - found = true; - break; - } + protected abstract void restoreReferences(ReferenceData[] referenceData, TRef[] refs); + + private static void askReferencesToRestore(Project project, PsiElement[] refs, ReferenceData[] referenceData) { + PsiManager manager = PsiManager.getInstance(project); + + ArrayList array = new ArrayList(); + Object[] refObjects = new Object[refs.length]; + for (int i = 0; i < referenceData.length; i++) { + PsiElement ref = refs[i]; + if (ref != null) { + LOG.assertTrue(ref.isValid()); + ReferenceData data = referenceData[i]; + PsiClass refClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(data.qClassName, ref.getResolveScope()); + if (refClass == null) { + continue; + } + + Object refObject = refClass; + if (data.staticMemberName != null) { + //Show static members as Strings + refObject = refClass.getQualifiedName() + "." + data.staticMemberName; + } + refObjects[i] = refObject; + + if (!array.contains(refObject)) { + array.add(refObject); + } + } } - if (!found) { - refs[i] = null; + if (array.isEmpty()) { + return; + } + + Object[] selectedObjects = ArrayUtil.toObjectArray(array); + Arrays.sort(selectedObjects, new Comparator() { + @Override + public int compare(Object o1, Object o2) { + String fqName1 = getFQName(o1); + String fqName2 = getFQName(o2); + return fqName1.compareToIgnoreCase(fqName2); + } + }); + + RestoreReferencesDialog dialog = new RestoreReferencesDialog(project, selectedObjects); + dialog.show(); + selectedObjects = dialog.getSelectedElements(); + + for (int i = 0; i < referenceData.length; i++) { + PsiElement ref = refs[i]; + if (ref != null) { + LOG.assertTrue(ref.isValid()); + Object refObject = refObjects[i]; + boolean found = false; + for (Object selected : selectedObjects) { + if (Comparing.equal(refObject, selected)) { + found = true; + break; + } + } + if (!found) { + refs[i] = null; + } + } } - } } - } - private static String getFQName(Object element) { - return element instanceof PsiClass ? ((PsiClass) element).getQualifiedName() : (String) element; - } + private static String getFQName(Object element) { + return element instanceof PsiClass ? ((PsiClass)element).getQualifiedName() : (String)element; + } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java index 345f1d302..16d166b0e 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java @@ -43,192 +43,199 @@ * @author dsl */ public class ChangeClassSignatureProcessor extends BaseRefactoringProcessor { - private static final Logger LOG = Logger.getInstance(ChangeClassSignatureProcessor.class); - private PsiClass myClass; - private final TypeParameterInfo[] myNewSignature; - - public ChangeClassSignatureProcessor(Project project, PsiClass aClass, TypeParameterInfo[] newSignature) { - super(project); - myClass = aClass; - myNewSignature = newSignature; - } - - protected void refreshElements(PsiElement[] elements) { - LOG.assertTrue(elements.length == 1); - LOG.assertTrue(elements[0] instanceof PsiClass); - myClass = (PsiClass)elements[0]; - } - - protected String getCommandName() { - return ChangeClassSignatureDialog.REFACTORING_NAME; - } - - @Nonnull - protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { - return new ChangeClassSigntaureViewDescriptor(myClass); - } - - @Override - protected boolean preprocessUsages(Ref refUsages) { - final MultiMap conflicts = new MultiMap(); - - final PsiTypeParameter[] parameters = myClass.getTypeParameters(); - final Map infos = new HashMap(); - for (TypeParameterInfo info : myNewSignature) { - final String newName = info.isForExistingParameter() ? parameters[info.getOldParameterIndex()].getName() : info.getNewName(); - TypeParameterInfo existing = infos.get(newName); - if (existing != null) { - conflicts.putValue(myClass, RefactoringUIUtil.getDescription(myClass, false) + " already contains type parameter " + newName); - } - infos.put(newName, info); + private static final Logger LOG = Logger.getInstance(ChangeClassSignatureProcessor.class); + private PsiClass myClass; + private final TypeParameterInfo[] myNewSignature; + + public ChangeClassSignatureProcessor(Project project, PsiClass aClass, TypeParameterInfo[] newSignature) { + super(project); + myClass = aClass; + myNewSignature = newSignature; } - return showConflicts(conflicts, refUsages.get()); - } - - @Nonnull - protected UsageInfo[] findUsages() { - GlobalSearchScope projectScope = GlobalSearchScope.projectScope(myProject); - List result = new ArrayList(); - - boolean hadTypeParameters = myClass.hasTypeParameters(); - for (final PsiReference reference : ReferencesSearch.search(myClass, projectScope, false)) { - if (reference.getElement() instanceof PsiJavaCodeReferenceElement) { - PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)reference.getElement(); - PsiElement parent = referenceElement.getParent(); - if (parent instanceof PsiTypeElement && parent.getParent() instanceof PsiInstanceOfExpression) continue; - if (parent instanceof PsiTypeElement || parent instanceof PsiNewExpression || parent instanceof PsiAnonymousClass || - parent instanceof PsiReferenceList) { - if (!hadTypeParameters || referenceElement.getTypeParameters().length > 0) { - result.add(new UsageInfo(referenceElement)); - } - } - } + + protected void refreshElements(PsiElement[] elements) { + LOG.assertTrue(elements.length == 1); + LOG.assertTrue(elements[0] instanceof PsiClass); + myClass = (PsiClass)elements[0]; } - return result.toArray(new UsageInfo[result.size()]); - } - protected void performRefactoring(UsageInfo[] usages) { - LocalHistoryAction a = LocalHistory.getInstance().startAction(getCommandName()); - try { - doRefactoring(usages); + protected String getCommandName() { + return ChangeClassSignatureDialog.REFACTORING_NAME; } - catch (IncorrectOperationException e) { - LOG.error(e); + + @Nonnull + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { + return new ChangeClassSigntaureViewDescriptor(myClass); } - finally { - a.finish(); + + @Override + protected boolean preprocessUsages(Ref refUsages) { + final MultiMap conflicts = new MultiMap(); + + final PsiTypeParameter[] parameters = myClass.getTypeParameters(); + final Map infos = new HashMap(); + for (TypeParameterInfo info : myNewSignature) { + final String newName = info.isForExistingParameter() ? parameters[info.getOldParameterIndex()].getName() : info.getNewName(); + TypeParameterInfo existing = infos.get(newName); + if (existing != null) { + conflicts.putValue( + myClass, + RefactoringUIUtil.getDescription(myClass, false) + " already contains type parameter " + newName + ); + } + infos.put(newName, info); + } + return showConflicts(conflicts, refUsages.get()); } - } - private void doRefactoring(UsageInfo[] usages) throws IncorrectOperationException { - final PsiTypeParameter[] typeParameters = myClass.getTypeParameters(); - final boolean[] toRemoveParms = detectRemovedParameters(typeParameters); + @Nonnull + protected UsageInfo[] findUsages() { + GlobalSearchScope projectScope = GlobalSearchScope.projectScope(myProject); + List result = new ArrayList(); + + boolean hadTypeParameters = myClass.hasTypeParameters(); + for (final PsiReference reference : ReferencesSearch.search(myClass, projectScope, false)) { + if (reference.getElement() instanceof PsiJavaCodeReferenceElement) { + PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)reference.getElement(); + PsiElement parent = referenceElement.getParent(); + if (parent instanceof PsiTypeElement && parent.getParent() instanceof PsiInstanceOfExpression) { + continue; + } + if (parent instanceof PsiTypeElement || parent instanceof PsiNewExpression || parent instanceof PsiAnonymousClass || + parent instanceof PsiReferenceList) { + if (!hadTypeParameters || referenceElement.getTypeParameters().length > 0) { + result.add(new UsageInfo(referenceElement)); + } + } + } + } + return result.toArray(new UsageInfo[result.size()]); + } - for (final UsageInfo usage : usages) { - LOG.assertTrue(usage.getElement() instanceof PsiJavaCodeReferenceElement); - processUsage(usage, typeParameters, toRemoveParms); + protected void performRefactoring(UsageInfo[] usages) { + LocalHistoryAction a = LocalHistory.getInstance().startAction(getCommandName()); + try { + doRefactoring(usages); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + finally { + a.finish(); + } } - final Map supersMap = new HashMap(); - myClass.accept(new JavaRecursiveElementWalkingVisitor() { - @Override - public void visitTypeElement(PsiTypeElement typeElement) { - super.visitTypeElement(typeElement); - final PsiType type = typeElement.getType(); - final PsiClass psiClass = PsiUtil.resolveClassInType(type); - if (psiClass instanceof PsiTypeParameter) { - final int i = ArrayUtil.find(typeParameters, psiClass); - if ( i >= 0 && i < toRemoveParms.length && toRemoveParms[i]) { - supersMap.put(typeElement, psiClass.getSuperClass()); - } + + private void doRefactoring(UsageInfo[] usages) throws IncorrectOperationException { + final PsiTypeParameter[] typeParameters = myClass.getTypeParameters(); + final boolean[] toRemoveParms = detectRemovedParameters(typeParameters); + + for (final UsageInfo usage : usages) { + LOG.assertTrue(usage.getElement() instanceof PsiJavaCodeReferenceElement); + processUsage(usage, typeParameters, toRemoveParms); + } + final Map supersMap = new HashMap(); + myClass.accept(new JavaRecursiveElementWalkingVisitor() { + @Override + public void visitTypeElement(PsiTypeElement typeElement) { + super.visitTypeElement(typeElement); + final PsiType type = typeElement.getType(); + final PsiClass psiClass = PsiUtil.resolveClassInType(type); + if (psiClass instanceof PsiTypeParameter) { + final int i = ArrayUtil.find(typeParameters, psiClass); + if (i >= 0 && i < toRemoveParms.length && toRemoveParms[i]) { + supersMap.put(typeElement, psiClass.getSuperClass()); + } + } + } + }); + final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject); + for (Map.Entry classEntry : supersMap.entrySet()) { + classEntry.getKey().replace(elementFactory.createTypeElement(elementFactory.createType(classEntry.getValue()))); } - } - }); - final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject); - for (Map.Entry classEntry : supersMap.entrySet()) { - classEntry.getKey().replace(elementFactory.createTypeElement(elementFactory.createType(classEntry.getValue()))); + changeClassSignature(typeParameters, toRemoveParms); } - changeClassSignature(typeParameters, toRemoveParms); - } - - private void changeClassSignature(final PsiTypeParameter[] originalTypeParameters, boolean[] toRemoveParms) - throws IncorrectOperationException { - PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory(); - List newTypeParameters = new ArrayList(); - for (final TypeParameterInfo info : myNewSignature) { - int oldIndex = info.getOldParameterIndex(); - if (oldIndex >= 0) { - newTypeParameters.add(originalTypeParameters[oldIndex]); - } - else { - newTypeParameters.add(factory.createTypeParameterFromText(info.getNewName(), null)); - } + + private void changeClassSignature(final PsiTypeParameter[] originalTypeParameters, boolean[] toRemoveParms) + throws IncorrectOperationException { + PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory(); + List newTypeParameters = new ArrayList(); + for (final TypeParameterInfo info : myNewSignature) { + int oldIndex = info.getOldParameterIndex(); + if (oldIndex >= 0) { + newTypeParameters.add(originalTypeParameters[oldIndex]); + } + else { + newTypeParameters.add(factory.createTypeParameterFromText(info.getNewName(), null)); + } + } + ChangeSignatureUtil.synchronizeList(myClass.getTypeParameterList(), newTypeParameters, TypeParameterList.INSTANCE, toRemoveParms); } - ChangeSignatureUtil.synchronizeList(myClass.getTypeParameterList(), newTypeParameters, TypeParameterList.INSTANCE, toRemoveParms); - } - - private boolean[] detectRemovedParameters(final PsiTypeParameter[] originaltypeParameters) { - final boolean[] toRemoveParms = new boolean[originaltypeParameters.length]; - Arrays.fill(toRemoveParms, true); - for (final TypeParameterInfo info : myNewSignature) { - int oldParameterIndex = info.getOldParameterIndex(); - if (oldParameterIndex >= 0) { - toRemoveParms[oldParameterIndex] = false; - } + + private boolean[] detectRemovedParameters(final PsiTypeParameter[] originaltypeParameters) { + final boolean[] toRemoveParms = new boolean[originaltypeParameters.length]; + Arrays.fill(toRemoveParms, true); + for (final TypeParameterInfo info : myNewSignature) { + int oldParameterIndex = info.getOldParameterIndex(); + if (oldParameterIndex >= 0) { + toRemoveParms[oldParameterIndex] = false; + } + } + return toRemoveParms; } - return toRemoveParms; - } - - private void processUsage(final UsageInfo usage, final PsiTypeParameter[] originalTypeParameters, final boolean[] toRemoveParms) - throws IncorrectOperationException { - PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory(); - PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)usage.getElement(); - PsiSubstitutor usageSubstitutor = determineUsageSubstitutor(referenceElement); - - PsiReferenceParameterList referenceParameterList = referenceElement.getParameterList(); - PsiTypeElement[] oldValues = referenceParameterList.getTypeParameterElements(); - if (oldValues.length != originalTypeParameters.length) return; - List newValues = new ArrayList(); - for (final TypeParameterInfo info : myNewSignature) { - int oldIndex = info.getOldParameterIndex(); - if (oldIndex >= 0) { - newValues.add(oldValues[oldIndex]); - } - else { - PsiType type = info.getDefaultValue().getType(myClass.getLBrace(), PsiManager.getInstance(myProject)); - - PsiTypeElement newValue = factory.createTypeElement(usageSubstitutor.substitute(type)); - newValues.add(newValue); - } + + private void processUsage(final UsageInfo usage, final PsiTypeParameter[] originalTypeParameters, final boolean[] toRemoveParms) + throws IncorrectOperationException { + PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory(); + PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)usage.getElement(); + PsiSubstitutor usageSubstitutor = determineUsageSubstitutor(referenceElement); + + PsiReferenceParameterList referenceParameterList = referenceElement.getParameterList(); + PsiTypeElement[] oldValues = referenceParameterList.getTypeParameterElements(); + if (oldValues.length != originalTypeParameters.length) { + return; + } + List newValues = new ArrayList(); + for (final TypeParameterInfo info : myNewSignature) { + int oldIndex = info.getOldParameterIndex(); + if (oldIndex >= 0) { + newValues.add(oldValues[oldIndex]); + } + else { + PsiType type = info.getDefaultValue().getType(myClass.getLBrace(), PsiManager.getInstance(myProject)); + + PsiTypeElement newValue = factory.createTypeElement(usageSubstitutor.substitute(type)); + newValues.add(newValue); + } + } + ChangeSignatureUtil.synchronizeList(referenceParameterList, newValues, ReferenceParameterList.INSTANCE, toRemoveParms); } - ChangeSignatureUtil.synchronizeList(referenceParameterList, newValues, ReferenceParameterList.INSTANCE, toRemoveParms); - } - - private PsiSubstitutor determineUsageSubstitutor(PsiJavaCodeReferenceElement referenceElement) { - PsiType[] typeArguments = referenceElement.getTypeParameters(); - PsiSubstitutor usageSubstitutor = PsiSubstitutor.EMPTY; - PsiTypeParameter[] typeParameters = myClass.getTypeParameters(); - if (typeParameters.length == typeArguments.length) { - for (int i = 0; i < typeParameters.length; i++) { - usageSubstitutor = usageSubstitutor.put(typeParameters[i], typeArguments[i]); - } + + private PsiSubstitutor determineUsageSubstitutor(PsiJavaCodeReferenceElement referenceElement) { + PsiType[] typeArguments = referenceElement.getTypeParameters(); + PsiSubstitutor usageSubstitutor = PsiSubstitutor.EMPTY; + PsiTypeParameter[] typeParameters = myClass.getTypeParameters(); + if (typeParameters.length == typeArguments.length) { + for (int i = 0; i < typeParameters.length; i++) { + usageSubstitutor = usageSubstitutor.put(typeParameters[i], typeArguments[i]); + } + } + return usageSubstitutor; } - return usageSubstitutor; - } - private static class ReferenceParameterList implements ChangeSignatureUtil.ChildrenGenerator { - private static final ReferenceParameterList INSTANCE = new ReferenceParameterList(); + private static class ReferenceParameterList implements ChangeSignatureUtil.ChildrenGenerator { + private static final ReferenceParameterList INSTANCE = new ReferenceParameterList(); - public List getChildren(PsiReferenceParameterList list) { - return Arrays.asList(list.getTypeParameterElements()); + public List getChildren(PsiReferenceParameterList list) { + return Arrays.asList(list.getTypeParameterElements()); + } } - } - private static class TypeParameterList implements ChangeSignatureUtil.ChildrenGenerator { - private static final TypeParameterList INSTANCE = new TypeParameterList(); + private static class TypeParameterList implements ChangeSignatureUtil.ChildrenGenerator { + private static final TypeParameterList INSTANCE = new TypeParameterList(); - public List getChildren(PsiTypeParameterList psiTypeParameterList) { - return Arrays.asList(psiTypeParameterList.getTypeParameters()); + public List getChildren(PsiTypeParameterList psiTypeParameterList) { + return Arrays.asList(psiTypeParameterList.getTypeParameters()); + } } - } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/ChangeSignatureProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/ChangeSignatureProcessor.java index a56da6d09..a7e336447 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/ChangeSignatureProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/ChangeSignatureProcessor.java @@ -50,296 +50,305 @@ import java.util.*; public class ChangeSignatureProcessor extends ChangeSignatureProcessorBase { - private static final Logger LOG = Logger.getInstance(ChangeSignatureProcessor.class); + private static final Logger LOG = Logger.getInstance(ChangeSignatureProcessor.class); - public ChangeSignatureProcessor( - Project project, - PsiMethod method, - final boolean generateDelegate, - @PsiModifier.ModifierConstant String newVisibility, - String newName, - PsiType newType, - @Nonnull ParameterInfoImpl[] parameterInfo - ) { - this( - project, - method, - generateDelegate, - newVisibility, - newName, - newType != null ? CanonicalTypes.createTypeWrapper(newType) : null, - parameterInfo, - null, - null, - null - ); - } + public ChangeSignatureProcessor( + Project project, + PsiMethod method, + final boolean generateDelegate, + @PsiModifier.ModifierConstant String newVisibility, + String newName, + PsiType newType, + @Nonnull ParameterInfoImpl[] parameterInfo + ) { + this( + project, + method, + generateDelegate, + newVisibility, + newName, + newType != null ? CanonicalTypes.createTypeWrapper(newType) : null, + parameterInfo, + null, + null, + null + ); + } + + public ChangeSignatureProcessor( + Project project, + PsiMethod method, + final boolean generateDelegate, + @PsiModifier.ModifierConstant String newVisibility, + String newName, + PsiType newType, + ParameterInfoImpl[] parameterInfo, + ThrownExceptionInfo[] exceptionInfos + ) { + this( + project, + method, + generateDelegate, + newVisibility, + newName, + newType != null ? CanonicalTypes.createTypeWrapper(newType) : null, + parameterInfo, + exceptionInfos, + null, + null + ); + } - public ChangeSignatureProcessor( - Project project, - PsiMethod method, - final boolean generateDelegate, - @PsiModifier.ModifierConstant String newVisibility, - String newName, - PsiType newType, - ParameterInfoImpl[] parameterInfo, - ThrownExceptionInfo[] exceptionInfos - ) { - this( - project, - method, - generateDelegate, - newVisibility, - newName, - newType != null ? CanonicalTypes.createTypeWrapper(newType) : null, - parameterInfo, - exceptionInfos, - null, - null - ); - } + public ChangeSignatureProcessor( + Project project, + PsiMethod method, + boolean generateDelegate, + @PsiModifier.ModifierConstant String newVisibility, + String newName, + CanonicalTypes.Type newType, + @Nonnull ParameterInfoImpl[] parameterInfo, + ThrownExceptionInfo[] thrownExceptions, + Set propagateParametersMethods, + Set propagateExceptionsMethods + ) { + this( + project, + generateChangeInfo( + method, + generateDelegate, + newVisibility, + newName, + newType, + parameterInfo, + thrownExceptions, + propagateParametersMethods, + propagateExceptionsMethods + ) + ); + } - public ChangeSignatureProcessor( - Project project, - PsiMethod method, - boolean generateDelegate, - @PsiModifier.ModifierConstant String newVisibility, - String newName, - CanonicalTypes.Type newType, - @Nonnull ParameterInfoImpl[] parameterInfo, - ThrownExceptionInfo[] thrownExceptions, - Set propagateParametersMethods, - Set propagateExceptionsMethods - ) { - this( - project, - generateChangeInfo( - method, - generateDelegate, - newVisibility, - newName, - newType, - parameterInfo, - thrownExceptions, - propagateParametersMethods, - propagateExceptionsMethods - ) - ); - } + public ChangeSignatureProcessor(Project project, final JavaChangeInfo changeInfo) { + super(project, changeInfo); + LOG.assertTrue(myChangeInfo.getMethod().isValid()); + } - public ChangeSignatureProcessor(Project project, final JavaChangeInfo changeInfo) { - super(project, changeInfo); - LOG.assertTrue(myChangeInfo.getMethod().isValid()); - } + private static JavaChangeInfo generateChangeInfo( + PsiMethod method, + boolean generateDelegate, + @PsiModifier.ModifierConstant String newVisibility, + String newName, + CanonicalTypes.Type newType, + @Nonnull ParameterInfoImpl[] parameterInfo, + ThrownExceptionInfo[] thrownExceptions, + Set propagateParametersMethods, + Set propagateExceptionsMethods + ) { + Set myPropagateParametersMethods = propagateParametersMethods != null ? propagateParametersMethods : new HashSet<>(); + Set myPropagateExceptionsMethods = propagateExceptionsMethods != null ? propagateExceptionsMethods : new HashSet<>(); - private static JavaChangeInfo generateChangeInfo( - PsiMethod method, - boolean generateDelegate, - @PsiModifier.ModifierConstant String newVisibility, - String newName, - CanonicalTypes.Type newType, - @Nonnull ParameterInfoImpl[] parameterInfo, - ThrownExceptionInfo[] thrownExceptions, - Set propagateParametersMethods, - Set propagateExceptionsMethods - ) { - Set myPropagateParametersMethods = propagateParametersMethods != null ? propagateParametersMethods : new HashSet<>(); - Set myPropagateExceptionsMethods = propagateExceptionsMethods != null ? propagateExceptionsMethods : new HashSet<>(); + LOG.assertTrue(method.isValid()); + if (newVisibility == null) { + newVisibility = VisibilityUtil.getVisibilityModifier(method.getModifierList()); + } - LOG.assertTrue(method.isValid()); - if (newVisibility == null) { - newVisibility = VisibilityUtil.getVisibilityModifier(method.getModifierList()); + return new JavaChangeInfoImpl( + newVisibility, + method, + newName, + newType, + parameterInfo, + thrownExceptions, + generateDelegate, + myPropagateParametersMethods, + myPropagateExceptionsMethods + ); } - return new JavaChangeInfoImpl( - newVisibility, - method, - newName, - newType, - parameterInfo, - thrownExceptions, - generateDelegate, - myPropagateParametersMethods, - myPropagateExceptionsMethods - ); - } + @Override + @Nonnull + protected UsageViewDescriptor createUsageViewDescriptor(@Nonnull UsageInfo[] usages) { + return new ChangeSignatureViewDescriptor(getChangeInfo().getMethod()); + } - @Override - @Nonnull - protected UsageViewDescriptor createUsageViewDescriptor(@Nonnull UsageInfo[] usages) { - return new ChangeSignatureViewDescriptor(getChangeInfo().getMethod()); - } + @Override + public JavaChangeInfoImpl getChangeInfo() { + return (JavaChangeInfoImpl)super.getChangeInfo(); + } - @Override - public JavaChangeInfoImpl getChangeInfo() { - return (JavaChangeInfoImpl) super.getChangeInfo(); - } + @Override + protected void refreshElements(PsiElement[] elements) { + boolean condition = elements.length == 1 && elements[0] instanceof PsiMethod; + LOG.assertTrue(condition); + getChangeInfo().updateMethod((PsiMethod)elements[0]); + } - @Override - protected void refreshElements(PsiElement[] elements) { - boolean condition = elements.length == 1 && elements[0] instanceof PsiMethod; - LOG.assertTrue(condition); - getChangeInfo().updateMethod((PsiMethod) elements[0]); - } + @Override + @RequiredUIAccess + protected boolean preprocessUsages(@Nonnull Ref refUsages) { + for (ChangeSignatureUsageProcessor processor : ChangeSignatureUsageProcessor.EP_NAME.getExtensions()) { + if (processor instanceof ChangeSignatureUsageProcessorEx && ((ChangeSignatureUsageProcessorEx)processor).setupDefaultValues + (myChangeInfo, refUsages, myProject)) { + return false; + } + } + MultiMap conflictDescriptions = new MultiMap<>(); + for (ChangeSignatureUsageProcessor usageProcessor : ChangeSignatureUsageProcessor.EP_NAME.getExtensions()) { + final MultiMap conflicts = usageProcessor.findConflicts(myChangeInfo, refUsages); + for (PsiElement key : conflicts.keySet()) { + Collection collection = conflictDescriptions.get(key); + if (collection.size() == 0) { + collection = new HashSet<>(); + } + collection.addAll(conflicts.get(key)); + conflictDescriptions.put(key, collection); + } + } - @Override - @RequiredUIAccess - protected boolean preprocessUsages(@Nonnull Ref refUsages) { - for (ChangeSignatureUsageProcessor processor : ChangeSignatureUsageProcessor.EP_NAME.getExtensions()) { - if (processor instanceof ChangeSignatureUsageProcessorEx && ((ChangeSignatureUsageProcessorEx) processor).setupDefaultValues - (myChangeInfo, refUsages, myProject)) { - return false; - } - } - MultiMap conflictDescriptions = new MultiMap<>(); - for (ChangeSignatureUsageProcessor usageProcessor : ChangeSignatureUsageProcessor.EP_NAME.getExtensions()) { - final MultiMap conflicts = usageProcessor.findConflicts(myChangeInfo, refUsages); - for (PsiElement key : conflicts.keySet()) { - Collection collection = conflictDescriptions.get(key); - if (collection.size() == 0) { - collection = new HashSet<>(); + final UsageInfo[] usagesIn = refUsages.get(); + RenameUtil.addConflictDescriptions(usagesIn, conflictDescriptions); + Set usagesSet = new HashSet<>(Arrays.asList(usagesIn)); + RenameUtil.removeConflictUsages(usagesSet); + if (!conflictDescriptions.isEmpty()) { + if (myProject.getApplication().isUnitTestMode()) { + throw new ConflictsInTestsException(conflictDescriptions.values()); + } + if (myPrepareSuccessfulSwingThreadCallback != null) { + ConflictsDialog dialog = prepareConflictsDialog(conflictDescriptions, usagesIn); + dialog.show(); + if (!dialog.isOK()) { + if (dialog.isShowConflicts()) { + prepareSuccessful(); + } + return false; + } + } } - collection.addAll(conflicts.get(key)); - conflictDescriptions.put(key, collection); - } - } - final UsageInfo[] usagesIn = refUsages.get(); - RenameUtil.addConflictDescriptions(usagesIn, conflictDescriptions); - Set usagesSet = new HashSet<>(Arrays.asList(usagesIn)); - RenameUtil.removeConflictUsages(usagesSet); - if (!conflictDescriptions.isEmpty()) { - if (myProject.getApplication().isUnitTestMode()) { - throw new ConflictsInTestsException(conflictDescriptions.values()); - } - if (myPrepareSuccessfulSwingThreadCallback != null) { - ConflictsDialog dialog = prepareConflictsDialog(conflictDescriptions, usagesIn); - dialog.show(); - if (!dialog.isOK()) { - if (dialog.isShowConflicts()) { - prepareSuccessful(); - } - return false; + if (myChangeInfo.isReturnTypeChanged()) { + askToRemoveCovariantOverriders(usagesSet); } - } - } - if (myChangeInfo.isReturnTypeChanged()) { - askToRemoveCovariantOverriders(usagesSet); + refUsages.set(usagesSet.toArray(new UsageInfo[usagesSet.size()])); + prepareSuccessful(); + return true; } - refUsages.set(usagesSet.toArray(new UsageInfo[usagesSet.size()])); - prepareSuccessful(); - return true; - } - - @RequiredUIAccess - private void askToRemoveCovariantOverriders(Set usages) { - if (PsiUtil.isLanguageLevel5OrHigher(myChangeInfo.getMethod())) { - List covariantOverriderInfos = new ArrayList<>(); - for (UsageInfo usageInfo : usages) { - if (usageInfo instanceof OverriderUsageInfo) { - final OverriderUsageInfo info = (OverriderUsageInfo) usageInfo; - PsiMethod overrider = info.getElement(); - PsiMethod baseMethod = info.getBaseMethod(); - PsiSubstitutor substitutor = calculateSubstitutor(overrider, baseMethod); - PsiType type; - try { - type = substitutor.substitute(getChangeInfo().newReturnType.getType(myChangeInfo.getMethod(), myManager)); - } catch (IncorrectOperationException e) { - LOG.error(e); - return; - } - final PsiType overriderType = overrider.getReturnType(); - if (overriderType != null && type.isAssignableFrom(overriderType)) { - covariantOverriderInfos.add(usageInfo); - } - } - } + @RequiredUIAccess + private void askToRemoveCovariantOverriders(Set usages) { + if (PsiUtil.isLanguageLevel5OrHigher(myChangeInfo.getMethod())) { + List covariantOverriderInfos = new ArrayList<>(); + for (UsageInfo usageInfo : usages) { + if (usageInfo instanceof OverriderUsageInfo) { + final OverriderUsageInfo info = (OverriderUsageInfo)usageInfo; + PsiMethod overrider = info.getElement(); + PsiMethod baseMethod = info.getBaseMethod(); + PsiSubstitutor substitutor = calculateSubstitutor(overrider, baseMethod); + PsiType type; + try { + type = substitutor.substitute(getChangeInfo().newReturnType.getType(myChangeInfo.getMethod(), myManager)); + } + catch (IncorrectOperationException e) { + LOG.error(e); + return; + } + final PsiType overriderType = overrider.getReturnType(); + if (overriderType != null && type.isAssignableFrom(overriderType)) { + covariantOverriderInfos.add(usageInfo); + } + } + } - // to be able to do filtering - preprocessCovariantOverriders(covariantOverriderInfos); + // to be able to do filtering + preprocessCovariantOverriders(covariantOverriderInfos); - if (!covariantOverriderInfos.isEmpty()) { - if (myProject.getApplication().isUnitTestMode() || !isProcessCovariantOverriders()) { - for (UsageInfo usageInfo : covariantOverriderInfos) { - usages.remove(usageInfo); - } + if (!covariantOverriderInfos.isEmpty()) { + if (myProject.getApplication().isUnitTestMode() || !isProcessCovariantOverriders()) { + for (UsageInfo usageInfo : covariantOverriderInfos) { + usages.remove(usageInfo); + } + } + } } - } } - } - protected void preprocessCovariantOverriders(final List covariantOverriderInfos) { - } + protected void preprocessCovariantOverriders(final List covariantOverriderInfos) { + } - @RequiredUIAccess - protected boolean isProcessCovariantOverriders() { - return Messages.showYesNoDialog( - myProject, - RefactoringLocalize.doYouWantToProcessOverridingMethodsWithCovariantReturnType().get(), - JavaChangeSignatureHandler.REFACTORING_NAME.get(), - UIUtil.getQuestionIcon() - ) == DialogWrapper.OK_EXIT_CODE; - } + @RequiredUIAccess + protected boolean isProcessCovariantOverriders() { + return Messages.showYesNoDialog( + myProject, + RefactoringLocalize.doYouWantToProcessOverridingMethodsWithCovariantReturnType().get(), + JavaChangeSignatureHandler.REFACTORING_NAME.get(), + UIUtil.getQuestionIcon() + ) == DialogWrapper.OK_EXIT_CODE; + } - public static void makeEmptyBody(final PsiElementFactory factory, final PsiMethod delegate) throws IncorrectOperationException { - PsiCodeBlock body = delegate.getBody(); - if (body != null) { - body.replace(factory.createCodeBlock()); - } else { - delegate.add(factory.createCodeBlock()); + public static void makeEmptyBody(final PsiElementFactory factory, final PsiMethod delegate) throws IncorrectOperationException { + PsiCodeBlock body = delegate.getBody(); + if (body != null) { + body.replace(factory.createCodeBlock()); + } + else { + delegate.add(factory.createCodeBlock()); + } + PsiUtil.setModifierProperty(delegate, PsiModifier.ABSTRACT, false); } - PsiUtil.setModifierProperty(delegate, PsiModifier.ABSTRACT, false); - } - @Nullable - public static PsiCallExpression addDelegatingCallTemplate(final PsiMethod delegate, final String newName) throws IncorrectOperationException { - Project project = delegate.getProject(); - PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory(); - PsiCodeBlock body = delegate.getBody(); - assert body != null; - final PsiCallExpression callExpression; - if (delegate.isConstructor()) { - PsiElement callStatement = factory.createStatementFromText("this();", null); - callStatement = CodeStyleManager.getInstance(project).reformat(callStatement); - callStatement = body.add(callStatement); - callExpression = (PsiCallExpression) ((PsiExpressionStatement) callStatement).getExpression(); - } else { - if (PsiType.VOID.equals(delegate.getReturnType())) { - PsiElement callStatement = factory.createStatementFromText(newName + "();", null); - callStatement = CodeStyleManager.getInstance(project).reformat(callStatement); - callStatement = body.add(callStatement); - callExpression = (PsiCallExpression) ((PsiExpressionStatement) callStatement).getExpression(); - } else { - PsiElement callStatement = factory.createStatementFromText("return " + newName + "();", null); - callStatement = CodeStyleManager.getInstance(project).reformat(callStatement); - callStatement = body.add(callStatement); - callExpression = (PsiCallExpression) ((PsiReturnStatement) callStatement).getReturnValue(); - } + @Nullable + public static PsiCallExpression addDelegatingCallTemplate( + final PsiMethod delegate, + final String newName + ) throws IncorrectOperationException { + Project project = delegate.getProject(); + PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory(); + PsiCodeBlock body = delegate.getBody(); + assert body != null; + final PsiCallExpression callExpression; + if (delegate.isConstructor()) { + PsiElement callStatement = factory.createStatementFromText("this();", null); + callStatement = CodeStyleManager.getInstance(project).reformat(callStatement); + callStatement = body.add(callStatement); + callExpression = (PsiCallExpression)((PsiExpressionStatement)callStatement).getExpression(); + } + else { + if (PsiType.VOID.equals(delegate.getReturnType())) { + PsiElement callStatement = factory.createStatementFromText(newName + "();", null); + callStatement = CodeStyleManager.getInstance(project).reformat(callStatement); + callStatement = body.add(callStatement); + callExpression = (PsiCallExpression)((PsiExpressionStatement)callStatement).getExpression(); + } + else { + PsiElement callStatement = factory.createStatementFromText("return " + newName + "();", null); + callStatement = CodeStyleManager.getInstance(project).reformat(callStatement); + callStatement = body.add(callStatement); + callExpression = (PsiCallExpression)((PsiReturnStatement)callStatement).getReturnValue(); + } + } + return callExpression; } - return callExpression; - } - public static PsiSubstitutor calculateSubstitutor(PsiMethod derivedMethod, PsiMethod baseMethod) { - PsiSubstitutor substitutor; - if (derivedMethod.getManager().areElementsEquivalent(derivedMethod, baseMethod)) { - substitutor = PsiSubstitutor.EMPTY; - } else { - final PsiClass baseClass = baseMethod.getContainingClass(); - final PsiClass derivedClass = derivedMethod.getContainingClass(); - if (baseClass != null && derivedClass != null && InheritanceUtil.isInheritorOrSelf(derivedClass, baseClass, true)) { - final PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(baseClass, derivedClass, - PsiSubstitutor.EMPTY); - final MethodSignature superMethodSignature = baseMethod.getSignature(superClassSubstitutor); - final MethodSignature methodSignature = derivedMethod.getSignature(PsiSubstitutor.EMPTY); - final PsiSubstitutor superMethodSubstitutor = MethodSignatureUtil.getSuperMethodSignatureSubstitutor(methodSignature, - superMethodSignature); - substitutor = superMethodSubstitutor != null ? superMethodSubstitutor : superClassSubstitutor; - } else { - substitutor = PsiSubstitutor.EMPTY; - } + public static PsiSubstitutor calculateSubstitutor(PsiMethod derivedMethod, PsiMethod baseMethod) { + PsiSubstitutor substitutor; + if (derivedMethod.getManager().areElementsEquivalent(derivedMethod, baseMethod)) { + substitutor = PsiSubstitutor.EMPTY; + } + else { + final PsiClass baseClass = baseMethod.getContainingClass(); + final PsiClass derivedClass = derivedMethod.getContainingClass(); + if (baseClass != null && derivedClass != null && InheritanceUtil.isInheritorOrSelf(derivedClass, baseClass, true)) { + final PsiSubstitutor superClassSubstitutor = + TypeConversionUtil.getSuperClassSubstitutor(baseClass, derivedClass, PsiSubstitutor.EMPTY); + final MethodSignature superMethodSignature = baseMethod.getSignature(superClassSubstitutor); + final MethodSignature methodSignature = derivedMethod.getSignature(PsiSubstitutor.EMPTY); + final PsiSubstitutor superMethodSubstitutor = + MethodSignatureUtil.getSuperMethodSignatureSubstitutor(methodSignature, superMethodSignature); + substitutor = superMethodSubstitutor != null ? superMethodSubstitutor : superClassSubstitutor; + } + else { + substitutor = PsiSubstitutor.EMPTY; + } + } + return substitutor; } - return substitutor; - } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/ChangeSignatureUtil.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/ChangeSignatureUtil.java index bc740ffeb..cae71efd6 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/ChangeSignatureUtil.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/ChangeSignatureUtil.java @@ -35,88 +35,101 @@ * @author dsl */ public class ChangeSignatureUtil { - private ChangeSignatureUtil() { - } + private ChangeSignatureUtil() { + } - public static void synchronizeList(Parent list, - final List newElements, - ChildrenGenerator generator, - final boolean[] shouldRemoveChild) throws IncorrectOperationException { + public static void synchronizeList( + Parent list, + final List newElements, + ChildrenGenerator generator, + final boolean[] shouldRemoveChild + ) throws IncorrectOperationException { - ArrayList elementsToRemove = null; - List elements; + ArrayList elementsToRemove = null; + List elements; - int index = 0; - while (true) { - elements = generator.getChildren(list); - if (index == newElements.size()) { - break; - } + int index = 0; + while (true) { + elements = generator.getChildren(list); + if (index == newElements.size()) { + break; + } - if (elementsToRemove == null) { - elementsToRemove = new ArrayList(); - for (int i = 0; i < shouldRemoveChild.length; i++) { - if (shouldRemoveChild[i] && i < elements.size()) { - elementsToRemove.add(elements.get(i)); - } - } - } + if (elementsToRemove == null) { + elementsToRemove = new ArrayList(); + for (int i = 0; i < shouldRemoveChild.length; i++) { + if (shouldRemoveChild[i] && i < elements.size()) { + elementsToRemove.add(elements.get(i)); + } + } + } - Child oldElement = index < elements.size() ? elements.get(index) : null; - Child newElement = newElements.get(index); - if (newElement != null) { - if (!newElement.equals(oldElement)) { - if (oldElement != null && elementsToRemove.contains(oldElement)) { - oldElement.delete(); - index--; - } else { - assert list.isWritable() : PsiUtilBase.getVirtualFile(list); - list.addBefore(newElement, oldElement); - if (list.equals(newElement.getParent())) { - newElement.delete(); + Child oldElement = index < elements.size() ? elements.get(index) : null; + Child newElement = newElements.get(index); + if (newElement != null) { + if (!newElement.equals(oldElement)) { + if (oldElement != null && elementsToRemove.contains(oldElement)) { + oldElement.delete(); + index--; + } + else { + assert list.isWritable() : PsiUtilBase.getVirtualFile(list); + list.addBefore(newElement, oldElement); + if (list.equals(newElement.getParent())) { + newElement.delete(); + } + } + } + } + else { + if (newElements.size() > 1 && (!elements.isEmpty() || index < newElements.size() - 1)) { + PsiElement anchor; + if (index == 0) { + anchor = list.getFirstChild(); + } + else { + anchor = index - 1 < elements.size() ? elements.get(index - 1) : null; + } + final PsiElement psi = Factory.createSingleLeafElement( + JavaTokenType.COMMA, + ",", + 0, + 1, + SharedImplUtil.findCharTableByTree(list.getNode()), + list.getManager() + ).getPsi(); + if (anchor != null) { + list.addAfter(psi, anchor); + } + else { + list.add(psi); + } + } } - } + index++; } - } else { - if (newElements.size() > 1 && (!elements.isEmpty() || index < newElements.size() - 1)) { - PsiElement anchor; - if (index == 0) { - anchor = list.getFirstChild(); - } else { - anchor = index - 1 < elements.size() ? elements.get(index - 1) : null; - } - final PsiElement psi = Factory.createSingleLeafElement(JavaTokenType.COMMA, ",", 0, 1, SharedImplUtil.findCharTableByTree(list.getNode()), list.getManager()).getPsi(); - if (anchor != null) { - list.addAfter(psi, anchor); - } else { - list.add(psi); - } + for (int i = newElements.size(); i < elements.size(); i++) { + Child element = elements.get(i); + element.delete(); } - } - index++; - } - for (int i = newElements.size(); i < elements.size(); i++) { - Child element = elements.get(i); - element.delete(); } - } - public static void invokeChangeSignatureOn(PsiMethod method, Project project) { - final ChangeSignatureHandler handler = RefactoringSupportProvider.forLanguage(method.getLanguage()).getChangeSignatureHandler(); - handler.invoke(project, new PsiElement[]{method}, null); - } - - public static boolean deepTypeEqual(PsiType type1, PsiType type2) { - if (type1 == type2) { - return true; + public static void invokeChangeSignatureOn(PsiMethod method, Project project) { + final ChangeSignatureHandler handler = RefactoringSupportProvider.forLanguage(method.getLanguage()).getChangeSignatureHandler(); + handler.invoke(project, new PsiElement[]{method}, null); } - if (type1 == null || !type1.equals(type2)) { - return false; + + public static boolean deepTypeEqual(PsiType type1, PsiType type2) { + if (type1 == type2) { + return true; + } + if (type1 == null || !type1.equals(type2)) { + return false; + } + return Comparing.equal(type1.getCanonicalText(true), type2.getCanonicalText(true)); } - return Comparing.equal(type1.getCanonicalText(true), type2.getCanonicalText(true)); - } - public interface ChildrenGenerator { - List getChildren(Parent parent); - } + public interface ChildrenGenerator { + List getChildren(Parent parent); + } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java index ba1ada650..3532eda5b 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java @@ -75,953 +75,1094 @@ */ @ExtensionImpl(id = "javaProcessor") public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsageProcessorEx { - private static final Logger LOG = Logger.getInstance(JavaChangeSignatureUsageProcessor.class); + private static final Logger LOG = Logger.getInstance(JavaChangeSignatureUsageProcessor.class); - private static boolean isJavaUsage(UsageInfo info) { - final PsiElement element = info.getElement(); - if (element == null) { - return false; - } - return element.getLanguage() == JavaLanguage.INSTANCE; - } - - @Override - public UsageInfo[] findUsages(ChangeInfo info) { - if (info instanceof JavaChangeInfo) { - return new JavaChangeSignatureUsageSearcher((JavaChangeInfo) info).findUsages(); - } else { - return UsageInfo.EMPTY_ARRAY; - } - } - - @Override - public MultiMap findConflicts(ChangeInfo info, Ref refUsages) { - if (info instanceof JavaChangeInfo) { - return new ConflictSearcher((JavaChangeInfo) info).findConflicts(refUsages); - } else { - return new MultiMap(); + private static boolean isJavaUsage(UsageInfo info) { + final PsiElement element = info.getElement(); + if (element == null) { + return false; + } + return element.getLanguage() == JavaLanguage.INSTANCE; } - } - @Override - public boolean processUsage(ChangeInfo changeInfo, UsageInfo usage, boolean beforeMethodChange, UsageInfo[] usages) { - if (!isJavaUsage(usage)) { - return false; - } - if (!(changeInfo instanceof JavaChangeInfo)) { - return false; + @Override + public UsageInfo[] findUsages(ChangeInfo info) { + if (info instanceof JavaChangeInfo) { + return new JavaChangeSignatureUsageSearcher((JavaChangeInfo)info).findUsages(); + } + else { + return UsageInfo.EMPTY_ARRAY; + } } + @Override + public MultiMap findConflicts(ChangeInfo info, Ref refUsages) { + if (info instanceof JavaChangeInfo) { + return new ConflictSearcher((JavaChangeInfo)info).findConflicts(refUsages); + } + else { + return new MultiMap(); + } + } - if (beforeMethodChange) { - if (usage instanceof CallerUsageInfo) { - final CallerUsageInfo callerUsageInfo = (CallerUsageInfo) usage; - processCallerMethod((JavaChangeInfo) changeInfo, callerUsageInfo.getMethod(), null, callerUsageInfo.isToInsertParameter(), callerUsageInfo.isToInsertException()); - return true; - } else if (usage instanceof OverriderUsageInfo) { - OverriderUsageInfo info = (OverriderUsageInfo) usage; - final PsiMethod method = info.getElement(); - final PsiMethod baseMethod = info.getBaseMethod(); - if (info.isOriginalOverrider()) { - processPrimaryMethod((JavaChangeInfo) changeInfo, method, baseMethod, false); - } else { - processCallerMethod((JavaChangeInfo) changeInfo, method, baseMethod, info.isToInsertArgs(), info.isToCatchExceptions()); + @Override + public boolean processUsage(ChangeInfo changeInfo, UsageInfo usage, boolean beforeMethodChange, UsageInfo[] usages) { + if (!isJavaUsage(usage)) { + return false; } - return true; - } - - } else { - PsiElement element = usage.getElement(); - LOG.assertTrue(element != null); - - if (usage instanceof DefaultConstructorImplicitUsageInfo) { - final DefaultConstructorImplicitUsageInfo defConstructorUsage = (DefaultConstructorImplicitUsageInfo) usage; - PsiMethod constructor = defConstructorUsage.getConstructor(); - if (!constructor.isPhysical()) { - final boolean toPropagate = changeInfo instanceof JavaChangeInfoImpl && ((JavaChangeInfoImpl) changeInfo).propagateParametersMethods.remove(constructor); - final PsiClass containingClass = defConstructorUsage.getContainingClass(); - constructor = (PsiMethod) containingClass.add(constructor); - PsiUtil.setModifierProperty(constructor, VisibilityUtil.getVisibilityModifier(containingClass.getModifierList()), true); - if (toPropagate) { - ((JavaChangeInfoImpl) changeInfo).propagateParametersMethods.add(constructor); - } + if (!(changeInfo instanceof JavaChangeInfo)) { + return false; } - addSuperCall((JavaChangeInfo) changeInfo, constructor, defConstructorUsage.getBaseConstructor(), usages); - return true; - } else if (usage instanceof NoConstructorClassUsageInfo) { - addDefaultConstructor(((JavaChangeInfo) changeInfo), ((NoConstructorClassUsageInfo) usage).getPsiClass(), usages); - return true; - } else if (usage instanceof MethodCallUsageInfo) { - final MethodCallUsageInfo methodCallInfo = (MethodCallUsageInfo) usage; - processMethodUsage(methodCallInfo.getElement(), (JavaChangeInfo) changeInfo, methodCallInfo.isToChangeArguments(), methodCallInfo.isToCatchExceptions(), methodCallInfo - .getReferencedMethod(), methodCallInfo.getSubstitutor(), usages); - return true; - } else if (usage instanceof ChangeSignatureParameterUsageInfo) { - String newName = ((ChangeSignatureParameterUsageInfo) usage).newParameterName; - String oldName = ((ChangeSignatureParameterUsageInfo) usage).oldParameterName; - processParameterUsage((PsiReferenceExpression) element, oldName, newName); - return true; - } else if (usage instanceof CallReferenceUsageInfo) { - ((CallReferenceUsageInfo) usage).getReference().handleChangeSignature(changeInfo); - return true; - } else if (element instanceof PsiEnumConstant) { - fixActualArgumentsList(((PsiEnumConstant) element).getArgumentList(), (JavaChangeInfo) changeInfo, true, PsiSubstitutor.EMPTY); - return true; - } else if (!(usage instanceof OverriderUsageInfo)) { - PsiReference reference = usage instanceof MoveRenameUsageInfo ? usage.getReference() : element.getReference(); - if (reference != null) { - PsiElement target = changeInfo.getMethod(); - if (target != null) { - reference.bindToElement(target); - } + + + if (beforeMethodChange) { + if (usage instanceof CallerUsageInfo) { + final CallerUsageInfo callerUsageInfo = (CallerUsageInfo)usage; + processCallerMethod( + (JavaChangeInfo)changeInfo, + callerUsageInfo.getMethod(), + null, + callerUsageInfo.isToInsertParameter(), + callerUsageInfo.isToInsertException() + ); + return true; + } + else if (usage instanceof OverriderUsageInfo) { + OverriderUsageInfo info = (OverriderUsageInfo)usage; + final PsiMethod method = info.getElement(); + final PsiMethod baseMethod = info.getBaseMethod(); + if (info.isOriginalOverrider()) { + processPrimaryMethod((JavaChangeInfo)changeInfo, method, baseMethod, false); + } + else { + processCallerMethod((JavaChangeInfo)changeInfo, method, baseMethod, info.isToInsertArgs(), info.isToCatchExceptions()); + } + return true; + } + } - } + else { + PsiElement element = usage.getElement(); + LOG.assertTrue(element != null); + + if (usage instanceof DefaultConstructorImplicitUsageInfo) { + final DefaultConstructorImplicitUsageInfo defConstructorUsage = (DefaultConstructorImplicitUsageInfo)usage; + PsiMethod constructor = defConstructorUsage.getConstructor(); + if (!constructor.isPhysical()) { + final boolean toPropagate = changeInfo instanceof JavaChangeInfoImpl + && ((JavaChangeInfoImpl)changeInfo).propagateParametersMethods.remove(constructor); + final PsiClass containingClass = defConstructorUsage.getContainingClass(); + constructor = (PsiMethod)containingClass.add(constructor); + PsiUtil.setModifierProperty(constructor, VisibilityUtil.getVisibilityModifier(containingClass.getModifierList()), true); + if (toPropagate) { + ((JavaChangeInfoImpl)changeInfo).propagateParametersMethods.add(constructor); + } + } + addSuperCall((JavaChangeInfo)changeInfo, constructor, defConstructorUsage.getBaseConstructor(), usages); + return true; + } + else if (usage instanceof NoConstructorClassUsageInfo) { + addDefaultConstructor(((JavaChangeInfo)changeInfo), ((NoConstructorClassUsageInfo)usage).getPsiClass(), usages); + return true; + } + else if (usage instanceof MethodCallUsageInfo) { + final MethodCallUsageInfo methodCallInfo = (MethodCallUsageInfo)usage; + processMethodUsage( + methodCallInfo.getElement(), + (JavaChangeInfo)changeInfo, + methodCallInfo.isToChangeArguments(), + methodCallInfo.isToCatchExceptions(), + methodCallInfo.getReferencedMethod(), + methodCallInfo.getSubstitutor(), + usages + ); + return true; + } + else if (usage instanceof ChangeSignatureParameterUsageInfo) { + String newName = ((ChangeSignatureParameterUsageInfo)usage).newParameterName; + String oldName = ((ChangeSignatureParameterUsageInfo)usage).oldParameterName; + processParameterUsage((PsiReferenceExpression)element, oldName, newName); + return true; + } + else if (usage instanceof CallReferenceUsageInfo) { + ((CallReferenceUsageInfo)usage).getReference().handleChangeSignature(changeInfo); + return true; + } + else if (element instanceof PsiEnumConstant) { + fixActualArgumentsList( + ((PsiEnumConstant)element).getArgumentList(), + (JavaChangeInfo)changeInfo, + true, + PsiSubstitutor.EMPTY + ); + return true; + } + else if (!(usage instanceof OverriderUsageInfo)) { + PsiReference reference = usage instanceof MoveRenameUsageInfo ? usage.getReference() : element.getReference(); + if (reference != null) { + PsiElement target = changeInfo.getMethod(); + if (target != null) { + reference.bindToElement(target); + } + } + } + } + return false; } - return false; - } - private static void processParameterUsage(PsiReferenceExpression ref, String oldName, String newName) throws IncorrectOperationException { + private static void processParameterUsage( + PsiReferenceExpression ref, + String oldName, + String newName + ) throws IncorrectOperationException { + PsiElement last = ref.getReferenceNameElement(); + if (last instanceof PsiIdentifier && last.getText().equals(oldName)) { + PsiElementFactory factory = JavaPsiFacade.getInstance(ref.getProject()).getElementFactory(); + PsiIdentifier newNameIdentifier = factory.createIdentifier(newName); + last.replace(newNameIdentifier); + } + } - PsiElement last = ref.getReferenceNameElement(); - if (last instanceof PsiIdentifier && last.getText().equals(oldName)) { - PsiElementFactory factory = JavaPsiFacade.getInstance(ref.getProject()).getElementFactory(); - PsiIdentifier newNameIdentifier = factory.createIdentifier(newName); - last.replace(newNameIdentifier); + private static void addDefaultConstructor( + JavaChangeInfo changeInfo, + PsiClass aClass, + final UsageInfo[] usages + ) throws IncorrectOperationException { + if (!(aClass instanceof PsiAnonymousClass)) { + PsiElementFactory factory = JavaPsiFacade.getElementFactory(aClass.getProject()); + PsiMethod defaultConstructor = factory.createMethodFromText(aClass.getName() + "(){}", aClass); + defaultConstructor = (PsiMethod)CodeStyleManager.getInstance(aClass.getProject()).reformat(defaultConstructor); + defaultConstructor = (PsiMethod)aClass.add(defaultConstructor); + PsiUtil.setModifierProperty(defaultConstructor, VisibilityUtil.getVisibilityModifier(aClass.getModifierList()), true); + addSuperCall(changeInfo, defaultConstructor, null, usages); + } + else { + final PsiElement parent = aClass.getParent(); + if (parent instanceof PsiNewExpression) { + final PsiExpressionList argumentList = ((PsiNewExpression)parent).getArgumentList(); + final PsiClass baseClass = changeInfo.getMethod().getContainingClass(); + final PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(baseClass, aClass, PsiSubstitutor.EMPTY); + fixActualArgumentsList(argumentList, changeInfo, true, substitutor); + } + } } - } - - - private static void addDefaultConstructor(JavaChangeInfo changeInfo, PsiClass aClass, final UsageInfo[] usages) throws IncorrectOperationException { - if (!(aClass instanceof PsiAnonymousClass)) { - PsiElementFactory factory = JavaPsiFacade.getElementFactory(aClass.getProject()); - PsiMethod defaultConstructor = factory.createMethodFromText(aClass.getName() + "(){}", aClass); - defaultConstructor = (PsiMethod) CodeStyleManager.getInstance(aClass.getProject()).reformat(defaultConstructor); - defaultConstructor = (PsiMethod) aClass.add(defaultConstructor); - PsiUtil.setModifierProperty(defaultConstructor, VisibilityUtil.getVisibilityModifier(aClass.getModifierList()), true); - addSuperCall(changeInfo, defaultConstructor, null, usages); - } else { - final PsiElement parent = aClass.getParent(); - if (parent instanceof PsiNewExpression) { - final PsiExpressionList argumentList = ((PsiNewExpression) parent).getArgumentList(); + + private static void addSuperCall( + JavaChangeInfo changeInfo, + PsiMethod constructor, + PsiMethod callee, + final UsageInfo[] usages + ) throws IncorrectOperationException { + final PsiElementFactory factory = JavaPsiFacade.getElementFactory(constructor.getProject()); + PsiExpressionStatement superCall = (PsiExpressionStatement)factory.createStatementFromText("super();", constructor); + PsiCodeBlock body = constructor.getBody(); + assert body != null; + PsiStatement[] statements = body.getStatements(); + if (statements.length > 0) { + superCall = (PsiExpressionStatement)body.addBefore(superCall, statements[0]); + } + else { + superCall = (PsiExpressionStatement)body.add(superCall); + } + PsiMethodCallExpression callExpression = (PsiMethodCallExpression)superCall.getExpression(); + final PsiClass aClass = constructor.getContainingClass(); final PsiClass baseClass = changeInfo.getMethod().getContainingClass(); final PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(baseClass, aClass, PsiSubstitutor.EMPTY); - fixActualArgumentsList(argumentList, changeInfo, true, substitutor); - } - } - } - - private static void addSuperCall(JavaChangeInfo changeInfo, PsiMethod constructor, PsiMethod callee, final UsageInfo[] usages) throws IncorrectOperationException { - final PsiElementFactory factory = JavaPsiFacade.getElementFactory(constructor.getProject()); - PsiExpressionStatement superCall = (PsiExpressionStatement) factory.createStatementFromText("super();", constructor); - PsiCodeBlock body = constructor.getBody(); - assert body != null; - PsiStatement[] statements = body.getStatements(); - if (statements.length > 0) { - superCall = (PsiExpressionStatement) body.addBefore(superCall, statements[0]); - } else { - superCall = (PsiExpressionStatement) body.add(superCall); + processMethodUsage(callExpression.getMethodExpression(), changeInfo, true, false, callee, substitutor, usages); } - PsiMethodCallExpression callExpression = (PsiMethodCallExpression) superCall.getExpression(); - final PsiClass aClass = constructor.getContainingClass(); - final PsiClass baseClass = changeInfo.getMethod().getContainingClass(); - final PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(baseClass, aClass, PsiSubstitutor.EMPTY); - processMethodUsage(callExpression.getMethodExpression(), changeInfo, true, false, callee, substitutor, usages); - } - - private static void processMethodUsage(PsiElement ref, - JavaChangeInfo changeInfo, - boolean toChangeArguments, - boolean toCatchExceptions, - PsiMethod callee, - PsiSubstitutor subsitutor, - final UsageInfo[] usages) throws IncorrectOperationException { - if (changeInfo.isNameChanged()) { - if (ref instanceof PsiJavaCodeReferenceElement) { - PsiElement last = ((PsiJavaCodeReferenceElement) ref).getReferenceNameElement(); - if (last instanceof PsiIdentifier && last.getText().equals(changeInfo.getOldName())) { - last.replace(changeInfo.getNewNameIdentifier()); + + private static void processMethodUsage( + PsiElement ref, + JavaChangeInfo changeInfo, + boolean toChangeArguments, + boolean toCatchExceptions, + PsiMethod callee, + PsiSubstitutor subsitutor, + final UsageInfo[] usages + ) throws IncorrectOperationException { + if (changeInfo.isNameChanged()) { + if (ref instanceof PsiJavaCodeReferenceElement) { + PsiElement last = ((PsiJavaCodeReferenceElement)ref).getReferenceNameElement(); + if (last instanceof PsiIdentifier && last.getText().equals(changeInfo.getOldName())) { + last.replace(changeInfo.getNewNameIdentifier()); + } + } } - } - } - final PsiMethod caller = RefactoringUtil.getEnclosingMethod(ref); - if (toChangeArguments) { - final PsiExpressionList list = RefactoringUtil.getArgumentListByMethodReference(ref); - LOG.assertTrue(list != null); - boolean toInsertDefaultValue = needDefaultValue(changeInfo, caller); - if (toInsertDefaultValue && ref instanceof PsiReferenceExpression) { - final PsiExpression qualifierExpression = ((PsiReferenceExpression) ref).getQualifierExpression(); - if (qualifierExpression instanceof PsiSuperExpression && callerSignatureIsAboutToChangeToo(caller, usages)) { - toInsertDefaultValue = false; + final PsiMethod caller = RefactoringUtil.getEnclosingMethod(ref); + if (toChangeArguments) { + final PsiExpressionList list = RefactoringUtil.getArgumentListByMethodReference(ref); + LOG.assertTrue(list != null); + boolean toInsertDefaultValue = needDefaultValue(changeInfo, caller); + if (toInsertDefaultValue && ref instanceof PsiReferenceExpression) { + final PsiExpression qualifierExpression = ((PsiReferenceExpression)ref).getQualifierExpression(); + if (qualifierExpression instanceof PsiSuperExpression && callerSignatureIsAboutToChangeToo(caller, usages)) { + toInsertDefaultValue = false; + } + } + + fixActualArgumentsList(list, changeInfo, toInsertDefaultValue, subsitutor); } - } - fixActualArgumentsList(list, changeInfo, toInsertDefaultValue, subsitutor); + if (toCatchExceptions) { + if (!(ref instanceof PsiReferenceExpression + && JavaHighlightUtil.isSuperOrThisCall(PsiTreeUtil.getParentOfType(ref, PsiStatement.class), true, false))) { + if (needToCatchExceptions(changeInfo, caller)) { + PsiClassType[] newExceptions = + callee != null ? getCalleeChangedExceptionInfo(callee) : getPrimaryChangedExceptionInfo(changeInfo); + fixExceptions(ref, newExceptions); + } + } + } } - if (toCatchExceptions) { - if (!(ref instanceof PsiReferenceExpression && JavaHighlightUtil.isSuperOrThisCall(PsiTreeUtil.getParentOfType(ref, PsiStatement.class), true, false))) { - if (needToCatchExceptions(changeInfo, caller)) { - PsiClassType[] newExceptions = callee != null ? getCalleeChangedExceptionInfo(callee) : getPrimaryChangedExceptionInfo(changeInfo); - fixExceptions(ref, newExceptions); + private static boolean callerSignatureIsAboutToChangeToo(final PsiMethod caller, final UsageInfo[] usages) { + for (UsageInfo usage : usages) { + if (usage instanceof MethodCallUsageInfo + && MethodSignatureUtil.isSuperMethod(((MethodCallUsageInfo)usage).getReferencedMethod(), caller)) { + return true; + } } - } + return false; } - } - private static boolean callerSignatureIsAboutToChangeToo(final PsiMethod caller, final UsageInfo[] usages) { - for (UsageInfo usage : usages) { - if (usage instanceof MethodCallUsageInfo && MethodSignatureUtil.isSuperMethod(((MethodCallUsageInfo) usage).getReferencedMethod(), caller)) { - return true; - } + private static PsiClassType[] getCalleeChangedExceptionInfo(final PsiMethod callee) { + return callee.getThrowsList().getReferencedTypes(); //Callee method's throws list is already modified! } - return false; - } - - private static PsiClassType[] getCalleeChangedExceptionInfo(final PsiMethod callee) { - return callee.getThrowsList().getReferencedTypes(); //Callee method's throws list is already modified! - } - - private static void fixExceptions(PsiElement ref, PsiClassType[] newExceptions) throws IncorrectOperationException { - //methods' throws lists are already modified, may use ExceptionUtil.collectUnhandledExceptions - newExceptions = filterCheckedExceptions(newExceptions); - - PsiElement context = PsiTreeUtil.getParentOfType(ref, PsiTryStatement.class, PsiMethod.class); - if (context instanceof PsiTryStatement) { - PsiTryStatement tryStatement = (PsiTryStatement) context; - PsiCodeBlock tryBlock = tryStatement.getTryBlock(); - - //Remove unused catches - Collection classes = ExceptionUtil.collectUnhandledExceptions(tryBlock, tryBlock); - PsiParameter[] catchParameters = tryStatement.getCatchBlockParameters(); - for (PsiParameter parameter : catchParameters) { - final PsiType caughtType = parameter.getType(); - - if (!(caughtType instanceof PsiClassType)) { - continue; + + private static void fixExceptions(PsiElement ref, PsiClassType[] newExceptions) throws IncorrectOperationException { + //methods' throws lists are already modified, may use ExceptionUtil.collectUnhandledExceptions + newExceptions = filterCheckedExceptions(newExceptions); + + PsiElement context = PsiTreeUtil.getParentOfType(ref, PsiTryStatement.class, PsiMethod.class); + if (context instanceof PsiTryStatement) { + PsiTryStatement tryStatement = (PsiTryStatement)context; + PsiCodeBlock tryBlock = tryStatement.getTryBlock(); + + //Remove unused catches + Collection classes = ExceptionUtil.collectUnhandledExceptions(tryBlock, tryBlock); + PsiParameter[] catchParameters = tryStatement.getCatchBlockParameters(); + for (PsiParameter parameter : catchParameters) { + final PsiType caughtType = parameter.getType(); + + if (!(caughtType instanceof PsiClassType)) { + continue; + } + if (ExceptionUtil.isUncheckedExceptionOrSuperclass((PsiClassType)caughtType)) { + continue; + } + + if (!isCatchParameterRedundant((PsiClassType)caughtType, classes)) { + continue; + } + parameter.getParent().delete(); //delete catch section + } + + PsiClassType[] exceptionsToAdd = filterUnhandledExceptions(newExceptions, tryBlock); + addExceptions(exceptionsToAdd, tryStatement); + + adjustPossibleEmptyTryStatement(tryStatement); } - if (ExceptionUtil.isUncheckedExceptionOrSuperclass((PsiClassType) caughtType)) { - continue; + else { + newExceptions = filterUnhandledExceptions(newExceptions, ref); + if (newExceptions.length > 0) { + //Add new try statement + PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(ref.getProject()); + PsiTryStatement tryStatement = + (PsiTryStatement)elementFactory.createStatementFromText("try {} catch (Exception e) {}", null); + PsiStatement anchor = PsiTreeUtil.getParentOfType(ref, PsiStatement.class); + LOG.assertTrue(anchor != null); + tryStatement.getTryBlock().add(anchor); + tryStatement = (PsiTryStatement)anchor.getParent().addAfter(tryStatement, anchor); + + addExceptions(newExceptions, tryStatement); + anchor.delete(); + tryStatement.getCatchSections()[0].delete(); //Delete dummy catch section + } } + } - if (!isCatchParameterRedundant((PsiClassType) caughtType, classes)) { - continue; + private static PsiClassType[] filterCheckedExceptions(PsiClassType[] exceptions) { + List result = new ArrayList(); + for (PsiClassType exceptionType : exceptions) { + if (!ExceptionUtil.isUncheckedException(exceptionType)) { + result.add(exceptionType); + } } - parameter.getParent().delete(); //delete catch section - } - - PsiClassType[] exceptionsToAdd = filterUnhandledExceptions(newExceptions, tryBlock); - addExceptions(exceptionsToAdd, tryStatement); - - adjustPossibleEmptyTryStatement(tryStatement); - } else { - newExceptions = filterUnhandledExceptions(newExceptions, ref); - if (newExceptions.length > 0) { - //Add new try statement - PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(ref.getProject()); - PsiTryStatement tryStatement = (PsiTryStatement) elementFactory.createStatementFromText("try {} catch (Exception e) {}", null); - PsiStatement anchor = PsiTreeUtil.getParentOfType(ref, PsiStatement.class); - LOG.assertTrue(anchor != null); - tryStatement.getTryBlock().add(anchor); - tryStatement = (PsiTryStatement) anchor.getParent().addAfter(tryStatement, anchor); - - addExceptions(newExceptions, tryStatement); - anchor.delete(); - tryStatement.getCatchSections()[0].delete(); //Delete dummy catch section - } + return result.toArray(new PsiClassType[result.size()]); } - } - - private static PsiClassType[] filterCheckedExceptions(PsiClassType[] exceptions) { - List result = new ArrayList(); - for (PsiClassType exceptionType : exceptions) { - if (!ExceptionUtil.isUncheckedException(exceptionType)) { - result.add(exceptionType); - } - } - return result.toArray(new PsiClassType[result.size()]); - } - - private static void adjustPossibleEmptyTryStatement(PsiTryStatement tryStatement) throws IncorrectOperationException { - PsiCodeBlock tryBlock = tryStatement.getTryBlock(); - if (tryBlock != null) { - if (tryStatement.getCatchSections().length == 0 && tryStatement.getFinallyBlock() == null) { - PsiElement firstBodyElement = tryBlock.getFirstBodyElement(); - if (firstBodyElement != null) { - tryStatement.getParent().addRangeAfter(firstBodyElement, tryBlock.getLastBodyElement(), tryStatement); + + private static void adjustPossibleEmptyTryStatement(PsiTryStatement tryStatement) throws IncorrectOperationException { + PsiCodeBlock tryBlock = tryStatement.getTryBlock(); + if (tryBlock != null) { + if (tryStatement.getCatchSections().length == 0 && tryStatement.getFinallyBlock() == null) { + PsiElement firstBodyElement = tryBlock.getFirstBodyElement(); + if (firstBodyElement != null) { + tryStatement.getParent().addRangeAfter(firstBodyElement, tryBlock.getLastBodyElement(), tryStatement); + } + tryStatement.delete(); + } } - tryStatement.delete(); - } } - } - private static void addExceptions(PsiClassType[] exceptionsToAdd, PsiTryStatement tryStatement) throws IncorrectOperationException { - for (PsiClassType type : exceptionsToAdd) { - final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(tryStatement.getProject()); - String name = styleManager.suggestVariableName(VariableKind.PARAMETER, null, null, type).names[0]; - name = styleManager.suggestUniqueVariableName(name, tryStatement, false); + private static void addExceptions(PsiClassType[] exceptionsToAdd, PsiTryStatement tryStatement) throws IncorrectOperationException { + for (PsiClassType type : exceptionsToAdd) { + final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(tryStatement.getProject()); + String name = styleManager.suggestVariableName(VariableKind.PARAMETER, null, null, type).names[0]; + name = styleManager.suggestUniqueVariableName(name, tryStatement, false); - PsiCatchSection catchSection = JavaPsiFacade.getInstance(tryStatement.getProject()).getElementFactory().createCatchSection(type, name, tryStatement); - tryStatement.add(catchSection); - } - } - - private static PsiClassType[] filterUnhandledExceptions(PsiClassType[] exceptions, PsiElement place) { - List result = new ArrayList(); - for (PsiClassType exception : exceptions) { - if (!ExceptionUtil.isHandled(exception, place)) { - result.add(exception); - } - } - return result.toArray(new PsiClassType[result.size()]); - } - - private static boolean isCatchParameterRedundant(PsiClassType catchParamType, Collection thrownTypes) { - for (PsiType exceptionType : thrownTypes) { - if (exceptionType.isConvertibleFrom(catchParamType)) { - return false; - } - } - return true; - } - - //This methods works equally well for primary usages as well as for propagated callers' usages - private static void fixActualArgumentsList(PsiExpressionList list, JavaChangeInfo changeInfo, boolean toInsertDefaultValue, PsiSubstitutor substitutor) throws IncorrectOperationException { - final PsiElementFactory factory = JavaPsiFacade.getInstance(list.getProject()).getElementFactory(); - if (changeInfo.isParameterSetOrOrderChanged()) { - if (changeInfo instanceof JavaChangeInfoImpl && ((JavaChangeInfoImpl) changeInfo).isPropagationEnabled) { - final ParameterInfoImpl[] createdParmsInfo = ((JavaChangeInfoImpl) changeInfo).getCreatedParmsInfoWithoutVarargs(); - for (ParameterInfoImpl info : createdParmsInfo) { - PsiExpression newArg; - if (toInsertDefaultValue) { - newArg = createDefaultValue(changeInfo, factory, info, list); - } else { - newArg = factory.createExpressionFromText(info.getName(), list); - } - if (newArg != null) { - JavaCodeStyleManager.getInstance(list.getProject()).shortenClassReferences(list.add(newArg)); - } - } - } else { - final PsiExpression[] args = list.getExpressions(); - final int nonVarargCount = getNonVarargCount(changeInfo, args); - final int varargCount = args.length - nonVarargCount; - if (varargCount < 0) { - return; + PsiCatchSection catchSection = + JavaPsiFacade.getInstance(tryStatement.getProject()).getElementFactory().createCatchSection(type, name, tryStatement); + tryStatement.add(catchSection); } - PsiExpression[] newVarargInitializers = null; + } - final int newArgsLength; - final int newNonVarargCount; - final JavaParameterInfo[] newParms = changeInfo.getNewParameters(); - if (changeInfo.isArrayToVarargs()) { - newNonVarargCount = newParms.length - 1; - final JavaParameterInfo lastNewParm = newParms[newParms.length - 1]; - final PsiExpression arrayToConvert = args[lastNewParm.getOldIndex()]; - if (arrayToConvert instanceof PsiNewExpression) { - final PsiNewExpression expression = (PsiNewExpression) arrayToConvert; - final PsiArrayInitializerExpression arrayInitializer = expression.getArrayInitializer(); - if (arrayInitializer != null) { - newVarargInitializers = arrayInitializer.getInitializers(); + private static PsiClassType[] filterUnhandledExceptions(PsiClassType[] exceptions, PsiElement place) { + List result = new ArrayList(); + for (PsiClassType exception : exceptions) { + if (!ExceptionUtil.isHandled(exception, place)) { + result.add(exception); } - } - newArgsLength = newVarargInitializers == null ? newParms.length : newNonVarargCount + newVarargInitializers.length; - } else if (changeInfo.isRetainsVarargs()) { - newNonVarargCount = newParms.length - 1; - newArgsLength = newNonVarargCount + varargCount; - } else if (changeInfo.isObtainsVarags()) { - newNonVarargCount = newParms.length - 1; - newArgsLength = newNonVarargCount; - } else { - newNonVarargCount = newParms.length; - newArgsLength = newParms.length; } + return result.toArray(new PsiClassType[result.size()]); + } - String[] oldVarargs = null; - if (changeInfo.wasVararg() && !changeInfo.isRetainsVarargs()) { - oldVarargs = new String[varargCount]; - for (int i = nonVarargCount; i < args.length; i++) { - oldVarargs[i - nonVarargCount] = args[i].getText(); - } + private static boolean isCatchParameterRedundant(PsiClassType catchParamType, Collection thrownTypes) { + for (PsiType exceptionType : thrownTypes) { + if (exceptionType.isConvertibleFrom(catchParamType)) { + return false; + } } + return true; + } - final PsiExpression[] newArgs = new PsiExpression[newArgsLength]; - for (int i = 0; i < newNonVarargCount; i++) { - if (newParms[i].getOldIndex() == nonVarargCount && oldVarargs != null) { - PsiType type = newParms[i].createType(changeInfo.getMethod(), list.getManager()); - if (type instanceof PsiArrayType) { - type = substitutor.substitute(type); - type = TypeConversionUtil.erasure(type); - String typeText = type.getCanonicalText(); - if (type instanceof PsiEllipsisType) { - typeText = typeText.replace("...", "[]"); - } - String text = "new " + typeText + "{" + StringUtil.join(oldVarargs, ",") + "}"; - newArgs[i] = factory.createExpressionFromText(text, changeInfo.getMethod()); - continue; + //This methods works equally well for primary usages as well as for propagated callers' usages + private static void fixActualArgumentsList( + PsiExpressionList list, + JavaChangeInfo changeInfo, + boolean toInsertDefaultValue, + PsiSubstitutor substitutor + ) throws IncorrectOperationException { + final PsiElementFactory factory = JavaPsiFacade.getInstance(list.getProject()).getElementFactory(); + if (changeInfo.isParameterSetOrOrderChanged()) { + if (changeInfo instanceof JavaChangeInfoImpl && ((JavaChangeInfoImpl)changeInfo).isPropagationEnabled) { + final ParameterInfoImpl[] createdParmsInfo = ((JavaChangeInfoImpl)changeInfo).getCreatedParmsInfoWithoutVarargs(); + for (ParameterInfoImpl info : createdParmsInfo) { + PsiExpression newArg; + if (toInsertDefaultValue) { + newArg = createDefaultValue(changeInfo, factory, info, list); + } + else { + newArg = factory.createExpressionFromText(info.getName(), list); + } + if (newArg != null) { + JavaCodeStyleManager.getInstance(list.getProject()).shortenClassReferences(list.add(newArg)); + } + } } - } - newArgs[i] = createActualArgument(changeInfo, list, newParms[i], toInsertDefaultValue, args); - } - if (changeInfo.isArrayToVarargs()) { - if (newVarargInitializers == null) { - newArgs[newNonVarargCount] = createActualArgument(changeInfo, list, newParms[newNonVarargCount], toInsertDefaultValue, args); - } else { - System.arraycopy(newVarargInitializers, 0, newArgs, newNonVarargCount, newVarargInitializers.length); - } - } else { - final int newVarargCount = newArgsLength - newNonVarargCount; - LOG.assertTrue(newVarargCount == 0 || newVarargCount == varargCount); - for (int i = newNonVarargCount; i < newArgsLength; i++) { - final int oldIndex = newParms[newNonVarargCount].getOldIndex(); - if (oldIndex >= 0 && oldIndex != nonVarargCount) { - newArgs[i] = createActualArgument(changeInfo, list, newParms[newNonVarargCount], toInsertDefaultValue, args); - } else { - System.arraycopy(args, nonVarargCount, newArgs, newNonVarargCount, newVarargCount); - break; + else { + final PsiExpression[] args = list.getExpressions(); + final int nonVarargCount = getNonVarargCount(changeInfo, args); + final int varargCount = args.length - nonVarargCount; + if (varargCount < 0) { + return; + } + PsiExpression[] newVarargInitializers = null; + + final int newArgsLength; + final int newNonVarargCount; + final JavaParameterInfo[] newParms = changeInfo.getNewParameters(); + if (changeInfo.isArrayToVarargs()) { + newNonVarargCount = newParms.length - 1; + final JavaParameterInfo lastNewParm = newParms[newParms.length - 1]; + final PsiExpression arrayToConvert = args[lastNewParm.getOldIndex()]; + if (arrayToConvert instanceof PsiNewExpression) { + final PsiNewExpression expression = (PsiNewExpression)arrayToConvert; + final PsiArrayInitializerExpression arrayInitializer = expression.getArrayInitializer(); + if (arrayInitializer != null) { + newVarargInitializers = arrayInitializer.getInitializers(); + } + } + newArgsLength = newVarargInitializers == null ? newParms.length : newNonVarargCount + newVarargInitializers.length; + } + else if (changeInfo.isRetainsVarargs()) { + newNonVarargCount = newParms.length - 1; + newArgsLength = newNonVarargCount + varargCount; + } + else if (changeInfo.isObtainsVarags()) { + newNonVarargCount = newParms.length - 1; + newArgsLength = newNonVarargCount; + } + else { + newNonVarargCount = newParms.length; + newArgsLength = newParms.length; + } + + String[] oldVarargs = null; + if (changeInfo.wasVararg() && !changeInfo.isRetainsVarargs()) { + oldVarargs = new String[varargCount]; + for (int i = nonVarargCount; i < args.length; i++) { + oldVarargs[i - nonVarargCount] = args[i].getText(); + } + } + + final PsiExpression[] newArgs = new PsiExpression[newArgsLength]; + for (int i = 0; i < newNonVarargCount; i++) { + if (newParms[i].getOldIndex() == nonVarargCount && oldVarargs != null) { + PsiType type = newParms[i].createType(changeInfo.getMethod(), list.getManager()); + if (type instanceof PsiArrayType) { + type = substitutor.substitute(type); + type = TypeConversionUtil.erasure(type); + String typeText = type.getCanonicalText(); + if (type instanceof PsiEllipsisType) { + typeText = typeText.replace("...", "[]"); + } + String text = "new " + typeText + "{" + StringUtil.join(oldVarargs, ",") + "}"; + newArgs[i] = factory.createExpressionFromText(text, changeInfo.getMethod()); + continue; + } + } + newArgs[i] = createActualArgument(changeInfo, list, newParms[i], toInsertDefaultValue, args); + } + if (changeInfo.isArrayToVarargs()) { + if (newVarargInitializers == null) { + newArgs[newNonVarargCount] = + createActualArgument(changeInfo, list, newParms[newNonVarargCount], toInsertDefaultValue, args); + } + else { + System.arraycopy(newVarargInitializers, 0, newArgs, newNonVarargCount, newVarargInitializers.length); + } + } + else { + final int newVarargCount = newArgsLength - newNonVarargCount; + LOG.assertTrue(newVarargCount == 0 || newVarargCount == varargCount); + for (int i = newNonVarargCount; i < newArgsLength; i++) { + final int oldIndex = newParms[newNonVarargCount].getOldIndex(); + if (oldIndex >= 0 && oldIndex != nonVarargCount) { + newArgs[i] = createActualArgument(changeInfo, list, newParms[newNonVarargCount], toInsertDefaultValue, args); + } + else { + System.arraycopy(args, nonVarargCount, newArgs, newNonVarargCount, newVarargCount); + break; + } + } + } + ChangeSignatureUtil.synchronizeList(list, Arrays.asList(newArgs), ExpressionList.INSTANCE, changeInfo.toRemoveParm()); } - } } - ChangeSignatureUtil.synchronizeList(list, Arrays.asList(newArgs), ExpressionList.INSTANCE, changeInfo.toRemoveParm()); - } } - } - private static int getNonVarargCount(JavaChangeInfo changeInfo, PsiExpression[] args) { - if (!changeInfo.wasVararg()) { - return args.length; - } - return changeInfo.getOldParameterTypes().length - 1; - } - - - @Nullable - private static PsiExpression createActualArgument(JavaChangeInfo changeInfo, - final PsiExpressionList list, - final JavaParameterInfo info, - final boolean toInsertDefaultValue, - final PsiExpression[] args) throws IncorrectOperationException { - final PsiElementFactory factory = JavaPsiFacade.getInstance(list.getProject()).getElementFactory(); - final int index = info.getOldIndex(); - if (index >= 0) { - return args[index]; - } else { - if (toInsertDefaultValue) { - return createDefaultValue(changeInfo, factory, info, list); - } else { - return factory.createExpressionFromText(info.getName(), list); - } - } - } - - @Nullable - private static PsiExpression createDefaultValue(JavaChangeInfo changeInfo, - final PsiElementFactory factory, - final JavaParameterInfo info, - final PsiExpressionList list) throws IncorrectOperationException { - if (info.isUseAnySingleVariable()) { - final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(list.getProject()).getResolveHelper(); - final PsiType type = info.getTypeWrapper().getType(changeInfo.getMethod(), list.getManager()); - final VariablesProcessor processor = new VariablesProcessor(false) { - @Override - protected boolean check(PsiVariable var, ResolveState state) { - if (var instanceof PsiField && !resolveHelper.isAccessible((PsiField) var, list, null)) { - return false; - } - if (var instanceof PsiLocalVariable && list.getTextRange().getStartOffset() <= var.getTextRange().getStartOffset()) { - return false; - } - if (PsiTreeUtil.isAncestor(var, list, false)) { - return false; - } - final PsiType varType = state.get(PsiSubstitutor.KEY).substitute(var.getType()); - return type.isAssignableFrom(varType); + private static int getNonVarargCount(JavaChangeInfo changeInfo, PsiExpression[] args) { + if (!changeInfo.wasVararg()) { + return args.length; } + return changeInfo.getOldParameterTypes().length - 1; + } - @Override - public boolean execute(@Nonnull PsiElement pe, ResolveState state) { - super.execute(pe, state); - return size() < 2; + + @Nullable + private static PsiExpression createActualArgument( + JavaChangeInfo changeInfo, + final PsiExpressionList list, + final JavaParameterInfo info, + final boolean toInsertDefaultValue, + final PsiExpression[] args + ) throws IncorrectOperationException { + final PsiElementFactory factory = JavaPsiFacade.getInstance(list.getProject()).getElementFactory(); + final int index = info.getOldIndex(); + if (index >= 0) { + return args[index]; } - }; - PsiScopesUtil.treeWalkUp(processor, list, null); - if (processor.size() == 1) { - final PsiVariable result = processor.getResult(0); - return factory.createExpressionFromText(result.getName(), list); - } - if (processor.size() == 0) { - final PsiClass parentClass = PsiTreeUtil.getParentOfType(list, PsiClass.class); - if (parentClass != null) { - PsiClass containingClass = parentClass; - final Set containingClasses = new HashSet(); - while (containingClass != null) { - if (type.isAssignableFrom(factory.createType(containingClass, PsiSubstitutor.EMPTY))) { - containingClasses.add(containingClass); - } - containingClass = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class); - } - if (containingClasses.size() == 1) { - return RefactoringChangeUtil.createThisExpression(parentClass.getManager(), containingClasses.contains(parentClass) ? null : containingClasses.iterator().next()); - } + else if (toInsertDefaultValue) { + return createDefaultValue(changeInfo, factory, info, list); + } + else { + return factory.createExpressionFromText(info.getName(), list); } - } } - final PsiCallExpression callExpression = PsiTreeUtil.getParentOfType(list, PsiCallExpression.class); - final String defaultValue = info.getDefaultValue(); - return callExpression != null ? info.getValue(callExpression) : defaultValue.length() > 0 ? factory.createExpressionFromText(defaultValue, list) : null; - } + @Nullable + private static PsiExpression createDefaultValue( + JavaChangeInfo changeInfo, + final PsiElementFactory factory, + final JavaParameterInfo info, + final PsiExpressionList list + ) throws IncorrectOperationException { + if (info.isUseAnySingleVariable()) { + final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(list.getProject()).getResolveHelper(); + final PsiType type = info.getTypeWrapper().getType(changeInfo.getMethod(), list.getManager()); + final VariablesProcessor processor = new VariablesProcessor(false) { + @Override + protected boolean check(PsiVariable var, ResolveState state) { + if (var instanceof PsiField && !resolveHelper.isAccessible((PsiField)var, list, null)) { + return false; + } + if (var instanceof PsiLocalVariable && list.getTextRange().getStartOffset() <= var.getTextRange().getStartOffset()) { + return false; + } + if (PsiTreeUtil.isAncestor(var, list, false)) { + return false; + } + final PsiType varType = state.get(PsiSubstitutor.KEY).substitute(var.getType()); + return type.isAssignableFrom(varType); + } - @Override - public boolean processPrimaryMethod(ChangeInfo changeInfo) { - if (!JavaLanguage.INSTANCE.equals(changeInfo.getLanguage()) || !(changeInfo instanceof JavaChangeInfo)) { - return false; - } - final PsiElement element = changeInfo.getMethod(); - LOG.assertTrue(element instanceof PsiMethod); - if (changeInfo.isGenerateDelegate()) { - generateDelegate((JavaChangeInfo) changeInfo); - } - processPrimaryMethod((JavaChangeInfo) changeInfo, (PsiMethod) element, null, true); - return true; - } - - @Override - public boolean shouldPreviewUsages(ChangeInfo changeInfo, UsageInfo[] usages) { - return false; - } - - @Override - public boolean setupDefaultValues(ChangeInfo changeInfo, Ref refUsages, Project project) { - if (!(changeInfo instanceof JavaChangeInfo)) { - return false; - } - for (UsageInfo usageInfo : refUsages.get()) { - if (usageInfo instanceof MethodCallUsageInfo) { - MethodCallUsageInfo methodCallUsageInfo = (MethodCallUsageInfo) usageInfo; - if (methodCallUsageInfo.isToChangeArguments()) { - final PsiElement element = methodCallUsageInfo.getElement(); - if (element == null) { - continue; - } - final PsiMethod caller = RefactoringUtil.getEnclosingMethod(element); - final boolean needDefaultValue = needDefaultValue(changeInfo, caller); - if (needDefaultValue && (caller == null || !MethodSignatureUtil.isSuperMethod(methodCallUsageInfo.getReferencedMethod(), caller))) { - final ParameterInfo[] parameters = changeInfo.getNewParameters(); - for (ParameterInfo parameter : parameters) { - final String defaultValue = parameter.getDefaultValue(); - if (defaultValue == null && parameter.getOldIndex() == -1) { - ((ParameterInfoImpl) parameter).setDefaultValue(""); - if (!ApplicationManager.getApplication().isUnitTestMode()) { - final PsiType type = ((ParameterInfoImpl) parameter).getTypeWrapper().getType(element, element.getManager()); - final DefaultValueChooser chooser = new DefaultValueChooser(project, parameter.getName(), PsiTypesUtil.getDefaultValueOfType(type)); - chooser.show(); - if (chooser.isOK()) { - if (chooser.feelLucky()) { - parameter.setUseAnySingleVariable(true); - } else { - ((ParameterInfoImpl) parameter).setDefaultValue(chooser.getDefaultValue()); + @Override + public boolean execute(@Nonnull PsiElement pe, ResolveState state) { + super.execute(pe, state); + return size() < 2; + } + }; + PsiScopesUtil.treeWalkUp(processor, list, null); + if (processor.size() == 1) { + final PsiVariable result = processor.getResult(0); + return factory.createExpressionFromText(result.getName(), list); + } + if (processor.size() == 0) { + final PsiClass parentClass = PsiTreeUtil.getParentOfType(list, PsiClass.class); + if (parentClass != null) { + PsiClass containingClass = parentClass; + final Set containingClasses = new HashSet(); + while (containingClass != null) { + if (type.isAssignableFrom(factory.createType(containingClass, PsiSubstitutor.EMPTY))) { + containingClasses.add(containingClass); + } + containingClass = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class); + } + if (containingClasses.size() == 1) { + return RefactoringChangeUtil.createThisExpression( + parentClass.getManager(), + containingClasses.contains(parentClass) ? null : containingClasses.iterator().next() + ); } - } else { - return true; - } } - } } - } } - } + final PsiCallExpression callExpression = PsiTreeUtil.getParentOfType(list, PsiCallExpression.class); + final String defaultValue = info.getDefaultValue(); + return callExpression != null + ? info.getValue(callExpression) + : defaultValue.length() > 0 + ? factory.createExpressionFromText(defaultValue, list) + : null; } - return false; - } - - @Override - public void registerConflictResolvers(List snapshots, @Nonnull ResolveSnapshotProvider resolveSnapshotProvider, UsageInfo[] usages, ChangeInfo changeInfo) { - snapshots.add(resolveSnapshotProvider.createSnapshot(changeInfo.getMethod())); - for (UsageInfo usage : usages) { - if (usage instanceof OverriderUsageInfo) { - snapshots.add(resolveSnapshotProvider.createSnapshot(usage.getElement())); - } - } - } - - private static boolean needDefaultValue(ChangeInfo changeInfo, PsiMethod method) { - return !(changeInfo instanceof JavaChangeInfoImpl) || !((JavaChangeInfoImpl) changeInfo).propagateParametersMethods.contains(method); - } - - public static void generateDelegate(JavaChangeInfo changeInfo) throws IncorrectOperationException { - final PsiMethod delegate = generateDelegatePrototype(changeInfo); - PsiClass targetClass = changeInfo.getMethod().getContainingClass(); - LOG.assertTrue(targetClass != null); - targetClass.addBefore(delegate, changeInfo.getMethod()); - } - - public static PsiMethod generateDelegatePrototype(JavaChangeInfo changeInfo) { - final PsiMethod delegate = (PsiMethod) changeInfo.getMethod().copy(); - PsiClass targetClass = changeInfo.getMethod().getContainingClass(); - LOG.assertTrue(targetClass != null); - if (targetClass.isInterface() && delegate.getBody() == null) { - delegate.getModifierList().setModifierProperty(PsiModifier.DEFAULT, true); + + + @Override + public boolean processPrimaryMethod(ChangeInfo changeInfo) { + if (!JavaLanguage.INSTANCE.equals(changeInfo.getLanguage()) || !(changeInfo instanceof JavaChangeInfo)) { + return false; + } + final PsiElement element = changeInfo.getMethod(); + LOG.assertTrue(element instanceof PsiMethod); + if (changeInfo.isGenerateDelegate()) { + generateDelegate((JavaChangeInfo)changeInfo); + } + processPrimaryMethod((JavaChangeInfo)changeInfo, (PsiMethod)element, null, true); + return true; } - PsiElementFactory factory = JavaPsiFacade.getElementFactory(targetClass.getProject()); - ChangeSignatureProcessor.makeEmptyBody(factory, delegate); - final PsiCallExpression callExpression = ChangeSignatureProcessor.addDelegatingCallTemplate(delegate, changeInfo.getNewName()); - addDelegateArguments(changeInfo, factory, callExpression); - return delegate; - } - - private static void addDelegateArguments(JavaChangeInfo changeInfo, PsiElementFactory factory, final PsiCallExpression callExpression) throws IncorrectOperationException { - final JavaParameterInfo[] newParms = changeInfo.getNewParameters(); - final String[] oldParameterNames = changeInfo.getOldParameterNames(); - for (int i = 0; i < newParms.length; i++) { - JavaParameterInfo newParm = newParms[i]; - final PsiExpression actualArg; - if (newParm.getOldIndex() >= 0) { - actualArg = factory.createExpressionFromText(oldParameterNames[newParm.getOldIndex()], callExpression); - } else { - actualArg = changeInfo.getValue(i, callExpression); - } - final PsiExpressionList argumentList = callExpression.getArgumentList(); - if (actualArg != null && argumentList != null) { - JavaCodeStyleManager.getInstance(callExpression.getProject()).shortenClassReferences(argumentList.add(actualArg)); - } + + @Override + public boolean shouldPreviewUsages(ChangeInfo changeInfo, UsageInfo[] usages) { + return false; } - } - private static void processPrimaryMethod(JavaChangeInfo changeInfo, PsiMethod method, PsiMethod baseMethod, boolean isOriginal) throws IncorrectOperationException { - PsiElementFactory factory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory(); + @Override + public boolean setupDefaultValues(ChangeInfo changeInfo, Ref refUsages, Project project) { + if (!(changeInfo instanceof JavaChangeInfo)) { + return false; + } + for (UsageInfo usageInfo : refUsages.get()) { + if (usageInfo instanceof MethodCallUsageInfo) { + MethodCallUsageInfo methodCallUsageInfo = (MethodCallUsageInfo)usageInfo; + if (methodCallUsageInfo.isToChangeArguments()) { + final PsiElement element = methodCallUsageInfo.getElement(); + if (element == null) { + continue; + } + final PsiMethod caller = RefactoringUtil.getEnclosingMethod(element); + final boolean needDefaultValue = needDefaultValue(changeInfo, caller); + if (needDefaultValue + && (caller == null || !MethodSignatureUtil.isSuperMethod(methodCallUsageInfo.getReferencedMethod(), caller))) { + final ParameterInfo[] parameters = changeInfo.getNewParameters(); + for (ParameterInfo parameter : parameters) { + final String defaultValue = parameter.getDefaultValue(); + if (defaultValue == null && parameter.getOldIndex() == -1) { + ((ParameterInfoImpl)parameter).setDefaultValue(""); + if (!ApplicationManager.getApplication().isUnitTestMode()) { + final PsiType type = + ((ParameterInfoImpl)parameter).getTypeWrapper().getType(element, element.getManager()); + final DefaultValueChooser chooser = + new DefaultValueChooser(project, parameter.getName(), PsiTypesUtil.getDefaultValueOfType(type)); + chooser.show(); + if (chooser.isOK()) { + if (chooser.feelLucky()) { + parameter.setUseAnySingleVariable(true); + } + else { + ((ParameterInfoImpl)parameter).setDefaultValue(chooser.getDefaultValue()); + } + } + else { + return true; + } + } + } + } + } + } + } + } + return false; + } - if (changeInfo.isVisibilityChanged()) { - PsiModifierList modifierList = method.getModifierList(); - final String highestVisibility = isOriginal ? changeInfo.getNewVisibility() : VisibilityUtil.getHighestVisibility(changeInfo.getNewVisibility(), VisibilityUtil.getVisibilityModifier - (modifierList)); - VisibilityUtil.setVisibility(modifierList, highestVisibility); + @Override + public void registerConflictResolvers( + List snapshots, + @Nonnull ResolveSnapshotProvider resolveSnapshotProvider, + UsageInfo[] usages, + ChangeInfo changeInfo + ) { + snapshots.add(resolveSnapshotProvider.createSnapshot(changeInfo.getMethod())); + for (UsageInfo usage : usages) { + if (usage instanceof OverriderUsageInfo) { + snapshots.add(resolveSnapshotProvider.createSnapshot(usage.getElement())); + } + } } - if (changeInfo.isNameChanged()) { - String newName = baseMethod == null ? changeInfo.getNewName() : RefactoringUtil.suggestNewOverriderName(method.getName(), baseMethod.getName(), changeInfo.getNewName()); + private static boolean needDefaultValue(ChangeInfo changeInfo, PsiMethod method) { + return !(changeInfo instanceof JavaChangeInfoImpl) || !((JavaChangeInfoImpl)changeInfo).propagateParametersMethods.contains(method); + } - if (newName != null && !newName.equals(method.getName())) { - final PsiIdentifier nameId = method.getNameIdentifier(); - assert nameId != null; - nameId.replace(JavaPsiFacade.getInstance(method.getProject()).getElementFactory().createIdentifier(newName)); - } + public static void generateDelegate(JavaChangeInfo changeInfo) throws IncorrectOperationException { + final PsiMethod delegate = generateDelegatePrototype(changeInfo); + PsiClass targetClass = changeInfo.getMethod().getContainingClass(); + LOG.assertTrue(targetClass != null); + targetClass.addBefore(delegate, changeInfo.getMethod()); } - final PsiSubstitutor substitutor = baseMethod == null ? PsiSubstitutor.EMPTY : ChangeSignatureProcessor.calculateSubstitutor(method, baseMethod); + public static PsiMethod generateDelegatePrototype(JavaChangeInfo changeInfo) { + final PsiMethod delegate = (PsiMethod)changeInfo.getMethod().copy(); + PsiClass targetClass = changeInfo.getMethod().getContainingClass(); + LOG.assertTrue(targetClass != null); + if (targetClass.isInterface() && delegate.getBody() == null) { + delegate.getModifierList().setModifierProperty(PsiModifier.DEFAULT, true); + } + PsiElementFactory factory = JavaPsiFacade.getElementFactory(targetClass.getProject()); + ChangeSignatureProcessor.makeEmptyBody(factory, delegate); + final PsiCallExpression callExpression = ChangeSignatureProcessor.addDelegatingCallTemplate(delegate, changeInfo.getNewName()); + addDelegateArguments(changeInfo, factory, callExpression); + return delegate; + } - if (changeInfo.isReturnTypeChanged()) { - PsiType newTypeElement = changeInfo.getNewReturnType().getType(changeInfo.getMethod().getParameterList(), method.getManager()); - final PsiType returnType = substitutor.substitute(newTypeElement); - // don't modify return type for non-Java overriders (EJB) - if (method.getName().equals(changeInfo.getNewName())) { - final PsiTypeElement typeElement = method.getReturnTypeElement(); - if (typeElement != null) { - typeElement.replace(factory.createTypeElement(returnType)); + private static void addDelegateArguments( + JavaChangeInfo changeInfo, + PsiElementFactory factory, + final PsiCallExpression callExpression + ) throws IncorrectOperationException { + final JavaParameterInfo[] newParms = changeInfo.getNewParameters(); + final String[] oldParameterNames = changeInfo.getOldParameterNames(); + for (int i = 0; i < newParms.length; i++) { + JavaParameterInfo newParm = newParms[i]; + final PsiExpression actualArg; + if (newParm.getOldIndex() >= 0) { + actualArg = factory.createExpressionFromText(oldParameterNames[newParm.getOldIndex()], callExpression); + } + else { + actualArg = changeInfo.getValue(i, callExpression); + } + final PsiExpressionList argumentList = callExpression.getArgumentList(); + if (actualArg != null && argumentList != null) { + JavaCodeStyleManager.getInstance(callExpression.getProject()).shortenClassReferences(argumentList.add(actualArg)); + } } - } } - PsiParameterList list = method.getParameterList(); - PsiParameter[] parameters = list.getParameters(); - - final JavaParameterInfo[] parameterInfos = changeInfo.getNewParameters(); - final int delta = baseMethod != null ? baseMethod.getParameterList().getParametersCount() - method.getParameterList().getParametersCount() : 0; - PsiParameter[] newParms = new PsiParameter[Math.max(parameterInfos.length - delta, 0)]; - final String[] oldParameterNames = changeInfo.getOldParameterNames(); - final String[] oldParameterTypes = changeInfo.getOldParameterTypes(); - for (int i = 0; i < newParms.length; i++) { - JavaParameterInfo info = parameterInfos[i]; - int index = info.getOldIndex(); - if (index >= 0) { - PsiParameter parameter = parameters[index]; - newParms[i] = parameter; - - String oldName = oldParameterNames[index]; - if (!oldName.equals(info.getName()) && oldName.equals(parameter.getName())) { - PsiIdentifier newIdentifier = factory.createIdentifier(info.getName()); - parameter.getNameIdentifier().replace(newIdentifier); + private static void processPrimaryMethod( + JavaChangeInfo changeInfo, + PsiMethod method, + PsiMethod baseMethod, + boolean isOriginal + ) throws IncorrectOperationException { + PsiElementFactory factory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory(); + + if (changeInfo.isVisibilityChanged()) { + PsiModifierList modifierList = method.getModifierList(); + final String highestVisibility = isOriginal + ? changeInfo.getNewVisibility() + : VisibilityUtil.getHighestVisibility(changeInfo.getNewVisibility(), VisibilityUtil.getVisibilityModifier(modifierList)); + VisibilityUtil.setVisibility(modifierList, highestVisibility); } - String oldType = oldParameterTypes[index]; - if (!oldType.equals(info.getTypeText())) { - parameter.normalizeDeclaration(); - PsiType newType = substitutor.substitute(info.createType(changeInfo.getMethod().getParameterList(), method.getManager())); + if (changeInfo.isNameChanged()) { + String newName = baseMethod == null + ? changeInfo.getNewName() + : RefactoringUtil.suggestNewOverriderName(method.getName(), baseMethod.getName(), changeInfo.getNewName()); - parameter.getTypeElement().replace(factory.createTypeElement(newType)); + if (newName != null && !newName.equals(method.getName())) { + final PsiIdentifier nameId = method.getNameIdentifier(); + assert nameId != null; + nameId.replace(JavaPsiFacade.getInstance(method.getProject()).getElementFactory().createIdentifier(newName)); + } } - } else { - newParms[i] = createNewParameter(changeInfo, info, substitutor); - } - } + final PsiSubstitutor substitutor = + baseMethod == null ? PsiSubstitutor.EMPTY : ChangeSignatureProcessor.calculateSubstitutor(method, baseMethod); + + if (changeInfo.isReturnTypeChanged()) { + PsiType newTypeElement = changeInfo.getNewReturnType().getType(changeInfo.getMethod().getParameterList(), method.getManager()); + final PsiType returnType = substitutor.substitute(newTypeElement); + // don't modify return type for non-Java overriders (EJB) + if (method.getName().equals(changeInfo.getNewName())) { + final PsiTypeElement typeElement = method.getReturnTypeElement(); + if (typeElement != null) { + typeElement.replace(factory.createTypeElement(returnType)); + } + } + } - resolveParameterVsFieldsConflicts(newParms, method, list, changeInfo.toRemoveParm()); - fixJavadocsForChangedMethod(method, changeInfo, newParms.length); - if (changeInfo.isExceptionSetOrOrderChanged()) { - final PsiClassType[] newExceptions = getPrimaryChangedExceptionInfo(changeInfo); - fixPrimaryThrowsLists(method, newExceptions); - } - } - - private static PsiClassType[] getPrimaryChangedExceptionInfo(JavaChangeInfo changeInfo) throws IncorrectOperationException { - final ThrownExceptionInfo[] newExceptionInfos = changeInfo.getNewExceptions(); - PsiClassType[] newExceptions = new PsiClassType[newExceptionInfos.length]; - final PsiMethod method = changeInfo.getMethod(); - for (int i = 0; i < newExceptions.length; i++) { - newExceptions[i] = (PsiClassType) newExceptionInfos[i].createType(method, method.getManager()); //context really does not matter here - } - return newExceptions; - } - - - private static void processCallerMethod(JavaChangeInfo changeInfo, PsiMethod caller, PsiMethod baseMethod, boolean toInsertParams, boolean toInsertThrows) throws IncorrectOperationException { - LOG.assertTrue(toInsertParams || toInsertThrows); - if (toInsertParams) { - List newParameters = new ArrayList(); - ContainerUtil.addAll(newParameters, caller.getParameterList().getParameters()); - final JavaParameterInfo[] primaryNewParms = changeInfo.getNewParameters(); - PsiSubstitutor substitutor = baseMethod == null ? PsiSubstitutor.EMPTY : ChangeSignatureProcessor.calculateSubstitutor(caller, baseMethod); - final PsiClass aClass = changeInfo.getMethod().getContainingClass(); - final PsiClass callerContainingClass = caller.getContainingClass(); - final PsiSubstitutor psiSubstitutor = aClass != null && callerContainingClass != null && callerContainingClass.isInheritor(aClass, true) ? TypeConversionUtil.getSuperClassSubstitutor - (aClass, callerContainingClass, substitutor) : PsiSubstitutor.EMPTY; - for (JavaParameterInfo info : primaryNewParms) { - if (info.getOldIndex() < 0) { - newParameters.add(createNewParameter(changeInfo, info, psiSubstitutor, substitutor)); + PsiParameterList list = method.getParameterList(); + PsiParameter[] parameters = list.getParameters(); + + final JavaParameterInfo[] parameterInfos = changeInfo.getNewParameters(); + final int delta = + baseMethod != null ? baseMethod.getParameterList().getParametersCount() - method.getParameterList().getParametersCount() : 0; + PsiParameter[] newParms = new PsiParameter[Math.max(parameterInfos.length - delta, 0)]; + final String[] oldParameterNames = changeInfo.getOldParameterNames(); + final String[] oldParameterTypes = changeInfo.getOldParameterTypes(); + for (int i = 0; i < newParms.length; i++) { + JavaParameterInfo info = parameterInfos[i]; + int index = info.getOldIndex(); + if (index >= 0) { + PsiParameter parameter = parameters[index]; + newParms[i] = parameter; + + String oldName = oldParameterNames[index]; + if (!oldName.equals(info.getName()) && oldName.equals(parameter.getName())) { + PsiIdentifier newIdentifier = factory.createIdentifier(info.getName()); + parameter.getNameIdentifier().replace(newIdentifier); + } + + String oldType = oldParameterTypes[index]; + if (!oldType.equals(info.getTypeText())) { + parameter.normalizeDeclaration(); + PsiType newType = + substitutor.substitute(info.createType(changeInfo.getMethod().getParameterList(), method.getManager())); + + parameter.getTypeElement().replace(factory.createTypeElement(newType)); + } + } + else { + newParms[i] = createNewParameter(changeInfo, info, substitutor); + } } - } - PsiParameter[] arrayed = newParameters.toArray(new PsiParameter[newParameters.size()]); - boolean[] toRemoveParm = new boolean[arrayed.length]; - Arrays.fill(toRemoveParm, false); - resolveParameterVsFieldsConflicts(arrayed, caller, caller.getParameterList(), toRemoveParm); - } - if (toInsertThrows) { - List newThrowns = new ArrayList(); - final PsiReferenceList throwsList = caller.getThrowsList(); - ContainerUtil.addAll(newThrowns, throwsList.getReferenceElements()); - final ThrownExceptionInfo[] primaryNewExns = changeInfo.getNewExceptions(); - for (ThrownExceptionInfo thrownExceptionInfo : primaryNewExns) { - if (thrownExceptionInfo.getOldIndex() < 0) { - final PsiClassType type = (PsiClassType) thrownExceptionInfo.createType(caller, caller.getManager()); - final PsiJavaCodeReferenceElement ref = JavaPsiFacade.getInstance(caller.getProject()).getElementFactory().createReferenceElementByType(type); - newThrowns.add(ref); + + resolveParameterVsFieldsConflicts(newParms, method, list, changeInfo.toRemoveParm()); + fixJavadocsForChangedMethod(method, changeInfo, newParms.length); + if (changeInfo.isExceptionSetOrOrderChanged()) { + final PsiClassType[] newExceptions = getPrimaryChangedExceptionInfo(changeInfo); + fixPrimaryThrowsLists(method, newExceptions); } - } - PsiJavaCodeReferenceElement[] arrayed = newThrowns.toArray(new PsiJavaCodeReferenceElement[newThrowns.size()]); - boolean[] toRemoveParm = new boolean[arrayed.length]; - Arrays.fill(toRemoveParm, false); - ChangeSignatureUtil.synchronizeList(throwsList, Arrays.asList(arrayed), ThrowsList.INSTANCE, toRemoveParm); } - } - private static void fixPrimaryThrowsLists(PsiMethod method, PsiClassType[] newExceptions) throws IncorrectOperationException { - PsiElementFactory elementFactory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory(); - PsiJavaCodeReferenceElement[] refs = new PsiJavaCodeReferenceElement[newExceptions.length]; - for (int i = 0; i < refs.length; i++) { - refs[i] = elementFactory.createReferenceElementByType(newExceptions[i]); - } - PsiReferenceList throwsList = elementFactory.createReferenceList(refs); - - PsiReferenceList methodThrowsList = (PsiReferenceList) method.getThrowsList().replace(throwsList); - methodThrowsList = (PsiReferenceList) JavaCodeStyleManager.getInstance(method.getProject()).shortenClassReferences(methodThrowsList); - CodeStyleManager.getInstance(method.getManager().getProject()).reformatRange(method, method.getParameterList().getTextRange().getEndOffset(), methodThrowsList.getTextRange().getEndOffset()); - } - - private static void fixJavadocsForChangedMethod(final PsiMethod method, final JavaChangeInfo changeInfo, int newParamsLength) throws IncorrectOperationException { - final PsiParameter[] parameters = method.getParameterList().getParameters(); - final JavaParameterInfo[] newParms = changeInfo.getNewParameters(); - LOG.assertTrue(parameters.length <= newParamsLength); - final Set newParameters = new HashSet(); - final String[] oldParameterNames = changeInfo.getOldParameterNames(); - for (int i = 0; i < newParamsLength; i++) { - JavaParameterInfo newParm = newParms[i]; - if (newParm.getOldIndex() < 0 || newParm.getOldIndex() == i && !(newParm.getName().equals(oldParameterNames[newParm.getOldIndex()]) && newParm.getTypeText().equals(changeInfo - .getOldParameterTypes()[newParm.getOldIndex()]))) { - newParameters.add(parameters[i]); - } - } - RefactoringUtil.fixJavadocsForParams(method, newParameters, new Condition>() { - @Override - public boolean value(Pair pair) { - final PsiParameter parameter = pair.first; - final String oldParamName = pair.second; - final int idx = Arrays.binarySearch(oldParameterNames, oldParamName); - return idx >= 0 && idx == method.getParameterList().getParameterIndex(parameter) && changeInfo.getNewParameters()[idx].getOldIndex() == idx; - } - }); - } - - private static PsiParameter createNewParameter(JavaChangeInfo changeInfo, JavaParameterInfo newParm, PsiSubstitutor... substitutor) throws IncorrectOperationException { - final PsiParameterList list = changeInfo.getMethod().getParameterList(); - final PsiElementFactory factory = JavaPsiFacade.getInstance(list.getProject()).getElementFactory(); - PsiType type = newParm.createType(list, list.getManager()); - for (PsiSubstitutor psiSubstitutor : substitutor) { - type = psiSubstitutor.substitute(type); - } - return factory.createParameter(newParm.getName(), type); - } - - private static void resolveParameterVsFieldsConflicts(final PsiParameter[] newParms, final PsiMethod method, final PsiParameterList list, boolean[] toRemoveParm) throws - IncorrectOperationException { - List conflictResolvers = new ArrayList(); - for (PsiParameter parameter : newParms) { - conflictResolvers.add(new FieldConflictsResolver(parameter.getName(), method.getBody())); - } - ChangeSignatureUtil.synchronizeList(list, Arrays.asList(newParms), ParameterList.INSTANCE, toRemoveParm); - JavaCodeStyleManager.getInstance(list.getProject()).shortenClassReferences(list); - for (FieldConflictsResolver fieldConflictsResolver : conflictResolvers) { - fieldConflictsResolver.fix(); + private static PsiClassType[] getPrimaryChangedExceptionInfo(JavaChangeInfo changeInfo) throws IncorrectOperationException { + final ThrownExceptionInfo[] newExceptionInfos = changeInfo.getNewExceptions(); + PsiClassType[] newExceptions = new PsiClassType[newExceptionInfos.length]; + final PsiMethod method = changeInfo.getMethod(); + for (int i = 0; i < newExceptions.length; i++) { + newExceptions[i] = + (PsiClassType)newExceptionInfos[i].createType(method, method.getManager()); //context really does not matter here + } + return newExceptions; } - } - private static boolean needToCatchExceptions(JavaChangeInfo changeInfo, PsiMethod caller) { - return changeInfo.isExceptionSetOrOrderChanged() && !(changeInfo instanceof JavaChangeInfoImpl && ((JavaChangeInfoImpl) changeInfo).propagateExceptionsMethods.contains(caller)); - } - private static class ParameterList implements ChangeSignatureUtil.ChildrenGenerator { - public static final ParameterList INSTANCE = new ParameterList(); + private static void processCallerMethod( + JavaChangeInfo changeInfo, + PsiMethod caller, + PsiMethod baseMethod, + boolean toInsertParams, + boolean toInsertThrows + ) throws IncorrectOperationException { + LOG.assertTrue(toInsertParams || toInsertThrows); + if (toInsertParams) { + List newParameters = new ArrayList(); + ContainerUtil.addAll(newParameters, caller.getParameterList().getParameters()); + final JavaParameterInfo[] primaryNewParms = changeInfo.getNewParameters(); + PsiSubstitutor substitutor = + baseMethod == null ? PsiSubstitutor.EMPTY : ChangeSignatureProcessor.calculateSubstitutor(caller, baseMethod); + final PsiClass aClass = changeInfo.getMethod().getContainingClass(); + final PsiClass callerContainingClass = caller.getContainingClass(); + final PsiSubstitutor psiSubstitutor = aClass != null && callerContainingClass != null && callerContainingClass.isInheritor( + aClass, + true + ) ? TypeConversionUtil.getSuperClassSubstitutor + (aClass, callerContainingClass, substitutor) : PsiSubstitutor.EMPTY; + for (JavaParameterInfo info : primaryNewParms) { + if (info.getOldIndex() < 0) { + newParameters.add(createNewParameter(changeInfo, info, psiSubstitutor, substitutor)); + } + } + PsiParameter[] arrayed = newParameters.toArray(new PsiParameter[newParameters.size()]); + boolean[] toRemoveParm = new boolean[arrayed.length]; + Arrays.fill(toRemoveParm, false); + resolveParameterVsFieldsConflicts(arrayed, caller, caller.getParameterList(), toRemoveParm); + } - @Override - public List getChildren(PsiParameterList psiParameterList) { - return Arrays.asList(psiParameterList.getParameters()); + if (toInsertThrows) { + List newThrowns = new ArrayList(); + final PsiReferenceList throwsList = caller.getThrowsList(); + ContainerUtil.addAll(newThrowns, throwsList.getReferenceElements()); + final ThrownExceptionInfo[] primaryNewExns = changeInfo.getNewExceptions(); + for (ThrownExceptionInfo thrownExceptionInfo : primaryNewExns) { + if (thrownExceptionInfo.getOldIndex() < 0) { + final PsiClassType type = (PsiClassType)thrownExceptionInfo.createType(caller, caller.getManager()); + final PsiJavaCodeReferenceElement ref = + JavaPsiFacade.getInstance(caller.getProject()).getElementFactory().createReferenceElementByType(type); + newThrowns.add(ref); + } + } + PsiJavaCodeReferenceElement[] arrayed = newThrowns.toArray(new PsiJavaCodeReferenceElement[newThrowns.size()]); + boolean[] toRemoveParm = new boolean[arrayed.length]; + Arrays.fill(toRemoveParm, false); + ChangeSignatureUtil.synchronizeList(throwsList, Arrays.asList(arrayed), ThrowsList.INSTANCE, toRemoveParm); + } } - } - private static class ThrowsList implements ChangeSignatureUtil.ChildrenGenerator { - public static final ThrowsList INSTANCE = new ThrowsList(); + private static void fixPrimaryThrowsLists(PsiMethod method, PsiClassType[] newExceptions) throws IncorrectOperationException { + PsiElementFactory elementFactory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory(); + PsiJavaCodeReferenceElement[] refs = new PsiJavaCodeReferenceElement[newExceptions.length]; + for (int i = 0; i < refs.length; i++) { + refs[i] = elementFactory.createReferenceElementByType(newExceptions[i]); + } + PsiReferenceList throwsList = elementFactory.createReferenceList(refs); - @Override - public List getChildren(PsiReferenceList throwsList) { - return Arrays.asList(throwsList.getReferenceElements()); + PsiReferenceList methodThrowsList = (PsiReferenceList)method.getThrowsList().replace(throwsList); + methodThrowsList = (PsiReferenceList)JavaCodeStyleManager.getInstance(method.getProject()).shortenClassReferences(methodThrowsList); + CodeStyleManager.getInstance(method.getManager().getProject()) + .reformatRange(method, method.getParameterList().getTextRange().getEndOffset(), methodThrowsList.getTextRange().getEndOffset()); } - } - private static class ConflictSearcher { - private final JavaChangeInfo myChangeInfo; + private static void fixJavadocsForChangedMethod( + final PsiMethod method, + final JavaChangeInfo changeInfo, + int newParamsLength + ) throws IncorrectOperationException { + final PsiParameter[] parameters = method.getParameterList().getParameters(); + final JavaParameterInfo[] newParms = changeInfo.getNewParameters(); + LOG.assertTrue(parameters.length <= newParamsLength); + final Set newParameters = new HashSet(); + final String[] oldParameterNames = changeInfo.getOldParameterNames(); + for (int i = 0; i < newParamsLength; i++) { + JavaParameterInfo newParm = newParms[i]; + if (newParm.getOldIndex() < 0 + || newParm.getOldIndex() == i && !(newParm.getName().equals(oldParameterNames[newParm.getOldIndex()]) + && newParm.getTypeText().equals(changeInfo.getOldParameterTypes()[newParm.getOldIndex()]))) { + newParameters.add(parameters[i]); + } + } + RefactoringUtil.fixJavadocsForParams(method, newParameters, new Condition>() { + @Override + public boolean value(Pair pair) { + final PsiParameter parameter = pair.first; + final String oldParamName = pair.second; + final int idx = Arrays.binarySearch(oldParameterNames, oldParamName); + return idx >= 0 && idx == method.getParameterList().getParameterIndex(parameter) + && changeInfo.getNewParameters()[idx].getOldIndex() == idx; + } + }); + } - private ConflictSearcher(JavaChangeInfo changeInfo) { - this.myChangeInfo = changeInfo; + private static PsiParameter createNewParameter( + JavaChangeInfo changeInfo, + JavaParameterInfo newParm, + PsiSubstitutor... substitutor + ) throws IncorrectOperationException { + final PsiParameterList list = changeInfo.getMethod().getParameterList(); + final PsiElementFactory factory = JavaPsiFacade.getInstance(list.getProject()).getElementFactory(); + PsiType type = newParm.createType(list, list.getManager()); + for (PsiSubstitutor psiSubstitutor : substitutor) { + type = psiSubstitutor.substitute(type); + } + return factory.createParameter(newParm.getName(), type); } - public MultiMap findConflicts(Ref refUsages) { - MultiMap conflictDescriptions = new MultiMap(); - addMethodConflicts(conflictDescriptions); - Set usagesSet = new HashSet(Arrays.asList(refUsages.get())); - RenameUtil.removeConflictUsages(usagesSet); - if (myChangeInfo.isVisibilityChanged()) { - try { - addInaccessibilityDescriptions(usagesSet, conflictDescriptions); - } catch (IncorrectOperationException e) { - LOG.error(e); + private static void resolveParameterVsFieldsConflicts( + final PsiParameter[] newParms, + final PsiMethod method, + final PsiParameterList list, + boolean[] toRemoveParm + ) throws + IncorrectOperationException { + List conflictResolvers = new ArrayList(); + for (PsiParameter parameter : newParms) { + conflictResolvers.add(new FieldConflictsResolver(parameter.getName(), method.getBody())); } - } - - for (UsageInfo usageInfo : usagesSet) { - final PsiElement element = usageInfo.getElement(); - if (usageInfo instanceof OverriderUsageInfo) { - final PsiMethod method = (PsiMethod) element; - final PsiMethod baseMethod = ((OverriderUsageInfo) usageInfo).getBaseMethod(); - final int delta = baseMethod.getParameterList().getParametersCount() - method.getParameterList().getParametersCount(); - if (delta > 0) { - final boolean[] toRemove = myChangeInfo.toRemoveParm(); - if (toRemove[toRemove.length - 1]) { //todo check if implicit parameter is not the last one - conflictDescriptions.putValue(baseMethod, "Implicit last parameter should not be deleted"); - } - } - } else if (element instanceof PsiMethodReferenceExpression) { - conflictDescriptions.putValue(element, "Changed method is used in method reference"); + ChangeSignatureUtil.synchronizeList(list, Arrays.asList(newParms), ParameterList.INSTANCE, toRemoveParm); + JavaCodeStyleManager.getInstance(list.getProject()).shortenClassReferences(list); + for (FieldConflictsResolver fieldConflictsResolver : conflictResolvers) { + fieldConflictsResolver.fix(); } - } - - return conflictDescriptions; } - private boolean needToChangeCalls() { - return myChangeInfo.isNameChanged() || myChangeInfo.isParameterSetOrOrderChanged() || myChangeInfo.isExceptionSetOrOrderChanged(); + private static boolean needToCatchExceptions(JavaChangeInfo changeInfo, PsiMethod caller) { + return changeInfo.isExceptionSetOrOrderChanged() + && !(changeInfo instanceof JavaChangeInfoImpl && ((JavaChangeInfoImpl)changeInfo).propagateExceptionsMethods.contains(caller)); } + private static class ParameterList implements ChangeSignatureUtil.ChildrenGenerator { + public static final ParameterList INSTANCE = new ParameterList(); - private void addInaccessibilityDescriptions(Set usages, MultiMap conflictDescriptions) throws IncorrectOperationException { - PsiMethod method = myChangeInfo.getMethod(); - PsiModifierList modifierList = (PsiModifierList) method.getModifierList().copy(); - VisibilityUtil.setVisibility(modifierList, myChangeInfo.getNewVisibility()); - - for (Iterator iterator = usages.iterator(); iterator.hasNext(); ) { - UsageInfo usageInfo = iterator.next(); - PsiElement element = usageInfo.getElement(); - if (element != null) { - if (element instanceof PsiQualifiedReference) { - PsiClass accessObjectClass = null; - PsiElement qualifier = ((PsiQualifiedReference) element).getQualifier(); - if (qualifier instanceof PsiExpression) { - accessObjectClass = (PsiClass) PsiUtil.getAccessObjectClass((PsiExpression) qualifier).getElement(); - } + @Override + public List getChildren(PsiParameterList psiParameterList) { + return Arrays.asList(psiParameterList.getParameters()); + } + } - if (!JavaPsiFacade.getInstance(element.getProject()).getResolveHelper().isAccessible(method, modifierList, element, accessObjectClass, null)) { - LocalizeValue message = RefactoringLocalize.zeroWith1VisibilityIsNotAccessibleFrom2( - RefactoringUIUtil.getDescription(method, true), - VisibilityUtil.toPresentableText(myChangeInfo.getNewVisibility()), - RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(element), true) - ); - conflictDescriptions.putValue(method, message.get()); - if (!needToChangeCalls()) { - iterator.remove(); - } - } - } + private static class ThrowsList implements ChangeSignatureUtil.ChildrenGenerator { + public static final ThrowsList INSTANCE = new ThrowsList(); + + @Override + public List getChildren(PsiReferenceList throwsList) { + return Arrays.asList(throwsList.getReferenceElements()); } - } } + private static class ConflictSearcher { + private final JavaChangeInfo myChangeInfo; - private void addMethodConflicts(MultiMap conflicts) { - String newMethodName = myChangeInfo.getNewName(); - if (!(myChangeInfo instanceof JavaChangeInfo)) { - return; - } - try { - PsiMethod prototype; - final PsiMethod method = myChangeInfo.getMethod(); - if (!JavaLanguage.INSTANCE.equals(method.getLanguage())) { - return; + private ConflictSearcher(JavaChangeInfo changeInfo) { + this.myChangeInfo = changeInfo; } - PsiManager manager = method.getManager(); - PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); - final CanonicalTypes.Type returnType = myChangeInfo.getNewReturnType(); - if (returnType != null) { - prototype = factory.createMethod(newMethodName, returnType.getType(method, manager)); - } else { - prototype = factory.createConstructor(); - prototype.setName(newMethodName); + + public MultiMap findConflicts(Ref refUsages) { + MultiMap conflictDescriptions = new MultiMap(); + addMethodConflicts(conflictDescriptions); + Set usagesSet = new HashSet(Arrays.asList(refUsages.get())); + RenameUtil.removeConflictUsages(usagesSet); + if (myChangeInfo.isVisibilityChanged()) { + try { + addInaccessibilityDescriptions(usagesSet, conflictDescriptions); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + for (UsageInfo usageInfo : usagesSet) { + final PsiElement element = usageInfo.getElement(); + if (usageInfo instanceof OverriderUsageInfo) { + final PsiMethod method = (PsiMethod)element; + final PsiMethod baseMethod = ((OverriderUsageInfo)usageInfo).getBaseMethod(); + final int delta = baseMethod.getParameterList().getParametersCount() - method.getParameterList().getParametersCount(); + if (delta > 0) { + final boolean[] toRemove = myChangeInfo.toRemoveParm(); + if (toRemove[toRemove.length - 1]) { //todo check if implicit parameter is not the last one + conflictDescriptions.putValue(baseMethod, "Implicit last parameter should not be deleted"); + } + } + } + else if (element instanceof PsiMethodReferenceExpression) { + conflictDescriptions.putValue(element, "Changed method is used in method reference"); + } + } + + return conflictDescriptions; + } + + private boolean needToChangeCalls() { + return myChangeInfo.isNameChanged() || myChangeInfo.isParameterSetOrOrderChanged() || myChangeInfo.isExceptionSetOrOrderChanged(); } - JavaParameterInfo[] parameters = myChangeInfo.getNewParameters(); - for (JavaParameterInfo info : parameters) { - PsiType parameterType = info.createType(method, manager); - if (parameterType == null) { - parameterType = JavaPsiFacade.getElementFactory(method.getProject()).createTypeFromText(JavaClassNames.JAVA_LANG_OBJECT, method); - } - PsiParameter param = factory.createParameter(info.getName(), parameterType); - prototype.getParameterList().add(param); + private void addInaccessibilityDescriptions( + Set usages, + MultiMap conflictDescriptions + ) throws IncorrectOperationException { + PsiMethod method = myChangeInfo.getMethod(); + PsiModifierList modifierList = (PsiModifierList)method.getModifierList().copy(); + VisibilityUtil.setVisibility(modifierList, myChangeInfo.getNewVisibility()); + + for (Iterator iterator = usages.iterator(); iterator.hasNext(); ) { + UsageInfo usageInfo = iterator.next(); + PsiElement element = usageInfo.getElement(); + if (element != null) { + if (element instanceof PsiQualifiedReference) { + PsiClass accessObjectClass = null; + PsiElement qualifier = ((PsiQualifiedReference)element).getQualifier(); + if (qualifier instanceof PsiExpression) { + accessObjectClass = (PsiClass)PsiUtil.getAccessObjectClass((PsiExpression)qualifier).getElement(); + } + + if (!JavaPsiFacade.getInstance(element.getProject()).getResolveHelper() + .isAccessible(method, modifierList, element, accessObjectClass, null)) { + LocalizeValue message = RefactoringLocalize.zeroWith1VisibilityIsNotAccessibleFrom2( + RefactoringUIUtil.getDescription(method, true), + VisibilityUtil.toPresentableText(myChangeInfo.getNewVisibility()), + RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(element), true) + ); + conflictDescriptions.putValue(method, message.get()); + if (!needToChangeCalls()) { + iterator.remove(); + } + } + } + } + } } - ConflictsUtil.checkMethodConflicts(method.getContainingClass(), method, prototype, conflicts); - } catch (IncorrectOperationException e) { - LOG.error(e); - } + + private void addMethodConflicts(MultiMap conflicts) { + String newMethodName = myChangeInfo.getNewName(); + if (!(myChangeInfo instanceof JavaChangeInfo)) { + return; + } + try { + PsiMethod prototype; + final PsiMethod method = myChangeInfo.getMethod(); + if (!JavaLanguage.INSTANCE.equals(method.getLanguage())) { + return; + } + PsiManager manager = method.getManager(); + PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); + final CanonicalTypes.Type returnType = myChangeInfo.getNewReturnType(); + if (returnType != null) { + prototype = factory.createMethod(newMethodName, returnType.getType(method, manager)); + } + else { + prototype = factory.createConstructor(); + prototype.setName(newMethodName); + } + JavaParameterInfo[] parameters = myChangeInfo.getNewParameters(); + + + for (JavaParameterInfo info : parameters) { + PsiType parameterType = info.createType(method, manager); + if (parameterType == null) { + parameterType = JavaPsiFacade.getElementFactory(method.getProject()) + .createTypeFromText(JavaClassNames.JAVA_LANG_OBJECT, method); + } + PsiParameter param = factory.createParameter(info.getName(), parameterType); + prototype.getParameterList().add(param); + } + + ConflictsUtil.checkMethodConflicts(method.getContainingClass(), method, prototype, conflicts); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } } - } - private static class ExpressionList implements ChangeSignatureUtil.ChildrenGenerator { - public static final ExpressionList INSTANCE = new ExpressionList(); + private static class ExpressionList implements ChangeSignatureUtil.ChildrenGenerator { + public static final ExpressionList INSTANCE = new ExpressionList(); - @Override - public List getChildren(PsiExpressionList psiExpressionList) { - return Arrays.asList(psiExpressionList.getExpressions()); + @Override + public List getChildren(PsiExpressionList psiExpressionList) { + return Arrays.asList(psiExpressionList.getExpressions()); + } } - } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractclass/ExtractClassProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractclass/ExtractClassProcessor.java index a41fee354..488ac0619 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractclass/ExtractClassProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractclass/ExtractClassProcessor.java @@ -672,12 +672,14 @@ else if (RefactoringUtil.isAssignmentLHS(exp)) { usages.add( isStatic ? new ReplaceStaticVariableAssignment(exp, qualifiedName) - : new ReplaceInstanceVariableAssignment(PsiTreeUtil.getParentOfType(exp, PsiAssignmentExpression.class), - delegateFieldName, - setter, - getter, - field.getName() - )); + : new ReplaceInstanceVariableAssignment( + PsiTreeUtil.getParentOfType(exp, PsiAssignmentExpression.class), + delegateFieldName, + setter, + getter, + field.getName() + ) + ); } else { usages.add( diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractclass/ExtractEnumProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractclass/ExtractEnumProcessor.java index c3baf35e0..6cca85cf2 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractclass/ExtractEnumProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractclass/ExtractEnumProcessor.java @@ -31,218 +31,181 @@ import consulo.util.lang.function.Functions; import consulo.language.util.IncorrectOperationException; -public class ExtractEnumProcessor -{ - private final Project myProject; - private final List myEnumConstants; - private final PsiClass myClass; - - private TypeMigrationProcessor myTypeMigrationProcessor; - - public ExtractEnumProcessor(Project project, List enumConstants, PsiClass aClass) - { - myProject = project; - myEnumConstants = enumConstants; - myClass = aClass; - } - - - public void findEnumConstantConflicts(final Ref refUsages) - { - if(hasUsages2Migrate()) - { - final List resolvableConflicts = new ArrayList<>(); - for(UsageInfo failedUsage : myTypeMigrationProcessor.getLabeler().getFailedUsages()) - { - final PsiElement element = failedUsage.getElement(); - if(element instanceof PsiReferenceExpression) - { - resolvableConflicts.add(new FixableUsageInfo(element) - { - @Override - public void fixUsage() throws IncorrectOperationException - { - final PsiReferenceExpression expression = (PsiReferenceExpression) element; - final String link = GenerateMembersUtil.suggestGetterName("value", expression.getType(), myProject) + "()"; - MutationUtils.replaceExpression(expression.getReferenceName() + "." + link, expression); - } - }); - } - else if(element != null) - { - resolvableConflicts.add(new ConflictUsageInfo(element, null)); - } - } - if(!resolvableConflicts.isEmpty()) - { - final List usageInfos = new ArrayList<>(Arrays.asList(refUsages.get())); - for(Iterator iterator = resolvableConflicts.iterator(); iterator.hasNext(); ) - { - final UsageInfo conflict = iterator.next(); - for(UsageInfo usageInfo : usageInfos) - { - if(conflict.getElement() == usageInfo.getElement()) - { - iterator.remove(); - break; - } - } - } - resolvableConflicts.addAll(0, usageInfos); - refUsages.set(resolvableConflicts.toArray(UsageInfo.EMPTY_ARRAY)); - } - } - } - - private boolean hasUsages2Migrate() - { - return myTypeMigrationProcessor != null; - } - - public List findEnumConstantUsages(List fieldUsages) - { - final List result = new ArrayList<>(); - if(!myEnumConstants.isEmpty()) - { - final Set switchStatements = new HashSet<>(); - for(UsageInfo usage : fieldUsages) - { - if(usage instanceof ReplaceStaticVariableAccess) - { - final PsiElement element = usage.getElement(); - final PsiSwitchStatement switchStatement = PsiTreeUtil.getParentOfType(element, PsiSwitchStatement.class); - if(switchStatement != null) - { - switchStatements.add(switchStatement); - } - } - } - - final PsiConstantEvaluationHelper evaluationHelper = JavaPsiFacade.getInstance(myProject).getConstantEvaluationHelper(); - final Set enumValues = new HashSet<>(); - for(PsiField enumConstant : myEnumConstants) - { - enumValues.add(evaluationHelper.computeConstantExpression(enumConstant.getInitializer())); - } - final PsiType enumValueType = myEnumConstants.get(0).getType(); - - for(PsiSwitchStatement switchStatement : switchStatements) - { - final PsiStatement errStatement = EnumConstantsUtil.isEnumSwitch(switchStatement, enumValueType, enumValues); - if(errStatement != null) - { - String description = null; - if(errStatement instanceof PsiSwitchLabelStatement) - { - final PsiExpression caseValue = ((PsiSwitchLabelStatement) errStatement).getCaseValue(); - if(caseValue != null) - { - description = caseValue.getText() + " can not be replaced with enum"; - } - } - result.add(new ConflictUsageInfo(errStatement, description)); - - } - else - { - final PsiExpression expression = switchStatement.getExpression(); - if(expression instanceof PsiReferenceExpression) - { - final PsiElement element = ((PsiReferenceExpression) expression).resolve(); - if(element != null) - { - if(!element.getManager().isInProject(element)) - { - result.add(new ConflictUsageInfo(expression, StringUtil.capitalize(RefactoringUIUtil.getDescription(element, false)) + " is out of project")); - } - } - } - else - { - result.add(new ConflictUsageInfo(expression, null)); - } - } - } - - final TypeMigrationRules rules = new TypeMigrationRules(myProject); - rules.addConversionDescriptor(new EnumTypeConversionRule(myEnumConstants)); - rules.setBoundScope(GlobalSearchScope.projectScope(myProject)); - myTypeMigrationProcessor = new TypeMigrationProcessor(myProject, PsiUtilCore.toPsiElementArray(myEnumConstants), Functions.constant(JavaPsiFacade.getElementFactory(myProject).createType - (myClass)), rules, true); - for(UsageInfo usageInfo : myTypeMigrationProcessor.findUsages()) - { - final PsiElement migrateElement = usageInfo.getElement(); - if(migrateElement instanceof PsiField) - { - final PsiField enumConstantField = (PsiField) migrateElement; - if(enumConstantField.hasModifierProperty(PsiModifier.STATIC) && enumConstantField.hasModifierProperty(PsiModifier.FINAL) && enumConstantField.hasInitializer() && !myEnumConstants - .contains(enumConstantField)) - { - continue; - } - } - result.add(new EnumTypeMigrationUsageInfo(usageInfo)); - } - } - return result; - } - - public void performEnumConstantTypeMigration(UsageInfo[] usageInfos) - { - if(hasUsages2Migrate()) - { - final List migrationInfos = new ArrayList<>(); - for(UsageInfo usageInfo : usageInfos) - { - if(usageInfo instanceof EnumTypeMigrationUsageInfo) - { - migrationInfos.add(((EnumTypeMigrationUsageInfo) usageInfo).getUsageInfo()); - } - } - myTypeMigrationProcessor.performRefactoring(migrationInfos.toArray(UsageInfo.EMPTY_ARRAY)); - } - } - - private static class EnumTypeMigrationUsageInfo extends FixableUsageInfo - { - private final UsageInfo myUsageInfo; - - public EnumTypeMigrationUsageInfo(UsageInfo usageInfo) - { - super(usageInfo.getElement()); - myUsageInfo = usageInfo; - } - - @Override - public void fixUsage() throws IncorrectOperationException - { - } - - public UsageInfo getUsageInfo() - { - return myUsageInfo; - } - } - - private static class ConflictUsageInfo extends FixableUsageInfo - { - private final String myDescription; - - public ConflictUsageInfo(PsiElement expression, String description) - { - super(expression); - myDescription = description; - } - - @Override - public void fixUsage() throws IncorrectOperationException - { - } - - @Override - public String getConflictMessage() - { - return "Unable to migrate statement to enum constant." + (myDescription != null ? " " + myDescription : ""); - } - } +public class ExtractEnumProcessor { + private final Project myProject; + private final List myEnumConstants; + private final PsiClass myClass; + + private TypeMigrationProcessor myTypeMigrationProcessor; + + public ExtractEnumProcessor(Project project, List enumConstants, PsiClass aClass) { + myProject = project; + myEnumConstants = enumConstants; + myClass = aClass; + } + + public void findEnumConstantConflicts(final Ref refUsages) { + if (hasUsages2Migrate()) { + final List resolvableConflicts = new ArrayList<>(); + for (UsageInfo failedUsage : myTypeMigrationProcessor.getLabeler().getFailedUsages()) { + final PsiElement element = failedUsage.getElement(); + if (element instanceof PsiReferenceExpression) { + resolvableConflicts.add(new FixableUsageInfo(element) { + @Override + public void fixUsage() throws IncorrectOperationException { + final PsiReferenceExpression expression = (PsiReferenceExpression)element; + final String link = GenerateMembersUtil.suggestGetterName("value", expression.getType(), myProject) + "()"; + MutationUtils.replaceExpression(expression.getReferenceName() + "." + link, expression); + } + }); + } + else if (element != null) { + resolvableConflicts.add(new ConflictUsageInfo(element, null)); + } + } + if (!resolvableConflicts.isEmpty()) { + final List usageInfos = new ArrayList<>(Arrays.asList(refUsages.get())); + for (Iterator iterator = resolvableConflicts.iterator(); iterator.hasNext(); ) { + final UsageInfo conflict = iterator.next(); + for (UsageInfo usageInfo : usageInfos) { + if (conflict.getElement() == usageInfo.getElement()) { + iterator.remove(); + break; + } + } + } + resolvableConflicts.addAll(0, usageInfos); + refUsages.set(resolvableConflicts.toArray(UsageInfo.EMPTY_ARRAY)); + } + } + } + + private boolean hasUsages2Migrate() { + return myTypeMigrationProcessor != null; + } + + public List findEnumConstantUsages(List fieldUsages) { + final List result = new ArrayList<>(); + if (!myEnumConstants.isEmpty()) { + final Set switchStatements = new HashSet<>(); + for (UsageInfo usage : fieldUsages) { + if (usage instanceof ReplaceStaticVariableAccess) { + final PsiElement element = usage.getElement(); + final PsiSwitchStatement switchStatement = PsiTreeUtil.getParentOfType(element, PsiSwitchStatement.class); + if (switchStatement != null) { + switchStatements.add(switchStatement); + } + } + } + + final PsiConstantEvaluationHelper evaluationHelper = JavaPsiFacade.getInstance(myProject).getConstantEvaluationHelper(); + final Set enumValues = new HashSet<>(); + for (PsiField enumConstant : myEnumConstants) { + enumValues.add(evaluationHelper.computeConstantExpression(enumConstant.getInitializer())); + } + final PsiType enumValueType = myEnumConstants.get(0).getType(); + + for (PsiSwitchStatement switchStatement : switchStatements) { + final PsiStatement errStatement = EnumConstantsUtil.isEnumSwitch(switchStatement, enumValueType, enumValues); + if (errStatement != null) { + String description = null; + if (errStatement instanceof PsiSwitchLabelStatement) { + final PsiExpression caseValue = ((PsiSwitchLabelStatement)errStatement).getCaseValue(); + if (caseValue != null) { + description = caseValue.getText() + " can not be replaced with enum"; + } + } + result.add(new ConflictUsageInfo(errStatement, description)); + } + else { + final PsiExpression expression = switchStatement.getExpression(); + if (expression instanceof PsiReferenceExpression) { + final PsiElement element = ((PsiReferenceExpression)expression).resolve(); + if (element != null) { + if (!element.getManager().isInProject(element)) { + result.add(new ConflictUsageInfo( + expression, + StringUtil.capitalize(RefactoringUIUtil.getDescription(element, false)) + " is out of project" + )); + } + } + } + else { + result.add(new ConflictUsageInfo(expression, null)); + } + } + } + + final TypeMigrationRules rules = new TypeMigrationRules(myProject); + rules.addConversionDescriptor(new EnumTypeConversionRule(myEnumConstants)); + rules.setBoundScope(GlobalSearchScope.projectScope(myProject)); + myTypeMigrationProcessor = new TypeMigrationProcessor( + myProject, + PsiUtilCore.toPsiElementArray(myEnumConstants), + Functions.constant(JavaPsiFacade.getElementFactory(myProject).createType(myClass)), + rules, + true + ); + for (UsageInfo usageInfo : myTypeMigrationProcessor.findUsages()) { + final PsiElement migrateElement = usageInfo.getElement(); + if (migrateElement instanceof PsiField) { + final PsiField enumConstantField = (PsiField)migrateElement; + if (enumConstantField.hasModifierProperty(PsiModifier.STATIC) + && enumConstantField.hasModifierProperty(PsiModifier.FINAL) + && enumConstantField.hasInitializer() && !myEnumConstants.contains(enumConstantField)) { + continue; + } + } + result.add(new EnumTypeMigrationUsageInfo(usageInfo)); + } + } + return result; + } + + public void performEnumConstantTypeMigration(UsageInfo[] usageInfos) { + if (hasUsages2Migrate()) { + final List migrationInfos = new ArrayList<>(); + for (UsageInfo usageInfo : usageInfos) { + if (usageInfo instanceof EnumTypeMigrationUsageInfo) { + migrationInfos.add(((EnumTypeMigrationUsageInfo)usageInfo).getUsageInfo()); + } + } + myTypeMigrationProcessor.performRefactoring(migrationInfos.toArray(UsageInfo.EMPTY_ARRAY)); + } + } + + private static class EnumTypeMigrationUsageInfo extends FixableUsageInfo { + private final UsageInfo myUsageInfo; + + public EnumTypeMigrationUsageInfo(UsageInfo usageInfo) { + super(usageInfo.getElement()); + myUsageInfo = usageInfo; + } + + @Override + public void fixUsage() throws IncorrectOperationException { + } + + public UsageInfo getUsageInfo() { + return myUsageInfo; + } + } + + private static class ConflictUsageInfo extends FixableUsageInfo { + private final String myDescription; + + public ConflictUsageInfo(PsiElement expression, String description) { + super(expression); + myDescription = description; + } + + @Override + public void fixUsage() throws IncorrectOperationException { + } + + @Override + public String getConflictMessage() { + return "Unable to migrate statement to enum constant." + (myDescription != null ? " " + myDescription : ""); + } + } } \ No newline at end of file diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/inline/InlineConstantFieldProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/inline/InlineConstantFieldProcessor.java index 4bc5807d4..8975fe26c 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/inline/InlineConstantFieldProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/inline/InlineConstantFieldProcessor.java @@ -50,349 +50,300 @@ /** * @author ven */ -public class InlineConstantFieldProcessor extends BaseRefactoringProcessor -{ - private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.inline" + - ".InlineConstantFieldProcessor"); - private PsiField myField; - private final PsiReferenceExpression myRefExpr; - private final boolean myInlineThisOnly; - private final boolean mySearchInCommentsAndStrings; - private final boolean mySearchForTextOccurrences; - - public InlineConstantFieldProcessor(PsiField field, - Project project, - PsiReferenceExpression ref, - boolean isInlineThisOnly) - { - this(field, project, ref, isInlineThisOnly, false, false); - } - - public InlineConstantFieldProcessor(PsiField field, - Project project, - PsiReferenceExpression ref, - boolean isInlineThisOnly, - boolean searchInCommentsAndStrings, - boolean searchForTextOccurrences) - { - super(project); - myField = field; - myRefExpr = ref; - myInlineThisOnly = isInlineThisOnly; - mySearchInCommentsAndStrings = searchInCommentsAndStrings; - mySearchForTextOccurrences = searchForTextOccurrences; - } - - @Override - @Nonnull - protected UsageViewDescriptor createUsageViewDescriptor(@Nonnull UsageInfo[] usages) - { - return new InlineViewDescriptor(myField); - } - - @Override - protected boolean isPreviewUsages(@Nonnull UsageInfo[] usages) - { - if (super.isPreviewUsages(usages)) - { - return true; - } - for (UsageInfo info : usages) - { - if (info instanceof NonCodeUsageInfo) - { - return true; - } - } - return false; - } - - private static class UsageFromJavaDoc extends UsageInfo - { - private UsageFromJavaDoc(@Nonnull PsiElement element) - { - super(element, true); - } - } - - @Override - @Nonnull - protected UsageInfo[] findUsages() - { - if (myInlineThisOnly) - { - return new UsageInfo[]{new UsageInfo(myRefExpr)}; - } - - List usages = new ArrayList(); - for (PsiReference ref : ReferencesSearch.search(myField, GlobalSearchScope.projectScope(myProject), false)) - { - PsiElement element = ref.getElement(); - UsageInfo info = new UsageInfo(element); - - if (!(element instanceof PsiExpression) && PsiTreeUtil.getParentOfType(element, - PsiImportStaticStatement.class) == null) - { - info = new UsageFromJavaDoc(element); - } - - usages.add(info); - } - if (mySearchInCommentsAndStrings || mySearchForTextOccurrences) - { - UsageInfoFactory nonCodeUsageFactory = new NonCodeUsageInfoFactory(myField, myField.getName()) - { - @Override - public UsageInfo createUsageInfo(@Nonnull PsiElement usage, int startOffset, int endOffset) - { - if (PsiTreeUtil.isAncestor(myField, usage, false)) - { - return null; - } - return super.createUsageInfo(usage, startOffset, endOffset); - } - }; - if (mySearchInCommentsAndStrings) - { - String stringToSearch = ElementDescriptionUtil.getElementDescription(myField, - NonCodeSearchDescriptionLocation.STRINGS_AND_COMMENTS); - TextOccurrencesUtil.addUsagesInStringsAndComments(myField, stringToSearch, usages, - nonCodeUsageFactory); - } - - if (mySearchForTextOccurrences) - { - String stringToSearch = ElementDescriptionUtil.getElementDescription(myField, - NonCodeSearchDescriptionLocation.NON_JAVA); - TextOccurrencesUtil.addTextOccurences(myField, stringToSearch, GlobalSearchScope.projectScope - (myProject), usages, nonCodeUsageFactory); - } - } - return usages.toArray(new UsageInfo[usages.size()]); - } - - @Override - protected void refreshElements(@Nonnull PsiElement[] elements) - { - LOG.assertTrue(elements.length == 1 && elements[0] instanceof PsiField); - myField = (PsiField) elements[0]; - } - - @Override - protected void performRefactoring(@Nonnull UsageInfo[] usages) - { - PsiExpression initializer = myField.getInitializer(); - LOG.assertTrue(initializer != null); - - initializer = normalize((PsiExpression) initializer.copy()); - for (UsageInfo info : usages) - { - if (info instanceof UsageFromJavaDoc) - { - continue; - } - if (info instanceof NonCodeUsageInfo) - { - continue; - } - final PsiElement element = info.getElement(); - if (element == null) - { - continue; - } - try - { - if (element instanceof PsiExpression) - { - inlineExpressionUsage((PsiExpression) element, initializer); - } - else - { - PsiImportStaticStatement importStaticStatement = PsiTreeUtil.getParentOfType(element, - PsiImportStaticStatement.class); - LOG.assertTrue(importStaticStatement != null, element.getText()); - importStaticStatement.delete(); - } - } - catch (IncorrectOperationException e) - { - LOG.error(e); - } - } - - if (!myInlineThisOnly) - { - try - { - myField.delete(); - } - catch (IncorrectOperationException e) - { - LOG.error(e); - } - } - } - - /*@Nullable - @Override - protected RefactoringEventData getBeforeData() - { - RefactoringEventData data = new RefactoringEventData(); - data.addElement(myField); - return data; - } - - @Nullable - @Override - protected String getRefactoringId() - { - return "refactoring.inline.field"; - } */ - - private void inlineExpressionUsage(PsiExpression expr, - PsiExpression initializer1) throws IncorrectOperationException - { - if (myField.isWritable()) - { - myField.normalizeDeclaration(); - } - if (expr instanceof PsiReferenceExpression) - { - PsiExpression qExpression = ((PsiReferenceExpression) expr).getQualifierExpression(); - if (qExpression != null) - { - PsiReferenceExpression referenceExpression = null; - if (initializer1 instanceof PsiReferenceExpression) - { - referenceExpression = (PsiReferenceExpression) initializer1; - } - else if (initializer1 instanceof PsiMethodCallExpression) - { - referenceExpression = ((PsiMethodCallExpression) initializer1).getMethodExpression(); - } - if (referenceExpression != null && - referenceExpression.getQualifierExpression() == null && - !(referenceExpression.advancedResolve(false).getCurrentFileResolveScope() instanceof - PsiImportStaticStatement)) - { - referenceExpression.setQualifierExpression(qExpression); - } - } - } - - InlineUtil.inlineVariable(myField, initializer1, (PsiJavaCodeReferenceElement) expr); - } - - private static PsiExpression normalize(PsiExpression expression) - { - if (expression instanceof PsiArrayInitializerExpression) - { - PsiElementFactory factory = JavaPsiFacade.getInstance(expression.getProject()).getElementFactory(); - try - { - final PsiType type = expression.getType(); - if (type != null) - { - String typeString = type.getCanonicalText(); - PsiNewExpression result = (PsiNewExpression) factory.createExpressionFromText("new " + typeString - + "{}", expression); - result.getArrayInitializer().replace(expression); - return result; - } - } - catch (IncorrectOperationException e) - { - LOG.error(e); - return expression; - } - } - - return expression; - } - - @Override - protected String getCommandName() - { - return RefactoringLocalize.inlineFieldCommand(DescriptiveNameUtil.getDescriptiveName(myField)).get(); - } - - @Override - protected boolean preprocessUsages(@Nonnull Ref refUsages) - { - UsageInfo[] usagesIn = refUsages.get(); - MultiMap conflicts = new MultiMap(); - - ReferencedElementsCollector collector = new ReferencedElementsCollector(); - PsiExpression initializer = myField.getInitializer(); - LOG.assertTrue(initializer != null); - initializer.accept(collector); - HashSet referencedWithVisibility = collector.myReferencedMembers; - - PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(myField.getProject()).getResolveHelper(); - for (UsageInfo info : usagesIn) - { - PsiElement element = info.getElement(); - if (element instanceof PsiExpression expression && isAccessedForWriting(expression)) - { - LocalizeValue message = RefactoringLocalize.zeroIsUsedForWritingIn1( - RefactoringUIUtil.getDescription(myField, true), - RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(element), true) - ); - conflicts.putValue(element, message.get()); - } - - for (PsiMember member : referencedWithVisibility) - { - if (!resolveHelper.isAccessible(member, element, null)) - { - LocalizeValue message = RefactoringLocalize.zeroWillNotBeAccessibleFrom1AfterInlining( - RefactoringUIUtil.getDescription(member, true), - RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(element), true) - ); - conflicts.putValue(member, message.get()); - } - } - } - - if (!myInlineThisOnly) - { - for (UsageInfo info : usagesIn) - { - if (info instanceof UsageFromJavaDoc) - { - final PsiElement element = info.getElement(); - if (element instanceof PsiDocMethodOrFieldRef && !PsiTreeUtil.isAncestor(myField, element, false)) - { - conflicts.putValue(element, "Inlined method is used in javadoc"); - } - } - } - } - - return showConflicts(conflicts, usagesIn); - } - - private static boolean isAccessedForWriting(PsiExpression expr) - { - while (expr.getParent() instanceof PsiArrayAccessExpression) - { - expr = (PsiExpression) expr.getParent(); - } - - return PsiUtil.isAccessedForWriting(expr); - } - - @Override - @Nonnull - protected Collection getElementsToWrite(@Nonnull final UsageViewDescriptor descriptor) - { - if (myInlineThisOnly) - { - return Collections.singletonList(myRefExpr); - } - else - { - return super.getElementsToWrite(descriptor); - } - } +public class InlineConstantFieldProcessor extends BaseRefactoringProcessor { + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.inline" + + ".InlineConstantFieldProcessor"); + private PsiField myField; + private final PsiReferenceExpression myRefExpr; + private final boolean myInlineThisOnly; + private final boolean mySearchInCommentsAndStrings; + private final boolean mySearchForTextOccurrences; + + public InlineConstantFieldProcessor( + PsiField field, + Project project, + PsiReferenceExpression ref, + boolean isInlineThisOnly + ) { + this(field, project, ref, isInlineThisOnly, false, false); + } + + public InlineConstantFieldProcessor( + PsiField field, + Project project, + PsiReferenceExpression ref, + boolean isInlineThisOnly, + boolean searchInCommentsAndStrings, + boolean searchForTextOccurrences + ) { + super(project); + myField = field; + myRefExpr = ref; + myInlineThisOnly = isInlineThisOnly; + mySearchInCommentsAndStrings = searchInCommentsAndStrings; + mySearchForTextOccurrences = searchForTextOccurrences; + } + + @Override + @Nonnull + protected UsageViewDescriptor createUsageViewDescriptor(@Nonnull UsageInfo[] usages) { + return new InlineViewDescriptor(myField); + } + + @Override + protected boolean isPreviewUsages(@Nonnull UsageInfo[] usages) { + if (super.isPreviewUsages(usages)) { + return true; + } + for (UsageInfo info : usages) { + if (info instanceof NonCodeUsageInfo) { + return true; + } + } + return false; + } + + private static class UsageFromJavaDoc extends UsageInfo { + private UsageFromJavaDoc(@Nonnull PsiElement element) { + super(element, true); + } + } + + @Override + @Nonnull + protected UsageInfo[] findUsages() { + if (myInlineThisOnly) { + return new UsageInfo[]{new UsageInfo(myRefExpr)}; + } + + List usages = new ArrayList(); + for (PsiReference ref : ReferencesSearch.search(myField, GlobalSearchScope.projectScope(myProject), false)) { + PsiElement element = ref.getElement(); + UsageInfo info = new UsageInfo(element); + + if (!(element instanceof PsiExpression) + && PsiTreeUtil.getParentOfType(element, PsiImportStaticStatement.class) == null) { + info = new UsageFromJavaDoc(element); + } + + usages.add(info); + } + if (mySearchInCommentsAndStrings || mySearchForTextOccurrences) { + UsageInfoFactory nonCodeUsageFactory = new NonCodeUsageInfoFactory(myField, myField.getName()) { + @Override + public UsageInfo createUsageInfo(@Nonnull PsiElement usage, int startOffset, int endOffset) { + if (PsiTreeUtil.isAncestor(myField, usage, false)) { + return null; + } + return super.createUsageInfo(usage, startOffset, endOffset); + } + }; + if (mySearchInCommentsAndStrings) { + String stringToSearch = + ElementDescriptionUtil.getElementDescription(myField, NonCodeSearchDescriptionLocation.STRINGS_AND_COMMENTS); + TextOccurrencesUtil.addUsagesInStringsAndComments(myField, stringToSearch, usages, nonCodeUsageFactory); + } + + if (mySearchForTextOccurrences) { + String stringToSearch = + ElementDescriptionUtil.getElementDescription(myField, NonCodeSearchDescriptionLocation.NON_JAVA); + TextOccurrencesUtil.addTextOccurences( + myField, + stringToSearch, + GlobalSearchScope.projectScope(myProject), + usages, + nonCodeUsageFactory + ); + } + } + return usages.toArray(new UsageInfo[usages.size()]); + } + + @Override + protected void refreshElements(@Nonnull PsiElement[] elements) { + LOG.assertTrue(elements.length == 1 && elements[0] instanceof PsiField); + myField = (PsiField)elements[0]; + } + + @Override + protected void performRefactoring(@Nonnull UsageInfo[] usages) { + PsiExpression initializer = myField.getInitializer(); + LOG.assertTrue(initializer != null); + + initializer = normalize((PsiExpression)initializer.copy()); + for (UsageInfo info : usages) { + if (info instanceof UsageFromJavaDoc) { + continue; + } + if (info instanceof NonCodeUsageInfo) { + continue; + } + final PsiElement element = info.getElement(); + if (element == null) { + continue; + } + try { + if (element instanceof PsiExpression) { + inlineExpressionUsage((PsiExpression)element, initializer); + } + else { + PsiImportStaticStatement importStaticStatement = + PsiTreeUtil.getParentOfType(element, PsiImportStaticStatement.class); + LOG.assertTrue(importStaticStatement != null, element.getText()); + importStaticStatement.delete(); + } + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + + if (!myInlineThisOnly) { + try { + myField.delete(); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + } + + /* + @Nullable + @Override + protected RefactoringEventData getBeforeData() + { + RefactoringEventData data = new RefactoringEventData(); + data.addElement(myField); + return data; + } + + @Nullable + @Override + protected String getRefactoringId() + { + return "refactoring.inline.field"; + } + */ + + private void inlineExpressionUsage( + PsiExpression expr, + PsiExpression initializer1 + ) throws IncorrectOperationException { + if (myField.isWritable()) { + myField.normalizeDeclaration(); + } + if (expr instanceof PsiReferenceExpression) { + PsiExpression qExpression = ((PsiReferenceExpression)expr).getQualifierExpression(); + if (qExpression != null) { + PsiReferenceExpression referenceExpression = null; + if (initializer1 instanceof PsiReferenceExpression) { + referenceExpression = (PsiReferenceExpression)initializer1; + } + else if (initializer1 instanceof PsiMethodCallExpression) { + referenceExpression = ((PsiMethodCallExpression)initializer1).getMethodExpression(); + } + if (referenceExpression != null + && referenceExpression.getQualifierExpression() == null + && !(referenceExpression.advancedResolve(false).getCurrentFileResolveScope() instanceof PsiImportStaticStatement)) { + referenceExpression.setQualifierExpression(qExpression); + } + } + } + + InlineUtil.inlineVariable(myField, initializer1, (PsiJavaCodeReferenceElement)expr); + } + + private static PsiExpression normalize(PsiExpression expression) { + if (expression instanceof PsiArrayInitializerExpression) { + PsiElementFactory factory = JavaPsiFacade.getInstance(expression.getProject()).getElementFactory(); + try { + final PsiType type = expression.getType(); + if (type != null) { + String typeString = type.getCanonicalText(); + PsiNewExpression result = (PsiNewExpression)factory.createExpressionFromText("new " + typeString + + "{}", expression); + result.getArrayInitializer().replace(expression); + return result; + } + } + catch (IncorrectOperationException e) { + LOG.error(e); + return expression; + } + } + + return expression; + } + + @Override + protected String getCommandName() { + return RefactoringLocalize.inlineFieldCommand(DescriptiveNameUtil.getDescriptiveName(myField)).get(); + } + + @Override + protected boolean preprocessUsages(@Nonnull Ref refUsages) { + UsageInfo[] usagesIn = refUsages.get(); + MultiMap conflicts = new MultiMap(); + + ReferencedElementsCollector collector = new ReferencedElementsCollector(); + PsiExpression initializer = myField.getInitializer(); + LOG.assertTrue(initializer != null); + initializer.accept(collector); + HashSet referencedWithVisibility = collector.myReferencedMembers; + + PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(myField.getProject()).getResolveHelper(); + for (UsageInfo info : usagesIn) { + PsiElement element = info.getElement(); + if (element instanceof PsiExpression expression && isAccessedForWriting(expression)) { + LocalizeValue message = RefactoringLocalize.zeroIsUsedForWritingIn1( + RefactoringUIUtil.getDescription(myField, true), + RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(element), true) + ); + conflicts.putValue(element, message.get()); + } + + for (PsiMember member : referencedWithVisibility) { + if (!resolveHelper.isAccessible(member, element, null)) { + LocalizeValue message = RefactoringLocalize.zeroWillNotBeAccessibleFrom1AfterInlining( + RefactoringUIUtil.getDescription(member, true), + RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(element), true) + ); + conflicts.putValue(member, message.get()); + } + } + } + + if (!myInlineThisOnly) { + for (UsageInfo info : usagesIn) { + if (info instanceof UsageFromJavaDoc) { + final PsiElement element = info.getElement(); + if (element instanceof PsiDocMethodOrFieldRef && !PsiTreeUtil.isAncestor(myField, element, false)) { + conflicts.putValue(element, "Inlined method is used in javadoc"); + } + } + } + } + + return showConflicts(conflicts, usagesIn); + } + + private static boolean isAccessedForWriting(PsiExpression expr) { + while (expr.getParent() instanceof PsiArrayAccessExpression) { + expr = (PsiExpression)expr.getParent(); + } + + return PsiUtil.isAccessedForWriting(expr); + } + + @Override + @Nonnull + protected Collection getElementsToWrite(@Nonnull final UsageViewDescriptor descriptor) { + if (myInlineThisOnly) { + return Collections.singletonList(myRefExpr); + } + else { + return super.getElementsToWrite(descriptor); + } + } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/inline/InlineParameterExpressionProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/inline/InlineParameterExpressionProcessor.java index eab4b9473..c0851d7d9 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/inline/InlineParameterExpressionProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/inline/InlineParameterExpressionProcessor.java @@ -39,373 +39,408 @@ import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; + import java.util.*; /** * @author yole */ public class InlineParameterExpressionProcessor extends BaseRefactoringProcessor { - private static final Logger LOG = Logger.getInstance(InlineParameterExpressionProcessor.class); - public static final Key CREATE_LOCAL_FOR_TESTS = Key.create("CREATE_INLINE_PARAMETER_LOCAL_FOR_TESTS"); - - private final PsiCallExpression myMethodCall; - private final PsiMethod myMethod; - private final PsiParameter myParameter; - private PsiExpression myInitializer; - private final boolean mySameClass; - private final PsiMethod myCallingMethod; - private final boolean myCreateLocal; - - public InlineParameterExpressionProcessor(final PsiCallExpression methodCall, - final PsiMethod method, - final PsiParameter parameter, - final PsiExpression initializer, - boolean createLocal) { - super(method.getProject()); - myMethodCall = methodCall; - myMethod = method; - myParameter = parameter; - myInitializer = initializer; - myCreateLocal = createLocal; - - PsiClass callingClass = PsiTreeUtil.getParentOfType(methodCall, PsiClass.class); - mySameClass = (callingClass == myMethod.getContainingClass()); - myCallingMethod = PsiTreeUtil.getParentOfType(myMethodCall, PsiMethod.class); - } - - @Override - protected String getCommandName() { - return InlineParameterHandler.REFACTORING_NAME; - } - - - @Nonnull - @Override - protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { - return new InlineViewDescriptor(myParameter); - } - - @Nonnull - @Override - protected UsageInfo[] findUsages() { - - int parameterIndex = myMethod.getParameterList().getParameterIndex(myParameter); - final Map localToParamRef = new HashMap(); - final PsiExpression[] arguments = myMethodCall.getArgumentList().getExpressions(); - for (int i = 0; i < arguments.length; i++) { - if (i != parameterIndex && arguments[i] instanceof PsiReferenceExpression) { - final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) arguments[i]; - final PsiElement element = referenceExpression.resolve(); - if (element instanceof PsiLocalVariable || element instanceof PsiParameter) { - final PsiParameter param = myMethod.getParameterList().getParameters()[i]; - final PsiExpression paramRef = - JavaPsiFacade.getInstance(myMethod.getProject()).getElementFactory().createExpressionFromText(param.getName(), myMethod); - localToParamRef.put((PsiVariable) element, paramRef); - } - } + private static final Logger LOG = Logger.getInstance(InlineParameterExpressionProcessor.class); + public static final Key CREATE_LOCAL_FOR_TESTS = Key.create("CREATE_INLINE_PARAMETER_LOCAL_FOR_TESTS"); + + private final PsiCallExpression myMethodCall; + private final PsiMethod myMethod; + private final PsiParameter myParameter; + private PsiExpression myInitializer; + private final boolean mySameClass; + private final PsiMethod myCallingMethod; + private final boolean myCreateLocal; + + public InlineParameterExpressionProcessor( + final PsiCallExpression methodCall, + final PsiMethod method, + final PsiParameter parameter, + final PsiExpression initializer, + boolean createLocal + ) { + super(method.getProject()); + myMethodCall = methodCall; + myMethod = method; + myParameter = parameter; + myInitializer = initializer; + myCreateLocal = createLocal; + + PsiClass callingClass = PsiTreeUtil.getParentOfType(methodCall, PsiClass.class); + mySameClass = (callingClass == myMethod.getContainingClass()); + myCallingMethod = PsiTreeUtil.getParentOfType(myMethodCall, PsiMethod.class); + } + + @Override + protected String getCommandName() { + return InlineParameterHandler.REFACTORING_NAME; } - final List result = new ArrayList(); - myInitializer.accept(new JavaRecursiveElementVisitor() { - @Override - public void visitReferenceExpression(final PsiReferenceExpression expression) { - super.visitReferenceExpression(expression); - final PsiElement element = expression.resolve(); - if (element instanceof PsiLocalVariable) { - final PsiLocalVariable localVariable = (PsiLocalVariable) element; - final PsiElement[] elements = DefUseUtil.getDefs(myCallingMethod.getBody(), localVariable, expression); - if (elements.length == 1) { - PsiExpression localInitializer = null; - if (elements[0] instanceof PsiLocalVariable) { - localInitializer = ((PsiLocalVariable) elements[0]).getInitializer(); - } else if (elements[0] instanceof PsiAssignmentExpression) { - localInitializer = ((PsiAssignmentExpression) elements[0]).getRExpression(); - } else if (elements[0] instanceof PsiReferenceExpression) { - final PsiReferenceExpression refElement = (PsiReferenceExpression) elements[0]; - final PsiElement parent = refElement.getParent(); - if (parent instanceof PsiAssignmentExpression && ((PsiAssignmentExpression) parent).getLExpression() == refElement) { - localInitializer = ((PsiAssignmentExpression) parent).getRExpression(); - } - } - if (localInitializer != null) { - final PsiElement replacement; - if (localToParamRef.containsKey(localVariable)) { - replacement = localToParamRef.get(localVariable); - } else { - replacement = replaceArgs(localToParamRef, localInitializer.copy()); - } - result.add(new LocalReplacementUsageInfo(expression, replacement)); - } - } - } - } - }); - if (!myCreateLocal) { - for (PsiReference ref : ReferencesSearch.search(myParameter).findAll()) { - result.add(new UsageInfo(ref)); - } + @Nonnull + @Override + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { + return new InlineViewDescriptor(myParameter); } - final UsageInfo[] usageInfos = result.toArray(new UsageInfo[result.size()]); - return UsageViewUtil.removeDuplicatedUsages(usageInfos); - } - - private static PsiElement replaceArgs(final Map elementsToReplace, PsiElement expression) { - final Map replacements = new HashMap(); - expression.accept(new JavaRecursiveElementVisitor() { - @Override - public void visitReferenceExpression(PsiReferenceExpression referenceExpression) { - super.visitReferenceExpression(referenceExpression); - final PsiElement resolved = referenceExpression.resolve(); - if (resolved instanceof PsiVariable) { - final PsiVariable variable = (PsiVariable) resolved; - final PsiElement replacement = elementsToReplace.get(variable); - if (replacement != null) { - replacements.put(referenceExpression, replacement); - } + @Nonnull + @Override + protected UsageInfo[] findUsages() { + + int parameterIndex = myMethod.getParameterList().getParameterIndex(myParameter); + final Map localToParamRef = new HashMap(); + final PsiExpression[] arguments = myMethodCall.getArgumentList().getExpressions(); + for (int i = 0; i < arguments.length; i++) { + if (i != parameterIndex && arguments[i] instanceof PsiReferenceExpression) { + final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)arguments[i]; + final PsiElement element = referenceExpression.resolve(); + if (element instanceof PsiLocalVariable || element instanceof PsiParameter) { + final PsiParameter param = myMethod.getParameterList().getParameters()[i]; + final PsiExpression paramRef = + JavaPsiFacade.getInstance(myMethod.getProject()) + .getElementFactory() + .createExpressionFromText(param.getName(), myMethod); + localToParamRef.put((PsiVariable)element, paramRef); + } + } } - } - }); - return RefactoringUtil.replaceElementsWithMap(expression, replacements); - } - - @Override - protected boolean preprocessUsages(Ref refUsages) { - final MultiMap conflicts = new MultiMap(); - final UsageInfo[] usages = refUsages.get(); - final InaccessibleExpressionsDetector detector = new InaccessibleExpressionsDetector(conflicts); - myInitializer.accept(detector); - for (UsageInfo usage : usages) { - if (usage instanceof LocalReplacementUsageInfo) { - final PsiElement replacement = ((LocalReplacementUsageInfo) usage).getReplacement(); - if (replacement != null) { - replacement.accept(detector); + + final List result = new ArrayList(); + myInitializer.accept(new JavaRecursiveElementVisitor() { + @Override + public void visitReferenceExpression(final PsiReferenceExpression expression) { + super.visitReferenceExpression(expression); + final PsiElement element = expression.resolve(); + if (element instanceof PsiLocalVariable) { + final PsiLocalVariable localVariable = (PsiLocalVariable)element; + final PsiElement[] elements = DefUseUtil.getDefs(myCallingMethod.getBody(), localVariable, expression); + if (elements.length == 1) { + PsiExpression localInitializer = null; + if (elements[0] instanceof PsiLocalVariable) { + localInitializer = ((PsiLocalVariable)elements[0]).getInitializer(); + } + else if (elements[0] instanceof PsiAssignmentExpression) { + localInitializer = ((PsiAssignmentExpression)elements[0]).getRExpression(); + } + else if (elements[0] instanceof PsiReferenceExpression) { + final PsiReferenceExpression refElement = (PsiReferenceExpression)elements[0]; + final PsiElement parent = refElement.getParent(); + if (parent instanceof PsiAssignmentExpression && ((PsiAssignmentExpression)parent).getLExpression() == refElement) { + localInitializer = ((PsiAssignmentExpression)parent).getRExpression(); + } + } + if (localInitializer != null) { + final PsiElement replacement; + if (localToParamRef.containsKey(localVariable)) { + replacement = localToParamRef.get(localVariable); + } + else { + replacement = replaceArgs(localToParamRef, localInitializer.copy()); + } + result.add(new LocalReplacementUsageInfo(expression, replacement)); + } + } + } + } + }); + + if (!myCreateLocal) { + for (PsiReference ref : ReferencesSearch.search(myParameter).findAll()) { + result.add(new UsageInfo(ref)); + } } - } + + final UsageInfo[] usageInfos = result.toArray(new UsageInfo[result.size()]); + return UsageViewUtil.removeDuplicatedUsages(usageInfos); } - final Set vars = new HashSet(); - for (UsageInfo usageInfo : usages) { - if (usageInfo instanceof LocalReplacementUsageInfo) { - final PsiVariable var = ((LocalReplacementUsageInfo) usageInfo).getVariable(); - if (var != null) { - vars.add(var); - } - } + private static PsiElement replaceArgs(final Map elementsToReplace, PsiElement expression) { + final Map replacements = new HashMap(); + expression.accept(new JavaRecursiveElementVisitor() { + @Override + public void visitReferenceExpression(PsiReferenceExpression referenceExpression) { + super.visitReferenceExpression(referenceExpression); + final PsiElement resolved = referenceExpression.resolve(); + if (resolved instanceof PsiVariable) { + final PsiVariable variable = (PsiVariable)resolved; + final PsiElement replacement = elementsToReplace.get(variable); + if (replacement != null) { + replacements.put(referenceExpression, replacement); + } + } + } + }); + return RefactoringUtil.replaceElementsWithMap(expression, replacements); } - for (PsiVariable var : vars) { - for (PsiReference ref : ReferencesSearch.search(var)) { - final PsiElement element = ref.getElement(); - if (element instanceof PsiExpression && isAccessedForWriting((PsiExpression) element)) { - conflicts.putValue(element, "Parameter initializer depends on value which is not available inside method and cannot be inlined"); - break; + + @Override + protected boolean preprocessUsages(Ref refUsages) { + final MultiMap conflicts = new MultiMap(); + final UsageInfo[] usages = refUsages.get(); + final InaccessibleExpressionsDetector detector = new InaccessibleExpressionsDetector(conflicts); + myInitializer.accept(detector); + for (UsageInfo usage : usages) { + if (usage instanceof LocalReplacementUsageInfo) { + final PsiElement replacement = ((LocalReplacementUsageInfo)usage).getReplacement(); + if (replacement != null) { + replacement.accept(detector); + } + } } - } - } - return showConflicts(conflicts, usages); - } - private static boolean isAccessedForWriting(PsiExpression expr) { - while (expr.getParent() instanceof PsiArrayAccessExpression) { - expr = (PsiExpression) expr.getParent(); - } - return PsiUtil.isAccessedForWriting(expr); - } - - @Override - protected void performRefactoring(UsageInfo[] usages) { - final List thrownExceptions = ExceptionUtil.getThrownCheckedExceptions(new PsiElement[]{myInitializer}); - final Set varsUsedInInitializer = new HashSet(); - final Set paramRefsToInline = new HashSet(); - final Map replacements = new HashMap(); - for (UsageInfo usage : usages) { - if (usage instanceof LocalReplacementUsageInfo) { - final LocalReplacementUsageInfo replacementUsageInfo = (LocalReplacementUsageInfo) usage; - final PsiElement element = replacementUsageInfo.getElement(); - final PsiElement replacement = replacementUsageInfo.getReplacement(); - if (element != null && replacement != null) { - replacements.put(element, replacement); + final Set vars = new HashSet(); + for (UsageInfo usageInfo : usages) { + if (usageInfo instanceof LocalReplacementUsageInfo) { + final PsiVariable var = ((LocalReplacementUsageInfo)usageInfo).getVariable(); + if (var != null) { + vars.add(var); + } + } } - varsUsedInInitializer.add(replacementUsageInfo.getVariable()); - } else { - LOG.assertTrue(!myCreateLocal); - paramRefsToInline.add((PsiJavaCodeReferenceElement) usage.getElement()); - } - } - myInitializer = (PsiExpression) RefactoringUtil.replaceElementsWithMap(myInitializer, replacements); - - if (myCreateLocal) { - final PsiElementFactory factory = JavaPsiFacade.getInstance(myMethod.getProject()).getElementFactory(); - PsiDeclarationStatement localDeclaration = - factory.createVariableDeclarationStatement(myParameter.getName(), myParameter.getType(), myInitializer); - final PsiLocalVariable declaredVar = (PsiLocalVariable) localDeclaration.getDeclaredElements()[0]; - PsiUtil.setModifierProperty(declaredVar, PsiModifier.FINAL, myParameter.hasModifierProperty(PsiModifier.FINAL)); - final PsiExpression localVarInitializer = - InlineUtil.inlineVariable(myParameter, myInitializer, (PsiReferenceExpression) factory.createExpressionFromText(myParameter.getName(), myMethod)); - final PsiExpression initializer = declaredVar.getInitializer(); - LOG.assertTrue(initializer != null); - initializer.replace(localVarInitializer); - final PsiCodeBlock body = myMethod.getBody(); - if (body != null) { - PsiElement anchor = findAnchorForLocalVariableDeclaration(body); - body.addAfter(localDeclaration, anchor); - } - } else { - for (PsiJavaCodeReferenceElement paramRef : paramRefsToInline) { - InlineUtil.inlineVariable(myParameter, myInitializer, paramRef); - } + for (PsiVariable var : vars) { + for (PsiReference ref : ReferencesSearch.search(var)) { + final PsiElement element = ref.getElement(); + if (element instanceof PsiExpression && isAccessedForWriting((PsiExpression)element)) { + conflicts.putValue( + element, + "Parameter initializer depends on value which is not available inside method and cannot be inlined" + ); + break; + } + } + } + return showConflicts(conflicts, usages); } - //delete var if it becomes unused - for (PsiVariable variable : varsUsedInInitializer) { - if (variable != null && variable.isValid()) { - if (ReferencesSearch.search(variable).findFirst() == null) { - variable.delete(); + private static boolean isAccessedForWriting(PsiExpression expr) { + while (expr.getParent() instanceof PsiArrayAccessExpression) { + expr = (PsiExpression)expr.getParent(); } - } + return PsiUtil.isAccessedForWriting(expr); } - SameParameterValueInspection.InlineParameterValueFix.removeParameter(myMethod, myParameter); - - if (!thrownExceptions.isEmpty()) { - for (PsiClassType exception : thrownExceptions) { - PsiClass exceptionClass = exception.resolve(); - if (exceptionClass != null) { - PsiUtil.addException(myMethod, exceptionClass); + @Override + protected void performRefactoring(UsageInfo[] usages) { + final List thrownExceptions = ExceptionUtil.getThrownCheckedExceptions(new PsiElement[]{myInitializer}); + final Set varsUsedInInitializer = new HashSet(); + final Set paramRefsToInline = new HashSet(); + final Map replacements = new HashMap(); + for (UsageInfo usage : usages) { + if (usage instanceof LocalReplacementUsageInfo) { + final LocalReplacementUsageInfo replacementUsageInfo = (LocalReplacementUsageInfo)usage; + final PsiElement element = replacementUsageInfo.getElement(); + final PsiElement replacement = replacementUsageInfo.getReplacement(); + if (element != null && replacement != null) { + replacements.put(element, replacement); + } + varsUsedInInitializer.add(replacementUsageInfo.getVariable()); + } + else { + LOG.assertTrue(!myCreateLocal); + paramRefsToInline.add((PsiJavaCodeReferenceElement)usage.getElement()); + } } - } - } - } - - @Nullable - private PsiElement findAnchorForLocalVariableDeclaration(PsiCodeBlock body) { - PsiElement anchor = body.getLBrace(); - if (myMethod.isConstructor()) { - final PsiStatement[] statements = body.getStatements(); - if (statements.length > 0 && statements[0] instanceof PsiExpressionStatement) { - final PsiExpression expression = ((PsiExpressionStatement) statements[0]).getExpression(); - if (expression instanceof PsiMethodCallExpression) { - final String referenceName = ((PsiMethodCallExpression) expression).getMethodExpression().getReferenceName(); - if (PsiKeyword.SUPER.equals(referenceName) || PsiKeyword.THIS.equals(referenceName)) { - anchor = statements[0]; - } + myInitializer = (PsiExpression)RefactoringUtil.replaceElementsWithMap(myInitializer, replacements); + + if (myCreateLocal) { + final PsiElementFactory factory = JavaPsiFacade.getInstance(myMethod.getProject()).getElementFactory(); + PsiDeclarationStatement localDeclaration = + factory.createVariableDeclarationStatement(myParameter.getName(), myParameter.getType(), myInitializer); + final PsiLocalVariable declaredVar = (PsiLocalVariable)localDeclaration.getDeclaredElements()[0]; + PsiUtil.setModifierProperty(declaredVar, PsiModifier.FINAL, myParameter.hasModifierProperty(PsiModifier.FINAL)); + final PsiExpression localVarInitializer = InlineUtil.inlineVariable( + myParameter, + myInitializer, + (PsiReferenceExpression)factory.createExpressionFromText(myParameter.getName(), myMethod) + ); + final PsiExpression initializer = declaredVar.getInitializer(); + LOG.assertTrue(initializer != null); + initializer.replace(localVarInitializer); + final PsiCodeBlock body = myMethod.getBody(); + if (body != null) { + PsiElement anchor = findAnchorForLocalVariableDeclaration(body); + body.addAfter(localDeclaration, anchor); + } + } + else { + for (PsiJavaCodeReferenceElement paramRef : paramRefsToInline) { + InlineUtil.inlineVariable(myParameter, myInitializer, paramRef); + } } - } - } - return anchor; - } - - private static class LocalReplacementUsageInfo extends UsageInfo { - private final PsiElement myReplacement; - private final PsiVariable myVariable; - - public LocalReplacementUsageInfo(@Nonnull PsiReference element, @Nonnull PsiElement replacement) { - super(element); - final PsiElement resolved = element.resolve(); - myVariable = resolved instanceof PsiVariable ? (PsiVariable) resolved : null; - myReplacement = replacement; - } - @Nullable - public PsiElement getReplacement() { - return myReplacement.isValid() ? myReplacement : null; + //delete var if it becomes unused + for (PsiVariable variable : varsUsedInInitializer) { + if (variable != null && variable.isValid()) { + if (ReferencesSearch.search(variable).findFirst() == null) { + variable.delete(); + } + } + } + + SameParameterValueInspection.InlineParameterValueFix.removeParameter(myMethod, myParameter); + + if (!thrownExceptions.isEmpty()) { + for (PsiClassType exception : thrownExceptions) { + PsiClass exceptionClass = exception.resolve(); + if (exceptionClass != null) { + PsiUtil.addException(myMethod, exceptionClass); + } + } + } } @Nullable - public PsiVariable getVariable() { - return myVariable != null && myVariable.isValid() ? myVariable : null; + private PsiElement findAnchorForLocalVariableDeclaration(PsiCodeBlock body) { + PsiElement anchor = body.getLBrace(); + if (myMethod.isConstructor()) { + final PsiStatement[] statements = body.getStatements(); + if (statements.length > 0 && statements[0] instanceof PsiExpressionStatement) { + final PsiExpression expression = ((PsiExpressionStatement)statements[0]).getExpression(); + if (expression instanceof PsiMethodCallExpression) { + final String referenceName = ((PsiMethodCallExpression)expression).getMethodExpression().getReferenceName(); + if (PsiKeyword.SUPER.equals(referenceName) || PsiKeyword.THIS.equals(referenceName)) { + anchor = statements[0]; + } + } + } + } + return anchor; } - } - private class InaccessibleExpressionsDetector extends JavaRecursiveElementWalkingVisitor { - private final MultiMap myConflicts; + private static class LocalReplacementUsageInfo extends UsageInfo { + private final PsiElement myReplacement; + private final PsiVariable myVariable; - public InaccessibleExpressionsDetector(MultiMap conflicts) { - myConflicts = conflicts; - } + public LocalReplacementUsageInfo(@Nonnull PsiReference element, @Nonnull PsiElement replacement) { + super(element); + final PsiElement resolved = element.resolve(); + myVariable = resolved instanceof PsiVariable ? (PsiVariable)resolved : null; + myReplacement = replacement; + } - @Override - public void visitReferenceExpression(final PsiReferenceExpression expression) { - super.visitReferenceExpression(expression); - final PsiElement element = expression.resolve(); - if (element instanceof PsiMember && !((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC)) { - if (myMethod.hasModifierProperty(PsiModifier.STATIC)) { - myConflicts.putValue(expression, "Parameter initializer depends on " + RefactoringUIUtil.getDescription(element, false) + " which is not available inside the static method"); + @Nullable + public PsiElement getReplacement() { + return myReplacement.isValid() ? myReplacement : null; } - } - if (element instanceof PsiMethod || element instanceof PsiField) { - if (!mySameClass && !((PsiModifierListOwner) element).hasModifierProperty(PsiModifier.STATIC)) { - myConflicts.putValue(expression, "Parameter initializer depends on non static member from some other class"); - } else if (!PsiUtil.isAccessible((PsiMember) element, myMethod, null)) { - myConflicts.putValue(expression, "Parameter initializer depends on value which is not available inside method"); + + @Nullable + public PsiVariable getVariable() { + return myVariable != null && myVariable.isValid() ? myVariable : null; } - } else if (element instanceof PsiParameter) { - myConflicts.putValue(expression, "Parameter initializer depends on callers parameter"); - } } - @Override - public void visitThisExpression(PsiThisExpression thisExpression) { - super.visitThisExpression(thisExpression); - final PsiJavaCodeReferenceElement qualifier = thisExpression.getQualifier(); - PsiElement containingClass; - if (qualifier != null) { - containingClass = qualifier.resolve(); - } else { - containingClass = PsiTreeUtil.getParentOfType(myMethodCall, PsiClass.class); - } - final PsiClass methodContainingClass = myMethod.getContainingClass(); - LOG.assertTrue(methodContainingClass != null); - if (!PsiTreeUtil.isAncestor(containingClass, methodContainingClass, false)) { - myConflicts.putValue(thisExpression, - "Parameter initializer depends on this which is not available inside the method and cannot be inlined"); - } else if (myMethod.hasModifierProperty(PsiModifier.STATIC)) { - myConflicts.putValue(thisExpression, "Parameter initializer depends on this which is not available inside the static method"); - } - } + private class InaccessibleExpressionsDetector extends JavaRecursiveElementWalkingVisitor { + private final MultiMap myConflicts; - @Override - public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { - super.visitReferenceElement(reference); - if (myMethod.hasModifierProperty(PsiModifier.STATIC)) { - final PsiElement resolved = reference.resolve(); - if (resolved instanceof PsiClass && !((PsiClass) resolved).hasModifierProperty(PsiModifier.STATIC)) { - myConflicts.putValue(reference, "Parameter initializer depends on non static class which is not available inside static method"); + public InaccessibleExpressionsDetector(MultiMap conflicts) { + myConflicts = conflicts; } - } - } - @Override - public void visitNewExpression(PsiNewExpression expression) { - super.visitNewExpression(expression); - final PsiJavaCodeReferenceElement reference = expression.getClassOrAnonymousClassReference(); - if (reference != null) { - final PsiElement resolved = reference.resolve(); - if (resolved instanceof PsiClass) { - final PsiClass refClass = (PsiClass) resolved; - final String classUnavailableMessage = "Parameter initializer depends on " + - RefactoringUIUtil.getDescription(refClass, true) + - " which is not available inside method and cannot be inlined"; - if (!PsiUtil.isAccessible(refClass, myMethod, null)) { - myConflicts.putValue(expression, classUnavailableMessage); - } else { + @Override + public void visitReferenceExpression(final PsiReferenceExpression expression) { + super.visitReferenceExpression(expression); + final PsiElement element = expression.resolve(); + if (element instanceof PsiMember && !((PsiModifierListOwner)element).hasModifierProperty(PsiModifier.STATIC)) { + if (myMethod.hasModifierProperty(PsiModifier.STATIC)) { + myConflicts.putValue( + expression, + "Parameter initializer depends on " + RefactoringUIUtil.getDescription( + element, + false + ) + " which is not available inside the static method" + ); + } + } + if (element instanceof PsiMethod || element instanceof PsiField) { + if (!mySameClass && !((PsiModifierListOwner)element).hasModifierProperty(PsiModifier.STATIC)) { + myConflicts.putValue(expression, "Parameter initializer depends on non static member from some other class"); + } + else if (!PsiUtil.isAccessible((PsiMember)element, myMethod, null)) { + myConflicts.putValue(expression, "Parameter initializer depends on value which is not available inside method"); + } + } + else if (element instanceof PsiParameter) { + myConflicts.putValue(expression, "Parameter initializer depends on callers parameter"); + } + } + + @Override + public void visitThisExpression(PsiThisExpression thisExpression) { + super.visitThisExpression(thisExpression); + final PsiJavaCodeReferenceElement qualifier = thisExpression.getQualifier(); + PsiElement containingClass; + if (qualifier != null) { + containingClass = qualifier.resolve(); + } + else { + containingClass = PsiTreeUtil.getParentOfType(myMethodCall, PsiClass.class); + } final PsiClass methodContainingClass = myMethod.getContainingClass(); LOG.assertTrue(methodContainingClass != null); - if (!PsiTreeUtil.isAncestor(myMethod, refClass, false)) { - PsiElement parent = refClass; - while ((parent = parent.getParent()) instanceof PsiClass) { - if (!PsiUtil.isAccessible((PsiClass) parent, myMethod, null)) { - break; + if (!PsiTreeUtil.isAncestor(containingClass, methodContainingClass, false)) { + myConflicts.putValue( + thisExpression, + "Parameter initializer depends on this which is not available inside the method and cannot be inlined" + ); + } + else if (myMethod.hasModifierProperty(PsiModifier.STATIC)) { + myConflicts.putValue( + thisExpression, + "Parameter initializer depends on this which is not available inside the static method" + ); + } + } + + @Override + public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { + super.visitReferenceElement(reference); + if (myMethod.hasModifierProperty(PsiModifier.STATIC)) { + final PsiElement resolved = reference.resolve(); + if (resolved instanceof PsiClass && !((PsiClass)resolved).hasModifierProperty(PsiModifier.STATIC)) { + myConflicts.putValue( + reference, + "Parameter initializer depends on non static class which is not available inside static method" + ); + } + } + } + + @Override + public void visitNewExpression(PsiNewExpression expression) { + super.visitNewExpression(expression); + final PsiJavaCodeReferenceElement reference = expression.getClassOrAnonymousClassReference(); + if (reference != null) { + final PsiElement resolved = reference.resolve(); + if (resolved instanceof PsiClass) { + final PsiClass refClass = (PsiClass)resolved; + final String classUnavailableMessage = "Parameter initializer depends on " + + RefactoringUIUtil.getDescription(refClass, true) + + " which is not available inside method and cannot be inlined"; + if (!PsiUtil.isAccessible(refClass, myMethod, null)) { + myConflicts.putValue(expression, classUnavailableMessage); + } + else { + final PsiClass methodContainingClass = myMethod.getContainingClass(); + LOG.assertTrue(methodContainingClass != null); + if (!PsiTreeUtil.isAncestor(myMethod, refClass, false)) { + PsiElement parent = refClass; + while ((parent = parent.getParent()) instanceof PsiClass) { + if (!PsiUtil.isAccessible((PsiClass)parent, myMethod, null)) { + break; + } + } + if (!(parent instanceof PsiFile)) { + myConflicts.putValue(expression, classUnavailableMessage); + } + } + } } - } - if (!(parent instanceof PsiFile)) { - myConflicts.putValue(expression, classUnavailableMessage); - } } - } } - } } - } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java index acbc93c4e..4195113bc 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java @@ -55,345 +55,389 @@ import java.util.Map; public class InlineSuperClassRefactoringProcessor extends FixableUsagesRefactoringProcessor { - public static final Logger LOG = Logger.getInstance(InlineSuperClassRefactoringProcessor.class); + public static final Logger LOG = Logger.getInstance(InlineSuperClassRefactoringProcessor.class); - private final PsiClass myCurrentInheritor; - private final PsiClass mySuperClass; - private final int myPolicy; - private final PsiClass[] myTargetClasses; - private final MemberInfo[] myMemberInfos; + private final PsiClass myCurrentInheritor; + private final PsiClass mySuperClass; + private final int myPolicy; + private final PsiClass[] myTargetClasses; + private final MemberInfo[] myMemberInfos; - public InlineSuperClassRefactoringProcessor( - Project project, - PsiClass currentInheritor, - PsiClass superClass, - int policy, - final PsiClass... targetClasses - ) { - super(project); - myCurrentInheritor = currentInheritor; - mySuperClass = superClass; - myPolicy = policy; - myTargetClasses = currentInheritor != null ? new PsiClass[]{currentInheritor} : targetClasses; - MemberInfoStorage memberInfoStorage = new MemberInfoStorage(mySuperClass, new MemberInfo.Filter() { - public boolean includeMember(PsiMember element) { - return !(element instanceof PsiClass) || PsiTreeUtil.isAncestor(mySuperClass, element, true); - } - }); - List members = memberInfoStorage.getClassMemberInfos(mySuperClass); - for (MemberInfo member : members) { - member.setChecked(true); + public InlineSuperClassRefactoringProcessor( + Project project, + PsiClass currentInheritor, + PsiClass superClass, + int policy, + final PsiClass... targetClasses + ) { + super(project); + myCurrentInheritor = currentInheritor; + mySuperClass = superClass; + myPolicy = policy; + myTargetClasses = currentInheritor != null ? new PsiClass[]{currentInheritor} : targetClasses; + MemberInfoStorage memberInfoStorage = new MemberInfoStorage(mySuperClass, new MemberInfo.Filter() { + public boolean includeMember(PsiMember element) { + return !(element instanceof PsiClass) || PsiTreeUtil.isAncestor(mySuperClass, element, true); + } + }); + List members = memberInfoStorage.getClassMemberInfos(mySuperClass); + for (MemberInfo member : members) { + member.setChecked(true); + } + myMemberInfos = members.toArray(new MemberInfo[members.size()]); } - myMemberInfos = members.toArray(new MemberInfo[members.size()]); - } - @Nonnull - protected UsageViewDescriptor createUsageViewDescriptor(final UsageInfo[] usages) { - return new InlineSuperClassUsageViewDescriptor(mySuperClass); - } + @Nonnull + protected UsageViewDescriptor createUsageViewDescriptor(final UsageInfo[] usages) { + return new InlineSuperClassUsageViewDescriptor(mySuperClass); + } - @RequiredReadAction - protected void findUsages(@Nonnull final List usages) { - final JavaPsiFacade facade = JavaPsiFacade.getInstance(myProject); - final PsiElementFactory elementFactory = facade.getElementFactory(); - final PsiResolveHelper resolveHelper = facade.getResolveHelper(); + @RequiredReadAction + protected void findUsages(@Nonnull final List usages) { + final JavaPsiFacade facade = JavaPsiFacade.getInstance(myProject); + final PsiElementFactory elementFactory = facade.getElementFactory(); + final PsiResolveHelper resolveHelper = facade.getResolveHelper(); - ReferencesSearch.search(mySuperClass).forEach(reference -> { - final PsiElement element = reference.getElement(); - if (element instanceof PsiJavaCodeReferenceElement) { - if (myCurrentInheritor != null) { - final PsiElement parent = element.getParent(); - if (parent instanceof PsiReferenceList) { - final PsiElement pparent = parent.getParent(); - if (pparent instanceof PsiClass) { - final PsiClass inheritor = (PsiClass) pparent; - if (parent.equals(inheritor.getExtendsList()) || parent.equals(inheritor.getImplementsList())) { - if (myCurrentInheritor.equals(inheritor)) { - usages.add(new ReplaceExtendsListUsageInfo((PsiJavaCodeReferenceElement) element, mySuperClass, inheritor)); + ReferencesSearch.search(mySuperClass).forEach(reference -> { + final PsiElement element = reference.getElement(); + if (element instanceof PsiJavaCodeReferenceElement) { + if (myCurrentInheritor != null) { + final PsiElement parent = element.getParent(); + if (parent instanceof PsiReferenceList) { + final PsiElement pparent = parent.getParent(); + if (pparent instanceof PsiClass) { + final PsiClass inheritor = (PsiClass)pparent; + if (parent.equals(inheritor.getExtendsList()) || parent.equals(inheritor.getImplementsList())) { + if (myCurrentInheritor.equals(inheritor)) { + usages.add(new ReplaceExtendsListUsageInfo( + (PsiJavaCodeReferenceElement)element, + mySuperClass, + inheritor + )); + } + } + } + } + return true; + } + final PsiImportStaticStatement staticImportStatement = PsiTreeUtil.getParentOfType(element, PsiImportStaticStatement.class); + if (staticImportStatement != null) { + usages.add(new ReplaceStaticImportUsageInfo(staticImportStatement, myTargetClasses)); + } + else { + final PsiImportStatement importStatement = PsiTreeUtil.getParentOfType(element, PsiImportStatement.class); + if (importStatement != null) { + usages.add(new RemoveImportUsageInfo(importStatement)); + } + else { + final PsiElement parent = element.getParent(); + if (parent instanceof PsiReferenceList) { + final PsiElement pparent = parent.getParent(); + if (pparent instanceof PsiClass) { + final PsiClass inheritor = (PsiClass)pparent; + if (parent.equals(inheritor.getExtendsList()) || parent.equals(inheritor.getImplementsList())) { + usages.add(new ReplaceExtendsListUsageInfo( + (PsiJavaCodeReferenceElement)element, + mySuperClass, + inheritor + )); + } + } + } + else { + final PsiClass targetClass = myTargetClasses[0]; + final PsiClassType targetClassType = elementFactory.createType( + targetClass, + TypeConversionUtil.getSuperClassSubstitutor(mySuperClass, targetClass, PsiSubstitutor.EMPTY) + ); + + if (parent instanceof PsiTypeElement) { + final PsiType superClassType = ((PsiTypeElement)parent).getType(); + PsiSubstitutor subst = + getSuperClassSubstitutor(superClassType, targetClassType, resolveHelper, targetClass); + usages.add(new ReplaceWithSubtypeUsageInfo( + ((PsiTypeElement)parent), + elementFactory.createType(targetClass, subst), + myTargetClasses + )); + } + else if (parent instanceof PsiNewExpression) { + final PsiClassType newType = elementFactory.createType( + targetClass, + getSuperClassSubstitutor( + ((PsiNewExpression)parent).getType(), + targetClassType, + resolveHelper, + targetClass + ) + ); + usages.add(new ReplaceConstructorUsageInfo(((PsiNewExpression)parent), newType, myTargetClasses)); + } + else if (parent instanceof PsiJavaCodeReferenceElement) { + usages.add(new ReplaceReferenceUsageInfo( + ((PsiJavaCodeReferenceElement)parent).getQualifier(), + myTargetClasses + )); + } + } + } } - } } - } - return true; - } - final PsiImportStaticStatement staticImportStatement = PsiTreeUtil.getParentOfType(element, PsiImportStaticStatement.class); - if (staticImportStatement != null) { - usages.add(new ReplaceStaticImportUsageInfo(staticImportStatement, myTargetClasses)); - } else { - final PsiImportStatement importStatement = PsiTreeUtil.getParentOfType(element, PsiImportStatement.class); - if (importStatement != null) { - usages.add(new RemoveImportUsageInfo(importStatement)); - } else { - final PsiElement parent = element.getParent(); - if (parent instanceof PsiReferenceList) { - final PsiElement pparent = parent.getParent(); - if (pparent instanceof PsiClass) { - final PsiClass inheritor = (PsiClass) pparent; - if (parent.equals(inheritor.getExtendsList()) || parent.equals(inheritor.getImplementsList())) { - usages.add(new ReplaceExtendsListUsageInfo((PsiJavaCodeReferenceElement) element, mySuperClass, inheritor)); + return true; + }); + for (PsiClass targetClass : myTargetClasses) { + for (MemberInfo memberInfo : myMemberInfos) { + final PsiMember member = memberInfo.getMember(); + for (PsiReference reference : ReferencesSearch.search(member, member.getUseScope(), true)) { + final PsiElement element = reference.getElement(); + if (element instanceof PsiReferenceExpression && + ((PsiReferenceExpression)element).getQualifierExpression() instanceof PsiSuperExpression && + PsiTreeUtil.isAncestor(targetClass, element, false)) { + usages.add(new RemoveQualifierUsageInfo((PsiReferenceExpression)element)); + } + } + } + + final PsiMethod[] superConstructors = mySuperClass.getConstructors(); + for (PsiMethod constructor : targetClass.getConstructors()) { + final PsiCodeBlock constrBody = constructor.getBody(); + LOG.assertTrue(constrBody != null); + final PsiStatement[] statements = constrBody.getStatements(); + if (statements.length > 0) { + final PsiStatement firstConstrStatement = statements[0]; + if (firstConstrStatement instanceof PsiExpressionStatement) { + final PsiExpression expression = ((PsiExpressionStatement)firstConstrStatement).getExpression(); + if (expression instanceof PsiMethodCallExpression) { + final PsiReferenceExpression methodExpression = ((PsiMethodCallExpression)expression).getMethodExpression(); + if (methodExpression.getText().equals(PsiKeyword.SUPER)) { + final PsiMethod superConstructor = ((PsiMethodCallExpression)expression).resolveMethod(); + if (superConstructor != null && superConstructor.getBody() != null) { + usages.add(new InlineSuperCallUsageInfo((PsiMethodCallExpression)expression)); + continue; + } + } + } + } } - } - } else { - final PsiClass targetClass = myTargetClasses[0]; - final PsiClassType targetClassType = elementFactory - .createType(targetClass, TypeConversionUtil.getSuperClassSubstitutor(mySuperClass, targetClass, PsiSubstitutor.EMPTY)); - if (parent instanceof PsiTypeElement) { - final PsiType superClassType = ((PsiTypeElement) parent).getType(); - PsiSubstitutor subst = getSuperClassSubstitutor(superClassType, targetClassType, resolveHelper, targetClass); - usages.add(new ReplaceWithSubtypeUsageInfo(((PsiTypeElement) parent), elementFactory.createType(targetClass, subst), myTargetClasses)); - } else if (parent instanceof PsiNewExpression) { - final PsiClassType newType = elementFactory.createType(targetClass, - getSuperClassSubstitutor(((PsiNewExpression) parent).getType(), - targetClassType, resolveHelper, - targetClass)); - usages.add(new ReplaceConstructorUsageInfo(((PsiNewExpression) parent), newType, myTargetClasses)); - } else if (parent instanceof PsiJavaCodeReferenceElement) { - usages.add(new ReplaceReferenceUsageInfo(((PsiJavaCodeReferenceElement) parent).getQualifier(), myTargetClasses)); - } + //insert implicit call to super + for (PsiMethod superConstructor : superConstructors) { + if (superConstructor.getParameterList().getParametersCount() == 0) { + final PsiExpression expression = + JavaPsiFacade.getElementFactory(myProject).createExpressionFromText("super()", constructor); + usages.add(new InlineSuperCallUsageInfo((PsiMethodCallExpression)expression, constrBody)); + } + } } - } - } - } - return true; - }); - for (PsiClass targetClass : myTargetClasses) { - for (MemberInfo memberInfo : myMemberInfos) { - final PsiMember member = memberInfo.getMember(); - for (PsiReference reference : ReferencesSearch.search(member, member.getUseScope(), true)) { - final PsiElement element = reference.getElement(); - if (element instanceof PsiReferenceExpression && - ((PsiReferenceExpression) element).getQualifierExpression() instanceof PsiSuperExpression && - PsiTreeUtil.isAncestor(targetClass, element, false)) { - usages.add(new RemoveQualifierUsageInfo((PsiReferenceExpression) element)); - } - } - } - final PsiMethod[] superConstructors = mySuperClass.getConstructors(); - for (PsiMethod constructor : targetClass.getConstructors()) { - final PsiCodeBlock constrBody = constructor.getBody(); - LOG.assertTrue(constrBody != null); - final PsiStatement[] statements = constrBody.getStatements(); - if (statements.length > 0) { - final PsiStatement firstConstrStatement = statements[0]; - if (firstConstrStatement instanceof PsiExpressionStatement) { - final PsiExpression expression = ((PsiExpressionStatement) firstConstrStatement).getExpression(); - if (expression instanceof PsiMethodCallExpression) { - final PsiReferenceExpression methodExpression = ((PsiMethodCallExpression) expression).getMethodExpression(); - if (methodExpression.getText().equals(PsiKeyword.SUPER)) { - final PsiMethod superConstructor = ((PsiMethodCallExpression) expression).resolveMethod(); - if (superConstructor != null && superConstructor.getBody() != null) { - usages.add(new InlineSuperCallUsageInfo((PsiMethodCallExpression) expression)); - continue; + if (targetClass.getConstructors().length == 0) { + //copy default constructor + for (PsiMethod superConstructor : superConstructors) { + if (superConstructor.getParameterList().getParametersCount() == 0) { + usages.add(new CopyDefaultConstructorUsageInfo(targetClass, superConstructor)); + break; + } } - } } - } } + } - //insert implicit call to super - for (PsiMethod superConstructor : superConstructors) { - if (superConstructor.getParameterList().getParametersCount() == 0) { - final PsiExpression expression = JavaPsiFacade.getElementFactory(myProject).createExpressionFromText("super()", constructor); - usages.add(new InlineSuperCallUsageInfo((PsiMethodCallExpression) expression, constrBody)); - } + @Override + protected boolean preprocessUsages(final Ref refUsages) { + final MultiMap conflicts = new MultiMap<>(); + final PushDownConflicts pushDownConflicts = new PushDownConflicts(mySuperClass, myMemberInfos); + for (PsiClass targetClass : myTargetClasses) { + for (MemberInfo info : myMemberInfos) { + final PsiMember member = info.getMember(); + pushDownConflicts.checkMemberPlacementInTargetClassConflict(targetClass, member); + } + //todo check accessibility conflicts } - } - - if (targetClass.getConstructors().length == 0) { - //copy default constructor - for (PsiMethod superConstructor : superConstructors) { - if (superConstructor.getParameterList().getParametersCount() == 0) { - usages.add(new CopyDefaultConstructorUsageInfo(targetClass, superConstructor)); - break; - } + final MultiMap conflictsMap = pushDownConflicts.getConflicts(); + for (PsiElement element : conflictsMap.keySet()) { + conflicts.put(element, conflictsMap.get(element)); } - } + if (myCurrentInheritor != null) { + ReferencesSearch.search(myCurrentInheritor).forEach(reference -> { + final PsiElement element = reference.getElement(); + if (element != null) { + final PsiElement parent = element.getParent(); + if (parent instanceof PsiNewExpression) { + final PsiClass aClass = PsiUtil.resolveClassInType(getPlaceExpectedType(parent)); + if (aClass == mySuperClass) { + conflicts.putValue(parent, "Instance of target type is passed to a place where super class is expected."); + return false; + } + } + } + return true; + }); + } + checkConflicts(refUsages, conflicts); + return showConflicts(conflicts, refUsages.get()); } - } - @Override - protected boolean preprocessUsages(final Ref refUsages) { - final MultiMap conflicts = new MultiMap<>(); - final PushDownConflicts pushDownConflicts = new PushDownConflicts(mySuperClass, myMemberInfos); - for (PsiClass targetClass : myTargetClasses) { - for (MemberInfo info : myMemberInfos) { - final PsiMember member = info.getMember(); - pushDownConflicts.checkMemberPlacementInTargetClassConflict(targetClass, member); - } - //todo check accessibility conflicts - } - final MultiMap conflictsMap = pushDownConflicts.getConflicts(); - for (PsiElement element : conflictsMap.keySet()) { - conflicts.put(element, conflictsMap.get(element)); - } - if (myCurrentInheritor != null) { - ReferencesSearch.search(myCurrentInheritor).forEach(reference -> { - final PsiElement element = reference.getElement(); - if (element != null) { - final PsiElement parent = element.getParent(); - if (parent instanceof PsiNewExpression) { - final PsiClass aClass = PsiUtil.resolveClassInType(getPlaceExpectedType(parent)); - if (aClass == mySuperClass) { - conflicts.putValue(parent, "Instance of target type is passed to a place where super class is expected."); - return false; + @Nullable + private static PsiType getPlaceExpectedType(PsiElement parent) { + PsiType type = PsiTypesUtil.getExpectedTypeByParent(parent); + if (type == null) { + final PsiElement arg = PsiUtil.skipParenthesizedExprUp(parent); + final PsiElement gParent = arg.getParent(); + if (gParent instanceof PsiExpressionList) { + int i = ArrayUtilRt.find(((PsiExpressionList)gParent).getExpressions(), arg); + final PsiElement pParent = gParent.getParent(); + if (pParent instanceof PsiCallExpression) { + final PsiMethod method = ((PsiCallExpression)pParent).resolveMethod(); + if (method != null) { + final PsiParameter[] parameters = method.getParameterList().getParameters(); + if (i >= parameters.length) { + if (method.isVarArgs()) { + return ((PsiEllipsisType)parameters[parameters.length - 1].getType()).getComponentType(); + } + } + else { + return parameters[i].getType(); + } + } + } } - } } - return true; - }); + return type; } - checkConflicts(refUsages, conflicts); - return showConflicts(conflicts, refUsages.get()); - } - @Nullable - private static PsiType getPlaceExpectedType(PsiElement parent) { - PsiType type = PsiTypesUtil.getExpectedTypeByParent(parent); - if (type == null) { - final PsiElement arg = PsiUtil.skipParenthesizedExprUp(parent); - final PsiElement gParent = arg.getParent(); - if (gParent instanceof PsiExpressionList) { - int i = ArrayUtilRt.find(((PsiExpressionList) gParent).getExpressions(), arg); - final PsiElement pParent = gParent.getParent(); - if (pParent instanceof PsiCallExpression) { - final PsiMethod method = ((PsiCallExpression) pParent).resolveMethod(); - if (method != null) { - final PsiParameter[] parameters = method.getParameterList().getParameters(); - if (i >= parameters.length) { - if (method.isVarArgs()) { - return ((PsiEllipsisType) parameters[parameters.length - 1].getType()).getComponentType(); - } - } else { - return parameters[i].getType(); + protected void performRefactoring(final UsageInfo[] usages) { + new PushDownProcessor(mySuperClass.getProject(), myMemberInfos, mySuperClass, new DocCommentPolicy(myPolicy)) { + //push down conflicts are already collected + @Override + protected boolean showConflicts(@Nonnull MultiMap conflicts, UsageInfo[] usages) { + return true; } - } - } - } - } - return type; - } - protected void performRefactoring(final UsageInfo[] usages) { - new PushDownProcessor(mySuperClass.getProject(), myMemberInfos, mySuperClass, new DocCommentPolicy(myPolicy)) { - //push down conflicts are already collected - @Override - protected boolean showConflicts(@Nonnull MultiMap conflicts, UsageInfo[] usages) { - return true; - } + @Override + @RequiredUIAccess + protected void performRefactoring(@Nonnull UsageInfo[] pushDownUsages) { + if (myCurrentInheritor != null) { + encodeRefs(); + pushDownToClass(myCurrentInheritor); + } + else { + super.performRefactoring(pushDownUsages); + } + CommonRefactoringUtil.sortDepthFirstRightLeftOrder(usages); + for (UsageInfo usageInfo : usages) { + if (!(usageInfo instanceof ReplaceExtendsListUsageInfo || usageInfo instanceof RemoveImportUsageInfo)) { + try { + ((FixableUsageInfo)usageInfo).fixUsage(); + } + catch (IncorrectOperationException e) { + LOG.info(e); + } + } + } + replaceInnerTypeUsages(); - @Override - @RequiredUIAccess - protected void performRefactoring(@Nonnull UsageInfo[] pushDownUsages) { - if (myCurrentInheritor != null) { - encodeRefs(); - pushDownToClass(myCurrentInheritor); - } else { - super.performRefactoring(pushDownUsages); - } - CommonRefactoringUtil.sortDepthFirstRightLeftOrder(usages); - for (UsageInfo usageInfo : usages) { - if (!(usageInfo instanceof ReplaceExtendsListUsageInfo || usageInfo instanceof RemoveImportUsageInfo)) { - try { - ((FixableUsageInfo) usageInfo).fixUsage(); - } catch (IncorrectOperationException e) { - LOG.info(e); + //postpone broken hierarchy + for (UsageInfo usage : usages) { + if (usage instanceof ReplaceExtendsListUsageInfo || usage instanceof RemoveImportUsageInfo) { + ((FixableUsageInfo)usage).fixUsage(); + } + } + if (myCurrentInheritor == null) { + try { + mySuperClass.delete(); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } } - } - } - replaceInnerTypeUsages(); + }.run(); + } - //postpone broken hierarchy - for (UsageInfo usage : usages) { - if (usage instanceof ReplaceExtendsListUsageInfo || usage instanceof RemoveImportUsageInfo) { - ((FixableUsageInfo) usage).fixUsage(); - } - } - if (myCurrentInheritor == null) { - try { - mySuperClass.delete(); - } catch (IncorrectOperationException e) { - LOG.error(e); - } - } - } - }.run(); - } + private void replaceInnerTypeUsages() { + final JavaPsiFacade facade = JavaPsiFacade.getInstance(myProject); + final PsiElementFactory elementFactory = facade.getElementFactory(); + final PsiResolveHelper resolveHelper = facade.getResolveHelper(); + final Map replacementMap = new HashMap<>(); + for (final PsiClass targetClass : myTargetClasses) { + final PsiSubstitutor superClassSubstitutor = + TypeConversionUtil.getSuperClassSubstitutor(mySuperClass, targetClass, PsiSubstitutor.EMPTY); + final PsiClassType targetClassType = elementFactory.createType(targetClass, superClassSubstitutor); + targetClass.accept(new JavaRecursiveElementWalkingVisitor() { + @Override + public void visitTypeElement(@Nonnull final PsiTypeElement typeElement) { + super.visitTypeElement(typeElement); + final PsiType superClassType = typeElement.getType(); + if (PsiUtil.resolveClassInType(superClassType) == mySuperClass) { + PsiSubstitutor subst = getSuperClassSubstitutor(superClassType, targetClassType, resolveHelper, targetClass); + replacementMap.put( + new UsageInfo(typeElement), + elementFactory.createTypeElement(elementFactory.createType(targetClass, subst)) + ); + } + } - private void replaceInnerTypeUsages() { - final JavaPsiFacade facade = JavaPsiFacade.getInstance(myProject); - final PsiElementFactory elementFactory = facade.getElementFactory(); - final PsiResolveHelper resolveHelper = facade.getResolveHelper(); - final Map replacementMap = new HashMap<>(); - for (final PsiClass targetClass : myTargetClasses) { - final PsiSubstitutor superClassSubstitutor = - TypeConversionUtil.getSuperClassSubstitutor(mySuperClass, targetClass, PsiSubstitutor.EMPTY); - final PsiClassType targetClassType = elementFactory.createType(targetClass, superClassSubstitutor); - targetClass.accept(new JavaRecursiveElementWalkingVisitor() { - @Override - public void visitTypeElement(@Nonnull final PsiTypeElement typeElement) { - super.visitTypeElement(typeElement); - final PsiType superClassType = typeElement.getType(); - if (PsiUtil.resolveClassInType(superClassType) == mySuperClass) { - PsiSubstitutor subst = getSuperClassSubstitutor(superClassType, targetClassType, resolveHelper, targetClass); - replacementMap.put(new UsageInfo(typeElement), elementFactory.createTypeElement(elementFactory.createType(targetClass, subst))); - } + @Override + @RequiredReadAction + public void visitNewExpression(@Nonnull final PsiNewExpression expression) { + super.visitNewExpression(expression); + final PsiType superClassType = expression.getType(); + if (PsiUtil.resolveClassInType(superClassType) == mySuperClass) { + PsiSubstitutor subst = getSuperClassSubstitutor(superClassType, targetClassType, resolveHelper, targetClass); + try { + replacementMap.put( + new UsageInfo(expression), + elementFactory.createExpressionFromText( + "new " + elementFactory.createType(targetClass, subst).getCanonicalText() + + expression.getArgumentList().getText(), + expression + ) + ); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + } + }); } - - @Override - @RequiredReadAction - public void visitNewExpression(@Nonnull final PsiNewExpression expression) { - super.visitNewExpression(expression); - final PsiType superClassType = expression.getType(); - if (PsiUtil.resolveClassInType(superClassType) == mySuperClass) { - PsiSubstitutor subst = getSuperClassSubstitutor(superClassType, targetClassType, resolveHelper, targetClass); - try { - replacementMap.put(new UsageInfo(expression), elementFactory.createExpressionFromText("new " + elementFactory.createType( - targetClass, subst).getCanonicalText() + expression.getArgumentList().getText(), expression)); - } catch (IncorrectOperationException e) { - LOG.error(e); + try { + for (Map.Entry elementEntry : replacementMap.entrySet()) { + final PsiElement element = elementEntry.getKey().getElement(); + if (element != null) { + element.replace(elementEntry.getValue()); + } } - } } - }); - } - try { - for (Map.Entry elementEntry : replacementMap.entrySet()) { - final PsiElement element = elementEntry.getKey().getElement(); - if (element != null) { - element.replace(elementEntry.getValue()); + catch (IncorrectOperationException e) { + LOG.error(e); } - } - } catch (IncorrectOperationException e) { - LOG.error(e); } - } - @RequiredReadAction - private static PsiSubstitutor getSuperClassSubstitutor( - final PsiType superClassType, - final PsiClassType targetClassType, - final PsiResolveHelper resolveHelper, - PsiClass targetClass - ) { - PsiSubstitutor subst = PsiSubstitutor.EMPTY; - for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(targetClass)) { - subst = subst.put( - typeParameter, - resolveHelper.getSubstitutionForTypeParameter( - typeParameter, - targetClassType, - superClassType, - false, - PsiUtil.getLanguageLevel(targetClass) - ) - ); + @RequiredReadAction + private static PsiSubstitutor getSuperClassSubstitutor( + final PsiType superClassType, + final PsiClassType targetClassType, + final PsiResolveHelper resolveHelper, + PsiClass targetClass + ) { + PsiSubstitutor subst = PsiSubstitutor.EMPTY; + for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(targetClass)) { + subst = subst.put( + typeParameter, + resolveHelper.getSubstitutionForTypeParameter( + typeParameter, + targetClassType, + superClassType, + false, + PsiUtil.getLanguageLevel(targetClass) + ) + ); + } + return subst; } - return subst; - } - protected String getCommandName() { - return InlineSuperClassRefactoringHandler.REFACTORING_NAME; - } + protected String getCommandName() { + return InlineSuperClassRefactoringHandler.REFACTORING_NAME; + } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/invertBoolean/InvertBooleanProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/invertBoolean/InvertBooleanProcessor.java index 7ad899cfc..f00d4692d 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/invertBoolean/InvertBooleanProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/invertBoolean/InvertBooleanProcessor.java @@ -35,6 +35,7 @@ import java.util.HashMap; import java.util.HashSet; + import jakarta.annotation.Nonnull; import java.util.ArrayList; @@ -46,224 +47,238 @@ * @author ven */ public class InvertBooleanProcessor extends BaseRefactoringProcessor { - private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.invertBoolean.InvertBooleanMethodProcessor"); + private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.invertBoolean.InvertBooleanMethodProcessor"); - private PsiNamedElement myElement; - private final String myNewName; - private final RenameProcessor myRenameProcessor; - private final Map myToInvert = new HashMap(); - private final SmartPointerManager mySmartPointerManager; + private PsiNamedElement myElement; + private final String myNewName; + private final RenameProcessor myRenameProcessor; + private final Map myToInvert = new HashMap(); + private final SmartPointerManager mySmartPointerManager; - public InvertBooleanProcessor(final PsiNamedElement namedElement, final String newName) { - super(namedElement.getProject()); - myElement = namedElement; - myNewName = newName; - final Project project = namedElement.getProject(); - myRenameProcessor = new RenameProcessor(project, namedElement, newName, false, false); - mySmartPointerManager = SmartPointerManager.getInstance(project); - } + public InvertBooleanProcessor(final PsiNamedElement namedElement, final String newName) { + super(namedElement.getProject()); + myElement = namedElement; + myNewName = newName; + final Project project = namedElement.getProject(); + myRenameProcessor = new RenameProcessor(project, namedElement, newName, false, false); + mySmartPointerManager = SmartPointerManager.getInstance(project); + } - @Override - @Nonnull - protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { - return new InvertBooleanUsageViewDescriptor(myElement); - } + @Override + @Nonnull + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { + return new InvertBooleanUsageViewDescriptor(myElement); + } - @Override - protected boolean preprocessUsages(Ref refUsages) { - if (myRenameProcessor.preprocessUsages(refUsages)) { - prepareSuccessful(); - return true; + @Override + protected boolean preprocessUsages(Ref refUsages) { + if (myRenameProcessor.preprocessUsages(refUsages)) { + prepareSuccessful(); + return true; + } + return false; } - return false; - } - @Override - @Nonnull - protected UsageInfo[] findUsages() { - final List toInvert = new ArrayList(); + @Override + @Nonnull + protected UsageInfo[] findUsages() { + final List toInvert = new ArrayList(); - addRefsToInvert(toInvert, myElement); + addRefsToInvert(toInvert, myElement); - if (myElement instanceof PsiMethod) { - final Collection overriders = OverridingMethodsSearch.search((PsiMethod)myElement).findAll(); - for (PsiMethod overrider : overriders) { - myRenameProcessor.addElement(overrider, myNewName); - } + if (myElement instanceof PsiMethod) { + final Collection overriders = OverridingMethodsSearch.search((PsiMethod)myElement).findAll(); + for (PsiMethod overrider : overriders) { + myRenameProcessor.addElement(overrider, myNewName); + } - Collection allMethods = new HashSet(overriders); - allMethods.add((PsiMethod)myElement); + Collection allMethods = new HashSet(overriders); + allMethods.add((PsiMethod)myElement); - for (PsiMethod method : allMethods) { - method.accept(new JavaRecursiveElementWalkingVisitor() { - @Override public void visitReturnStatement(PsiReturnStatement statement) { - final PsiExpression returnValue = statement.getReturnValue(); - if (returnValue != null && PsiType.BOOLEAN.equals(returnValue.getType())) { - toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(returnValue)); - } - } + for (PsiMethod method : allMethods) { + method.accept(new JavaRecursiveElementWalkingVisitor() { + @Override + public void visitReturnStatement(PsiReturnStatement statement) { + final PsiExpression returnValue = statement.getReturnValue(); + if (returnValue != null && PsiType.BOOLEAN.equals(returnValue.getType())) { + toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(returnValue)); + } + } - @Override - public void visitClass(PsiClass aClass) { - } - }); - } - } else if (myElement instanceof PsiParameter && ((PsiParameter)myElement).getDeclarationScope() instanceof PsiMethod) { - final PsiMethod method = (PsiMethod)((PsiParameter)myElement).getDeclarationScope(); - int index = method.getParameterList().getParameterIndex((PsiParameter)myElement); - LOG.assertTrue(index >= 0); - final Query methodQuery = MethodReferencesSearch.search(method); - final Collection methodRefs = methodQuery.findAll(); - for (PsiReference ref : methodRefs) { - PsiElement parent = ref.getElement().getParent(); - if (parent instanceof PsiAnonymousClass) { - parent = parent.getParent(); + @Override + public void visitClass(PsiClass aClass) { + } + }); + } } - if (parent instanceof PsiCall) { - final PsiCall call = (PsiCall)parent; - final PsiReferenceExpression methodExpression = call instanceof PsiMethodCallExpression ? - ((PsiMethodCallExpression)call).getMethodExpression() : - null; - final PsiExpressionList argumentList = call.getArgumentList(); - if (argumentList != null) { - final PsiExpression[] args = argumentList.getExpressions(); - if (index < args.length) { - if (methodExpression == null || methodExpression.getQualifier() == null || !"super".equals(methodExpression.getQualifierExpression().getText())) { - toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(args[index])); - } + else if (myElement instanceof PsiParameter && ((PsiParameter)myElement).getDeclarationScope() instanceof PsiMethod) { + final PsiMethod method = (PsiMethod)((PsiParameter)myElement).getDeclarationScope(); + int index = method.getParameterList().getParameterIndex((PsiParameter)myElement); + LOG.assertTrue(index >= 0); + final Query methodQuery = MethodReferencesSearch.search(method); + final Collection methodRefs = methodQuery.findAll(); + for (PsiReference ref : methodRefs) { + PsiElement parent = ref.getElement().getParent(); + if (parent instanceof PsiAnonymousClass) { + parent = parent.getParent(); + } + if (parent instanceof PsiCall) { + final PsiCall call = (PsiCall)parent; + final PsiReferenceExpression methodExpression = call instanceof PsiMethodCallExpression ? + ((PsiMethodCallExpression)call).getMethodExpression() : + null; + final PsiExpressionList argumentList = call.getArgumentList(); + if (argumentList != null) { + final PsiExpression[] args = argumentList.getExpressions(); + if (index < args.length) { + if (methodExpression == null || methodExpression.getQualifier() == null + || !"super".equals(methodExpression.getQualifierExpression().getText())) { + toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(args[index])); + } + } + } + } + } + final Collection overriders = OverridingMethodsSearch.search(method).findAll(); + for (PsiMethod overrider : overriders) { + final PsiParameter overriderParameter = overrider.getParameterList().getParameters()[index]; + myRenameProcessor.addElement(overriderParameter, myNewName); + addRefsToInvert(toInvert, overriderParameter); } - } } - } - final Collection overriders = OverridingMethodsSearch.search(method).findAll(); - for (PsiMethod overrider : overriders) { - final PsiParameter overriderParameter = overrider.getParameterList().getParameters()[index]; - myRenameProcessor.addElement(overriderParameter, myNewName); - addRefsToInvert(toInvert, overriderParameter); - } - } - final UsageInfo[] renameUsages = myRenameProcessor.findUsages(); + final UsageInfo[] renameUsages = myRenameProcessor.findUsages(); - final SmartPsiElementPointer[] usagesToInvert = toInvert.toArray(new SmartPsiElementPointer[toInvert.size()]); + final SmartPsiElementPointer[] usagesToInvert = toInvert.toArray(new SmartPsiElementPointer[toInvert.size()]); - //merge rename and invert usages - Map expressionsToUsages = new HashMap(); - List result = new ArrayList(); - for (UsageInfo renameUsage : renameUsages) { - expressionsToUsages.put(renameUsage.getElement(), renameUsage); - result.add(renameUsage); - } + //merge rename and invert usages + Map expressionsToUsages = new HashMap(); + List result = new ArrayList(); + for (UsageInfo renameUsage : renameUsages) { + expressionsToUsages.put(renameUsage.getElement(), renameUsage); + result.add(renameUsage); + } - for (SmartPsiElementPointer pointer : usagesToInvert) { - final PsiExpression expression = (PsiExpression)pointer.getElement(); - if (!expressionsToUsages.containsKey(expression)) { - final UsageInfo usageInfo = new UsageInfo(expression); - expressionsToUsages.put(expression, usageInfo); - result.add(usageInfo); //fake UsageInfo - myToInvert.put(usageInfo, pointer); - } else { - myToInvert.put(expressionsToUsages.get(expression), pointer); - } + for (SmartPsiElementPointer pointer : usagesToInvert) { + final PsiExpression expression = (PsiExpression)pointer.getElement(); + if (!expressionsToUsages.containsKey(expression)) { + final UsageInfo usageInfo = new UsageInfo(expression); + expressionsToUsages.put(expression, usageInfo); + result.add(usageInfo); //fake UsageInfo + myToInvert.put(usageInfo, pointer); + } + else { + myToInvert.put(expressionsToUsages.get(expression), pointer); + } + } + + return result.toArray(new UsageInfo[result.size()]); } - return result.toArray(new UsageInfo[result.size()]); - } + private void addRefsToInvert(final List toInvert, final PsiNamedElement namedElement) { + final Query query = namedElement instanceof PsiMethod ? + MethodReferencesSearch.search((PsiMethod)namedElement) : + ReferencesSearch.search(namedElement); + final Collection refs = query.findAll(); - private void addRefsToInvert(final List toInvert, final PsiNamedElement namedElement) { - final Query query = namedElement instanceof PsiMethod ? - MethodReferencesSearch.search((PsiMethod)namedElement) : - ReferencesSearch.search(namedElement); - final Collection refs = query.findAll(); + for (PsiReference ref : refs) { + final PsiElement element = ref.getElement(); + if (element instanceof PsiReferenceExpression) { + final PsiReferenceExpression refExpr = (PsiReferenceExpression)element; + PsiElement parent = refExpr.getParent(); + if (parent instanceof PsiAssignmentExpression && refExpr.equals(((PsiAssignmentExpression)parent).getLExpression())) { + toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(((PsiAssignmentExpression)parent).getRExpression())); + } + else { + if (namedElement instanceof PsiParameter) { //filter usages in super method calls + if (refExpr.getParent().getParent() instanceof PsiMethodCallExpression) { + final PsiReferenceExpression methodExpression = + ((PsiMethodCallExpression)refExpr.getParent().getParent()).getMethodExpression(); + if (methodExpression.getQualifier() != null && "super".equals(methodExpression.getQualifierExpression() + .getText())) { + continue; + } + } + } - for (PsiReference ref : refs) { - final PsiElement element = ref.getElement(); - if (element instanceof PsiReferenceExpression) { - final PsiReferenceExpression refExpr = (PsiReferenceExpression)element; - PsiElement parent = refExpr.getParent(); - if (parent instanceof PsiAssignmentExpression && refExpr.equals(((PsiAssignmentExpression)parent).getLExpression())) { - toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(((PsiAssignmentExpression)parent).getRExpression())); - } - else { - if (namedElement instanceof PsiParameter) { //filter usages in super method calls - if (refExpr.getParent().getParent() instanceof PsiMethodCallExpression) { - final PsiReferenceExpression methodExpression = ((PsiMethodCallExpression)refExpr.getParent().getParent()).getMethodExpression(); - if (methodExpression.getQualifier() != null && "super".equals(methodExpression.getQualifierExpression().getText())) { - continue; - } + toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(refExpr)); + } } - } + } - toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(refExpr)); + if (namedElement instanceof PsiVariable) { + final PsiExpression initializer = ((PsiVariable)namedElement).getInitializer(); + if (initializer != null) { + toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(initializer)); + } } - } } - if (namedElement instanceof PsiVariable) { - final PsiExpression initializer = ((PsiVariable)namedElement).getInitializer(); - if (initializer != null) { - toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(initializer)); - } + @Override + protected void refreshElements(PsiElement[] elements) { + LOG.assertTrue(elements.length == 1 && elements[0] instanceof PsiMethod); + myElement = (PsiMethod)elements[0]; } - } - @Override - protected void refreshElements(PsiElement[] elements) { - LOG.assertTrue(elements.length == 1 && elements[0] instanceof PsiMethod); - myElement = (PsiMethod)elements[0]; - } - - private static UsageInfo[] extractUsagesForElement(PsiElement element, UsageInfo[] usages) { - final ArrayList extractedUsages = new ArrayList(usages.length); - for (UsageInfo usage : usages) { - if (usage instanceof MoveRenameUsageInfo) { - MoveRenameUsageInfo usageInfo = (MoveRenameUsageInfo)usage; - if (element.equals(usageInfo.getReferencedElement())) { - extractedUsages.add(usageInfo); + private static UsageInfo[] extractUsagesForElement(PsiElement element, UsageInfo[] usages) { + final ArrayList extractedUsages = new ArrayList(usages.length); + for (UsageInfo usage : usages) { + if (usage instanceof MoveRenameUsageInfo) { + MoveRenameUsageInfo usageInfo = (MoveRenameUsageInfo)usage; + if (element.equals(usageInfo.getReferencedElement())) { + extractedUsages.add(usageInfo); + } + } } - } + return extractedUsages.toArray(new UsageInfo[extractedUsages.size()]); } - return extractedUsages.toArray(new UsageInfo[extractedUsages.size()]); - } - @Override - protected void performRefactoring(UsageInfo[] usages) { - for (final PsiElement element : myRenameProcessor.getElements()) { - try { - RenameUtil.doRename(element, myRenameProcessor.getNewName(element), extractUsagesForElement(element, usages), myProject, null); - } - catch (final IncorrectOperationException e) { - RenameUtil.showErrorMessage(e, element, myProject); - return; - } - } + @Override + protected void performRefactoring(UsageInfo[] usages) { + for (final PsiElement element : myRenameProcessor.getElements()) { + try { + RenameUtil.doRename( + element, + myRenameProcessor.getNewName(element), + extractUsagesForElement(element, usages), + myProject, + null + ); + } + catch (final IncorrectOperationException e) { + RenameUtil.showErrorMessage(e, element, myProject); + return; + } + } - for (UsageInfo usage : usages) { - final SmartPsiElementPointer pointerToInvert = myToInvert.get(usage); - if (pointerToInvert != null) { - PsiExpression expression = (PsiExpression)pointerToInvert.getElement(); - LOG.assertTrue(expression != null); - if (expression.getParent() instanceof PsiMethodCallExpression) expression = (PsiExpression)expression.getParent(); - try { - while (expression.getParent() instanceof PsiPrefixExpression && - ((PsiPrefixExpression)expression.getParent()).getOperationTokenType() == JavaTokenType.EXCL) { - expression = (PsiExpression)expression.getParent(); - } - if (!(expression.getParent() instanceof PsiExpressionStatement)) { - expression.replace(CodeInsightServicesUtil.invertCondition(expression)); - } - } - catch (IncorrectOperationException e) { - LOG.error(e); + for (UsageInfo usage : usages) { + final SmartPsiElementPointer pointerToInvert = myToInvert.get(usage); + if (pointerToInvert != null) { + PsiExpression expression = (PsiExpression)pointerToInvert.getElement(); + LOG.assertTrue(expression != null); + if (expression.getParent() instanceof PsiMethodCallExpression) { + expression = (PsiExpression)expression.getParent(); + } + try { + while (expression.getParent() instanceof PsiPrefixExpression && + ((PsiPrefixExpression)expression.getParent()).getOperationTokenType() == JavaTokenType.EXCL) { + expression = (PsiExpression)expression.getParent(); + } + if (!(expression.getParent() instanceof PsiExpressionStatement)) { + expression.replace(CodeInsightServicesUtil.invertCondition(expression)); + } + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } } - } } - } - @Override - protected String getCommandName() { - return InvertBooleanHandler.REFACTORING_NAME; - } + @Override + protected String getCommandName() { + return InvertBooleanHandler.REFACTORING_NAME; + } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/migration/MigrationProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/migration/MigrationProcessor.java index 3a637fef9..d2601fa41 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/migration/MigrationProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/migration/MigrationProcessor.java @@ -39,194 +39,165 @@ import consulo.util.lang.ref.Ref; import jakarta.annotation.Nonnull; + import java.util.ArrayList; /** * @author ven */ -public class MigrationProcessor extends BaseRefactoringProcessor -{ - private final MigrationMap myMigrationMap; - private static final String REFACTORING_NAME = RefactoringBundle.message("migration.title"); - private PsiMigration myPsiMigration; - private final SearchScope mySearchScope; - private ArrayList> myRefsToShorten; - - public MigrationProcessor(Project project, MigrationMap migrationMap) - { - this(project, migrationMap, GlobalSearchScope.projectScope(project)); - } - - public MigrationProcessor(Project project, MigrationMap migrationMap, SearchScope scope) - { - super(project); - myMigrationMap = migrationMap; - mySearchScope = scope; - myPsiMigration = startMigration(project); - } - - @Override - @Nonnull - protected UsageViewDescriptor createUsageViewDescriptor(@Nonnull UsageInfo[] usages) - { - return new MigrationUsagesViewDescriptor(myMigrationMap, false); - } - - private PsiMigration startMigration(Project project) - { - final PsiMigration migration = PsiMigrationManager.getInstance(project).startMigration(); - findOrCreateEntries(project, migration); - return migration; - } - - private void findOrCreateEntries(Project project, final PsiMigration migration) - { - for (int i = 0; i < myMigrationMap.getEntryCount(); i++) - { - MigrationMapEntry entry = myMigrationMap.getEntryAt(i); - if (entry.getType() == MigrationMapEntry.PACKAGE) - { - MigrationUtil.findOrCreatePackage(project, migration, entry.getOldName()); - } - else - { - MigrationUtil.findOrCreateClass(project, migration, entry.getOldName()); - } - } - } - - @Override - protected void refreshElements(@Nonnull PsiElement[] elements) - { - myPsiMigration = startMigration(myProject); - } - - @Override - @Nonnull - protected UsageInfo[] findUsages() - { - ArrayList usagesVector = new ArrayList<>(); - try - { - if (myMigrationMap == null) - { - return UsageInfo.EMPTY_ARRAY; - } - for (int i = 0; i < myMigrationMap.getEntryCount(); i++) - { - MigrationMapEntry entry = myMigrationMap.getEntryAt(i); - UsageInfo[] usages; - if (entry.getType() == MigrationMapEntry.PACKAGE) - { - usages = MigrationUtil.findPackageUsages(myProject, myPsiMigration, entry.getOldName(), mySearchScope); - } - else - { - usages = MigrationUtil.findClassUsages(myProject, myPsiMigration, entry.getOldName(), mySearchScope); - } - - for (UsageInfo usage : usages) - { - usagesVector.add(new MigrationUsageInfo(usage, entry)); - } - } - } - finally - { - //invalidating resolve caches without write action could lead to situations when somebody with read action resolves reference and gets ResolveResult - //then here, in another read actions, all caches are invalidated but those resolve result is used without additional checks inside that read action - but it's already invalid - ApplicationManager.getApplication().invokeLater(() -> WriteAction.run(this::finishFindMigration), myProject.getDisposed()); - } - return usagesVector.toArray(UsageInfo.EMPTY_ARRAY); - } - - private void finishFindMigration() - { - if (myPsiMigration != null) - { - myPsiMigration.finish(); - myPsiMigration = null; - } - } - - @Override - @RequiredUIAccess - protected boolean preprocessUsages(@Nonnull Ref refUsages) - { - if (refUsages.get().length == 0) - { - Messages.showInfoMessage(myProject, RefactoringLocalize.migrationNoUsagesFoundInTheProject().get(), REFACTORING_NAME); - return false; - } - setPreviewUsages(true); - return true; - } - - @Override - protected void performRefactoring(@Nonnull UsageInfo[] usages) - { - finishFindMigration(); - final PsiMigration psiMigration = PsiMigrationManager.getInstance(myProject).startMigration(); - LocalHistoryAction a = LocalHistory.getInstance().startAction(getCommandName()); - - myRefsToShorten = new ArrayList<>(); - try - { - boolean sameShortNames = false; - for (int i = 0; i < myMigrationMap.getEntryCount(); i++) - { - MigrationMapEntry entry = myMigrationMap.getEntryAt(i); - String newName = entry.getNewName(); - PsiElement element = entry.getType() == MigrationMapEntry.PACKAGE ? MigrationUtil.findOrCreatePackage(myProject, psiMigration, newName) : MigrationUtil.findOrCreateClass(myProject, - psiMigration, newName); - MigrationUtil.doMigration(element, newName, usages, myRefsToShorten); - if (!sameShortNames && Comparing.strEqual(StringUtil.getShortName(entry.getOldName()), StringUtil.getShortName(entry.getNewName()))) - { - sameShortNames = true; - } - } - - if (!sameShortNames) - { - myRefsToShorten.clear(); - } - } - finally - { - a.finish(); - psiMigration.finish(); - } - } - - @Override - protected void performPsiSpoilingRefactoring() - { - JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(myProject); - for (SmartPsiElementPointer pointer : myRefsToShorten) - { - PsiElement element = pointer.getElement(); - if (element != null) - { - styleManager.shortenClassReferences(element); - } - } - } - - @Override - @Nonnull - protected String getCommandName() - { - return REFACTORING_NAME; - } - - static class MigrationUsageInfo extends UsageInfo - { - MigrationMapEntry mapEntry; - - MigrationUsageInfo(UsageInfo info, MigrationMapEntry mapEntry) - { - super(info.getElement(), info.getRangeInElement().getStartOffset(), info.getRangeInElement().getEndOffset()); - this.mapEntry = mapEntry; - } - } +public class MigrationProcessor extends BaseRefactoringProcessor { + private final MigrationMap myMigrationMap; + private static final String REFACTORING_NAME = RefactoringBundle.message("migration.title"); + private PsiMigration myPsiMigration; + private final SearchScope mySearchScope; + private ArrayList> myRefsToShorten; + + public MigrationProcessor(Project project, MigrationMap migrationMap) { + this(project, migrationMap, GlobalSearchScope.projectScope(project)); + } + + public MigrationProcessor(Project project, MigrationMap migrationMap, SearchScope scope) { + super(project); + myMigrationMap = migrationMap; + mySearchScope = scope; + myPsiMigration = startMigration(project); + } + + @Override + @Nonnull + protected UsageViewDescriptor createUsageViewDescriptor(@Nonnull UsageInfo[] usages) { + return new MigrationUsagesViewDescriptor(myMigrationMap, false); + } + + private PsiMigration startMigration(Project project) { + final PsiMigration migration = PsiMigrationManager.getInstance(project).startMigration(); + findOrCreateEntries(project, migration); + return migration; + } + + private void findOrCreateEntries(Project project, final PsiMigration migration) { + for (int i = 0; i < myMigrationMap.getEntryCount(); i++) { + MigrationMapEntry entry = myMigrationMap.getEntryAt(i); + if (entry.getType() == MigrationMapEntry.PACKAGE) { + MigrationUtil.findOrCreatePackage(project, migration, entry.getOldName()); + } + else { + MigrationUtil.findOrCreateClass(project, migration, entry.getOldName()); + } + } + } + + @Override + protected void refreshElements(@Nonnull PsiElement[] elements) { + myPsiMigration = startMigration(myProject); + } + + @Override + @Nonnull + protected UsageInfo[] findUsages() { + ArrayList usagesVector = new ArrayList<>(); + try { + if (myMigrationMap == null) { + return UsageInfo.EMPTY_ARRAY; + } + for (int i = 0; i < myMigrationMap.getEntryCount(); i++) { + MigrationMapEntry entry = myMigrationMap.getEntryAt(i); + UsageInfo[] usages; + if (entry.getType() == MigrationMapEntry.PACKAGE) { + usages = MigrationUtil.findPackageUsages(myProject, myPsiMigration, entry.getOldName(), mySearchScope); + } + else { + usages = MigrationUtil.findClassUsages(myProject, myPsiMigration, entry.getOldName(), mySearchScope); + } + + for (UsageInfo usage : usages) { + usagesVector.add(new MigrationUsageInfo(usage, entry)); + } + } + } + finally { + //invalidating resolve caches without write action could lead to situations when somebody with read action resolves reference and gets ResolveResult + //then here, in another read actions, all caches are invalidated but those resolve result is used without additional checks inside that read action - but it's already invalid + ApplicationManager.getApplication().invokeLater(() -> WriteAction.run(this::finishFindMigration), myProject.getDisposed()); + } + return usagesVector.toArray(UsageInfo.EMPTY_ARRAY); + } + + private void finishFindMigration() { + if (myPsiMigration != null) { + myPsiMigration.finish(); + myPsiMigration = null; + } + } + + @Override + @RequiredUIAccess + protected boolean preprocessUsages(@Nonnull Ref refUsages) { + if (refUsages.get().length == 0) { + Messages.showInfoMessage(myProject, RefactoringLocalize.migrationNoUsagesFoundInTheProject().get(), REFACTORING_NAME); + return false; + } + setPreviewUsages(true); + return true; + } + + @Override + protected void performRefactoring(@Nonnull UsageInfo[] usages) { + finishFindMigration(); + final PsiMigration psiMigration = PsiMigrationManager.getInstance(myProject).startMigration(); + LocalHistoryAction a = LocalHistory.getInstance().startAction(getCommandName()); + + myRefsToShorten = new ArrayList<>(); + try { + boolean sameShortNames = false; + for (int i = 0; i < myMigrationMap.getEntryCount(); i++) { + MigrationMapEntry entry = myMigrationMap.getEntryAt(i); + String newName = entry.getNewName(); + PsiElement element = entry.getType() == MigrationMapEntry.PACKAGE + ? MigrationUtil.findOrCreatePackage(myProject, psiMigration, newName) + : MigrationUtil.findOrCreateClass(myProject, psiMigration, newName); + MigrationUtil.doMigration(element, newName, usages, myRefsToShorten); + if (!sameShortNames && Comparing.strEqual( + StringUtil.getShortName(entry.getOldName()), + StringUtil.getShortName(entry.getNewName()) + )) { + sameShortNames = true; + } + } + + if (!sameShortNames) { + myRefsToShorten.clear(); + } + } + finally { + a.finish(); + psiMigration.finish(); + } + } + + @Override + protected void performPsiSpoilingRefactoring() { + JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(myProject); + for (SmartPsiElementPointer pointer : myRefsToShorten) { + PsiElement element = pointer.getElement(); + if (element != null) { + styleManager.shortenClassReferences(element); + } + } + } + + @Override + @Nonnull + protected String getCommandName() { + return REFACTORING_NAME; + } + + static class MigrationUsageInfo extends UsageInfo { + MigrationMapEntry mapEntry; + + MigrationUsageInfo(UsageInfo info, MigrationMapEntry mapEntry) { + super(info.getElement(), info.getRangeInElement().getStartOffset(), info.getRangeInElement().getEndOffset()); + this.mapEntry = mapEntry; + } + } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java index 48293dea6..d6b9b3429 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java @@ -52,247 +52,253 @@ import java.util.*; public class MoveDirectoryWithClassesProcessor extends BaseRefactoringProcessor { - private final PsiDirectory[] myDirectories; - private final PsiDirectory myTargetDirectory; - private final boolean mySearchInComments; - private final boolean mySearchInNonJavaFiles; - private final Map myFilesToMove; - private NonCodeUsageInfo[] myNonCodeUsages; - private final MoveCallback myMoveCallback; + private final PsiDirectory[] myDirectories; + private final PsiDirectory myTargetDirectory; + private final boolean mySearchInComments; + private final boolean mySearchInNonJavaFiles; + private final Map myFilesToMove; + private NonCodeUsageInfo[] myNonCodeUsages; + private final MoveCallback myMoveCallback; - @RequiredReadAction - public MoveDirectoryWithClassesProcessor( - Project project, - PsiDirectory[] directories, - PsiDirectory targetDirectory, - boolean searchInComments, - boolean searchInNonJavaFiles, - boolean includeSelf, - MoveCallback moveCallback - ) { - super(project); - if (targetDirectory != null) { - final List dirs = new ArrayList<>(Arrays.asList(directories)); - for (Iterator iterator = dirs.iterator(); iterator.hasNext(); ) { - final PsiDirectory directory = iterator.next(); - if (targetDirectory.equals(directory.getParentDirectory()) || targetDirectory.equals(directory)) { - iterator.remove(); + @RequiredReadAction + public MoveDirectoryWithClassesProcessor( + Project project, + PsiDirectory[] directories, + PsiDirectory targetDirectory, + boolean searchInComments, + boolean searchInNonJavaFiles, + boolean includeSelf, + MoveCallback moveCallback + ) { + super(project); + if (targetDirectory != null) { + final List dirs = new ArrayList<>(Arrays.asList(directories)); + for (Iterator iterator = dirs.iterator(); iterator.hasNext(); ) { + final PsiDirectory directory = iterator.next(); + if (targetDirectory.equals(directory.getParentDirectory()) || targetDirectory.equals(directory)) { + iterator.remove(); + } + } + directories = dirs.toArray(new PsiDirectory[dirs.size()]); + } + myDirectories = directories; + myTargetDirectory = targetDirectory; + mySearchInComments = searchInComments; + mySearchInNonJavaFiles = searchInNonJavaFiles; + myMoveCallback = moveCallback; + myFilesToMove = new HashMap<>(); + for (PsiDirectory dir : directories) { + collectFiles2Move(myFilesToMove, dir, includeSelf ? dir.getParentDirectory() : dir, getTargetDirectory(dir)); } - } - directories = dirs.toArray(new PsiDirectory[dirs.size()]); - } - myDirectories = directories; - myTargetDirectory = targetDirectory; - mySearchInComments = searchInComments; - mySearchInNonJavaFiles = searchInNonJavaFiles; - myMoveCallback = moveCallback; - myFilesToMove = new HashMap<>(); - for (PsiDirectory dir : directories) { - collectFiles2Move(myFilesToMove, dir, includeSelf ? dir.getParentDirectory() : dir, getTargetDirectory(dir)); } - } - - @Nonnull - @Override - protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { - PsiElement[] elements = new PsiElement[myFilesToMove.size()]; - final PsiFile[] classes = PsiUtilCore.toPsiFileArray(myFilesToMove.keySet()); - System.arraycopy(classes, 0, elements, 0, classes.length); - return new MoveMultipleElementsViewDescriptor(elements, getTargetName()); - } - protected String getTargetName() { - return RefactoringUIUtil.getDescription(getTargetDirectory(null).getTargetDirectory(), false); - } - - @Nonnull - @Override - public UsageInfo[] findUsages() { - final List usages = new ArrayList<>(); - for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) { - helper.findUsages(myFilesToMove.keySet(), myDirectories, usages, mySearchInComments, mySearchInNonJavaFiles, myProject); + @Nonnull + @Override + protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { + PsiElement[] elements = new PsiElement[myFilesToMove.size()]; + final PsiFile[] classes = PsiUtilCore.toPsiFileArray(myFilesToMove.keySet()); + System.arraycopy(classes, 0, elements, 0, classes.length); + return new MoveMultipleElementsViewDescriptor(elements, getTargetName()); } - return UsageViewUtil.removeDuplicatedUsages(usages.toArray(new UsageInfo[usages.size()])); - } - @Override - protected boolean preprocessUsages(Ref refUsages) { - final MultiMap conflicts = new MultiMap<>(); - for (PsiFile psiFile : myFilesToMove.keySet()) { - try { - myFilesToMove.get(psiFile).checkMove(psiFile); - } catch (IncorrectOperationException e) { - conflicts.putValue(psiFile, e.getMessage()); - } - } - for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) { - helper.preprocessUsages(myProject, myFilesToMove.keySet(), refUsages.get(), myTargetDirectory, conflicts); + protected String getTargetName() { + return RefactoringUIUtil.getDescription(getTargetDirectory(null).getTargetDirectory(), false); } - return showConflicts(conflicts, refUsages.get()); - } - @Override - protected void refreshElements(PsiElement[] elements) { - } - - @Override - public void performRefactoring(UsageInfo[] usages) { - //try to create all directories beforehand - try { - //top level directories should be created even if they are empty - for (PsiDirectory directory : myDirectories) { - getResultDirectory(directory).findOrCreateTargetDirectory(); - } - for (PsiFile psiFile : myFilesToMove.keySet()) { - myFilesToMove.get(psiFile).findOrCreateTargetDirectory(); - } - - DumbService.getInstance(myProject).completeJustSubmittedTasks(); - } catch (IncorrectOperationException e) { - Messages.showErrorDialog(myProject, e.getMessage(), CommonLocalize.titleError().get()); - return; - } - try { - final List movedFiles = new ArrayList<>(); - final Map oldToNewElementsMapping = new HashMap<>(); - for (PsiFile psiFile : myFilesToMove.keySet()) { + @Nonnull + @Override + public UsageInfo[] findUsages() { + final List usages = new ArrayList<>(); for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) { - helper.beforeMove(psiFile); + helper.findUsages(myFilesToMove.keySet(), myDirectories, usages, mySearchInComments, mySearchInNonJavaFiles, myProject); } - final RefactoringElementListener listener = getTransaction().getElementListener(psiFile); - final PsiDirectory moveDestination = myFilesToMove.get(psiFile).getTargetDirectory(); + return UsageViewUtil.removeDuplicatedUsages(usages.toArray(new UsageInfo[usages.size()])); + } - for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) { - boolean processed = helper.move(psiFile, moveDestination, oldToNewElementsMapping, movedFiles, listener); - if (processed) { - break; - } + @Override + protected boolean preprocessUsages(Ref refUsages) { + final MultiMap conflicts = new MultiMap<>(); + for (PsiFile psiFile : myFilesToMove.keySet()) { + try { + myFilesToMove.get(psiFile).checkMove(psiFile); + } + catch (IncorrectOperationException e) { + conflicts.putValue(psiFile, e.getMessage()); + } } - } - for (PsiElement newElement : oldToNewElementsMapping.values()) { for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) { - helper.afterMove(newElement); + helper.preprocessUsages(myProject, myFilesToMove.keySet(), refUsages.get(), myTargetDirectory, conflicts); } - } - - // fix references in moved files to outer files - for (PsiFile movedFile : movedFiles) { - MoveFileHandler.forElement(movedFile).updateMovedFile(movedFile); - FileReferenceContextUtil.decodeFileReferences(movedFile); - } + return showConflicts(conflicts, refUsages.get()); + } - myNonCodeUsages = CommonMoveUtil.retargetUsages(usages, oldToNewElementsMapping); - for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) { - helper.postProcessUsages(usages, dir -> getResultDirectory(dir).getTargetDirectory()); - } - for (PsiDirectory directory : myDirectories) { - directory.delete(); - } - } catch (IncorrectOperationException e) { - myNonCodeUsages = new NonCodeUsageInfo[0]; - RefactoringUIUtil.processIncorrectOperation(myProject, e); + @Override + protected void refreshElements(PsiElement[] elements) { } - } - @RequiredReadAction - private TargetDirectoryWrapper getResultDirectory(PsiDirectory dir) { - return myTargetDirectory != null - ? new TargetDirectoryWrapper(myTargetDirectory, dir.getName()) - : getTargetDirectory(dir); - } + @Override + public void performRefactoring(UsageInfo[] usages) { + //try to create all directories beforehand + try { + //top level directories should be created even if they are empty + for (PsiDirectory directory : myDirectories) { + getResultDirectory(directory).findOrCreateTargetDirectory(); + } + for (PsiFile psiFile : myFilesToMove.keySet()) { + myFilesToMove.get(psiFile).findOrCreateTargetDirectory(); + } - @Override - protected void performPsiSpoilingRefactoring() { - if (myNonCodeUsages == null) return; //refactoring was aborted - RenameUtil.renameNonCodeUsages(myProject, myNonCodeUsages); - if (myMoveCallback != null) { - myMoveCallback.refactoringCompleted(); - } - } + DumbService.getInstance(myProject).completeJustSubmittedTasks(); + } + catch (IncorrectOperationException e) { + Messages.showErrorDialog(myProject, e.getMessage(), CommonLocalize.titleError().get()); + return; + } + try { + final List movedFiles = new ArrayList<>(); + final Map oldToNewElementsMapping = new HashMap<>(); + for (PsiFile psiFile : myFilesToMove.keySet()) { + for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) { + helper.beforeMove(psiFile); + } + final RefactoringElementListener listener = getTransaction().getElementListener(psiFile); + final PsiDirectory moveDestination = myFilesToMove.get(psiFile).getTargetDirectory(); + + for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) { + boolean processed = helper.move(psiFile, moveDestination, oldToNewElementsMapping, movedFiles, listener); + if (processed) { + break; + } + } + } + for (PsiElement newElement : oldToNewElementsMapping.values()) { + for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) { + helper.afterMove(newElement); + } + } - @RequiredReadAction - private static void collectFiles2Move( - Map files2Move, - PsiDirectory directory, - PsiDirectory rootDirectory, - @Nonnull TargetDirectoryWrapper targetDirectory - ) { - final PsiElement[] children = directory.getChildren(); - final String relativePath = VfsUtilCore.getRelativePath(directory.getVirtualFile(), rootDirectory.getVirtualFile(), '/'); + // fix references in moved files to outer files + for (PsiFile movedFile : movedFiles) { + MoveFileHandler.forElement(movedFile).updateMovedFile(movedFile); + FileReferenceContextUtil.decodeFileReferences(movedFile); + } - final TargetDirectoryWrapper newTargetDirectory = relativePath.isEmpty() - ? targetDirectory - : targetDirectory.findOrCreateChild(relativePath); - for (PsiElement child : children) { - if (child instanceof PsiFile file) { - files2Move.put(file, newTargetDirectory); - } else if (child instanceof PsiDirectory psiDirectory) { - collectFiles2Move(files2Move, psiDirectory, directory, newTargetDirectory); - } + myNonCodeUsages = CommonMoveUtil.retargetUsages(usages, oldToNewElementsMapping); + for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) { + helper.postProcessUsages(usages, dir -> getResultDirectory(dir).getTargetDirectory()); + } + for (PsiDirectory directory : myDirectories) { + directory.delete(); + } + } + catch (IncorrectOperationException e) { + myNonCodeUsages = new NonCodeUsageInfo[0]; + RefactoringUIUtil.processIncorrectOperation(myProject, e); + } } - } - @Override - protected String getCommandName() { - return RefactoringLocalize.movingDirectoriesCommand().get(); - } + @RequiredReadAction + private TargetDirectoryWrapper getResultDirectory(PsiDirectory dir) { + return myTargetDirectory != null + ? new TargetDirectoryWrapper(myTargetDirectory, dir.getName()) + : getTargetDirectory(dir); + } - public TargetDirectoryWrapper getTargetDirectory(PsiDirectory dir) { - return new TargetDirectoryWrapper(myTargetDirectory); - } + @Override + protected void performPsiSpoilingRefactoring() { + if (myNonCodeUsages == null) { + return; //refactoring was aborted + } + RenameUtil.renameNonCodeUsages(myProject, myNonCodeUsages); + if (myMoveCallback != null) { + myMoveCallback.refactoringCompleted(); + } + } - public static class TargetDirectoryWrapper { - private TargetDirectoryWrapper myParentDirectory; - private PsiDirectory myTargetDirectory; - private String myRelativePath; + @RequiredReadAction + private static void collectFiles2Move( + Map files2Move, + PsiDirectory directory, + PsiDirectory rootDirectory, + @Nonnull TargetDirectoryWrapper targetDirectory + ) { + final PsiElement[] children = directory.getChildren(); + final String relativePath = VfsUtilCore.getRelativePath(directory.getVirtualFile(), rootDirectory.getVirtualFile(), '/'); - public TargetDirectoryWrapper(PsiDirectory targetDirectory) { - myTargetDirectory = targetDirectory; + final TargetDirectoryWrapper newTargetDirectory = relativePath.isEmpty() + ? targetDirectory + : targetDirectory.findOrCreateChild(relativePath); + for (PsiElement child : children) { + if (child instanceof PsiFile file) { + files2Move.put(file, newTargetDirectory); + } + else if (child instanceof PsiDirectory psiDirectory) { + collectFiles2Move(files2Move, psiDirectory, directory, newTargetDirectory); + } + } } - public TargetDirectoryWrapper(TargetDirectoryWrapper parentDirectory, String relativePath) { - myParentDirectory = parentDirectory; - myRelativePath = relativePath; + @Override + protected String getCommandName() { + return RefactoringLocalize.movingDirectoriesCommand().get(); } - public TargetDirectoryWrapper(PsiDirectory parentDirectory, String relativePath) { - myTargetDirectory = parentDirectory.findSubdirectory(relativePath); - //in case it was null - myParentDirectory = new TargetDirectoryWrapper(parentDirectory); - myRelativePath = relativePath; + public TargetDirectoryWrapper getTargetDirectory(PsiDirectory dir) { + return new TargetDirectoryWrapper(myTargetDirectory); } - public PsiDirectory findOrCreateTargetDirectory() throws IncorrectOperationException { - if (myTargetDirectory == null) { - final PsiDirectory root = myParentDirectory.findOrCreateTargetDirectory(); + public static class TargetDirectoryWrapper { + private TargetDirectoryWrapper myParentDirectory; + private PsiDirectory myTargetDirectory; + private String myRelativePath; - myTargetDirectory = root.findSubdirectory(myRelativePath); - if (myTargetDirectory == null) { - myTargetDirectory = root.createSubdirectory(myRelativePath); + public TargetDirectoryWrapper(PsiDirectory targetDirectory) { + myTargetDirectory = targetDirectory; } - } - return myTargetDirectory; - } - @Nullable - public PsiDirectory getTargetDirectory() { - return myTargetDirectory; - } + public TargetDirectoryWrapper(TargetDirectoryWrapper parentDirectory, String relativePath) { + myParentDirectory = parentDirectory; + myRelativePath = relativePath; + } - public TargetDirectoryWrapper findOrCreateChild(String relativePath) { - if (myTargetDirectory != null) { - final PsiDirectory psiDirectory = myTargetDirectory.findSubdirectory(relativePath); - if (psiDirectory != null) { - return new TargetDirectoryWrapper(psiDirectory); + public TargetDirectoryWrapper(PsiDirectory parentDirectory, String relativePath) { + myTargetDirectory = parentDirectory.findSubdirectory(relativePath); + //in case it was null + myParentDirectory = new TargetDirectoryWrapper(parentDirectory); + myRelativePath = relativePath; } - } - return new TargetDirectoryWrapper(this, relativePath); - } - public void checkMove(PsiFile psiFile) throws IncorrectOperationException { - if (myTargetDirectory != null) { - MoveFilesOrDirectoriesUtil.checkMove(psiFile, myTargetDirectory); - } + public PsiDirectory findOrCreateTargetDirectory() throws IncorrectOperationException { + if (myTargetDirectory == null) { + final PsiDirectory root = myParentDirectory.findOrCreateTargetDirectory(); + + myTargetDirectory = root.findSubdirectory(myRelativePath); + if (myTargetDirectory == null) { + myTargetDirectory = root.createSubdirectory(myRelativePath); + } + } + return myTargetDirectory; + } + + @Nullable + public PsiDirectory getTargetDirectory() { + return myTargetDirectory; + } + + public TargetDirectoryWrapper findOrCreateChild(String relativePath) { + if (myTargetDirectory != null) { + final PsiDirectory psiDirectory = myTargetDirectory.findSubdirectory(relativePath); + if (psiDirectory != null) { + return new TargetDirectoryWrapper(psiDirectory); + } + } + return new TargetDirectoryWrapper(this, relativePath); + } + + public void checkMove(PsiFile psiFile) throws IncorrectOperationException { + if (myTargetDirectory != null) { + MoveFilesOrDirectoriesUtil.checkMove(psiFile, myTargetDirectory); + } + } } - } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderProcessor.java index 951ee1b02..65b0c766c 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderProcessor.java @@ -48,6 +48,7 @@ import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; + import java.util.Collections; import java.util.List; import java.util.Map; @@ -57,273 +58,297 @@ * @since 04-Sep-2008 */ public class ReplaceConstructorWithBuilderProcessor extends FixableUsagesRefactoringProcessor { - public static final String REFACTORING_NAME = "Replace Constructor with Builder"; - private final PsiMethod[] myConstructors; - private final Map myParametersMap; - private final String myClassName; - private final String myPackageName; - private final boolean myCreateNewBuilderClass; - private final PsiElementFactory myElementFactory; - private MoveDestination myMoveDestination; - - - public ReplaceConstructorWithBuilderProcessor(Project project, - PsiMethod[] constructors, - Map parametersMap, - String className, - String packageName, - MoveDestination moveDestination, boolean createNewBuilderClass) { - super(project); - myMoveDestination = moveDestination; - myElementFactory = JavaPsiFacade.getInstance(myProject).getElementFactory(); - myConstructors = constructors; - myParametersMap = parametersMap; - - myClassName = className; - myPackageName = packageName; - myCreateNewBuilderClass = createNewBuilderClass; - } - - @Nonnull - protected UsageViewDescriptor createUsageViewDescriptor(final UsageInfo[] usages) { - return new ReplaceConstructorWithBuilderViewDescriptor(); - } - - protected void findUsages(@Nonnull final List usages) { - final String builderQualifiedName = StringUtil.getQualifiedName(myPackageName, myClassName); - final PsiClass builderClass = - JavaPsiFacade.getInstance(myProject).findClass(builderQualifiedName, GlobalSearchScope.projectScope(myProject)); - - for (PsiMethod constructor : myConstructors) { - for (PsiReference reference : ReferencesSearch.search(constructor)) { - final PsiElement element = reference.getElement(); - final PsiNewExpression newExpression = PsiTreeUtil.getParentOfType(element, PsiNewExpression.class); - if (newExpression != null && !PsiTreeUtil.isAncestor(builderClass, element, false)) { - usages.add(new ReplaceConstructorWithSettersChainInfo(newExpression, StringUtil.getQualifiedName(myPackageName, myClassName), myParametersMap)); - } - } + public static final String REFACTORING_NAME = "Replace Constructor with Builder"; + private final PsiMethod[] myConstructors; + private final Map myParametersMap; + private final String myClassName; + private final String myPackageName; + private final boolean myCreateNewBuilderClass; + private final PsiElementFactory myElementFactory; + private MoveDestination myMoveDestination; + + + public ReplaceConstructorWithBuilderProcessor( + Project project, + PsiMethod[] constructors, + Map parametersMap, + String className, + String packageName, + MoveDestination moveDestination, boolean createNewBuilderClass + ) { + super(project); + myMoveDestination = moveDestination; + myElementFactory = JavaPsiFacade.getInstance(myProject).getElementFactory(); + myConstructors = constructors; + myParametersMap = parametersMap; + + myClassName = className; + myPackageName = packageName; + myCreateNewBuilderClass = createNewBuilderClass; + } + + @Nonnull + protected UsageViewDescriptor createUsageViewDescriptor(final UsageInfo[] usages) { + return new ReplaceConstructorWithBuilderViewDescriptor(); } - } - - @Nullable - private PsiClass createBuilderClass() { - final PsiClass psiClass = myConstructors[0].getContainingClass(); - assert psiClass != null; - final PsiTypeParameterList typeParameterList = psiClass.getTypeParameterList(); - final String text = "public class " + myClassName + (typeParameterList != null ? typeParameterList.getText() : "") + "{}"; - final PsiFileFactory factory = PsiFileFactory.getInstance(myProject); - final PsiJavaFile newFile = (PsiJavaFile) factory.createFileFromText(myClassName + ".java", JavaFileType.INSTANCE, text); - - final PsiFile containingFile = myConstructors[0].getContainingFile(); - final PsiDirectory containingDirectory = containingFile.getContainingDirectory(); - final PsiDirectory directory; - if (myMoveDestination != null) { - directory = myMoveDestination.getTargetDirectory(containingDirectory); - } else { - final Module module = ModuleUtil.findModuleForPsiElement(containingFile); - assert module != null; - directory = PackageUtil.findOrCreateDirectoryForPackage(module, myPackageName, containingDirectory, true, true); + + protected void findUsages(@Nonnull final List usages) { + final String builderQualifiedName = StringUtil.getQualifiedName(myPackageName, myClassName); + final PsiClass builderClass = + JavaPsiFacade.getInstance(myProject).findClass(builderQualifiedName, GlobalSearchScope.projectScope(myProject)); + + for (PsiMethod constructor : myConstructors) { + for (PsiReference reference : ReferencesSearch.search(constructor)) { + final PsiElement element = reference.getElement(); + final PsiNewExpression newExpression = PsiTreeUtil.getParentOfType(element, PsiNewExpression.class); + if (newExpression != null && !PsiTreeUtil.isAncestor(builderClass, element, false)) { + usages.add(new ReplaceConstructorWithSettersChainInfo( + newExpression, + StringUtil.getQualifiedName(myPackageName, myClassName), + myParametersMap + )); + } + } + } } - if (directory != null) { + @Nullable + private PsiClass createBuilderClass() { + final PsiClass psiClass = myConstructors[0].getContainingClass(); + assert psiClass != null; + final PsiTypeParameterList typeParameterList = psiClass.getTypeParameterList(); + final String text = "public class " + myClassName + (typeParameterList != null ? typeParameterList.getText() : "") + "{}"; + final PsiFileFactory factory = PsiFileFactory.getInstance(myProject); + final PsiJavaFile newFile = (PsiJavaFile)factory.createFileFromText(myClassName + ".java", JavaFileType.INSTANCE, text); + + final PsiFile containingFile = myConstructors[0].getContainingFile(); + final PsiDirectory containingDirectory = containingFile.getContainingDirectory(); + final PsiDirectory directory; + if (myMoveDestination != null) { + directory = myMoveDestination.getTargetDirectory(containingDirectory); + } + else { + final Module module = ModuleUtil.findModuleForPsiElement(containingFile); + assert module != null; + directory = PackageUtil.findOrCreateDirectoryForPackage(module, myPackageName, containingDirectory, true, true); + } - final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(PsiManager.getInstance(myProject).getProject()); - final PsiJavaFile reformattedFile = (PsiJavaFile) codeStyleManager.reformat(JavaCodeStyleManager.getInstance(newFile.getProject()).shortenClassReferences(newFile)); + if (directory != null) { - if (directory.findFile(reformattedFile.getName()) != null) return reformattedFile.getClasses()[0]; - return ((PsiJavaFile) directory.add(reformattedFile)).getClasses()[0]; - } - return null; - } - - @Override - protected void performRefactoring(UsageInfo[] usageInfos) { - - final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(myProject); - final PsiClass builderClass = myCreateNewBuilderClass - ? createBuilderClass() - : psiFacade.findClass(StringUtil.getQualifiedName(myPackageName, myClassName), - GlobalSearchScope.projectScope(myProject)); - if (builderClass == null) return; - - for (String propertyName : myParametersMap.keySet()) { - final ParameterData parameterData = myParametersMap.get(propertyName); - final PsiField field = createField(builderClass, parameterData); - createSetter(builderClass, parameterData, field); + final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(PsiManager.getInstance(myProject).getProject()); + final PsiJavaFile reformattedFile = + (PsiJavaFile)codeStyleManager.reformat(JavaCodeStyleManager.getInstance(newFile.getProject()) + .shortenClassReferences(newFile)); + + if (directory.findFile(reformattedFile.getName()) != null) { + return reformattedFile.getClasses()[0]; + } + return ((PsiJavaFile)directory.add(reformattedFile)).getClasses()[0]; + } + return null; } - super.performRefactoring(usageInfos); + @Override + protected void performRefactoring(UsageInfo[] usageInfos) { + + final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(myProject); + final PsiClass builderClass = myCreateNewBuilderClass + ? createBuilderClass() + : psiFacade.findClass( + StringUtil.getQualifiedName(myPackageName, myClassName), + GlobalSearchScope.projectScope(myProject) + ); + if (builderClass == null) { + return; + } - final PsiMethod method = createMethodSignature(createMethodName()); - if (builderClass.findMethodBySignature(method, false) == null) { - builderClass.add(method); + for (String propertyName : myParametersMap.keySet()) { + final ParameterData parameterData = myParametersMap.get(propertyName); + final PsiField field = createField(builderClass, parameterData); + createSetter(builderClass, parameterData, field); + } + + super.performRefactoring(usageInfos); + + final PsiMethod method = createMethodSignature(createMethodName()); + if (builderClass.findMethodBySignature(method, false) == null) { + builderClass.add(method); + } + + //fix visibilities + final PsiMethod constructor = getWorkingConstructor(); + VisibilityUtil.escalateVisibility(constructor, builderClass); + PsiClass containingClass = constructor.getContainingClass(); + while (containingClass != null) { + VisibilityUtil.escalateVisibility(containingClass, builderClass); + containingClass = containingClass.getContainingClass(); + } } - //fix visibilities - final PsiMethod constructor = getWorkingConstructor(); - VisibilityUtil.escalateVisibility(constructor, builderClass); - PsiClass containingClass = constructor.getContainingClass(); - while (containingClass != null) { - VisibilityUtil.escalateVisibility(containingClass, builderClass); - containingClass = containingClass.getContainingClass(); + private void createSetter(PsiClass builderClass, ParameterData parameterData, PsiField field) { + PsiMethod setter = null; + for (PsiMethod method : builderClass.getMethods()) { + if (Comparing.strEqual(method.getName(), parameterData.getSetterName()) && method.getParameterList().getParametersCount() == 1 + && TypeConversionUtil.isAssignable(method.getParameterList().getParameters()[0].getType(), parameterData.getType())) { + setter = method; + fixSetterReturnType(builderClass, field, setter); + break; + } + } + if (setter == null) { + setter = PropertyUtil.generateSetterPrototype(field, builderClass, true); + final PsiIdentifier nameIdentifier = setter.getNameIdentifier(); + assert nameIdentifier != null; + nameIdentifier.replace(myElementFactory.createIdentifier(parameterData.getSetterName())); + setter.getParameterList().getParameters()[0].getTypeElement() + .replace(myElementFactory.createTypeElement(parameterData.getType())); //setter varargs + builderClass.add(setter); + } } - } - - private void createSetter(PsiClass builderClass, ParameterData parameterData, PsiField field) { - PsiMethod setter = null; - for (PsiMethod method : builderClass.getMethods()) { - if (Comparing.strEqual(method.getName(), parameterData.getSetterName()) && method.getParameterList().getParametersCount() == 1 - && TypeConversionUtil.isAssignable(method.getParameterList().getParameters()[0].getType(), parameterData.getType())) { - setter = method; - fixSetterReturnType(builderClass, field, setter); - break; - } + + private PsiField createField(PsiClass builderClass, ParameterData parameterData) { + PsiField field = builderClass.findFieldByName(parameterData.getFieldName(), false); + + if (field == null) { + PsiType type = parameterData.getType(); + if (type instanceof PsiEllipsisType) { + type = ((PsiEllipsisType)type).toArrayType(); + } + field = myElementFactory.createField(parameterData.getFieldName(), type); + field = (PsiField)builderClass.add(field); + } + + final String defaultValue = parameterData.getDefaultValue(); + if (defaultValue != null) { + final PsiExpression initializer = field.getInitializer(); + if (initializer == null) { + try { + field.setInitializer(myElementFactory.createExpressionFromText(defaultValue, field)); + } + catch (IncorrectOperationException e) { + //skip invalid default value + } + } + } + return field; } - if (setter == null) { - setter = PropertyUtil.generateSetterPrototype(field, builderClass, true); - final PsiIdentifier nameIdentifier = setter.getNameIdentifier(); - assert nameIdentifier != null; - nameIdentifier.replace(myElementFactory.createIdentifier(parameterData.getSetterName())); - setter.getParameterList().getParameters()[0].getTypeElement().replace(myElementFactory.createTypeElement(parameterData.getType())); //setter varargs - builderClass.add(setter); + + private void fixSetterReturnType(PsiClass builderClass, PsiField field, PsiMethod method) { + if (PsiUtil.resolveClassInType(method.getReturnType()) != builderClass) { + final PsiCodeBlock body = method.getBody(); + final PsiCodeBlock generatedBody = PropertyUtil.generateSetterPrototype(field, builderClass, true).getBody(); + assert body != null; + assert generatedBody != null; + body.replace(generatedBody); + final PsiTypeElement typeElement = method.getReturnTypeElement(); + assert typeElement != null; + typeElement.replace(myElementFactory.createTypeElement(myElementFactory.createType(builderClass))); + } } - } - - private PsiField createField(PsiClass builderClass, ParameterData parameterData) { - PsiField field = builderClass.findFieldByName(parameterData.getFieldName(), false); - - if (field == null) { - PsiType type = parameterData.getType(); - if (type instanceof PsiEllipsisType) { - type = ((PsiEllipsisType) type).toArrayType(); - } - field = myElementFactory.createField(parameterData.getFieldName(), type); - field = (PsiField) builderClass.add(field); + + private PsiMethod createMethodSignature(String createMethodName) { + JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(myProject); + final StringBuffer buf = new StringBuffer(); + final PsiMethod constructor = getWorkingConstructor(); + for (PsiParameter parameter : constructor.getParameterList().getParameters()) { + final String pureParamName = styleManager.variableNameToPropertyName(parameter.getName(), VariableKind.PARAMETER); + if (buf.length() > 0) { + buf.append(", "); + } + buf.append(myParametersMap.get(pureParamName).getFieldName()); + } + return myElementFactory.createMethodFromText("public " + + constructor.getName() + + " " + + createMethodName + + "(){\n return new " + + constructor.getName() + + "(" + + buf.toString() + + ")" + + ";\n}", constructor); } - final String defaultValue = parameterData.getDefaultValue(); - if (defaultValue != null) { - final PsiExpression initializer = field.getInitializer(); - if (initializer == null) { - try { - field.setInitializer(myElementFactory.createExpressionFromText(defaultValue, field)); - } catch (IncorrectOperationException e) { - //skip invalid default value + private PsiMethod getWorkingConstructor() { + PsiMethod constructor = getMostCommonConstructor(); + if (constructor == null) { + constructor = myConstructors[0]; + if (constructor.getParameterList().getParametersCount() == 0) { + constructor = myConstructors[1]; + } } - } + return constructor; } - return field; - } - - private void fixSetterReturnType(PsiClass builderClass, PsiField field, PsiMethod method) { - if (PsiUtil.resolveClassInType(method.getReturnType()) != builderClass) { - final PsiCodeBlock body = method.getBody(); - final PsiCodeBlock generatedBody = PropertyUtil.generateSetterPrototype(field, builderClass, true).getBody(); - assert body != null; - assert generatedBody != null; - body.replace(generatedBody); - final PsiTypeElement typeElement = method.getReturnTypeElement(); - assert typeElement != null; - typeElement.replace(myElementFactory.createTypeElement(myElementFactory.createType(builderClass))); + + @Nullable + private PsiMethod getMostCommonConstructor() { + if (myConstructors.length == 1) { + return myConstructors[0]; + } + PsiMethod commonConstructor = null; + for (PsiMethod constructor : myConstructors) { + final PsiMethod chainedConstructor = RefactoringUtil.getChainedConstructor(constructor); + if (chainedConstructor == null) { + if (commonConstructor != null) { + if (!isChained(commonConstructor, constructor)) { + return null; + } + } + commonConstructor = constructor; + } + else if (commonConstructor == null) { + commonConstructor = chainedConstructor; + } + else if (!isChained(commonConstructor, chainedConstructor)) { + return null; + } + } + return commonConstructor; } - } - - private PsiMethod createMethodSignature(String createMethodName) { - JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(myProject); - final StringBuffer buf = new StringBuffer(); - final PsiMethod constructor = getWorkingConstructor(); - for (PsiParameter parameter : constructor.getParameterList().getParameters()) { - final String pureParamName = styleManager.variableNameToPropertyName(parameter.getName(), VariableKind.PARAMETER); - if (buf.length() > 0) buf.append(", "); - buf.append(myParametersMap.get(pureParamName).getFieldName()); + + private static boolean isChained(PsiMethod first, PsiMethod last) { + if (first == null) { + return false; + } + if (first == last) { + return true; + } + return isChained(RefactoringUtil.getChainedConstructor(first), last); } - return myElementFactory.createMethodFromText("public " + - constructor.getName() + - " " + - createMethodName + - "(){\n return new " + - constructor.getName() + - "(" + - buf.toString() + - ")" + - ";\n}", constructor); - } - - private PsiMethod getWorkingConstructor() { - PsiMethod constructor = getMostCommonConstructor(); - if (constructor == null) { - constructor = myConstructors[0]; - if (constructor.getParameterList().getParametersCount() == 0) { - constructor = myConstructors[1]; - } + + private String createMethodName() { + return "create" + StringUtil.capitalize(myConstructors[0].getName()); } - return constructor; - } - - @Nullable - private PsiMethod getMostCommonConstructor() { - if (myConstructors.length == 1) return myConstructors[0]; - PsiMethod commonConstructor = null; - for (PsiMethod constructor : myConstructors) { - final PsiMethod chainedConstructor = RefactoringUtil.getChainedConstructor(constructor); - if (chainedConstructor == null) { - if (commonConstructor != null) { - if (!isChained(commonConstructor, constructor)) { - return null; - } + + + @Override + protected boolean preprocessUsages(Ref refUsages) { + final MultiMap conflicts = new MultiMap(); + final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(myProject); + final PsiClass builderClass = + psiFacade.findClass(StringUtil.getQualifiedName(myPackageName, myClassName), GlobalSearchScope.projectScope(myProject)); + if (builderClass == null) { + if (!myCreateNewBuilderClass) { + conflicts.putValue(null, "Selected class was not found."); + } + } + else if (myCreateNewBuilderClass) { + conflicts.putValue(builderClass, "Class with chosen name already exist."); + } + + if (myMoveDestination != null && myCreateNewBuilderClass) { + myMoveDestination.analyzeModuleConflicts(Collections.emptyList(), conflicts, refUsages.get()); } - commonConstructor = constructor; - } else { + + final PsiMethod commonConstructor = getMostCommonConstructor(); if (commonConstructor == null) { - commonConstructor = chainedConstructor; - } else { - if (!isChained(commonConstructor, chainedConstructor)) { - return null; - } + conflicts.putValue(null, "Found constructors are not reducible to simple chain"); } - } - } - return commonConstructor; - } - - private static boolean isChained(PsiMethod first, PsiMethod last) { - if (first == null) return false; - if (first == last) return true; - return isChained(RefactoringUtil.getChainedConstructor(first), last); - } - - private String createMethodName() { - return "create" + StringUtil.capitalize(myConstructors[0].getName()); - } - - - @Override - protected boolean preprocessUsages(Ref refUsages) { - final MultiMap conflicts = new MultiMap(); - final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(myProject); - final PsiClass builderClass = - psiFacade.findClass(StringUtil.getQualifiedName(myPackageName, myClassName), GlobalSearchScope.projectScope(myProject)); - if (builderClass == null) { - if (!myCreateNewBuilderClass) { - conflicts.putValue(null, "Selected class was not found."); - } - } else if (myCreateNewBuilderClass) { - conflicts.putValue(builderClass, "Class with chosen name already exist."); - } - if (myMoveDestination != null && myCreateNewBuilderClass) { - myMoveDestination.analyzeModuleConflicts(Collections.emptyList(), conflicts, refUsages.get()); + return showConflicts(conflicts, refUsages.get()); } - final PsiMethod commonConstructor = getMostCommonConstructor(); - if (commonConstructor == null) { - conflicts.putValue(null, "Found constructors are not reducible to simple chain"); + protected String getCommandName() { + return REFACTORING_NAME; } - - return showConflicts(conflicts, refUsages.get()); - } - - protected String getCommandName() { - return REFACTORING_NAME; - } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/TypeMigrationProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/TypeMigrationProcessor.java index 984de2ed7..5b7acd0b5 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/TypeMigrationProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/TypeMigrationProcessor.java @@ -46,243 +46,282 @@ import static consulo.util.lang.ObjectUtil.assertNotNull; public class TypeMigrationProcessor extends BaseRefactoringProcessor { - public volatile static boolean ourSkipFailedConversionInTestMode; - private final static int MAX_ROOT_IN_PREVIEW_PRESENTATION = 3; + public volatile static boolean ourSkipFailedConversionInTestMode; + private final static int MAX_ROOT_IN_PREVIEW_PRESENTATION = 3; - private PsiElement[] myRoots; - private final Function myRootTypes; - private final boolean myAllowDependentRoots; - private final TypeMigrationRules myRules; - private TypeMigrationLabeler myLabeler; + private PsiElement[] myRoots; + private final Function myRootTypes; + private final boolean myAllowDependentRoots; + private final TypeMigrationRules myRules; + private TypeMigrationLabeler myLabeler; - public TypeMigrationProcessor(final Project project, final PsiElement[] roots, final Function rootTypes, final TypeMigrationRules rules, final boolean allowDependentRoots) { - super(project); - myRoots = roots; - myRules = rules; - myRootTypes = rootTypes; - myAllowDependentRoots = allowDependentRoots; - } + public TypeMigrationProcessor( + final Project project, + final PsiElement[] roots, + final Function rootTypes, + final TypeMigrationRules rules, + final boolean allowDependentRoots + ) { + super(project); + myRoots = roots; + myRules = rules; + myRootTypes = rootTypes; + myAllowDependentRoots = allowDependentRoots; + } - public static void runHighlightingTypeMigration(final Project project, final Editor editor, final TypeMigrationRules rules, final PsiElement root, final PsiType migrationType) { - runHighlightingTypeMigration(project, editor, rules, root, migrationType, false, true); - } + public static void runHighlightingTypeMigration( + final Project project, + final Editor editor, + final TypeMigrationRules rules, + final PsiElement root, + final PsiType migrationType + ) { + runHighlightingTypeMigration(project, editor, rules, root, migrationType, false, true); + } - public static void runHighlightingTypeMigration(final Project project, - final Editor editor, - final TypeMigrationRules rules, - final PsiElement root, - final PsiType migrationType, - final boolean optimizeImports, - boolean allowDependentRoots) { - runHighlightingTypeMigration(project, editor, rules, new PsiElement[]{root}, Functions.constant(migrationType), optimizeImports, allowDependentRoots); - } + public static void runHighlightingTypeMigration( + final Project project, + final Editor editor, + final TypeMigrationRules rules, + final PsiElement root, + final PsiType migrationType, + final boolean optimizeImports, + boolean allowDependentRoots + ) { + runHighlightingTypeMigration( + project, + editor, + rules, + new PsiElement[]{root}, + Functions.constant(migrationType), + optimizeImports, + allowDependentRoots + ); + } - public static void runHighlightingTypeMigration(final Project project, - final Editor editor, - final TypeMigrationRules rules, - final PsiElement[] roots, - final Function migrationTypeFunction, - final boolean optimizeImports, - boolean allowDependentRoots) { - final Set containingFiles = ContainerUtil.map2Set(roots, PsiElement::getContainingFile); - final TypeMigrationProcessor processor = new TypeMigrationProcessor(project, roots, migrationTypeFunction, rules, allowDependentRoots) { - @Override - public void performRefactoring(@Nonnull final UsageInfo[] usages) { - super.performRefactoring(usages); - if (editor != null) { - ApplicationManager.getApplication().invokeLater(() -> - { - final List result = new ArrayList<>(); - for (UsageInfo usage : usages) { - final PsiElement element = usage.getElement(); - if (element == null || !containingFiles.contains(element.getContainingFile())) { - continue; - } - if (element instanceof PsiMethod) { - result.add(((PsiMethod) element).getReturnTypeElement()); - } else if (element instanceof PsiVariable) { - result.add(((PsiVariable) element).getTypeElement()); - } else { - result.add(element); - } - } - RefactoringUtil.highlightAllOccurrences(project, PsiUtilCore.toPsiElementArray(result), editor); - }); - } - if (optimizeImports) { - final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(myProject); - final Set affectedFiles = new HashSet<>(); - for (UsageInfo usage : usages) { - final PsiFile usageFile = usage.getFile(); - if (usageFile != null) { - affectedFiles.add(usageFile); - } - } - for (PsiFile file : affectedFiles) { - javaCodeStyleManager.optimizeImports(file); - javaCodeStyleManager.shortenClassReferences(file); - } - } - } - }; - processor.run(); - } + public static void runHighlightingTypeMigration( + final Project project, + final Editor editor, + final TypeMigrationRules rules, + final PsiElement[] roots, + final Function migrationTypeFunction, + final boolean optimizeImports, + boolean allowDependentRoots + ) { + final Set containingFiles = ContainerUtil.map2Set(roots, PsiElement::getContainingFile); + final TypeMigrationProcessor processor = + new TypeMigrationProcessor(project, roots, migrationTypeFunction, rules, allowDependentRoots) { + @Override + public void performRefactoring(@Nonnull final UsageInfo[] usages) { + super.performRefactoring(usages); + if (editor != null) { + ApplicationManager.getApplication().invokeLater(() -> + { + final List result = new ArrayList<>(); + for (UsageInfo usage : usages) { + final PsiElement element = usage.getElement(); + if (element == null || !containingFiles.contains(element.getContainingFile())) { + continue; + } + if (element instanceof PsiMethod) { + result.add(((PsiMethod)element).getReturnTypeElement()); + } + else if (element instanceof PsiVariable) { + result.add(((PsiVariable)element).getTypeElement()); + } + else { + result.add(element); + } + } + RefactoringUtil.highlightAllOccurrences(project, PsiUtilCore.toPsiElementArray(result), editor); + }); + } + if (optimizeImports) { + final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(myProject); + final Set affectedFiles = new HashSet<>(); + for (UsageInfo usage : usages) { + final PsiFile usageFile = usage.getFile(); + if (usageFile != null) { + affectedFiles.add(usageFile); + } + } + for (PsiFile file : affectedFiles) { + javaCodeStyleManager.optimizeImports(file); + javaCodeStyleManager.shortenClassReferences(file); + } + } + } + }; + processor.run(); + } - @Nonnull - @Override - protected UsageViewDescriptor createUsageViewDescriptor(@Nonnull UsageInfo[] usages) { - return new TypeMigrationViewDescriptor(myRoots[0]); - } + @Nonnull + @Override + protected UsageViewDescriptor createUsageViewDescriptor(@Nonnull UsageInfo[] usages) { + return new TypeMigrationViewDescriptor(myRoots[0]); + } - @Override - protected boolean preprocessUsages(@Nonnull Ref refUsages) { - if (hasFailedConversions()) { - if (ApplicationManager.getApplication().isUnitTestMode()) { - if (ourSkipFailedConversionInTestMode) { - prepareSuccessful(); - return true; + @Override + protected boolean preprocessUsages(@Nonnull Ref refUsages) { + if (hasFailedConversions()) { + if (ApplicationManager.getApplication().isUnitTestMode()) { + if (ourSkipFailedConversionInTestMode) { + prepareSuccessful(); + return true; + } + throw new BaseRefactoringProcessor.ConflictsInTestsException(Arrays.asList(myLabeler.getFailedConversionsReport())); + } + FailedConversionsDialog dialog = new FailedConversionsDialog(myLabeler.getFailedConversionsReport(), myProject); + if (!dialog.showAndGet()) { + final int exitCode = dialog.getExitCode(); + prepareSuccessful(); + if (exitCode == FailedConversionsDialog.VIEW_USAGES_EXIT_CODE) { + previewRefactoring(refUsages.get()); + } + return false; + } } - throw new BaseRefactoringProcessor.ConflictsInTestsException(Arrays.asList(myLabeler.getFailedConversionsReport())); - } - FailedConversionsDialog dialog = new FailedConversionsDialog(myLabeler.getFailedConversionsReport(), myProject); - if (!dialog.showAndGet()) { - final int exitCode = dialog.getExitCode(); prepareSuccessful(); - if (exitCode == FailedConversionsDialog.VIEW_USAGES_EXIT_CODE) { - previewRefactoring(refUsages.get()); - } - return false; - } + return true; } - prepareSuccessful(); - return true; - } - public boolean hasFailedConversions() { - return myLabeler.hasFailedConversions(); - } + public boolean hasFailedConversions() { + return myLabeler.hasFailedConversions(); + } - @Override - protected void previewRefactoring(@Nonnull final UsageInfo[] usages) { - MigrationPanel panel = new MigrationPanel(myRoots, myLabeler, myProject, isPreviewUsages()); - String name; - if (myRoots.length == 1) { - String fromType = assertNotNull(TypeMigrationLabeler.getElementType(myRoots[0])).getPresentableText(); - String toType = myRootTypes.apply(myRoots[0]).getPresentableText(); - String text; - text = getPresentation(myRoots[0]); - name = "Migrate Type of " + text + " from \'" + fromType + "\' to \'" + toType + "\'"; - } else { - final int rootsInPresentationCount = myRoots.length > MAX_ROOT_IN_PREVIEW_PRESENTATION ? MAX_ROOT_IN_PREVIEW_PRESENTATION : myRoots.length; - String[] rootsPresentation = new String[rootsInPresentationCount]; - for (int i = 0; i < rootsInPresentationCount; i++) { - final PsiElement root = myRoots[i]; - rootsPresentation[i] = root instanceof PsiNamedElement ? ((PsiNamedElement) root).getName() : root.getText(); - } - rootsPresentation = StringUtil.surround(rootsPresentation, "\'", "\'"); - name = "Migrate Type of " + StringUtil.join(rootsPresentation, ", "); - if (myRoots.length > MAX_ROOT_IN_PREVIEW_PRESENTATION) { - name += "..."; - } + @Override + protected void previewRefactoring(@Nonnull final UsageInfo[] usages) { + MigrationPanel panel = new MigrationPanel(myRoots, myLabeler, myProject, isPreviewUsages()); + String name; + if (myRoots.length == 1) { + String fromType = assertNotNull(TypeMigrationLabeler.getElementType(myRoots[0])).getPresentableText(); + String toType = myRootTypes.apply(myRoots[0]).getPresentableText(); + String text; + text = getPresentation(myRoots[0]); + name = "Migrate Type of " + text + " from \'" + fromType + "\' to \'" + toType + "\'"; + } + else { + final int rootsInPresentationCount = + myRoots.length > MAX_ROOT_IN_PREVIEW_PRESENTATION ? MAX_ROOT_IN_PREVIEW_PRESENTATION : myRoots.length; + String[] rootsPresentation = new String[rootsInPresentationCount]; + for (int i = 0; i < rootsInPresentationCount; i++) { + final PsiElement root = myRoots[i]; + rootsPresentation[i] = root instanceof PsiNamedElement ? ((PsiNamedElement)root).getName() : root.getText(); + } + rootsPresentation = StringUtil.surround(rootsPresentation, "\'", "\'"); + name = "Migrate Type of " + StringUtil.join(rootsPresentation, ", "); + if (myRoots.length > MAX_ROOT_IN_PREVIEW_PRESENTATION) { + name += "..."; + } + } + Content content = UsageViewContentManager.getInstance(myProject).addContent(name, false, panel, true, true); + panel.setContent(content); + ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.FIND).activate(null); } - Content content = UsageViewContentManager.getInstance(myProject).addContent(name, false, panel, true, true); - panel.setContent(content); - ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.FIND).activate(null); - } - public static String getPresentation(PsiElement element) { - String text; - if (element instanceof PsiField) { - text = "field \'" + ((PsiField) element).getName() + "\'"; - } else if (element instanceof PsiParameter) { - text = "parameter \'" + ((PsiParameter) element).getName() + "\'"; - } else if (element instanceof PsiLocalVariable) { - text = "variable \'" + ((PsiLocalVariable) element).getName() + "\'"; - } else if (element instanceof PsiMethod) { - text = "method \'" + ((PsiMethod) element).getName() + "\' return"; - } else { - text = element.getText(); + public static String getPresentation(PsiElement element) { + String text; + if (element instanceof PsiField) { + text = "field \'" + ((PsiField)element).getName() + "\'"; + } + else if (element instanceof PsiParameter) { + text = "parameter \'" + ((PsiParameter)element).getName() + "\'"; + } + else if (element instanceof PsiLocalVariable) { + text = "variable \'" + ((PsiLocalVariable)element).getName() + "\'"; + } + else if (element instanceof PsiMethod) { + text = "method \'" + ((PsiMethod)element).getName() + "\' return"; + } + else { + text = element.getText(); + } + return text; } - return text; - } - @Nonnull - @Override - public UsageInfo[] findUsages() { - myLabeler = new TypeMigrationLabeler(myRules, myRootTypes, myAllowDependentRoots ? null : myRoots, myProject); + @Nonnull + @Override + public UsageInfo[] findUsages() { + myLabeler = new TypeMigrationLabeler(myRules, myRootTypes, myAllowDependentRoots ? null : myRoots, myProject); - try { - return myLabeler.getMigratedUsages(!isPreviewUsages(), myRoots); - } catch (TypeMigrationLabeler.MigrateException e) { - setPreviewUsages(true); - myLabeler.clearStopException(); - return myLabeler.getMigratedUsages(false, myRoots); + try { + return myLabeler.getMigratedUsages(!isPreviewUsages(), myRoots); + } + catch (TypeMigrationLabeler.MigrateException e) { + setPreviewUsages(true); + myLabeler.clearStopException(); + return myLabeler.getMigratedUsages(false, myRoots); + } } - } - @Override - protected void refreshElements(@Nonnull PsiElement[] elements) { - myRoots = elements; - } + @Override + protected void refreshElements(@Nonnull PsiElement[] elements) { + myRoots = elements; + } - @Override - public void performRefactoring(@Nonnull UsageInfo[] usages) { - change(usages, myLabeler, myProject); - } + @Override + public void performRefactoring(@Nonnull UsageInfo[] usages) { + change(usages, myLabeler, myProject); + } - public static void change(UsageInfo[] usages, TypeMigrationLabeler labeler, Project project) { - final List> newExpressionsToCheckDiamonds = new SmartList<>(); - final TypeMigrationLabeler.MigrationProducer producer = labeler.createMigratorFor(usages); + public static void change(UsageInfo[] usages, TypeMigrationLabeler labeler, Project project) { + final List> newExpressionsToCheckDiamonds = new SmartList<>(); + final TypeMigrationLabeler.MigrationProducer producer = labeler.createMigratorFor(usages); - final SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(project); - List nonCodeUsages = new ArrayList<>(); - for (UsageInfo usage : usages) { - if (((TypeMigrationUsageInfo) usage).isExcluded()) { - continue; - } - final PsiElement element = usage.getElement(); - if (element instanceof PsiVariable || element instanceof PsiMember || element instanceof PsiExpression || element instanceof PsiReferenceParameterList) { - producer.change((TypeMigrationUsageInfo) usage, expression -> newExpressionsToCheckDiamonds.add(smartPointerManager.createSmartPsiElementPointer(expression))); - } else { - nonCodeUsages.add(usage); - } - } + final SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(project); + List nonCodeUsages = new ArrayList<>(); + for (UsageInfo usage : usages) { + if (((TypeMigrationUsageInfo)usage).isExcluded()) { + continue; + } + final PsiElement element = usage.getElement(); + if (element instanceof PsiVariable || element instanceof PsiMember || element instanceof PsiExpression || element instanceof PsiReferenceParameterList) { + producer.change( + (TypeMigrationUsageInfo)usage, + expression -> newExpressionsToCheckDiamonds.add(smartPointerManager.createSmartPsiElementPointer(expression)) + ); + } + else { + nonCodeUsages.add(usage); + } + } - for (SmartPsiElementPointer newExpressionPointer : newExpressionsToCheckDiamonds) { - final PsiNewExpression newExpression = newExpressionPointer.getElement(); - if (newExpression != null) { - labeler.postProcessNewExpression(newExpression); - } - } + for (SmartPsiElementPointer newExpressionPointer : newExpressionsToCheckDiamonds) { + final PsiNewExpression newExpression = newExpressionPointer.getElement(); + if (newExpression != null) { + labeler.postProcessNewExpression(newExpression); + } + } - for (UsageInfo usageInfo : nonCodeUsages) { - final PsiElement element = usageInfo.getElement(); - if (element != null) { - final PsiReference reference = element.getReference(); - if (reference != null) { - final Object target = producer.getConversion(usageInfo); - if (target instanceof PsiMember) { - try { - reference.bindToElement((PsiElement) target); - } catch (IncorrectOperationException ignored) { + for (UsageInfo usageInfo : nonCodeUsages) { + final PsiElement element = usageInfo.getElement(); + if (element != null) { + final PsiReference reference = element.getReference(); + if (reference != null) { + final Object target = producer.getConversion(usageInfo); + if (target instanceof PsiMember) { + try { + reference.bindToElement((PsiElement)target); + } + catch (IncorrectOperationException ignored) { + } + } + } } - } } - } - } - producer.flush(); - } + producer.flush(); + } - public TypeMigrationLabeler getLabeler() { - return myLabeler; - } + public TypeMigrationLabeler getLabeler() { + return myLabeler; + } - @Nonnull - @Override - protected String getCommandName() { - return "TypeMigration"; - } + @Nonnull + @Override + protected String getCommandName() { + return "TypeMigration"; + } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/util/FixableUsagesRefactoringProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/util/FixableUsagesRefactoringProcessor.java index 89617d60d..146c4d848 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/util/FixableUsagesRefactoringProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/util/FixableUsagesRefactoringProcessor.java @@ -27,48 +27,49 @@ import consulo.logging.Logger; import jakarta.annotation.Nonnull; + import java.util.ArrayList; import java.util.Collections; import java.util.List; public abstract class FixableUsagesRefactoringProcessor extends BaseRefactoringProcessor { - private static final Logger LOG = Logger.getInstance(FixableUsagesRefactoringProcessor.class); + private static final Logger LOG = Logger.getInstance(FixableUsagesRefactoringProcessor.class); - protected FixableUsagesRefactoringProcessor(Project project) { - super(project); - } + protected FixableUsagesRefactoringProcessor(Project project) { + super(project); + } - protected void performRefactoring(UsageInfo[] usageInfos) { - CommonRefactoringUtil.sortDepthFirstRightLeftOrder(usageInfos); - for (UsageInfo usageInfo : usageInfos) { - if (usageInfo instanceof FixableUsageInfo) { - try { - ((FixableUsageInfo) usageInfo).fixUsage(); - } catch (IncorrectOperationException e) { - LOG.info(e); + protected void performRefactoring(UsageInfo[] usageInfos) { + CommonRefactoringUtil.sortDepthFirstRightLeftOrder(usageInfos); + for (UsageInfo usageInfo : usageInfos) { + if (usageInfo instanceof FixableUsageInfo) { + try { + ((FixableUsageInfo)usageInfo).fixUsage(); + } + catch (IncorrectOperationException e) { + LOG.info(e); + } + } } - } } - } - - @Nonnull - protected final UsageInfo[] findUsages() { - final List usages = Collections.synchronizedList(new ArrayList()); - findUsages(usages); - final int numUsages = usages.size(); - final FixableUsageInfo[] usageArray = usages.toArray(new FixableUsageInfo[numUsages]); - return usageArray; - } + @Nonnull + protected final UsageInfo[] findUsages() { + final List usages = Collections.synchronizedList(new ArrayList()); + findUsages(usages); + final int numUsages = usages.size(); + final FixableUsageInfo[] usageArray = usages.toArray(new FixableUsageInfo[numUsages]); + return usageArray; + } - protected abstract void findUsages(@Nonnull List usages); + protected abstract void findUsages(@Nonnull List usages); - protected static void checkConflicts(final Ref refUsages, final MultiMap conflicts) { - for (UsageInfo info : refUsages.get()) { - final String conflict = ((FixableUsageInfo) info).getConflictMessage(); - if (conflict != null) { - conflicts.putValue(info.getElement(), XmlUtil.escape(conflict)); - } + protected static void checkConflicts(final Ref refUsages, final MultiMap conflicts) { + for (UsageInfo info : refUsages.get()) { + final String conflict = ((FixableUsageInfo)info).getConflictMessage(); + if (conflict != null) { + conflicts.putValue(info.getElement(), XmlUtil.escape(conflict)); + } + } } - } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java index ab445aab2..37f0f3478 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java @@ -59,7 +59,6 @@ import java.util.Set; public class WrapReturnValueProcessor extends FixableUsagesRefactoringProcessor { - private static final Logger LOG = Logger.getInstance("com.siyeh.rpp.wrapreturnvalue.WrapReturnValueProcessor"); private MoveDestination myMoveDestination; From afb3c8638d270c187dee2dedd2e487654fc69922 Mon Sep 17 00:00:00 2001 From: UNV Date: Wed, 9 Apr 2025 20:35:45 +0300 Subject: [PATCH 2/2] Refactoring descendants of FixableUsagesRefactoringProcessor. --- .../CopyPasteReferenceProcessor.java | 104 ++-- .../ChangeClassSignatureProcessor.java | 83 ++-- .../ChangeSignatureProcessor.java | 7 +- .../changeSignature/ChangeSignatureUtil.java | 49 +- .../JavaChangeSignatureUsageProcessor.java | 462 +++++++++--------- .../extractclass/ExtractClassProcessor.java | 192 ++++---- .../extractclass/ExtractEnumProcessor.java | 98 ++-- .../inline/InlineConstantFieldProcessor.java | 63 +-- .../InlineParameterExpressionProcessor.java | 232 +++++---- .../InlineSuperClassRefactoringProcessor.java | 255 +++++----- .../IntroduceParameterObjectProcessor.java | 140 +++--- .../invertBoolean/InvertBooleanProcessor.java | 164 +++---- .../migration/MigrationProcessor.java | 37 +- .../MoveDirectoryWithClassesProcessor.java | 42 +- .../RemoveMiddlemanProcessor.java | 29 +- ...eplaceConstructorWithBuilderProcessor.java | 57 +-- .../typeMigration/TypeMigrationProcessor.java | 142 +++--- .../FixableUsagesRefactoringProcessor.java | 23 +- .../WrapReturnValueProcessor.java | 104 ++-- .../ChangeSignatureUsageProcessorEx.java | 8 +- 20 files changed, 1138 insertions(+), 1153 deletions(-) diff --git a/plugin/src/main/java/com/intellij/java/impl/codeInsight/editorActions/CopyPasteReferenceProcessor.java b/plugin/src/main/java/com/intellij/java/impl/codeInsight/editorActions/CopyPasteReferenceProcessor.java index 345d87571..3ac5be19e 100644 --- a/plugin/src/main/java/com/intellij/java/impl/codeInsight/editorActions/CopyPasteReferenceProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/codeInsight/editorActions/CopyPasteReferenceProcessor.java @@ -15,25 +15,26 @@ */ package com.intellij.java.impl.codeInsight.editorActions; -import consulo.language.editor.CodeInsightSettings; -import consulo.language.editor.util.CollectHighlightsUtil; -import consulo.ide.impl.idea.codeInsight.editorActions.CopyPastePostProcessor; import com.intellij.java.language.psi.JavaPsiFacade; import com.intellij.java.language.psi.PsiClass; import com.intellij.java.language.psi.PsiClassOwner; -import consulo.application.ApplicationManager; -import consulo.document.Document; +import consulo.annotation.access.RequiredReadAction; +import consulo.application.Application; import consulo.codeEditor.Editor; +import consulo.document.Document; import consulo.document.RangeMarker; -import consulo.project.DumbService; -import consulo.project.Project; -import consulo.util.lang.Comparing; -import consulo.util.lang.ref.Ref; import consulo.document.util.TextRange; +import consulo.ide.impl.idea.codeInsight.editorActions.CopyPastePostProcessor; +import consulo.language.editor.CodeInsightSettings; +import consulo.language.editor.util.CollectHighlightsUtil; import consulo.language.psi.*; -import consulo.util.collection.ArrayUtil; import consulo.logging.Logger; - +import consulo.project.DumbService; +import consulo.project.Project; +import consulo.ui.annotation.RequiredUIAccess; +import consulo.util.collection.ArrayUtil; +import consulo.util.lang.Comparing; +import consulo.util.lang.ref.SimpleReference; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; @@ -41,18 +42,22 @@ import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; public abstract class CopyPasteReferenceProcessor extends CopyPastePostProcessor { private static final Logger LOG = Logger.getInstance(CopyPasteReferenceProcessor.class); @Nonnull @Override + @RequiredReadAction public List collectTransferableData( PsiFile file, - final Editor editor, - final int[] startOffsets, - final int[] endOffsets + Editor editor, + int[] startOffsets, + int[] endOffsets ) { if (CodeInsightSettings.getInstance().ADD_IMPORTS_ON_PASTE == CodeInsightSettings.NO) { return Collections.emptyList(); @@ -65,10 +70,10 @@ public List collectTransferableData( return Collections.emptyList(); } - final ArrayList array = new ArrayList(); + ArrayList array = new ArrayList<>(); for (int j = 0; j < startOffsets.length; j++) { - final int startOffset = startOffsets[j]; - for (final PsiElement element : CollectHighlightsUtil.getElementsInRange(file, startOffset, endOffsets[j])) { + int startOffset = startOffsets[j]; + for (PsiElement element : CollectHighlightsUtil.getElementsInRange(file, startOffset, endOffsets[j])) { addReferenceData(file, startOffset, element, array); } } @@ -84,18 +89,16 @@ public List collectTransferableData( @Nonnull @Override - public List extractTransferableData(final Transferable content) { + public List extractTransferableData(Transferable content) { ReferenceTransferableData referenceData = null; if (CodeInsightSettings.getInstance().ADD_IMPORTS_ON_PASTE != CodeInsightSettings.NO) { try { - final DataFlavor flavor = ReferenceData.getDataFlavor(); + DataFlavor flavor = ReferenceData.getDataFlavor(); if (flavor != null) { referenceData = (ReferenceTransferableData)content.getTransferData(flavor); } } - catch (UnsupportedFlavorException ignored) { - } - catch (IOException ignored) { + catch (UnsupportedFlavorException | IOException ignored) { } } @@ -107,19 +110,20 @@ public List extractTransferableData(final Transferabl } @Override + @RequiredUIAccess public void processTransferableData( - final Project project, - final Editor editor, - final RangeMarker bounds, + Project project, + Editor editor, + RangeMarker bounds, int caretOffset, - Ref indented, - final List values + SimpleReference indented, + List values ) { if (DumbService.getInstance(project).isDumb()) { return; } - final Document document = editor.getDocument(); - final PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document); + Document document = editor.getDocument(); + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document); if (!(file instanceof PsiClassOwner)) { return; @@ -127,28 +131,24 @@ public void processTransferableData( PsiDocumentManager.getInstance(project).commitAllDocuments(); assert values.size() == 1; - final ReferenceData[] referenceData = values.get(0).getData(); - final TRef[] refs = findReferencesToRestore(file, bounds, referenceData); + ReferenceData[] referenceData = values.get(0).getData(); + TRef[] refs = findReferencesToRestore(file, bounds, referenceData); if (CodeInsightSettings.getInstance().ADD_IMPORTS_ON_PASTE == CodeInsightSettings.ASK) { askReferencesToRestore(project, refs, referenceData); } PsiDocumentManager.getInstance(project).commitAllDocuments(); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - restoreReferences(referenceData, refs); - } - }); + Application.get().runWriteAction(() -> restoreReferences(referenceData, refs)); } + @RequiredReadAction protected static void addReferenceData( - final PsiElement element, - final ArrayList array, - final int startOffset, - final String qClassName, - @Nullable final String staticMemberName + PsiElement element, + ArrayList array, + int startOffset, + String qClassName, + @Nullable String staticMemberName ) { - final TextRange range = element.getTextRange(); + TextRange range = element.getTextRange(); array.add(new ReferenceData( range.getStartOffset() - startOffset, range.getEndOffset() - startOffset, @@ -159,10 +159,11 @@ protected static void addReferenceData( protected abstract TRef[] findReferencesToRestore(PsiFile file, RangeMarker bounds, ReferenceData[] referenceData); + @RequiredReadAction protected PsiElement resolveReferenceIgnoreOverriding(PsiPolyVariantReference reference) { PsiElement referent = reference.resolve(); if (referent == null) { - final ResolveResult[] results = reference.multiResolve(true); + ResolveResult[] results = reference.multiResolve(true); if (results.length > 0) { referent = results[0].getElement(); } @@ -172,10 +173,11 @@ protected PsiElement resolveReferenceIgnoreOverriding(PsiPolyVariantReference re protected abstract void restoreReferences(ReferenceData[] referenceData, TRef[] refs); + @RequiredUIAccess private static void askReferencesToRestore(Project project, PsiElement[] refs, ReferenceData[] referenceData) { PsiManager manager = PsiManager.getInstance(project); - ArrayList array = new ArrayList(); + ArrayList array = new ArrayList<>(); Object[] refObjects = new Object[refs.length]; for (int i = 0; i < referenceData.length; i++) { PsiElement ref = refs[i]; @@ -204,14 +206,14 @@ private static void askReferencesToRestore(Project project, PsiElement[] refs, R } Object[] selectedObjects = ArrayUtil.toObjectArray(array); - Arrays.sort(selectedObjects, new Comparator() { - @Override - public int compare(Object o1, Object o2) { + Arrays.sort( + selectedObjects, + (o1, o2) -> { String fqName1 = getFQName(o1); String fqName2 = getFQName(o2); return fqName1.compareToIgnoreCase(fqName2); } - }); + ); RestoreReferencesDialog dialog = new RestoreReferencesDialog(project, selectedObjects); dialog.show(); @@ -237,6 +239,6 @@ public int compare(Object o1, Object o2) { } private static String getFQName(Object element) { - return element instanceof PsiClass ? ((PsiClass)element).getQualifiedName() : (String)element; + return element instanceof PsiClass psiClass ? psiClass.getQualifiedName() : (String)element; } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java index 16d166b0e..cea397bfb 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/changeClassSignature/ChangeClassSignatureProcessor.java @@ -18,6 +18,7 @@ import com.intellij.java.impl.refactoring.changeSignature.ChangeSignatureUtil; import com.intellij.java.language.psi.*; import com.intellij.java.language.psi.util.PsiUtil; +import consulo.annotation.access.RequiredReadAction; import consulo.language.editor.refactoring.BaseRefactoringProcessor; import consulo.language.editor.refactoring.ui.RefactoringUIUtil; import consulo.language.psi.PsiElement; @@ -30,11 +31,12 @@ import consulo.localHistory.LocalHistoryAction; import consulo.logging.Logger; import consulo.project.Project; +import consulo.ui.annotation.RequiredUIAccess; import consulo.usage.UsageInfo; import consulo.usage.UsageViewDescriptor; import consulo.util.collection.ArrayUtil; import consulo.util.collection.MultiMap; -import consulo.util.lang.ref.Ref; +import consulo.util.lang.ref.SimpleReference; import jakarta.annotation.Nonnull; import java.util.*; @@ -53,29 +55,34 @@ public ChangeClassSignatureProcessor(Project project, PsiClass aClass, TypeParam myNewSignature = newSignature; } + @Override protected void refreshElements(PsiElement[] elements) { LOG.assertTrue(elements.length == 1); LOG.assertTrue(elements[0] instanceof PsiClass); myClass = (PsiClass)elements[0]; } + @Nonnull + @Override protected String getCommandName() { return ChangeClassSignatureDialog.REFACTORING_NAME; } @Nonnull - protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { + @Override + protected UsageViewDescriptor createUsageViewDescriptor(@Nonnull UsageInfo[] usages) { return new ChangeClassSigntaureViewDescriptor(myClass); } @Override - protected boolean preprocessUsages(Ref refUsages) { - final MultiMap conflicts = new MultiMap(); + @RequiredUIAccess + protected boolean preprocessUsages(@Nonnull SimpleReference refUsages) { + MultiMap conflicts = new MultiMap<>(); - final PsiTypeParameter[] parameters = myClass.getTypeParameters(); - final Map infos = new HashMap(); + PsiTypeParameter[] parameters = myClass.getTypeParameters(); + Map infos = new HashMap<>(); for (TypeParameterInfo info : myNewSignature) { - final String newName = info.isForExistingParameter() ? parameters[info.getOldParameterIndex()].getName() : info.getNewName(); + String newName = info.isForExistingParameter() ? parameters[info.getOldParameterIndex()].getName() : info.getNewName(); TypeParameterInfo existing = infos.get(newName); if (existing != null) { conflicts.putValue( @@ -89,20 +96,21 @@ protected boolean preprocessUsages(Ref refUsages) { } @Nonnull + @Override + @RequiredReadAction protected UsageInfo[] findUsages() { GlobalSearchScope projectScope = GlobalSearchScope.projectScope(myProject); - List result = new ArrayList(); + List result = new ArrayList<>(); boolean hadTypeParameters = myClass.hasTypeParameters(); - for (final PsiReference reference : ReferencesSearch.search(myClass, projectScope, false)) { - if (reference.getElement() instanceof PsiJavaCodeReferenceElement) { - PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)reference.getElement(); + for (PsiReference reference : ReferencesSearch.search(myClass, projectScope, false)) { + if (reference.getElement() instanceof PsiJavaCodeReferenceElement referenceElement) { PsiElement parent = referenceElement.getParent(); - if (parent instanceof PsiTypeElement && parent.getParent() instanceof PsiInstanceOfExpression) { + if (parent instanceof PsiTypeElement typeElem && typeElem.getParent() instanceof PsiInstanceOfExpression) { continue; } - if (parent instanceof PsiTypeElement || parent instanceof PsiNewExpression || parent instanceof PsiAnonymousClass || - parent instanceof PsiReferenceList) { + if (parent instanceof PsiTypeElement || parent instanceof PsiNewExpression + || parent instanceof PsiAnonymousClass || parent instanceof PsiReferenceList) { if (!hadTypeParameters || referenceElement.getTypeParameters().length > 0) { result.add(new UsageInfo(referenceElement)); } @@ -112,7 +120,8 @@ protected UsageInfo[] findUsages() { return result.toArray(new UsageInfo[result.size()]); } - protected void performRefactoring(UsageInfo[] usages) { + @Override + protected void performRefactoring(@Nonnull UsageInfo[] usages) { LocalHistoryAction a = LocalHistory.getInstance().startAction(getCommandName()); try { doRefactoring(usages); @@ -126,40 +135,38 @@ protected void performRefactoring(UsageInfo[] usages) { } private void doRefactoring(UsageInfo[] usages) throws IncorrectOperationException { - final PsiTypeParameter[] typeParameters = myClass.getTypeParameters(); - final boolean[] toRemoveParms = detectRemovedParameters(typeParameters); + PsiTypeParameter[] typeParameters = myClass.getTypeParameters(); + boolean[] toRemoveParms = detectRemovedParameters(typeParameters); - for (final UsageInfo usage : usages) { + for (UsageInfo usage : usages) { LOG.assertTrue(usage.getElement() instanceof PsiJavaCodeReferenceElement); processUsage(usage, typeParameters, toRemoveParms); } - final Map supersMap = new HashMap(); + Map supersMap = new HashMap<>(); myClass.accept(new JavaRecursiveElementWalkingVisitor() { @Override - public void visitTypeElement(PsiTypeElement typeElement) { + public void visitTypeElement(@Nonnull PsiTypeElement typeElement) { super.visitTypeElement(typeElement); - final PsiType type = typeElement.getType(); - final PsiClass psiClass = PsiUtil.resolveClassInType(type); - if (psiClass instanceof PsiTypeParameter) { - final int i = ArrayUtil.find(typeParameters, psiClass); + if (PsiUtil.resolveClassInType(typeElement.getType()) instanceof PsiTypeParameter typeParam) { + int i = ArrayUtil.find(typeParameters, typeParam); if (i >= 0 && i < toRemoveParms.length && toRemoveParms[i]) { - supersMap.put(typeElement, psiClass.getSuperClass()); + supersMap.put(typeElement, typeParam.getSuperClass()); } } } }); - final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject); + PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject); for (Map.Entry classEntry : supersMap.entrySet()) { classEntry.getKey().replace(elementFactory.createTypeElement(elementFactory.createType(classEntry.getValue()))); } changeClassSignature(typeParameters, toRemoveParms); } - private void changeClassSignature(final PsiTypeParameter[] originalTypeParameters, boolean[] toRemoveParms) + private void changeClassSignature(PsiTypeParameter[] originalTypeParameters, boolean[] toRemoveParms) throws IncorrectOperationException { PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory(); - List newTypeParameters = new ArrayList(); - for (final TypeParameterInfo info : myNewSignature) { + List newTypeParameters = new ArrayList<>(); + for (TypeParameterInfo info : myNewSignature) { int oldIndex = info.getOldParameterIndex(); if (oldIndex >= 0) { newTypeParameters.add(originalTypeParameters[oldIndex]); @@ -171,10 +178,10 @@ private void changeClassSignature(final PsiTypeParameter[] originalTypeParameter ChangeSignatureUtil.synchronizeList(myClass.getTypeParameterList(), newTypeParameters, TypeParameterList.INSTANCE, toRemoveParms); } - private boolean[] detectRemovedParameters(final PsiTypeParameter[] originaltypeParameters) { - final boolean[] toRemoveParms = new boolean[originaltypeParameters.length]; + private boolean[] detectRemovedParameters(PsiTypeParameter[] originaltypeParameters) { + boolean[] toRemoveParms = new boolean[originaltypeParameters.length]; Arrays.fill(toRemoveParms, true); - for (final TypeParameterInfo info : myNewSignature) { + for (TypeParameterInfo info : myNewSignature) { int oldParameterIndex = info.getOldParameterIndex(); if (oldParameterIndex >= 0) { toRemoveParms[oldParameterIndex] = false; @@ -183,7 +190,7 @@ private boolean[] detectRemovedParameters(final PsiTypeParameter[] originaltypeP return toRemoveParms; } - private void processUsage(final UsageInfo usage, final PsiTypeParameter[] originalTypeParameters, final boolean[] toRemoveParms) + private void processUsage(UsageInfo usage, PsiTypeParameter[] originalTypeParameters, boolean[] toRemoveParms) throws IncorrectOperationException { PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory(); PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)usage.getElement(); @@ -194,8 +201,8 @@ private void processUsage(final UsageInfo usage, final PsiTypeParameter[] origin if (oldValues.length != originalTypeParameters.length) { return; } - List newValues = new ArrayList(); - for (final TypeParameterInfo info : myNewSignature) { + List newValues = new ArrayList<>(); + for (TypeParameterInfo info : myNewSignature) { int oldIndex = info.getOldParameterIndex(); if (oldIndex >= 0) { newValues.add(oldValues[oldIndex]); @@ -222,9 +229,11 @@ private PsiSubstitutor determineUsageSubstitutor(PsiJavaCodeReferenceElement ref return usageSubstitutor; } - private static class ReferenceParameterList implements ChangeSignatureUtil.ChildrenGenerator { + private static class ReferenceParameterList + implements ChangeSignatureUtil.ChildrenGenerator { private static final ReferenceParameterList INSTANCE = new ReferenceParameterList(); + @Override public List getChildren(PsiReferenceParameterList list) { return Arrays.asList(list.getTypeParameterElements()); } @@ -233,9 +242,9 @@ public List getChildren(PsiReferenceParameterList list) { private static class TypeParameterList implements ChangeSignatureUtil.ChildrenGenerator { private static final TypeParameterList INSTANCE = new TypeParameterList(); + @Override public List getChildren(PsiTypeParameterList psiTypeParameterList) { return Arrays.asList(psiTypeParameterList.getTypeParameters()); } } - } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/ChangeSignatureProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/ChangeSignatureProcessor.java index a7e336447..c07e0bebb 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/ChangeSignatureProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/ChangeSignatureProcessor.java @@ -44,6 +44,7 @@ import consulo.usage.UsageViewDescriptor; import consulo.util.collection.MultiMap; import consulo.util.lang.ref.Ref; +import consulo.util.lang.ref.SimpleReference; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; @@ -184,10 +185,10 @@ protected void refreshElements(PsiElement[] elements) { @Override @RequiredUIAccess - protected boolean preprocessUsages(@Nonnull Ref refUsages) { + protected boolean preprocessUsages(@Nonnull SimpleReference refUsages) { for (ChangeSignatureUsageProcessor processor : ChangeSignatureUsageProcessor.EP_NAME.getExtensions()) { - if (processor instanceof ChangeSignatureUsageProcessorEx && ((ChangeSignatureUsageProcessorEx)processor).setupDefaultValues - (myChangeInfo, refUsages, myProject)) { + if (processor instanceof ChangeSignatureUsageProcessorEx changeSignatureUsageProcessorEx + && changeSignatureUsageProcessorEx.setupDefaultValues(myChangeInfo, refUsages, myProject)) { return false; } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/ChangeSignatureUtil.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/ChangeSignatureUtil.java index cae71efd6..e2818df42 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/ChangeSignatureUtil.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/ChangeSignatureUtil.java @@ -26,6 +26,7 @@ import consulo.language.psi.PsiElement; import consulo.language.util.IncorrectOperationException; import consulo.project.Project; +import consulo.ui.annotation.RequiredUIAccess; import consulo.util.lang.Comparing; import java.util.ArrayList; @@ -44,7 +45,6 @@ public static void synchro ChildrenGenerator generator, final boolean[] shouldRemoveChild ) throws IncorrectOperationException { - ArrayList elementsToRemove = null; List elements; @@ -56,7 +56,7 @@ public static void synchro } if (elementsToRemove == null) { - elementsToRemove = new ArrayList(); + elementsToRemove = new ArrayList<>(); for (int i = 0; i < shouldRemoveChild.length; i++) { if (shouldRemoveChild[i] && i < elements.size()) { elementsToRemove.add(elements.get(i)); @@ -81,29 +81,27 @@ public static void synchro } } } - else { - if (newElements.size() > 1 && (!elements.isEmpty() || index < newElements.size() - 1)) { - PsiElement anchor; - if (index == 0) { - anchor = list.getFirstChild(); - } - else { - anchor = index - 1 < elements.size() ? elements.get(index - 1) : null; - } - final PsiElement psi = Factory.createSingleLeafElement( - JavaTokenType.COMMA, - ",", - 0, - 1, - SharedImplUtil.findCharTableByTree(list.getNode()), - list.getManager() - ).getPsi(); - if (anchor != null) { - list.addAfter(psi, anchor); - } - else { - list.add(psi); - } + else if (newElements.size() > 1 && (!elements.isEmpty() || index < newElements.size() - 1)) { + PsiElement anchor; + if (index == 0) { + anchor = list.getFirstChild(); + } + else { + anchor = index - 1 < elements.size() ? elements.get(index - 1) : null; + } + final PsiElement psi = Factory.createSingleLeafElement( + JavaTokenType.COMMA, + ",", + 0, + 1, + SharedImplUtil.findCharTableByTree(list.getNode()), + list.getManager() + ).getPsi(); + if (anchor != null) { + list.addAfter(psi, anchor); + } + else { + list.add(psi); } } index++; @@ -114,6 +112,7 @@ public static void synchro } } + @RequiredUIAccess public static void invokeChangeSignatureOn(PsiMethod method, Project project) { final ChangeSignatureHandler handler = RefactoringSupportProvider.forLanguage(method.getLanguage()).getChangeSignatureHandler(); handler.invoke(project, new PsiElement[]{method}, null); diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java index 3532eda5b..5169e19ae 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java @@ -35,8 +35,10 @@ import com.intellij.java.language.psi.util.PsiUtil; import com.intellij.java.language.psi.util.TypeConversionUtil; import com.intellij.java.language.util.VisibilityUtil; +import consulo.annotation.access.RequiredReadAction; +import consulo.annotation.access.RequiredWriteAction; import consulo.annotation.component.ExtensionImpl; -import consulo.application.ApplicationManager; +import consulo.application.Application; import consulo.ide.impl.idea.refactoring.changeSignature.DefaultValueChooser; import consulo.java.impl.refactoring.changeSignature.ChangeSignatureUsageProcessorEx; import consulo.java.language.module.util.JavaClassNames; @@ -57,14 +59,13 @@ import consulo.localize.LocalizeValue; import consulo.logging.Logger; import consulo.project.Project; +import consulo.ui.annotation.RequiredUIAccess; import consulo.usage.MoveRenameUsageInfo; import consulo.usage.UsageInfo; import consulo.util.collection.ContainerUtil; import consulo.util.collection.MultiMap; -import consulo.util.lang.Pair; import consulo.util.lang.StringUtil; -import consulo.util.lang.function.Condition; -import consulo.util.lang.ref.Ref; +import consulo.util.lang.ref.SimpleReference; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; @@ -77,49 +78,54 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsageProcessorEx { private static final Logger LOG = Logger.getInstance(JavaChangeSignatureUsageProcessor.class); + @RequiredReadAction private static boolean isJavaUsage(UsageInfo info) { - final PsiElement element = info.getElement(); - if (element == null) { - return false; - } - return element.getLanguage() == JavaLanguage.INSTANCE; + PsiElement element = info.getElement(); + return element != null && element.getLanguage() == JavaLanguage.INSTANCE; } + @Nonnull @Override - public UsageInfo[] findUsages(ChangeInfo info) { - if (info instanceof JavaChangeInfo) { - return new JavaChangeSignatureUsageSearcher((JavaChangeInfo)info).findUsages(); + public UsageInfo[] findUsages(@Nonnull ChangeInfo info) { + if (info instanceof JavaChangeInfo javaChangeInfo) { + return new JavaChangeSignatureUsageSearcher(javaChangeInfo).findUsages(); } else { return UsageInfo.EMPTY_ARRAY; } } + @Nonnull @Override - public MultiMap findConflicts(ChangeInfo info, Ref refUsages) { - if (info instanceof JavaChangeInfo) { - return new ConflictSearcher((JavaChangeInfo)info).findConflicts(refUsages); + @RequiredReadAction + public MultiMap findConflicts(@Nonnull ChangeInfo info, SimpleReference refUsages) { + if (info instanceof JavaChangeInfo javaChangeInfo) { + return new ConflictSearcher(javaChangeInfo).findConflicts(refUsages); } else { - return new MultiMap(); + return new MultiMap<>(); } } @Override - public boolean processUsage(ChangeInfo changeInfo, UsageInfo usage, boolean beforeMethodChange, UsageInfo[] usages) { + @RequiredWriteAction + public boolean processUsage( + @Nonnull ChangeInfo changeInfo, + @Nonnull UsageInfo usage, + boolean beforeMethodChange, + @Nonnull UsageInfo[] usages + ) { if (!isJavaUsage(usage)) { return false; } - if (!(changeInfo instanceof JavaChangeInfo)) { + if (!(changeInfo instanceof JavaChangeInfo javaChangeInfo)) { return false; } - if (beforeMethodChange) { - if (usage instanceof CallerUsageInfo) { - final CallerUsageInfo callerUsageInfo = (CallerUsageInfo)usage; + if (usage instanceof CallerUsageInfo callerUsageInfo) { processCallerMethod( - (JavaChangeInfo)changeInfo, + javaChangeInfo, callerUsageInfo.getMethod(), null, callerUsageInfo.isToInsertParameter(), @@ -127,49 +133,45 @@ public boolean processUsage(ChangeInfo changeInfo, UsageInfo usage, boolean befo ); return true; } - else if (usage instanceof OverriderUsageInfo) { - OverriderUsageInfo info = (OverriderUsageInfo)usage; - final PsiMethod method = info.getElement(); - final PsiMethod baseMethod = info.getBaseMethod(); + else if (usage instanceof OverriderUsageInfo info) { + PsiMethod method = info.getElement(); + PsiMethod baseMethod = info.getBaseMethod(); if (info.isOriginalOverrider()) { - processPrimaryMethod((JavaChangeInfo)changeInfo, method, baseMethod, false); + processPrimaryMethod(javaChangeInfo, method, baseMethod, false); } else { - processCallerMethod((JavaChangeInfo)changeInfo, method, baseMethod, info.isToInsertArgs(), info.isToCatchExceptions()); + processCallerMethod(javaChangeInfo, method, baseMethod, info.isToInsertArgs(), info.isToCatchExceptions()); } return true; } - } else { PsiElement element = usage.getElement(); LOG.assertTrue(element != null); - if (usage instanceof DefaultConstructorImplicitUsageInfo) { - final DefaultConstructorImplicitUsageInfo defConstructorUsage = (DefaultConstructorImplicitUsageInfo)usage; + if (usage instanceof DefaultConstructorImplicitUsageInfo defConstructorUsage) { PsiMethod constructor = defConstructorUsage.getConstructor(); if (!constructor.isPhysical()) { - final boolean toPropagate = changeInfo instanceof JavaChangeInfoImpl - && ((JavaChangeInfoImpl)changeInfo).propagateParametersMethods.remove(constructor); - final PsiClass containingClass = defConstructorUsage.getContainingClass(); + boolean toPropagate = javaChangeInfo instanceof JavaChangeInfoImpl changeInfoImpl + && changeInfoImpl.propagateParametersMethods.remove(constructor); + PsiClass containingClass = defConstructorUsage.getContainingClass(); constructor = (PsiMethod)containingClass.add(constructor); PsiUtil.setModifierProperty(constructor, VisibilityUtil.getVisibilityModifier(containingClass.getModifierList()), true); if (toPropagate) { - ((JavaChangeInfoImpl)changeInfo).propagateParametersMethods.add(constructor); + ((JavaChangeInfoImpl)javaChangeInfo).propagateParametersMethods.add(constructor); } } - addSuperCall((JavaChangeInfo)changeInfo, constructor, defConstructorUsage.getBaseConstructor(), usages); + addSuperCall(javaChangeInfo, constructor, defConstructorUsage.getBaseConstructor(), usages); return true; } - else if (usage instanceof NoConstructorClassUsageInfo) { - addDefaultConstructor(((JavaChangeInfo)changeInfo), ((NoConstructorClassUsageInfo)usage).getPsiClass(), usages); + else if (usage instanceof NoConstructorClassUsageInfo noConstructorClassUsageInfo) { + addDefaultConstructor(javaChangeInfo, noConstructorClassUsageInfo.getPsiClass(), usages); return true; } - else if (usage instanceof MethodCallUsageInfo) { - final MethodCallUsageInfo methodCallInfo = (MethodCallUsageInfo)usage; + else if (usage instanceof MethodCallUsageInfo methodCallInfo) { processMethodUsage( methodCallInfo.getElement(), - (JavaChangeInfo)changeInfo, + javaChangeInfo, methodCallInfo.isToChangeArguments(), methodCallInfo.isToCatchExceptions(), methodCallInfo.getReferencedMethod(), @@ -178,20 +180,20 @@ else if (usage instanceof MethodCallUsageInfo) { ); return true; } - else if (usage instanceof ChangeSignatureParameterUsageInfo) { - String newName = ((ChangeSignatureParameterUsageInfo)usage).newParameterName; - String oldName = ((ChangeSignatureParameterUsageInfo)usage).oldParameterName; + else if (usage instanceof ChangeSignatureParameterUsageInfo parameterUsageInfo) { + String newName = parameterUsageInfo.newParameterName; + String oldName = parameterUsageInfo.oldParameterName; processParameterUsage((PsiReferenceExpression)element, oldName, newName); return true; } - else if (usage instanceof CallReferenceUsageInfo) { - ((CallReferenceUsageInfo)usage).getReference().handleChangeSignature(changeInfo); + else if (usage instanceof CallReferenceUsageInfo callUsageInfo) { + callUsageInfo.getReference().handleChangeSignature(javaChangeInfo); return true; } - else if (element instanceof PsiEnumConstant) { + else if (element instanceof PsiEnumConstant enumConstant) { fixActualArgumentsList( - ((PsiEnumConstant)element).getArgumentList(), - (JavaChangeInfo)changeInfo, + enumConstant.getArgumentList(), + javaChangeInfo, true, PsiSubstitutor.EMPTY ); @@ -200,7 +202,7 @@ else if (element instanceof PsiEnumConstant) { else if (!(usage instanceof OverriderUsageInfo)) { PsiReference reference = usage instanceof MoveRenameUsageInfo ? usage.getReference() : element.getReference(); if (reference != null) { - PsiElement target = changeInfo.getMethod(); + PsiElement target = javaChangeInfo.getMethod(); if (target != null) { reference.bindToElement(target); } @@ -216,17 +218,18 @@ private static void processParameterUsage( String newName ) throws IncorrectOperationException { PsiElement last = ref.getReferenceNameElement(); - if (last instanceof PsiIdentifier && last.getText().equals(oldName)) { + if (last instanceof PsiIdentifier identifier && identifier.getText().equals(oldName)) { PsiElementFactory factory = JavaPsiFacade.getInstance(ref.getProject()).getElementFactory(); PsiIdentifier newNameIdentifier = factory.createIdentifier(newName); last.replace(newNameIdentifier); } } + @RequiredReadAction private static void addDefaultConstructor( JavaChangeInfo changeInfo, PsiClass aClass, - final UsageInfo[] usages + UsageInfo[] usages ) throws IncorrectOperationException { if (!(aClass instanceof PsiAnonymousClass)) { PsiElementFactory factory = JavaPsiFacade.getElementFactory(aClass.getProject()); @@ -236,24 +239,21 @@ private static void addDefaultConstructor( PsiUtil.setModifierProperty(defaultConstructor, VisibilityUtil.getVisibilityModifier(aClass.getModifierList()), true); addSuperCall(changeInfo, defaultConstructor, null, usages); } - else { - final PsiElement parent = aClass.getParent(); - if (parent instanceof PsiNewExpression) { - final PsiExpressionList argumentList = ((PsiNewExpression)parent).getArgumentList(); - final PsiClass baseClass = changeInfo.getMethod().getContainingClass(); - final PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(baseClass, aClass, PsiSubstitutor.EMPTY); - fixActualArgumentsList(argumentList, changeInfo, true, substitutor); - } + else if (aClass.getParent() instanceof PsiNewExpression newExpr) { + PsiClass baseClass = changeInfo.getMethod().getContainingClass(); + PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(baseClass, aClass, PsiSubstitutor.EMPTY); + fixActualArgumentsList(newExpr.getArgumentList(), changeInfo, true, substitutor); } } + @RequiredReadAction private static void addSuperCall( JavaChangeInfo changeInfo, PsiMethod constructor, PsiMethod callee, - final UsageInfo[] usages + UsageInfo[] usages ) throws IncorrectOperationException { - final PsiElementFactory factory = JavaPsiFacade.getElementFactory(constructor.getProject()); + PsiElementFactory factory = JavaPsiFacade.getElementFactory(constructor.getProject()); PsiExpressionStatement superCall = (PsiExpressionStatement)factory.createStatementFromText("super();", constructor); PsiCodeBlock body = constructor.getBody(); assert body != null; @@ -265,12 +265,13 @@ private static void addSuperCall( superCall = (PsiExpressionStatement)body.add(superCall); } PsiMethodCallExpression callExpression = (PsiMethodCallExpression)superCall.getExpression(); - final PsiClass aClass = constructor.getContainingClass(); - final PsiClass baseClass = changeInfo.getMethod().getContainingClass(); - final PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(baseClass, aClass, PsiSubstitutor.EMPTY); + PsiClass aClass = constructor.getContainingClass(); + PsiClass baseClass = changeInfo.getMethod().getContainingClass(); + PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(baseClass, aClass, PsiSubstitutor.EMPTY); processMethodUsage(callExpression.getMethodExpression(), changeInfo, true, false, callee, substitutor, usages); } + @RequiredReadAction private static void processMethodUsage( PsiElement ref, JavaChangeInfo changeInfo, @@ -278,24 +279,22 @@ private static void processMethodUsage( boolean toCatchExceptions, PsiMethod callee, PsiSubstitutor subsitutor, - final UsageInfo[] usages + UsageInfo[] usages ) throws IncorrectOperationException { - if (changeInfo.isNameChanged()) { - if (ref instanceof PsiJavaCodeReferenceElement) { - PsiElement last = ((PsiJavaCodeReferenceElement)ref).getReferenceNameElement(); - if (last instanceof PsiIdentifier && last.getText().equals(changeInfo.getOldName())) { - last.replace(changeInfo.getNewNameIdentifier()); - } - } + if (changeInfo.isNameChanged() + && ref instanceof PsiJavaCodeReferenceElement javaCodeRef + && javaCodeRef.getReferenceNameElement() instanceof PsiIdentifier identifier + && identifier.getText().equals(changeInfo.getOldName())) { + identifier.replace(changeInfo.getNewNameIdentifier()); } - final PsiMethod caller = RefactoringUtil.getEnclosingMethod(ref); + PsiMethod caller = RefactoringUtil.getEnclosingMethod(ref); if (toChangeArguments) { - final PsiExpressionList list = RefactoringUtil.getArgumentListByMethodReference(ref); + PsiExpressionList list = RefactoringUtil.getArgumentListByMethodReference(ref); LOG.assertTrue(list != null); boolean toInsertDefaultValue = needDefaultValue(changeInfo, caller); - if (toInsertDefaultValue && ref instanceof PsiReferenceExpression) { - final PsiExpression qualifierExpression = ((PsiReferenceExpression)ref).getQualifierExpression(); + if (toInsertDefaultValue && ref instanceof PsiReferenceExpression refExpr) { + PsiExpression qualifierExpression = refExpr.getQualifierExpression(); if (qualifierExpression instanceof PsiSuperExpression && callerSignatureIsAboutToChangeToo(caller, usages)) { toInsertDefaultValue = false; } @@ -316,17 +315,17 @@ private static void processMethodUsage( } } - private static boolean callerSignatureIsAboutToChangeToo(final PsiMethod caller, final UsageInfo[] usages) { + private static boolean callerSignatureIsAboutToChangeToo(PsiMethod caller, UsageInfo[] usages) { for (UsageInfo usage : usages) { - if (usage instanceof MethodCallUsageInfo - && MethodSignatureUtil.isSuperMethod(((MethodCallUsageInfo)usage).getReferencedMethod(), caller)) { + if (usage instanceof MethodCallUsageInfo callUsageInfo + && MethodSignatureUtil.isSuperMethod(callUsageInfo.getReferencedMethod(), caller)) { return true; } } return false; } - private static PsiClassType[] getCalleeChangedExceptionInfo(final PsiMethod callee) { + private static PsiClassType[] getCalleeChangedExceptionInfo(PsiMethod callee) { return callee.getThrowsList().getReferencedTypes(); //Callee method's throws list is already modified! } @@ -334,16 +333,14 @@ private static void fixExceptions(PsiElement ref, PsiClassType[] newExceptions) //methods' throws lists are already modified, may use ExceptionUtil.collectUnhandledExceptions newExceptions = filterCheckedExceptions(newExceptions); - PsiElement context = PsiTreeUtil.getParentOfType(ref, PsiTryStatement.class, PsiMethod.class); - if (context instanceof PsiTryStatement) { - PsiTryStatement tryStatement = (PsiTryStatement)context; - PsiCodeBlock tryBlock = tryStatement.getTryBlock(); + if (PsiTreeUtil.getParentOfType(ref, PsiTryStatement.class, PsiMethod.class) instanceof PsiTryStatement tryStmt) { + PsiCodeBlock tryBlock = tryStmt.getTryBlock(); //Remove unused catches Collection classes = ExceptionUtil.collectUnhandledExceptions(tryBlock, tryBlock); - PsiParameter[] catchParameters = tryStatement.getCatchBlockParameters(); + PsiParameter[] catchParameters = tryStmt.getCatchBlockParameters(); for (PsiParameter parameter : catchParameters) { - final PsiType caughtType = parameter.getType(); + PsiType caughtType = parameter.getType(); if (!(caughtType instanceof PsiClassType)) { continue; @@ -359,9 +356,9 @@ private static void fixExceptions(PsiElement ref, PsiClassType[] newExceptions) } PsiClassType[] exceptionsToAdd = filterUnhandledExceptions(newExceptions, tryBlock); - addExceptions(exceptionsToAdd, tryStatement); + addExceptions(exceptionsToAdd, tryStmt); - adjustPossibleEmptyTryStatement(tryStatement); + adjustPossibleEmptyTryStatement(tryStmt); } else { newExceptions = filterUnhandledExceptions(newExceptions, ref); @@ -407,7 +404,7 @@ private static void adjustPossibleEmptyTryStatement(PsiTryStatement tryStatement private static void addExceptions(PsiClassType[] exceptionsToAdd, PsiTryStatement tryStatement) throws IncorrectOperationException { for (PsiClassType type : exceptionsToAdd) { - final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(tryStatement.getProject()); + JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(tryStatement.getProject()); String name = styleManager.suggestVariableName(VariableKind.PARAMETER, null, null, type).names[0]; name = styleManager.suggestUniqueVariableName(name, tryStatement, false); @@ -418,7 +415,7 @@ private static void addExceptions(PsiClassType[] exceptionsToAdd, PsiTryStatemen } private static PsiClassType[] filterUnhandledExceptions(PsiClassType[] exceptions, PsiElement place) { - List result = new ArrayList(); + List result = new ArrayList<>(); for (PsiClassType exception : exceptions) { if (!ExceptionUtil.isHandled(exception, place)) { result.add(exception); @@ -437,20 +434,21 @@ private static boolean isCatchParameterRedundant(PsiClassType catchParamType, Co } //This methods works equally well for primary usages as well as for propagated callers' usages + @RequiredUIAccess private static void fixActualArgumentsList( PsiExpressionList list, JavaChangeInfo changeInfo, boolean toInsertDefaultValue, PsiSubstitutor substitutor ) throws IncorrectOperationException { - final PsiElementFactory factory = JavaPsiFacade.getInstance(list.getProject()).getElementFactory(); + PsiElementFactory factory = JavaPsiFacade.getInstance(list.getProject()).getElementFactory(); if (changeInfo.isParameterSetOrOrderChanged()) { - if (changeInfo instanceof JavaChangeInfoImpl && ((JavaChangeInfoImpl)changeInfo).isPropagationEnabled) { - final ParameterInfoImpl[] createdParmsInfo = ((JavaChangeInfoImpl)changeInfo).getCreatedParmsInfoWithoutVarargs(); + if (changeInfo instanceof JavaChangeInfoImpl changeInfoImpl && changeInfoImpl.isPropagationEnabled) { + ParameterInfoImpl[] createdParmsInfo = changeInfoImpl.getCreatedParmsInfoWithoutVarargs(); for (ParameterInfoImpl info : createdParmsInfo) { PsiExpression newArg; if (toInsertDefaultValue) { - newArg = createDefaultValue(changeInfo, factory, info, list); + newArg = createDefaultValue(changeInfoImpl, factory, info, list); } else { newArg = factory.createExpressionFromText(info.getName(), list); @@ -461,24 +459,23 @@ private static void fixActualArgumentsList( } } else { - final PsiExpression[] args = list.getExpressions(); - final int nonVarargCount = getNonVarargCount(changeInfo, args); - final int varargCount = args.length - nonVarargCount; + PsiExpression[] args = list.getExpressions(); + int nonVarargCount = getNonVarargCount(changeInfo, args); + int varargCount = args.length - nonVarargCount; if (varargCount < 0) { return; } PsiExpression[] newVarargInitializers = null; - final int newArgsLength; - final int newNonVarargCount; - final JavaParameterInfo[] newParms = changeInfo.getNewParameters(); + int newArgsLength; + int newNonVarargCount; + JavaParameterInfo[] newParms = changeInfo.getNewParameters(); if (changeInfo.isArrayToVarargs()) { newNonVarargCount = newParms.length - 1; - final JavaParameterInfo lastNewParm = newParms[newParms.length - 1]; - final PsiExpression arrayToConvert = args[lastNewParm.getOldIndex()]; - if (arrayToConvert instanceof PsiNewExpression) { - final PsiNewExpression expression = (PsiNewExpression)arrayToConvert; - final PsiArrayInitializerExpression arrayInitializer = expression.getArrayInitializer(); + JavaParameterInfo lastNewParm = newParms[newParms.length - 1]; + PsiExpression arrayToConvert = args[lastNewParm.getOldIndex()]; + if (arrayToConvert instanceof PsiNewExpression newExpr) { + PsiArrayInitializerExpression arrayInitializer = newExpr.getArrayInitializer(); if (arrayInitializer != null) { newVarargInitializers = arrayInitializer.getInitializers(); } @@ -506,7 +503,7 @@ else if (changeInfo.isObtainsVarags()) { } } - final PsiExpression[] newArgs = new PsiExpression[newArgsLength]; + PsiExpression[] newArgs = new PsiExpression[newArgsLength]; for (int i = 0; i < newNonVarargCount; i++) { if (newParms[i].getOldIndex() == nonVarargCount && oldVarargs != null) { PsiType type = newParms[i].createType(changeInfo.getMethod(), list.getManager()); @@ -534,10 +531,10 @@ else if (changeInfo.isObtainsVarags()) { } } else { - final int newVarargCount = newArgsLength - newNonVarargCount; + int newVarargCount = newArgsLength - newNonVarargCount; LOG.assertTrue(newVarargCount == 0 || newVarargCount == varargCount); for (int i = newNonVarargCount; i < newArgsLength; i++) { - final int oldIndex = newParms[newNonVarargCount].getOldIndex(); + int oldIndex = newParms[newNonVarargCount].getOldIndex(); if (oldIndex >= 0 && oldIndex != nonVarargCount) { newArgs[i] = createActualArgument(changeInfo, list, newParms[newNonVarargCount], toInsertDefaultValue, args); } @@ -561,15 +558,16 @@ private static int getNonVarargCount(JavaChangeInfo changeInfo, PsiExpression[] @Nullable + @RequiredReadAction private static PsiExpression createActualArgument( JavaChangeInfo changeInfo, - final PsiExpressionList list, - final JavaParameterInfo info, - final boolean toInsertDefaultValue, - final PsiExpression[] args + PsiExpressionList list, + JavaParameterInfo info, + boolean toInsertDefaultValue, + PsiExpression[] args ) throws IncorrectOperationException { - final PsiElementFactory factory = JavaPsiFacade.getInstance(list.getProject()).getElementFactory(); - final int index = info.getOldIndex(); + PsiElementFactory factory = JavaPsiFacade.getInstance(list.getProject()).getElementFactory(); + int index = info.getOldIndex(); if (index >= 0) { return args[index]; } @@ -582,19 +580,21 @@ else if (toInsertDefaultValue) { } @Nullable + @RequiredReadAction private static PsiExpression createDefaultValue( JavaChangeInfo changeInfo, - final PsiElementFactory factory, - final JavaParameterInfo info, - final PsiExpressionList list + PsiElementFactory factory, + JavaParameterInfo info, + PsiExpressionList list ) throws IncorrectOperationException { if (info.isUseAnySingleVariable()) { - final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(list.getProject()).getResolveHelper(); - final PsiType type = info.getTypeWrapper().getType(changeInfo.getMethod(), list.getManager()); - final VariablesProcessor processor = new VariablesProcessor(false) { + PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(list.getProject()).getResolveHelper(); + PsiType type = info.getTypeWrapper().getType(changeInfo.getMethod(), list.getManager()); + VariablesProcessor processor = new VariablesProcessor(false) { @Override + @RequiredReadAction protected boolean check(PsiVariable var, ResolveState state) { - if (var instanceof PsiField && !resolveHelper.isAccessible((PsiField)var, list, null)) { + if (var instanceof PsiField field && !resolveHelper.isAccessible(field, list, null)) { return false; } if (var instanceof PsiLocalVariable && list.getTextRange().getStartOffset() <= var.getTextRange().getStartOffset()) { @@ -603,7 +603,7 @@ protected boolean check(PsiVariable var, ResolveState state) { if (PsiTreeUtil.isAncestor(var, list, false)) { return false; } - final PsiType varType = state.get(PsiSubstitutor.KEY).substitute(var.getType()); + PsiType varType = state.get(PsiSubstitutor.KEY).substitute(var.getType()); return type.isAssignableFrom(varType); } @@ -615,14 +615,14 @@ public boolean execute(@Nonnull PsiElement pe, ResolveState state) { }; PsiScopesUtil.treeWalkUp(processor, list, null); if (processor.size() == 1) { - final PsiVariable result = processor.getResult(0); + PsiVariable result = processor.getResult(0); return factory.createExpressionFromText(result.getName(), list); } if (processor.size() == 0) { - final PsiClass parentClass = PsiTreeUtil.getParentOfType(list, PsiClass.class); + PsiClass parentClass = PsiTreeUtil.getParentOfType(list, PsiClass.class); if (parentClass != null) { PsiClass containingClass = parentClass; - final Set containingClasses = new HashSet(); + Set containingClasses = new HashSet<>(); while (containingClass != null) { if (type.isAssignableFrom(factory.createType(containingClass, PsiSubstitutor.EMPTY))) { containingClasses.add(containingClass); @@ -638,8 +638,8 @@ public boolean execute(@Nonnull PsiElement pe, ResolveState state) { } } } - final PsiCallExpression callExpression = PsiTreeUtil.getParentOfType(list, PsiCallExpression.class); - final String defaultValue = info.getDefaultValue(); + PsiCallExpression callExpression = PsiTreeUtil.getParentOfType(list, PsiCallExpression.class); + String defaultValue = info.getDefaultValue(); return callExpression != null ? info.getValue(callExpression) : defaultValue.length() > 0 @@ -649,11 +649,12 @@ public boolean execute(@Nonnull PsiElement pe, ResolveState state) { @Override + @RequiredWriteAction public boolean processPrimaryMethod(ChangeInfo changeInfo) { if (!JavaLanguage.INSTANCE.equals(changeInfo.getLanguage()) || !(changeInfo instanceof JavaChangeInfo)) { return false; } - final PsiElement element = changeInfo.getMethod(); + PsiElement element = changeInfo.getMethod(); LOG.assertTrue(element instanceof PsiMethod); if (changeInfo.isGenerateDelegate()) { generateDelegate((JavaChangeInfo)changeInfo); @@ -663,50 +664,47 @@ public boolean processPrimaryMethod(ChangeInfo changeInfo) { } @Override - public boolean shouldPreviewUsages(ChangeInfo changeInfo, UsageInfo[] usages) { + public boolean shouldPreviewUsages(@Nonnull ChangeInfo changeInfo, @Nonnull UsageInfo[] usages) { return false; } @Override - public boolean setupDefaultValues(ChangeInfo changeInfo, Ref refUsages, Project project) { + @RequiredUIAccess + public boolean setupDefaultValues(ChangeInfo changeInfo, SimpleReference refUsages, Project project) { if (!(changeInfo instanceof JavaChangeInfo)) { return false; } for (UsageInfo usageInfo : refUsages.get()) { - if (usageInfo instanceof MethodCallUsageInfo) { - MethodCallUsageInfo methodCallUsageInfo = (MethodCallUsageInfo)usageInfo; - if (methodCallUsageInfo.isToChangeArguments()) { - final PsiElement element = methodCallUsageInfo.getElement(); - if (element == null) { - continue; - } - final PsiMethod caller = RefactoringUtil.getEnclosingMethod(element); - final boolean needDefaultValue = needDefaultValue(changeInfo, caller); - if (needDefaultValue - && (caller == null || !MethodSignatureUtil.isSuperMethod(methodCallUsageInfo.getReferencedMethod(), caller))) { - final ParameterInfo[] parameters = changeInfo.getNewParameters(); - for (ParameterInfo parameter : parameters) { - final String defaultValue = parameter.getDefaultValue(); - if (defaultValue == null && parameter.getOldIndex() == -1) { - ((ParameterInfoImpl)parameter).setDefaultValue(""); - if (!ApplicationManager.getApplication().isUnitTestMode()) { - final PsiType type = - ((ParameterInfoImpl)parameter).getTypeWrapper().getType(element, element.getManager()); - final DefaultValueChooser chooser = - new DefaultValueChooser(project, parameter.getName(), PsiTypesUtil.getDefaultValueOfType(type)); - chooser.show(); - if (chooser.isOK()) { - if (chooser.feelLucky()) { - parameter.setUseAnySingleVariable(true); - } - else { - ((ParameterInfoImpl)parameter).setDefaultValue(chooser.getDefaultValue()); - } + if (usageInfo instanceof MethodCallUsageInfo methodCallUsageInfo && methodCallUsageInfo.isToChangeArguments()) { + PsiElement element = methodCallUsageInfo.getElement(); + if (element == null) { + continue; + } + PsiMethod caller = RefactoringUtil.getEnclosingMethod(element); + boolean needDefaultValue = needDefaultValue(changeInfo, caller); + if (needDefaultValue + && (caller == null || !MethodSignatureUtil.isSuperMethod(methodCallUsageInfo.getReferencedMethod(), caller))) { + ParameterInfo[] parameters = changeInfo.getNewParameters(); + for (ParameterInfo parameter : parameters) { + String defaultValue = parameter.getDefaultValue(); + if (defaultValue == null && parameter.getOldIndex() == -1) { + ((ParameterInfoImpl)parameter).setDefaultValue(""); + if (!Application.get().isUnitTestMode()) { + PsiType type = ((ParameterInfoImpl)parameter).getTypeWrapper().getType(element, element.getManager()); + DefaultValueChooser chooser = + new DefaultValueChooser(project, parameter.getName(), PsiTypesUtil.getDefaultValueOfType(type)); + chooser.show(); + if (chooser.isOK()) { + if (chooser.feelLucky()) { + parameter.setUseAnySingleVariable(true); } else { - return true; + ((ParameterInfoImpl)parameter).setDefaultValue(chooser.getDefaultValue()); } } + else { + return true; + } } } } @@ -732,18 +730,18 @@ public void registerConflictResolvers( } private static boolean needDefaultValue(ChangeInfo changeInfo, PsiMethod method) { - return !(changeInfo instanceof JavaChangeInfoImpl) || !((JavaChangeInfoImpl)changeInfo).propagateParametersMethods.contains(method); + return !(changeInfo instanceof JavaChangeInfoImpl changeInfoImpl && changeInfoImpl.propagateParametersMethods.contains(method)); } public static void generateDelegate(JavaChangeInfo changeInfo) throws IncorrectOperationException { - final PsiMethod delegate = generateDelegatePrototype(changeInfo); + PsiMethod delegate = generateDelegatePrototype(changeInfo); PsiClass targetClass = changeInfo.getMethod().getContainingClass(); LOG.assertTrue(targetClass != null); targetClass.addBefore(delegate, changeInfo.getMethod()); } public static PsiMethod generateDelegatePrototype(JavaChangeInfo changeInfo) { - final PsiMethod delegate = (PsiMethod)changeInfo.getMethod().copy(); + PsiMethod delegate = (PsiMethod)changeInfo.getMethod().copy(); PsiClass targetClass = changeInfo.getMethod().getContainingClass(); LOG.assertTrue(targetClass != null); if (targetClass.isInterface() && delegate.getBody() == null) { @@ -751,7 +749,7 @@ public static PsiMethod generateDelegatePrototype(JavaChangeInfo changeInfo) { } PsiElementFactory factory = JavaPsiFacade.getElementFactory(targetClass.getProject()); ChangeSignatureProcessor.makeEmptyBody(factory, delegate); - final PsiCallExpression callExpression = ChangeSignatureProcessor.addDelegatingCallTemplate(delegate, changeInfo.getNewName()); + PsiCallExpression callExpression = ChangeSignatureProcessor.addDelegatingCallTemplate(delegate, changeInfo.getNewName()); addDelegateArguments(changeInfo, factory, callExpression); return delegate; } @@ -759,26 +757,27 @@ public static PsiMethod generateDelegatePrototype(JavaChangeInfo changeInfo) { private static void addDelegateArguments( JavaChangeInfo changeInfo, PsiElementFactory factory, - final PsiCallExpression callExpression + PsiCallExpression callExpression ) throws IncorrectOperationException { - final JavaParameterInfo[] newParms = changeInfo.getNewParameters(); - final String[] oldParameterNames = changeInfo.getOldParameterNames(); + JavaParameterInfo[] newParms = changeInfo.getNewParameters(); + String[] oldParameterNames = changeInfo.getOldParameterNames(); for (int i = 0; i < newParms.length; i++) { JavaParameterInfo newParm = newParms[i]; - final PsiExpression actualArg; + PsiExpression actualArg; if (newParm.getOldIndex() >= 0) { actualArg = factory.createExpressionFromText(oldParameterNames[newParm.getOldIndex()], callExpression); } else { actualArg = changeInfo.getValue(i, callExpression); } - final PsiExpressionList argumentList = callExpression.getArgumentList(); + PsiExpressionList argumentList = callExpression.getArgumentList(); if (actualArg != null && argumentList != null) { JavaCodeStyleManager.getInstance(callExpression.getProject()).shortenClassReferences(argumentList.add(actualArg)); } } } + @RequiredWriteAction private static void processPrimaryMethod( JavaChangeInfo changeInfo, PsiMethod method, @@ -789,7 +788,7 @@ private static void processPrimaryMethod( if (changeInfo.isVisibilityChanged()) { PsiModifierList modifierList = method.getModifierList(); - final String highestVisibility = isOriginal + String highestVisibility = isOriginal ? changeInfo.getNewVisibility() : VisibilityUtil.getHighestVisibility(changeInfo.getNewVisibility(), VisibilityUtil.getVisibilityModifier(modifierList)); VisibilityUtil.setVisibility(modifierList, highestVisibility); @@ -801,21 +800,21 @@ private static void processPrimaryMethod( : RefactoringUtil.suggestNewOverriderName(method.getName(), baseMethod.getName(), changeInfo.getNewName()); if (newName != null && !newName.equals(method.getName())) { - final PsiIdentifier nameId = method.getNameIdentifier(); + PsiIdentifier nameId = method.getNameIdentifier(); assert nameId != null; nameId.replace(JavaPsiFacade.getInstance(method.getProject()).getElementFactory().createIdentifier(newName)); } } - final PsiSubstitutor substitutor = + PsiSubstitutor substitutor = baseMethod == null ? PsiSubstitutor.EMPTY : ChangeSignatureProcessor.calculateSubstitutor(method, baseMethod); if (changeInfo.isReturnTypeChanged()) { PsiType newTypeElement = changeInfo.getNewReturnType().getType(changeInfo.getMethod().getParameterList(), method.getManager()); - final PsiType returnType = substitutor.substitute(newTypeElement); + PsiType returnType = substitutor.substitute(newTypeElement); // don't modify return type for non-Java overriders (EJB) if (method.getName().equals(changeInfo.getNewName())) { - final PsiTypeElement typeElement = method.getReturnTypeElement(); + PsiTypeElement typeElement = method.getReturnTypeElement(); if (typeElement != null) { typeElement.replace(factory.createTypeElement(returnType)); } @@ -825,12 +824,12 @@ private static void processPrimaryMethod( PsiParameterList list = method.getParameterList(); PsiParameter[] parameters = list.getParameters(); - final JavaParameterInfo[] parameterInfos = changeInfo.getNewParameters(); - final int delta = + JavaParameterInfo[] parameterInfos = changeInfo.getNewParameters(); + int delta = baseMethod != null ? baseMethod.getParameterList().getParametersCount() - method.getParameterList().getParametersCount() : 0; PsiParameter[] newParms = new PsiParameter[Math.max(parameterInfos.length - delta, 0)]; - final String[] oldParameterNames = changeInfo.getOldParameterNames(); - final String[] oldParameterTypes = changeInfo.getOldParameterTypes(); + String[] oldParameterNames = changeInfo.getOldParameterNames(); + String[] oldParameterTypes = changeInfo.getOldParameterTypes(); for (int i = 0; i < newParms.length; i++) { JavaParameterInfo info = parameterInfos[i]; int index = info.getOldIndex(); @@ -858,19 +857,18 @@ private static void processPrimaryMethod( } } - resolveParameterVsFieldsConflicts(newParms, method, list, changeInfo.toRemoveParm()); fixJavadocsForChangedMethod(method, changeInfo, newParms.length); if (changeInfo.isExceptionSetOrOrderChanged()) { - final PsiClassType[] newExceptions = getPrimaryChangedExceptionInfo(changeInfo); + PsiClassType[] newExceptions = getPrimaryChangedExceptionInfo(changeInfo); fixPrimaryThrowsLists(method, newExceptions); } } private static PsiClassType[] getPrimaryChangedExceptionInfo(JavaChangeInfo changeInfo) throws IncorrectOperationException { - final ThrownExceptionInfo[] newExceptionInfos = changeInfo.getNewExceptions(); + ThrownExceptionInfo[] newExceptionInfos = changeInfo.getNewExceptions(); PsiClassType[] newExceptions = new PsiClassType[newExceptionInfos.length]; - final PsiMethod method = changeInfo.getMethod(); + PsiMethod method = changeInfo.getMethod(); for (int i = 0; i < newExceptions.length; i++) { newExceptions[i] = (PsiClassType)newExceptionInfos[i].createType(method, method.getManager()); //context really does not matter here @@ -878,7 +876,6 @@ private static PsiClassType[] getPrimaryChangedExceptionInfo(JavaChangeInfo chan return newExceptions; } - private static void processCallerMethod( JavaChangeInfo changeInfo, PsiMethod caller, @@ -888,14 +885,14 @@ private static void processCallerMethod( ) throws IncorrectOperationException { LOG.assertTrue(toInsertParams || toInsertThrows); if (toInsertParams) { - List newParameters = new ArrayList(); + List newParameters = new ArrayList<>(); ContainerUtil.addAll(newParameters, caller.getParameterList().getParameters()); - final JavaParameterInfo[] primaryNewParms = changeInfo.getNewParameters(); + JavaParameterInfo[] primaryNewParms = changeInfo.getNewParameters(); PsiSubstitutor substitutor = baseMethod == null ? PsiSubstitutor.EMPTY : ChangeSignatureProcessor.calculateSubstitutor(caller, baseMethod); - final PsiClass aClass = changeInfo.getMethod().getContainingClass(); - final PsiClass callerContainingClass = caller.getContainingClass(); - final PsiSubstitutor psiSubstitutor = aClass != null && callerContainingClass != null && callerContainingClass.isInheritor( + PsiClass aClass = changeInfo.getMethod().getContainingClass(); + PsiClass callerContainingClass = caller.getContainingClass(); + PsiSubstitutor psiSubstitutor = aClass != null && callerContainingClass != null && callerContainingClass.isInheritor( aClass, true ) ? TypeConversionUtil.getSuperClassSubstitutor @@ -912,14 +909,14 @@ private static void processCallerMethod( } if (toInsertThrows) { - List newThrowns = new ArrayList(); - final PsiReferenceList throwsList = caller.getThrowsList(); + List newThrowns = new ArrayList<>(); + PsiReferenceList throwsList = caller.getThrowsList(); ContainerUtil.addAll(newThrowns, throwsList.getReferenceElements()); - final ThrownExceptionInfo[] primaryNewExns = changeInfo.getNewExceptions(); + ThrownExceptionInfo[] primaryNewExns = changeInfo.getNewExceptions(); for (ThrownExceptionInfo thrownExceptionInfo : primaryNewExns) { if (thrownExceptionInfo.getOldIndex() < 0) { - final PsiClassType type = (PsiClassType)thrownExceptionInfo.createType(caller, caller.getManager()); - final PsiJavaCodeReferenceElement ref = + PsiClassType type = (PsiClassType)thrownExceptionInfo.createType(caller, caller.getManager()); + PsiJavaCodeReferenceElement ref = JavaPsiFacade.getInstance(caller.getProject()).getElementFactory().createReferenceElementByType(type); newThrowns.add(ref); } @@ -931,6 +928,7 @@ private static void processCallerMethod( } } + @RequiredReadAction private static void fixPrimaryThrowsLists(PsiMethod method, PsiClassType[] newExceptions) throws IncorrectOperationException { PsiElementFactory elementFactory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory(); PsiJavaCodeReferenceElement[] refs = new PsiJavaCodeReferenceElement[newExceptions.length]; @@ -946,15 +944,15 @@ private static void fixPrimaryThrowsLists(PsiMethod method, PsiClassType[] newEx } private static void fixJavadocsForChangedMethod( - final PsiMethod method, - final JavaChangeInfo changeInfo, + PsiMethod method, + JavaChangeInfo changeInfo, int newParamsLength ) throws IncorrectOperationException { - final PsiParameter[] parameters = method.getParameterList().getParameters(); - final JavaParameterInfo[] newParms = changeInfo.getNewParameters(); + PsiParameter[] parameters = method.getParameterList().getParameters(); + JavaParameterInfo[] newParms = changeInfo.getNewParameters(); LOG.assertTrue(parameters.length <= newParamsLength); - final Set newParameters = new HashSet(); - final String[] oldParameterNames = changeInfo.getOldParameterNames(); + Set newParameters = new HashSet<>(); + String[] oldParameterNames = changeInfo.getOldParameterNames(); for (int i = 0; i < newParamsLength; i++) { JavaParameterInfo newParm = newParms[i]; if (newParm.getOldIndex() < 0 @@ -963,16 +961,17 @@ private static void fixJavadocsForChangedMethod( newParameters.add(parameters[i]); } } - RefactoringUtil.fixJavadocsForParams(method, newParameters, new Condition>() { - @Override - public boolean value(Pair pair) { - final PsiParameter parameter = pair.first; - final String oldParamName = pair.second; - final int idx = Arrays.binarySearch(oldParameterNames, oldParamName); + RefactoringUtil.fixJavadocsForParams( + method, + newParameters, + pair -> { + PsiParameter parameter = pair.first; + String oldParamName = pair.second; + int idx = Arrays.binarySearch(oldParameterNames, oldParamName); return idx >= 0 && idx == method.getParameterList().getParameterIndex(parameter) && changeInfo.getNewParameters()[idx].getOldIndex() == idx; } - }); + ); } private static PsiParameter createNewParameter( @@ -980,8 +979,8 @@ private static PsiParameter createNewParameter( JavaParameterInfo newParm, PsiSubstitutor... substitutor ) throws IncorrectOperationException { - final PsiParameterList list = changeInfo.getMethod().getParameterList(); - final PsiElementFactory factory = JavaPsiFacade.getInstance(list.getProject()).getElementFactory(); + PsiParameterList list = changeInfo.getMethod().getParameterList(); + PsiElementFactory factory = JavaPsiFacade.getInstance(list.getProject()).getElementFactory(); PsiType type = newParm.createType(list, list.getManager()); for (PsiSubstitutor psiSubstitutor : substitutor) { type = psiSubstitutor.substitute(type); @@ -990,13 +989,13 @@ private static PsiParameter createNewParameter( } private static void resolveParameterVsFieldsConflicts( - final PsiParameter[] newParms, - final PsiMethod method, - final PsiParameterList list, + PsiParameter[] newParms, + PsiMethod method, + PsiParameterList list, boolean[] toRemoveParm ) throws IncorrectOperationException { - List conflictResolvers = new ArrayList(); + List conflictResolvers = new ArrayList<>(); for (PsiParameter parameter : newParms) { conflictResolvers.add(new FieldConflictsResolver(parameter.getName(), method.getBody())); } @@ -1009,7 +1008,7 @@ private static void resolveParameterVsFieldsConflicts( private static boolean needToCatchExceptions(JavaChangeInfo changeInfo, PsiMethod caller) { return changeInfo.isExceptionSetOrOrderChanged() - && !(changeInfo instanceof JavaChangeInfoImpl && ((JavaChangeInfoImpl)changeInfo).propagateExceptionsMethods.contains(caller)); + && !(changeInfo instanceof JavaChangeInfoImpl changInfoImpl && changInfoImpl.propagateExceptionsMethods.contains(caller)); } private static class ParameterList implements ChangeSignatureUtil.ChildrenGenerator { @@ -1037,10 +1036,11 @@ private ConflictSearcher(JavaChangeInfo changeInfo) { this.myChangeInfo = changeInfo; } - public MultiMap findConflicts(Ref refUsages) { - MultiMap conflictDescriptions = new MultiMap(); + @RequiredReadAction + public MultiMap findConflicts(SimpleReference refUsages) { + MultiMap conflictDescriptions = new MultiMap<>(); addMethodConflicts(conflictDescriptions); - Set usagesSet = new HashSet(Arrays.asList(refUsages.get())); + Set usagesSet = new HashSet<>(Arrays.asList(refUsages.get())); RenameUtil.removeConflictUsages(usagesSet); if (myChangeInfo.isVisibilityChanged()) { try { @@ -1052,13 +1052,13 @@ public MultiMap findConflicts(Ref refUsages) { } for (UsageInfo usageInfo : usagesSet) { - final PsiElement element = usageInfo.getElement(); - if (usageInfo instanceof OverriderUsageInfo) { - final PsiMethod method = (PsiMethod)element; - final PsiMethod baseMethod = ((OverriderUsageInfo)usageInfo).getBaseMethod(); - final int delta = baseMethod.getParameterList().getParametersCount() - method.getParameterList().getParametersCount(); + PsiElement element = usageInfo.getElement(); + if (usageInfo instanceof OverriderUsageInfo overriderUsageInfo) { + PsiMethod method = (PsiMethod)element; + PsiMethod baseMethod = overriderUsageInfo.getBaseMethod(); + int delta = baseMethod.getParameterList().getParametersCount() - method.getParameterList().getParametersCount(); if (delta > 0) { - final boolean[] toRemove = myChangeInfo.toRemoveParm(); + boolean[] toRemove = myChangeInfo.toRemoveParm(); if (toRemove[toRemove.length - 1]) { //todo check if implicit parameter is not the last one conflictDescriptions.putValue(baseMethod, "Implicit last parameter should not be deleted"); } @@ -1089,12 +1089,10 @@ private void addInaccessibilityDescriptions( UsageInfo usageInfo = iterator.next(); PsiElement element = usageInfo.getElement(); if (element != null) { - if (element instanceof PsiQualifiedReference) { - PsiClass accessObjectClass = null; - PsiElement qualifier = ((PsiQualifiedReference)element).getQualifier(); - if (qualifier instanceof PsiExpression) { - accessObjectClass = (PsiClass)PsiUtil.getAccessObjectClass((PsiExpression)qualifier).getElement(); - } + if (element instanceof PsiQualifiedReference qualifiedRef) { + PsiClass accessObjectClass = qualifiedRef.getQualifier() instanceof PsiExpression expression + ? (PsiClass)PsiUtil.getAccessObjectClass(expression).getElement() + : null; if (!JavaPsiFacade.getInstance(element.getProject()).getResolveHelper() .isAccessible(method, modifierList, element, accessObjectClass, null)) { @@ -1113,7 +1111,7 @@ private void addInaccessibilityDescriptions( } } - + @RequiredReadAction private void addMethodConflicts(MultiMap conflicts) { String newMethodName = myChangeInfo.getNewName(); if (!(myChangeInfo instanceof JavaChangeInfo)) { @@ -1121,13 +1119,13 @@ private void addMethodConflicts(MultiMap conflicts) { } try { PsiMethod prototype; - final PsiMethod method = myChangeInfo.getMethod(); + PsiMethod method = myChangeInfo.getMethod(); if (!JavaLanguage.INSTANCE.equals(method.getLanguage())) { return; } PsiManager manager = method.getManager(); PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); - final CanonicalTypes.Type returnType = myChangeInfo.getNewReturnType(); + CanonicalTypes.Type returnType = myChangeInfo.getNewReturnType(); if (returnType != null) { prototype = factory.createMethod(newMethodName, returnType.getType(method, manager)); } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractclass/ExtractClassProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractclass/ExtractClassProcessor.java index 488ac0619..0edbd24d0 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractclass/ExtractClassProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractclass/ExtractClassProcessor.java @@ -61,7 +61,7 @@ import consulo.util.collection.ContainerUtil; import consulo.util.collection.MultiMap; import consulo.util.lang.StringUtil; -import consulo.util.lang.ref.Ref; +import consulo.util.lang.ref.SimpleReference; import jakarta.annotation.Nonnull; import java.util.*; @@ -173,7 +173,7 @@ public PsiClass getCreatedClass() { @Override @RequiredUIAccess - protected boolean preprocessUsages(@Nonnull final Ref refUsages) { + protected boolean preprocessUsages(@Nonnull final SimpleReference refUsages) { final MultiMap conflicts = new MultiMap<>(); myExtractEnumProcessor.findEnumConstantConflicts(refUsages); if (!DestinationFolderComboBox.isAccessible( @@ -294,7 +294,7 @@ protected UsageViewDescriptor createUsageViewDescriptor(@Nonnull UsageInfo[] usa @Override @RequiredReadAction - protected void performRefactoring(UsageInfo[] usageInfos) { + protected void performRefactoring(@Nonnull UsageInfo[] usageInfos) { final PsiClass psiClass = buildClass(); if (psiClass == null) { return; @@ -332,7 +332,7 @@ public void visitReferenceExpression(PsiReferenceExpression expression) { final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject); PsiMethod[] constructors = psiClass.getConstructors(); if (constructors.length == 0) { - final PsiMethod constructor = (PsiMethod)elementFactory.createConstructor().setName(psiClass.getName()); + PsiMethod constructor = (PsiMethod)elementFactory.createConstructor().setName(psiClass.getName()); constructors = new PsiMethod[]{(PsiMethod)psiClass.add(constructor)}; } for (PsiMethod constructor : constructors) { @@ -344,7 +344,7 @@ public void visitReferenceExpression(PsiReferenceExpression expression) { } if (myGenerateAccessors) { - final NecessaryAccessorsVisitor visitor = checkNecessaryGettersSetters4SourceClass(); + NecessaryAccessorsVisitor visitor = checkNecessaryGettersSetters4SourceClass(); for (PsiField field : visitor.getFieldsNeedingGetter()) { sourceClass.add(PropertyUtil.generateGetterPrototype(field)); } @@ -363,7 +363,7 @@ public void visitReferenceExpression(PsiReferenceExpression expression) { } private NecessaryAccessorsVisitor checkNecessaryGettersSetters4SourceClass() { - final NecessaryAccessorsVisitor visitor = new NecessaryAccessorsVisitor() { + NecessaryAccessorsVisitor visitor = new NecessaryAccessorsVisitor() { @Override protected boolean hasGetterOrSetter(PsiMethod[] getters) { for (PsiMethod getter : getters) { @@ -392,7 +392,7 @@ protected boolean isProhibitedReference(PsiField field) { } private NecessaryAccessorsVisitor checkNecessaryGettersSetters4ExtractedClass() { - final NecessaryAccessorsVisitor visitor = new NecessaryAccessorsVisitor() { + NecessaryAccessorsVisitor visitor = new NecessaryAccessorsVisitor() { @Override protected boolean hasGetterOrSetter(PsiMethod[] getters) { for (PsiMethod getter : getters) { @@ -439,16 +439,16 @@ public void visitClass(@Nonnull PsiClass aClass) { @RequiredReadAction private void buildDelegate() { - final PsiManager manager = sourceClass.getManager(); - final PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); - final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(manager.getProject()); - final StringBuilder fieldBuffer = new StringBuilder(); - final String delegateVisibility = calculateDelegateVisibility(); + PsiManager manager = sourceClass.getManager(); + PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); + CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(manager.getProject()); + StringBuilder fieldBuffer = new StringBuilder(); + String delegateVisibility = calculateDelegateVisibility(); if (delegateVisibility.length() > 0) { fieldBuffer.append(delegateVisibility).append(' '); } fieldBuffer.append("final "); - final String fullyQualifiedName = StringUtil.getQualifiedName(newPackageName, newClassName); + String fullyQualifiedName = StringUtil.getQualifiedName(newPackageName, newClassName); fieldBuffer.append(fullyQualifiedName); if (!typeParams.isEmpty()) { fieldBuffer.append('<'); @@ -474,9 +474,9 @@ private void buildDelegate() { fieldBuffer.append(");"); try { - final String fieldString = fieldBuffer.toString(); - final PsiField field = factory.createFieldFromText(fieldString, sourceClass); - final PsiElement newField = sourceClass.add(field); + String fieldString = fieldBuffer.toString(); + PsiField field = factory.createFieldFromText(fieldString, sourceClass); + PsiElement newField = sourceClass.add(field); codeStyleManager.reformat(JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(newField)); } catch (IncorrectOperationException e) { @@ -516,7 +516,7 @@ public void findUsages(@Nonnull List usages) { usages.add(new RemoveInnerClass(innerClass)); } for (PsiMethod method : methods) { - if (method.hasModifierProperty(PsiModifier.STATIC)) { + if (method.isStatic()) { findUsagesForStaticMethod(method, usages); } else { @@ -527,19 +527,19 @@ public void findUsages(@Nonnull List usages) { @RequiredReadAction private void findUsagesForInnerClass(PsiClass innerClass, List usages) { - final PsiManager psiManager = innerClass.getManager(); - final Project project = psiManager.getProject(); - final GlobalSearchScope scope = GlobalSearchScope.allScope(project); - final Iterable calls = ReferencesSearch.search(innerClass, scope); - final String innerName = innerClass.getQualifiedName(); + PsiManager psiManager = innerClass.getManager(); + Project project = psiManager.getProject(); + GlobalSearchScope scope = GlobalSearchScope.allScope(project); + Iterable calls = ReferencesSearch.search(innerClass, scope); + String innerName = innerClass.getQualifiedName(); assert innerName != null; - final String sourceClassQualifiedName = sourceClass.getQualifiedName(); + String sourceClassQualifiedName = sourceClass.getQualifiedName(); assert sourceClassQualifiedName != null; - final String newInnerClassName = + String newInnerClassName = StringUtil.getQualifiedName(newPackageName, newClassName) + innerName.substring(sourceClassQualifiedName.length()); boolean hasExternalReference = false; for (PsiReference reference : calls) { - final PsiElement referenceElement = reference.getElement(); + PsiElement referenceElement = reference.getElement(); if (referenceElement instanceof PsiJavaCodeReferenceElement javaCodeReferenceElement) { if (!isInMovedElement(referenceElement)) { usages.add(new ReplaceClassReference(javaCodeReferenceElement, newInnerClassName)); @@ -554,17 +554,17 @@ private void findUsagesForInnerClass(PsiClass innerClass, List @RequiredReadAction private void findUsagesForMethod(PsiMethod method, List usages) { - final PsiManager psiManager = method.getManager(); - final Project project = psiManager.getProject(); - final GlobalSearchScope scope = GlobalSearchScope.allScope(project); - final Iterable calls = ReferencesSearch.search(method, scope); + PsiManager psiManager = method.getManager(); + Project project = psiManager.getProject(); + GlobalSearchScope scope = GlobalSearchScope.allScope(project); + Iterable calls = ReferencesSearch.search(method, scope); for (PsiReference reference : calls) { if (reference.getElement().getParent() instanceof PsiMethodCallExpression call) { if (isInMovedElement(call)) { continue; } - final PsiReferenceExpression methodExpression = call.getMethodExpression(); - final PsiExpression qualifier = methodExpression.getQualifierExpression(); + PsiReferenceExpression methodExpression = call.getMethodExpression(); + PsiExpression qualifier = methodExpression.getQualifierExpression(); if (qualifier == null || qualifier instanceof PsiThisExpression) { usages.add(new ReplaceThisCallWithDelegateCall(call, delegateFieldName)); } @@ -586,22 +586,22 @@ private void findUsagesForMethod(PsiMethod method, List usages @RequiredReadAction private void findUsagesForStaticMethod(PsiMethod method, List usages) { - final PsiManager psiManager = method.getManager(); - final Project project = psiManager.getProject(); - final GlobalSearchScope scope = GlobalSearchScope.allScope(project); - final Iterable calls = ReferencesSearch.search(method, scope); - final String fullyQualifiedName = StringUtil.getQualifiedName(newPackageName, newClassName); + PsiManager psiManager = method.getManager(); + Project project = psiManager.getProject(); + GlobalSearchScope scope = GlobalSearchScope.allScope(project); + Iterable calls = ReferencesSearch.search(method, scope); + String fullyQualifiedName = StringUtil.getQualifiedName(newPackageName, newClassName); for (PsiReference reference : calls) { - final PsiElement referenceElement = reference.getElement(); + PsiElement referenceElement = reference.getElement(); - final PsiElement parent = referenceElement.getParent(); + PsiElement parent = referenceElement.getParent(); if (parent instanceof PsiMethodCallExpression call) { if (!isInMovedElement(call)) { usages.add(new RetargetStaticMethodCall(call, fullyQualifiedName)); } } else if (parent instanceof PsiImportStaticStatement psiImportStatic) { - final PsiJavaCodeReferenceElement importReference = psiImportStatic.getImportReference(); + PsiJavaCodeReferenceElement importReference = psiImportStatic.getImportReference(); if (importReference != null && importReference.getQualifier() instanceof PsiJavaCodeReferenceElement qualifier) { usages.add(new ReplaceClassReference(qualifier, fullyQualifiedName)); } @@ -626,17 +626,17 @@ private boolean isInMovedElement(PsiElement exp) { @RequiredReadAction private void findUsagesForField(PsiField field, List usages) { - final PsiManager psiManager = field.getManager(); - final Project project = psiManager.getProject(); - final GlobalSearchScope scope = GlobalSearchScope.allScope(project); + PsiManager psiManager = field.getManager(); + Project project = psiManager.getProject(); + GlobalSearchScope scope = GlobalSearchScope.allScope(project); - final String qualifiedName = StringUtil.getQualifiedName(newPackageName, newClassName); + String qualifiedName = StringUtil.getQualifiedName(newPackageName, newClassName); String getter = null; if (myGenerateAccessors) { getter = PropertyUtil.suggestGetterName(field); } else { - final PsiMethod fieldGetter = PropertyUtil.findPropertyGetter(sourceClass, field.getName(), false, false); + PsiMethod fieldGetter = PropertyUtil.findPropertyGetter(sourceClass, field.getName(), false, false); if (fieldGetter != null && isInMovedElement(fieldGetter)) { getter = fieldGetter.getName(); } @@ -647,15 +647,15 @@ private void findUsagesForField(PsiField field, List usages) { setter = PropertyUtil.suggestSetterName(field); } else { - final PsiMethod fieldSetter = PropertyUtil.findPropertySetter(sourceClass, field.getName(), false, false); + PsiMethod fieldSetter = PropertyUtil.findPropertySetter(sourceClass, field.getName(), false, false); if (fieldSetter != null && isInMovedElement(fieldSetter)) { setter = fieldSetter.getName(); } } - final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC); + boolean isStatic = field.isStatic(); for (PsiReference reference : ReferencesSearch.search(field, scope)) { - final PsiElement element = reference.getElement(); + PsiElement element = reference.getElement(); if (isInMovedElement(element)) { continue; } @@ -701,9 +701,9 @@ else if (element instanceof PsiDocTagValue) { @RequiredReadAction private PsiClass buildClass() { - final PsiManager manager = sourceClass.getManager(); - final Project project = sourceClass.getProject(); - final ExtractedClassBuilder extractedClassBuilder = new ExtractedClassBuilder(); + PsiManager manager = sourceClass.getManager(); + Project project = sourceClass.getProject(); + ExtractedClassBuilder extractedClassBuilder = new ExtractedClassBuilder(); extractedClassBuilder.setProject(myProject); extractedClassBuilder.setClassName(newClassName); extractedClassBuilder.setPackageName(newPackageName); @@ -720,36 +720,36 @@ private PsiClass buildClass() { extractedClassBuilder.addInnerClass(innerClass, innerClassesToMakePublic.contains(innerClass)); } extractedClassBuilder.setTypeArguments(typeParams); - final List interfaces = calculateInterfacesSupported(); + List interfaces = calculateInterfacesSupported(); extractedClassBuilder.setInterfaces(interfaces); if (myGenerateAccessors) { - final NecessaryAccessorsVisitor visitor = checkNecessaryGettersSetters4ExtractedClass(); + NecessaryAccessorsVisitor visitor = checkNecessaryGettersSetters4ExtractedClass(); sourceClass.accept(visitor); extractedClassBuilder.setFieldsNeedingGetters(visitor.getFieldsNeedingGetter()); extractedClassBuilder.setFieldsNeedingSetters(visitor.getFieldsNeedingSetter()); } - final String classString = extractedClassBuilder.buildBeanClass(); + String classString = extractedClassBuilder.buildBeanClass(); try { - final PsiFile containingFile = sourceClass.getContainingFile(); - final PsiDirectory directory; - final PsiDirectory containingDirectory = containingFile.getContainingDirectory(); + PsiFile containingFile = sourceClass.getContainingFile(); + PsiDirectory directory; + PsiDirectory containingDirectory = containingFile.getContainingDirectory(); if (myMoveDestination != null) { directory = myMoveDestination.getTargetDirectory(containingDirectory); } else { - final Module module = ModuleUtil.findModuleForPsiElement(containingFile); + Module module = ModuleUtil.findModuleForPsiElement(containingFile); assert module != null; directory = PackageUtil.findOrCreateDirectoryForPackage(module, newPackageName, containingDirectory, false, true); } if (directory != null) { - final PsiFileFactory factory = PsiFileFactory.getInstance(project); - final PsiFile newFile = factory.createFileFromText(newClassName + ".java", JavaFileType.INSTANCE, classString); - final PsiElement addedFile = directory.add(newFile); - final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(manager.getProject()); - final PsiElement shortenedFile = JavaCodeStyleManager.getInstance(project).shortenClassReferences(addedFile); + PsiFileFactory factory = PsiFileFactory.getInstance(project); + PsiFile newFile = factory.createFileFromText(newClassName + ".java", JavaFileType.INSTANCE, classString); + PsiElement addedFile = directory.add(newFile); + CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(manager.getProject()); + PsiElement shortenedFile = JavaCodeStyleManager.getInstance(project).shortenClassReferences(addedFile); return ((PsiJavaFile)codeStyleManager.reformat(shortenedFile)).getClasses()[0]; } else { @@ -762,13 +762,13 @@ private PsiClass buildClass() { } private List calculateInterfacesSupported() { - final List out = new ArrayList<>(); - final PsiClass[] supers = sourceClass.getSupers(); + List out = new ArrayList<>(); + PsiClass[] supers = sourceClass.getSupers(); for (PsiClass superClass : supers) { if (!superClass.isInterface()) { continue; } - final PsiMethod[] superclassMethods = superClass.getMethods(); + PsiMethod[] superclassMethods = superClass.getMethods(); if (superclassMethods.length == 0) { continue; } @@ -791,22 +791,22 @@ private List calculateInterfacesSupported() { out.add(superClass); } } - final Project project = sourceClass.getProject(); - final PsiManager manager = sourceClass.getManager(); - final GlobalSearchScope scope = GlobalSearchScope.allScope(project); + Project project = sourceClass.getProject(); + PsiManager manager = sourceClass.getManager(); + GlobalSearchScope scope = GlobalSearchScope.allScope(project); if (usesDefaultSerialization(sourceClass)) { - final PsiClass serializable = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.io.Serializable", scope); + PsiClass serializable = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.io.Serializable", scope); out.add(serializable); } if (usesDefaultClone(sourceClass)) { - final PsiClass cloneable = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.lang.Cloneable", scope); + PsiClass cloneable = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.lang.Cloneable", scope); out.add(cloneable); } return out; } private static boolean isSuperMethod(PsiMethod method, PsiMethod movedMethod) { - final PsiMethod[] superMethods = movedMethod.findSuperMethods(); + PsiMethod[] superMethods = movedMethod.findSuperMethods(); for (PsiMethod testMethod : superMethods) { if (testMethod.equals(method)) { return true; @@ -816,17 +816,17 @@ private static boolean isSuperMethod(PsiMethod method, PsiMethod movedMethod) { } private static boolean usesDefaultClone(PsiClass aClass) { - final Project project = aClass.getProject(); - final PsiManager manager = aClass.getManager(); - final GlobalSearchScope scope = GlobalSearchScope.allScope(project); - final PsiClass cloneable = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.lang.Cloneable", scope); + Project project = aClass.getProject(); + PsiManager manager = aClass.getManager(); + GlobalSearchScope scope = GlobalSearchScope.allScope(project); + PsiClass cloneable = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.lang.Cloneable", scope); if (!InheritanceUtil.isInheritorOrSelf(aClass, cloneable, true)) { return false; } - final PsiMethod[] methods = aClass.findMethodsByName("clone", false); + PsiMethod[] methods = aClass.findMethodsByName("clone", false); for (PsiMethod method : methods) { - final PsiParameterList parameterList = method.getParameterList(); - final PsiParameter[] parameters = parameterList.getParameters(); + PsiParameterList parameterList = method.getParameterList(); + PsiParameter[] parameters = parameterList.getParameters(); if (parameters.length == 0) { return false; } @@ -835,20 +835,20 @@ private static boolean usesDefaultClone(PsiClass aClass) { } private static boolean usesDefaultSerialization(PsiClass aClass) { - final Project project = aClass.getProject(); - final PsiManager manager = aClass.getManager(); - final GlobalSearchScope scope = GlobalSearchScope.allScope(project); - final PsiClass serializable = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.io.Serializable", scope); + Project project = aClass.getProject(); + PsiManager manager = aClass.getManager(); + GlobalSearchScope scope = GlobalSearchScope.allScope(project); + PsiClass serializable = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.io.Serializable", scope); if (!InheritanceUtil.isInheritorOrSelf(aClass, serializable, true)) { return false; } - final PsiMethod[] methods = aClass.findMethodsByName("writeObject", false); + PsiMethod[] methods = aClass.findMethodsByName("writeObject", false); for (PsiMethod method : methods) { - final PsiParameterList parameterList = method.getParameterList(); - final PsiParameter[] parameters = parameterList.getParameters(); + PsiParameterList parameterList = method.getParameterList(); + PsiParameter[] parameters = parameterList.getParameters(); if (parameters.length == 1) { - final PsiType type = parameters[0].getType(); - final String text = type.getCanonicalText(); + PsiType type = parameters[0].getType(); + String text = type.getCanonicalText(); if ("java.io.DataOutputStream".equals(text)) { return false; } @@ -866,7 +866,7 @@ private abstract class NecessaryAccessorsVisitor extends JavaRecursiveElementWal public void visitReferenceExpression(PsiReferenceExpression expression) { super.visitReferenceExpression(expression); if (isProhibitedReference(expression)) { - final PsiField field = getReferencedField(expression); + PsiField field = getReferencedField(expression); if (!hasGetter(field) && !(field.isStatic() && field.isFinal()) && !field.isPublic()) { fieldsNeedingGetter.add(field); } @@ -878,9 +878,9 @@ public void visitReferenceExpression(PsiReferenceExpression expression) { public void visitAssignmentExpression(@Nonnull PsiAssignmentExpression expression) { super.visitAssignmentExpression(expression); - final PsiExpression lhs = expression.getLExpression(); + PsiExpression lhs = expression.getLExpression(); if (isProhibitedReference(lhs)) { - final PsiField field = getReferencedField(lhs); + PsiField field = getReferencedField(lhs); if (!hasGetter(field) && !(field.isStatic() && field.isFinal()) && !field.isPublic()) { fieldsNeedingSetter.add(field); } @@ -902,13 +902,13 @@ public void visitPrefixExpression(@Nonnull PsiPrefixExpression expression) { } @RequiredReadAction - private void checkSetterNeeded(final PsiExpression operand, final PsiJavaToken sign) { - final IElementType tokenType = sign.getTokenType(); + private void checkSetterNeeded(PsiExpression operand, PsiJavaToken sign) { + IElementType tokenType = sign.getTokenType(); if (!tokenType.equals(JavaTokenType.PLUSPLUS) && !tokenType.equals(JavaTokenType.MINUSMINUS)) { return; } if (isProhibitedReference(operand)) { - final PsiField field = getReferencedField(operand); + PsiField field = getReferencedField(operand); if (!hasSetter(field) && !(field.isStatic() && field.isFinal())) { fieldsNeedingSetter.add(field); } @@ -923,15 +923,15 @@ public Set getFieldsNeedingSetter() { return fieldsNeedingSetter; } - private boolean hasGetter(final PsiField field) { + private boolean hasGetter(PsiField field) { return hasGetterOrSetter(sourceClass.findMethodsBySignature(PropertyUtil.generateGetterPrototype(field), false)); } - private boolean hasSetter(final PsiField field) { + private boolean hasSetter(PsiField field) { return hasGetterOrSetter(sourceClass.findMethodsBySignature(PropertyUtil.generateSetterPrototype(field), false)); } - protected abstract boolean hasGetterOrSetter(final PsiMethod[] getters); + protected abstract boolean hasGetterOrSetter(PsiMethod[] getters); protected boolean isProhibitedReference(PsiExpression expression) { return BackpointerUtil.isBackpointerReference(expression, NecessaryAccessorsVisitor.this::isProhibitedReference); diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractclass/ExtractEnumProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractclass/ExtractEnumProcessor.java index 6cca85cf2..552faf9ed 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/extractclass/ExtractEnumProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/extractclass/ExtractEnumProcessor.java @@ -4,32 +4,28 @@ package com.intellij.java.impl.refactoring.extractclass; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - import com.intellij.java.impl.codeInsight.generation.GenerateMembersUtil; -import com.intellij.java.language.psi.*; -import consulo.project.Project; -import consulo.util.lang.ref.Ref; -import consulo.util.lang.StringUtil; -import consulo.language.psi.*; -import consulo.language.psi.scope.GlobalSearchScope; -import consulo.language.psi.util.PsiTreeUtil; -import consulo.language.psi.PsiUtilCore; import com.intellij.java.impl.refactoring.extractclass.usageInfo.ReplaceStaticVariableAccess; import com.intellij.java.impl.refactoring.psi.MutationUtils; import com.intellij.java.impl.refactoring.typeMigration.TypeMigrationProcessor; import com.intellij.java.impl.refactoring.typeMigration.TypeMigrationRules; import com.intellij.java.impl.refactoring.util.EnumConstantsUtil; import com.intellij.java.impl.refactoring.util.FixableUsageInfo; +import com.intellij.java.language.psi.*; +import consulo.annotation.access.RequiredReadAction; import consulo.language.editor.refactoring.ui.RefactoringUIUtil; +import consulo.language.psi.PsiElement; +import consulo.language.psi.PsiUtilCore; +import consulo.language.psi.scope.GlobalSearchScope; +import consulo.language.psi.util.PsiTreeUtil; +import consulo.language.util.IncorrectOperationException; +import consulo.project.Project; import consulo.usage.UsageInfo; +import consulo.util.lang.StringUtil; import consulo.util.lang.function.Functions; -import consulo.language.util.IncorrectOperationException; +import consulo.util.lang.ref.SimpleReference; + +import java.util.*; public class ExtractEnumProcessor { private final Project myProject; @@ -44,17 +40,18 @@ public ExtractEnumProcessor(Project project, List enumConstants, PsiCl myClass = aClass; } - public void findEnumConstantConflicts(final Ref refUsages) { + @RequiredReadAction + public void findEnumConstantConflicts(SimpleReference refUsages) { if (hasUsages2Migrate()) { - final List resolvableConflicts = new ArrayList<>(); + List resolvableConflicts = new ArrayList<>(); for (UsageInfo failedUsage : myTypeMigrationProcessor.getLabeler().getFailedUsages()) { - final PsiElement element = failedUsage.getElement(); + PsiElement element = failedUsage.getElement(); if (element instanceof PsiReferenceExpression) { resolvableConflicts.add(new FixableUsageInfo(element) { @Override public void fixUsage() throws IncorrectOperationException { - final PsiReferenceExpression expression = (PsiReferenceExpression)element; - final String link = GenerateMembersUtil.suggestGetterName("value", expression.getType(), myProject) + "()"; + PsiReferenceExpression expression = (PsiReferenceExpression)element; + String link = GenerateMembersUtil.suggestGetterName("value", expression.getType(), myProject) + "()"; MutationUtils.replaceExpression(expression.getReferenceName() + "." + link, expression); } }); @@ -64,9 +61,9 @@ else if (element != null) { } } if (!resolvableConflicts.isEmpty()) { - final List usageInfos = new ArrayList<>(Arrays.asList(refUsages.get())); + List usageInfos = new ArrayList<>(Arrays.asList(refUsages.get())); for (Iterator iterator = resolvableConflicts.iterator(); iterator.hasNext(); ) { - final UsageInfo conflict = iterator.next(); + UsageInfo conflict = iterator.next(); for (UsageInfo usageInfo : usageInfos) { if (conflict.getElement() == usageInfo.getElement()) { iterator.remove(); @@ -84,33 +81,34 @@ private boolean hasUsages2Migrate() { return myTypeMigrationProcessor != null; } + @RequiredReadAction public List findEnumConstantUsages(List fieldUsages) { - final List result = new ArrayList<>(); + List result = new ArrayList<>(); if (!myEnumConstants.isEmpty()) { - final Set switchStatements = new HashSet<>(); + Set switchStatements = new HashSet<>(); for (UsageInfo usage : fieldUsages) { if (usage instanceof ReplaceStaticVariableAccess) { - final PsiElement element = usage.getElement(); - final PsiSwitchStatement switchStatement = PsiTreeUtil.getParentOfType(element, PsiSwitchStatement.class); + PsiElement element = usage.getElement(); + PsiSwitchStatement switchStatement = PsiTreeUtil.getParentOfType(element, PsiSwitchStatement.class); if (switchStatement != null) { switchStatements.add(switchStatement); } } } - final PsiConstantEvaluationHelper evaluationHelper = JavaPsiFacade.getInstance(myProject).getConstantEvaluationHelper(); - final Set enumValues = new HashSet<>(); + PsiConstantEvaluationHelper evaluationHelper = JavaPsiFacade.getInstance(myProject).getConstantEvaluationHelper(); + Set enumValues = new HashSet<>(); for (PsiField enumConstant : myEnumConstants) { enumValues.add(evaluationHelper.computeConstantExpression(enumConstant.getInitializer())); } - final PsiType enumValueType = myEnumConstants.get(0).getType(); + PsiType enumValueType = myEnumConstants.get(0).getType(); for (PsiSwitchStatement switchStatement : switchStatements) { - final PsiStatement errStatement = EnumConstantsUtil.isEnumSwitch(switchStatement, enumValueType, enumValues); + PsiStatement errStatement = EnumConstantsUtil.isEnumSwitch(switchStatement, enumValueType, enumValues); if (errStatement != null) { String description = null; - if (errStatement instanceof PsiSwitchLabelStatement) { - final PsiExpression caseValue = ((PsiSwitchLabelStatement)errStatement).getCaseValue(); + if (errStatement instanceof PsiSwitchLabelStatement switchLabelStmt) { + PsiExpression caseValue = switchLabelStmt.getCaseValue(); if (caseValue != null) { description = caseValue.getText() + " can not be replaced with enum"; } @@ -118,16 +116,14 @@ public List findEnumConstantUsages(List fiel result.add(new ConflictUsageInfo(errStatement, description)); } else { - final PsiExpression expression = switchStatement.getExpression(); - if (expression instanceof PsiReferenceExpression) { - final PsiElement element = ((PsiReferenceExpression)expression).resolve(); - if (element != null) { - if (!element.getManager().isInProject(element)) { - result.add(new ConflictUsageInfo( - expression, - StringUtil.capitalize(RefactoringUIUtil.getDescription(element, false)) + " is out of project" - )); - } + PsiExpression expression = switchStatement.getExpression(); + if (expression instanceof PsiReferenceExpression refExpr) { + PsiElement element = refExpr.resolve(); + if (element != null && !element.getManager().isInProject(element)) { + result.add(new ConflictUsageInfo( + expression, + StringUtil.capitalize(RefactoringUIUtil.getDescription(element, false)) + " is out of project" + )); } } else { @@ -136,7 +132,7 @@ public List findEnumConstantUsages(List fiel } } - final TypeMigrationRules rules = new TypeMigrationRules(myProject); + TypeMigrationRules rules = new TypeMigrationRules(myProject); rules.addConversionDescriptor(new EnumTypeConversionRule(myEnumConstants)); rules.setBoundScope(GlobalSearchScope.projectScope(myProject)); myTypeMigrationProcessor = new TypeMigrationProcessor( @@ -147,11 +143,9 @@ public List findEnumConstantUsages(List fiel true ); for (UsageInfo usageInfo : myTypeMigrationProcessor.findUsages()) { - final PsiElement migrateElement = usageInfo.getElement(); - if (migrateElement instanceof PsiField) { - final PsiField enumConstantField = (PsiField)migrateElement; - if (enumConstantField.hasModifierProperty(PsiModifier.STATIC) - && enumConstantField.hasModifierProperty(PsiModifier.FINAL) + PsiElement migrateElement = usageInfo.getElement(); + if (migrateElement instanceof PsiField enumConstantField) { + if (enumConstantField.isStatic() && enumConstantField.isFinal() && enumConstantField.hasInitializer() && !myEnumConstants.contains(enumConstantField)) { continue; } @@ -164,10 +158,10 @@ public List findEnumConstantUsages(List fiel public void performEnumConstantTypeMigration(UsageInfo[] usageInfos) { if (hasUsages2Migrate()) { - final List migrationInfos = new ArrayList<>(); + List migrationInfos = new ArrayList<>(); for (UsageInfo usageInfo : usageInfos) { - if (usageInfo instanceof EnumTypeMigrationUsageInfo) { - migrationInfos.add(((EnumTypeMigrationUsageInfo)usageInfo).getUsageInfo()); + if (usageInfo instanceof EnumTypeMigrationUsageInfo enumTypeMigrationUsageInfo) { + migrationInfos.add(enumTypeMigrationUsageInfo.getUsageInfo()); } } myTypeMigrationProcessor.performRefactoring(migrationInfos.toArray(UsageInfo.EMPTY_ARRAY)); diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/inline/InlineConstantFieldProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/inline/InlineConstantFieldProcessor.java index 8975fe26c..554d7651d 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/inline/InlineConstantFieldProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/inline/InlineConstantFieldProcessor.java @@ -20,6 +20,7 @@ import com.intellij.java.language.impl.psi.impl.source.javadoc.PsiDocMethodOrFieldRef; import com.intellij.java.language.psi.*; import com.intellij.java.language.psi.util.PsiUtil; +import consulo.annotation.access.RequiredReadAction; import consulo.language.editor.refactoring.BaseRefactoringProcessor; import consulo.language.editor.refactoring.localize.RefactoringLocalize; import consulo.language.editor.refactoring.rename.NonCodeUsageInfoFactory; @@ -37,12 +38,13 @@ import consulo.localize.LocalizeValue; import consulo.logging.Logger; import consulo.project.Project; +import consulo.ui.annotation.RequiredUIAccess; import consulo.usage.NonCodeUsageInfo; import consulo.usage.UsageInfo; import consulo.usage.UsageInfoFactory; import consulo.usage.UsageViewDescriptor; import consulo.util.collection.MultiMap; -import consulo.util.lang.ref.Ref; +import consulo.util.lang.ref.SimpleReference; import jakarta.annotation.Nonnull; import java.util.*; @@ -109,14 +111,15 @@ private UsageFromJavaDoc(@Nonnull PsiElement element) { } } - @Override @Nonnull + @Override + @RequiredUIAccess protected UsageInfo[] findUsages() { if (myInlineThisOnly) { return new UsageInfo[]{new UsageInfo(myRefExpr)}; } - List usages = new ArrayList(); + List usages = new ArrayList<>(); for (PsiReference ref : ReferencesSearch.search(myField, GlobalSearchScope.projectScope(myProject), false)) { PsiElement element = ref.getElement(); UsageInfo info = new UsageInfo(element); @@ -166,6 +169,7 @@ protected void refreshElements(@Nonnull PsiElement[] elements) { } @Override + @RequiredUIAccess protected void performRefactoring(@Nonnull UsageInfo[] usages) { PsiExpression initializer = myField.getInitializer(); LOG.assertTrue(initializer != null); @@ -178,13 +182,13 @@ protected void performRefactoring(@Nonnull UsageInfo[] usages) { if (info instanceof NonCodeUsageInfo) { continue; } - final PsiElement element = info.getElement(); + PsiElement element = info.getElement(); if (element == null) { continue; } try { - if (element instanceof PsiExpression) { - inlineExpressionUsage((PsiExpression)element, initializer); + if (element instanceof PsiExpression expression) { + inlineExpressionUsage(expression, initializer); } else { PsiImportStaticStatement importStaticStatement = @@ -226,27 +230,23 @@ protected String getRefactoringId() } */ - private void inlineExpressionUsage( - PsiExpression expr, - PsiExpression initializer1 - ) throws IncorrectOperationException { + private void inlineExpressionUsage(PsiExpression expr, PsiExpression initializer1) throws IncorrectOperationException { if (myField.isWritable()) { myField.normalizeDeclaration(); } - if (expr instanceof PsiReferenceExpression) { - PsiExpression qExpression = ((PsiReferenceExpression)expr).getQualifierExpression(); + if (expr instanceof PsiReferenceExpression refExpr) { + PsiExpression qExpression = refExpr.getQualifierExpression(); if (qExpression != null) { - PsiReferenceExpression referenceExpression = null; - if (initializer1 instanceof PsiReferenceExpression) { - referenceExpression = (PsiReferenceExpression)initializer1; + PsiReferenceExpression initRefExpr = null; + if (initializer1 instanceof PsiReferenceExpression initRefExpr1) { + initRefExpr = initRefExpr1; } - else if (initializer1 instanceof PsiMethodCallExpression) { - referenceExpression = ((PsiMethodCallExpression)initializer1).getMethodExpression(); + else if (initializer1 instanceof PsiMethodCallExpression methodCall) { + initRefExpr = methodCall.getMethodExpression(); } - if (referenceExpression != null - && referenceExpression.getQualifierExpression() == null - && !(referenceExpression.advancedResolve(false).getCurrentFileResolveScope() instanceof PsiImportStaticStatement)) { - referenceExpression.setQualifierExpression(qExpression); + if (initRefExpr != null && initRefExpr.getQualifierExpression() == null + && !(initRefExpr.advancedResolve(false).getCurrentFileResolveScope() instanceof PsiImportStaticStatement)) { + initRefExpr.setQualifierExpression(qExpression); } } } @@ -258,11 +258,11 @@ private static PsiExpression normalize(PsiExpression expression) { if (expression instanceof PsiArrayInitializerExpression) { PsiElementFactory factory = JavaPsiFacade.getInstance(expression.getProject()).getElementFactory(); try { - final PsiType type = expression.getType(); + PsiType type = expression.getType(); if (type != null) { String typeString = type.getCanonicalText(); - PsiNewExpression result = (PsiNewExpression)factory.createExpressionFromText("new " + typeString - + "{}", expression); + PsiNewExpression result = + (PsiNewExpression)factory.createExpressionFromText("new " + typeString + "{}", expression); result.getArrayInitializer().replace(expression); return result; } @@ -276,15 +276,18 @@ private static PsiExpression normalize(PsiExpression expression) { return expression; } + @Nonnull @Override + @RequiredReadAction protected String getCommandName() { return RefactoringLocalize.inlineFieldCommand(DescriptiveNameUtil.getDescriptiveName(myField)).get(); } @Override - protected boolean preprocessUsages(@Nonnull Ref refUsages) { + @RequiredUIAccess + protected boolean preprocessUsages(@Nonnull SimpleReference refUsages) { UsageInfo[] usagesIn = refUsages.get(); - MultiMap conflicts = new MultiMap(); + MultiMap conflicts = new MultiMap<>(); ReferencedElementsCollector collector = new ReferencedElementsCollector(); PsiExpression initializer = myField.getInitializer(); @@ -317,7 +320,7 @@ protected boolean preprocessUsages(@Nonnull Ref refUsages) { if (!myInlineThisOnly) { for (UsageInfo info : usagesIn) { if (info instanceof UsageFromJavaDoc) { - final PsiElement element = info.getElement(); + PsiElement element = info.getElement(); if (element instanceof PsiDocMethodOrFieldRef && !PsiTreeUtil.isAncestor(myField, element, false)) { conflicts.putValue(element, "Inlined method is used in javadoc"); } @@ -329,8 +332,8 @@ protected boolean preprocessUsages(@Nonnull Ref refUsages) { } private static boolean isAccessedForWriting(PsiExpression expr) { - while (expr.getParent() instanceof PsiArrayAccessExpression) { - expr = (PsiExpression)expr.getParent(); + while (expr.getParent() instanceof PsiArrayAccessExpression arrayAccess) { + expr = arrayAccess; } return PsiUtil.isAccessedForWriting(expr); @@ -338,7 +341,7 @@ private static boolean isAccessedForWriting(PsiExpression expr) { @Override @Nonnull - protected Collection getElementsToWrite(@Nonnull final UsageViewDescriptor descriptor) { + protected Collection getElementsToWrite(@Nonnull UsageViewDescriptor descriptor) { if (myInlineThisOnly) { return Collections.singletonList(myRefExpr); } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/inline/InlineParameterExpressionProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/inline/InlineParameterExpressionProcessor.java index c0851d7d9..4052e9e80 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/inline/InlineParameterExpressionProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/inline/InlineParameterExpressionProcessor.java @@ -22,6 +22,8 @@ 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.annotation.access.RequiredWriteAction; import consulo.language.editor.refactoring.BaseRefactoringProcessor; import consulo.language.editor.refactoring.ui.RefactoringUIUtil; import consulo.language.psi.PsiElement; @@ -30,13 +32,13 @@ import consulo.language.psi.search.ReferencesSearch; import consulo.language.psi.util.PsiTreeUtil; import consulo.logging.Logger; +import consulo.ui.annotation.RequiredUIAccess; import consulo.usage.UsageInfo; import consulo.usage.UsageViewDescriptor; import consulo.usage.UsageViewUtil; import consulo.util.collection.MultiMap; import consulo.util.dataholder.Key; -import consulo.util.lang.ref.Ref; - +import consulo.util.lang.ref.SimpleReference; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; @@ -58,10 +60,10 @@ public class InlineParameterExpressionProcessor extends BaseRefactoringProcessor private final boolean myCreateLocal; public InlineParameterExpressionProcessor( - final PsiCallExpression methodCall, - final PsiMethod method, - final PsiParameter parameter, - final PsiExpression initializer, + PsiCallExpression methodCall, + PsiMethod method, + PsiParameter parameter, + PsiExpression initializer, boolean createLocal ) { super(method.getProject()); @@ -76,66 +78,62 @@ public InlineParameterExpressionProcessor( myCallingMethod = PsiTreeUtil.getParentOfType(myMethodCall, PsiMethod.class); } + @Nonnull @Override protected String getCommandName() { return InlineParameterHandler.REFACTORING_NAME; } - @Nonnull @Override - protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { + protected UsageViewDescriptor createUsageViewDescriptor(@Nonnull UsageInfo[] usages) { return new InlineViewDescriptor(myParameter); } @Nonnull @Override + @RequiredReadAction protected UsageInfo[] findUsages() { - int parameterIndex = myMethod.getParameterList().getParameterIndex(myParameter); - final Map localToParamRef = new HashMap(); - final PsiExpression[] arguments = myMethodCall.getArgumentList().getExpressions(); + Map localToParamRef = new HashMap<>(); + PsiExpression[] arguments = myMethodCall.getArgumentList().getExpressions(); for (int i = 0; i < arguments.length; i++) { - if (i != parameterIndex && arguments[i] instanceof PsiReferenceExpression) { - final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)arguments[i]; - final PsiElement element = referenceExpression.resolve(); + if (i != parameterIndex && arguments[i] instanceof PsiReferenceExpression refExpr) { + PsiElement element = refExpr.resolve(); if (element instanceof PsiLocalVariable || element instanceof PsiParameter) { - final PsiParameter param = myMethod.getParameterList().getParameters()[i]; - final PsiExpression paramRef = - JavaPsiFacade.getInstance(myMethod.getProject()) - .getElementFactory() - .createExpressionFromText(param.getName(), myMethod); + PsiParameter param = myMethod.getParameterList().getParameters()[i]; + PsiExpression paramRef = JavaPsiFacade.getInstance(myMethod.getProject()) + .getElementFactory() + .createExpressionFromText(param.getName(), myMethod); localToParamRef.put((PsiVariable)element, paramRef); } } } - final List result = new ArrayList(); + List result = new ArrayList<>(); myInitializer.accept(new JavaRecursiveElementVisitor() { + @RequiredWriteAction @Override - public void visitReferenceExpression(final PsiReferenceExpression expression) { + public void visitReferenceExpression(PsiReferenceExpression expression) { super.visitReferenceExpression(expression); - final PsiElement element = expression.resolve(); - if (element instanceof PsiLocalVariable) { - final PsiLocalVariable localVariable = (PsiLocalVariable)element; - final PsiElement[] elements = DefUseUtil.getDefs(myCallingMethod.getBody(), localVariable, expression); + if (expression.resolve() instanceof PsiLocalVariable localVariable) { + PsiElement[] elements = DefUseUtil.getDefs(myCallingMethod.getBody(), localVariable, expression); if (elements.length == 1) { PsiExpression localInitializer = null; - if (elements[0] instanceof PsiLocalVariable) { - localInitializer = ((PsiLocalVariable)elements[0]).getInitializer(); + if (elements[0] instanceof PsiLocalVariable localVar) { + localInitializer = localVar.getInitializer(); } - else if (elements[0] instanceof PsiAssignmentExpression) { - localInitializer = ((PsiAssignmentExpression)elements[0]).getRExpression(); + else if (elements[0] instanceof PsiAssignmentExpression assignment) { + localInitializer = assignment.getRExpression(); } - else if (elements[0] instanceof PsiReferenceExpression) { - final PsiReferenceExpression refElement = (PsiReferenceExpression)elements[0]; - final PsiElement parent = refElement.getParent(); - if (parent instanceof PsiAssignmentExpression && ((PsiAssignmentExpression)parent).getLExpression() == refElement) { - localInitializer = ((PsiAssignmentExpression)parent).getRExpression(); + else if (elements[0] instanceof PsiReferenceExpression refElement) { + if (refElement.getParent() instanceof PsiAssignmentExpression assignment + && assignment.getLExpression() == refElement) { + localInitializer = assignment.getRExpression(); } } if (localInitializer != null) { - final PsiElement replacement; + PsiElement replacement; if (localToParamRef.containsKey(localVariable)) { replacement = localToParamRef.get(localVariable); } @@ -155,20 +153,20 @@ else if (elements[0] instanceof PsiReferenceExpression) { } } - final UsageInfo[] usageInfos = result.toArray(new UsageInfo[result.size()]); + UsageInfo[] usageInfos = result.toArray(new UsageInfo[result.size()]); return UsageViewUtil.removeDuplicatedUsages(usageInfos); } - private static PsiElement replaceArgs(final Map elementsToReplace, PsiElement expression) { - final Map replacements = new HashMap(); + @RequiredWriteAction + private static PsiElement replaceArgs(Map elementsToReplace, PsiElement expression) { + Map replacements = new HashMap<>(); expression.accept(new JavaRecursiveElementVisitor() { @Override + @RequiredReadAction public void visitReferenceExpression(PsiReferenceExpression referenceExpression) { super.visitReferenceExpression(referenceExpression); - final PsiElement resolved = referenceExpression.resolve(); - if (resolved instanceof PsiVariable) { - final PsiVariable variable = (PsiVariable)resolved; - final PsiElement replacement = elementsToReplace.get(variable); + if (referenceExpression.resolve() instanceof PsiVariable variable) { + PsiElement replacement = elementsToReplace.get(variable); if (replacement != null) { replacements.put(referenceExpression, replacement); } @@ -179,24 +177,25 @@ public void visitReferenceExpression(PsiReferenceExpression referenceExpression) } @Override - protected boolean preprocessUsages(Ref refUsages) { - final MultiMap conflicts = new MultiMap(); - final UsageInfo[] usages = refUsages.get(); - final InaccessibleExpressionsDetector detector = new InaccessibleExpressionsDetector(conflicts); + @RequiredUIAccess + protected boolean preprocessUsages(SimpleReference refUsages) { + MultiMap conflicts = new MultiMap<>(); + UsageInfo[] usages = refUsages.get(); + InaccessibleExpressionsDetector detector = new InaccessibleExpressionsDetector(conflicts); myInitializer.accept(detector); for (UsageInfo usage : usages) { - if (usage instanceof LocalReplacementUsageInfo) { - final PsiElement replacement = ((LocalReplacementUsageInfo)usage).getReplacement(); + if (usage instanceof LocalReplacementUsageInfo localReplacementUsageInfo) { + PsiElement replacement = localReplacementUsageInfo.getReplacement(); if (replacement != null) { replacement.accept(detector); } } } - final Set vars = new HashSet(); + Set vars = new HashSet<>(); for (UsageInfo usageInfo : usages) { - if (usageInfo instanceof LocalReplacementUsageInfo) { - final PsiVariable var = ((LocalReplacementUsageInfo)usageInfo).getVariable(); + if (usageInfo instanceof LocalReplacementUsageInfo localReplacementUsageInfo) { + PsiVariable var = localReplacementUsageInfo.getVariable(); if (var != null) { vars.add(var); } @@ -204,10 +203,9 @@ protected boolean preprocessUsages(Ref refUsages) { } for (PsiVariable var : vars) { for (PsiReference ref : ReferencesSearch.search(var)) { - final PsiElement element = ref.getElement(); - if (element instanceof PsiExpression && isAccessedForWriting((PsiExpression)element)) { + if (ref.getElement() instanceof PsiExpression expression && isAccessedForWriting(expression)) { conflicts.putValue( - element, + expression, "Parameter initializer depends on value which is not available inside method and cannot be inlined" ); break; @@ -218,23 +216,22 @@ protected boolean preprocessUsages(Ref refUsages) { } private static boolean isAccessedForWriting(PsiExpression expr) { - while (expr.getParent() instanceof PsiArrayAccessExpression) { - expr = (PsiExpression)expr.getParent(); + while (expr.getParent() instanceof PsiArrayAccessExpression arrayAccessExpr) { + expr = arrayAccessExpr; } return PsiUtil.isAccessedForWriting(expr); } @Override protected void performRefactoring(UsageInfo[] usages) { - final List thrownExceptions = ExceptionUtil.getThrownCheckedExceptions(new PsiElement[]{myInitializer}); - final Set varsUsedInInitializer = new HashSet(); - final Set paramRefsToInline = new HashSet(); - final Map replacements = new HashMap(); + List thrownExceptions = ExceptionUtil.getThrownCheckedExceptions(myInitializer); + Set varsUsedInInitializer = new HashSet<>(); + Set paramRefsToInline = new HashSet<>(); + Map replacements = new HashMap<>(); for (UsageInfo usage : usages) { - if (usage instanceof LocalReplacementUsageInfo) { - final LocalReplacementUsageInfo replacementUsageInfo = (LocalReplacementUsageInfo)usage; - final PsiElement element = replacementUsageInfo.getElement(); - final PsiElement replacement = replacementUsageInfo.getReplacement(); + if (usage instanceof LocalReplacementUsageInfo replacementUsageInfo) { + PsiElement element = replacementUsageInfo.getElement(); + PsiElement replacement = replacementUsageInfo.getReplacement(); if (element != null && replacement != null) { replacements.put(element, replacement); } @@ -248,20 +245,20 @@ protected void performRefactoring(UsageInfo[] usages) { myInitializer = (PsiExpression)RefactoringUtil.replaceElementsWithMap(myInitializer, replacements); if (myCreateLocal) { - final PsiElementFactory factory = JavaPsiFacade.getInstance(myMethod.getProject()).getElementFactory(); + PsiElementFactory factory = JavaPsiFacade.getInstance(myMethod.getProject()).getElementFactory(); PsiDeclarationStatement localDeclaration = factory.createVariableDeclarationStatement(myParameter.getName(), myParameter.getType(), myInitializer); - final PsiLocalVariable declaredVar = (PsiLocalVariable)localDeclaration.getDeclaredElements()[0]; + PsiLocalVariable declaredVar = (PsiLocalVariable)localDeclaration.getDeclaredElements()[0]; PsiUtil.setModifierProperty(declaredVar, PsiModifier.FINAL, myParameter.hasModifierProperty(PsiModifier.FINAL)); - final PsiExpression localVarInitializer = InlineUtil.inlineVariable( + PsiExpression localVarInitializer = InlineUtil.inlineVariable( myParameter, myInitializer, (PsiReferenceExpression)factory.createExpressionFromText(myParameter.getName(), myMethod) ); - final PsiExpression initializer = declaredVar.getInitializer(); + PsiExpression initializer = declaredVar.getInitializer(); LOG.assertTrue(initializer != null); initializer.replace(localVarInitializer); - final PsiCodeBlock body = myMethod.getBody(); + PsiCodeBlock body = myMethod.getBody(); if (body != null) { PsiElement anchor = findAnchorForLocalVariableDeclaration(body); body.addAfter(localDeclaration, anchor); @@ -298,14 +295,12 @@ protected void performRefactoring(UsageInfo[] usages) { private PsiElement findAnchorForLocalVariableDeclaration(PsiCodeBlock body) { PsiElement anchor = body.getLBrace(); if (myMethod.isConstructor()) { - final PsiStatement[] statements = body.getStatements(); - if (statements.length > 0 && statements[0] instanceof PsiExpressionStatement) { - final PsiExpression expression = ((PsiExpressionStatement)statements[0]).getExpression(); - if (expression instanceof PsiMethodCallExpression) { - final String referenceName = ((PsiMethodCallExpression)expression).getMethodExpression().getReferenceName(); - if (PsiKeyword.SUPER.equals(referenceName) || PsiKeyword.THIS.equals(referenceName)) { - anchor = statements[0]; - } + PsiStatement[] statements = body.getStatements(); + if (statements.length > 0 && statements[0] instanceof PsiExpressionStatement exprStmt + && exprStmt.getExpression() instanceof PsiMethodCallExpression methodCall) { + String referenceName = methodCall.getMethodExpression().getReferenceName(); + if (PsiKeyword.SUPER.equals(referenceName) || PsiKeyword.THIS.equals(referenceName)) { + anchor = exprStmt; } } } @@ -316,10 +311,10 @@ private static class LocalReplacementUsageInfo extends UsageInfo { private final PsiElement myReplacement; private final PsiVariable myVariable; + @RequiredReadAction public LocalReplacementUsageInfo(@Nonnull PsiReference element, @Nonnull PsiElement replacement) { super(element); - final PsiElement resolved = element.resolve(); - myVariable = resolved instanceof PsiVariable ? (PsiVariable)resolved : null; + myVariable = element.resolve() instanceof PsiVariable variable ? variable : null; myReplacement = replacement; } @@ -342,11 +337,12 @@ public InaccessibleExpressionsDetector(MultiMap conflicts) { } @Override - public void visitReferenceExpression(final PsiReferenceExpression expression) { + @RequiredReadAction + public void visitReferenceExpression(PsiReferenceExpression expression) { super.visitReferenceExpression(expression); - final PsiElement element = expression.resolve(); - if (element instanceof PsiMember && !((PsiModifierListOwner)element).hasModifierProperty(PsiModifier.STATIC)) { - if (myMethod.hasModifierProperty(PsiModifier.STATIC)) { + PsiElement element = expression.resolve(); + if (element instanceof PsiMember member && !member.isStatic()) { + if (myMethod.isStatic()) { myConflicts.putValue( expression, "Parameter initializer depends on " + RefactoringUIUtil.getDescription( @@ -370,9 +366,10 @@ else if (element instanceof PsiParameter) { } @Override - public void visitThisExpression(PsiThisExpression thisExpression) { + @RequiredReadAction + public void visitThisExpression(@Nonnull PsiThisExpression thisExpression) { super.visitThisExpression(thisExpression); - final PsiJavaCodeReferenceElement qualifier = thisExpression.getQualifier(); + PsiJavaCodeReferenceElement qualifier = thisExpression.getQualifier(); PsiElement containingClass; if (qualifier != null) { containingClass = qualifier.resolve(); @@ -380,7 +377,7 @@ public void visitThisExpression(PsiThisExpression thisExpression) { else { containingClass = PsiTreeUtil.getParentOfType(myMethodCall, PsiClass.class); } - final PsiClass methodContainingClass = myMethod.getContainingClass(); + PsiClass methodContainingClass = myMethod.getContainingClass(); LOG.assertTrue(methodContainingClass != null); if (!PsiTreeUtil.isAncestor(containingClass, methodContainingClass, false)) { myConflicts.putValue( @@ -388,7 +385,7 @@ public void visitThisExpression(PsiThisExpression thisExpression) { "Parameter initializer depends on this which is not available inside the method and cannot be inlined" ); } - else if (myMethod.hasModifierProperty(PsiModifier.STATIC)) { + else if (myMethod.isStatic()) { myConflicts.putValue( thisExpression, "Parameter initializer depends on this which is not available inside the static method" @@ -397,47 +394,42 @@ else if (myMethod.hasModifierProperty(PsiModifier.STATIC)) { } @Override - public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { + @RequiredReadAction + public void visitReferenceElement(@Nonnull PsiJavaCodeReferenceElement reference) { super.visitReferenceElement(reference); - if (myMethod.hasModifierProperty(PsiModifier.STATIC)) { - final PsiElement resolved = reference.resolve(); - if (resolved instanceof PsiClass && !((PsiClass)resolved).hasModifierProperty(PsiModifier.STATIC)) { - myConflicts.putValue( - reference, - "Parameter initializer depends on non static class which is not available inside static method" - ); - } + if (myMethod.isStatic() && reference.resolve() instanceof PsiClass psiClass && !psiClass.isStatic()) { + myConflicts.putValue( + reference, + "Parameter initializer depends on non static class which is not available inside static method" + ); } } @Override - public void visitNewExpression(PsiNewExpression expression) { + @RequiredReadAction + public void visitNewExpression(@Nonnull PsiNewExpression expression) { super.visitNewExpression(expression); - final PsiJavaCodeReferenceElement reference = expression.getClassOrAnonymousClassReference(); - if (reference != null) { - final PsiElement resolved = reference.resolve(); - if (resolved instanceof PsiClass) { - final PsiClass refClass = (PsiClass)resolved; - final String classUnavailableMessage = "Parameter initializer depends on " + - RefactoringUIUtil.getDescription(refClass, true) + - " which is not available inside method and cannot be inlined"; - if (!PsiUtil.isAccessible(refClass, myMethod, null)) { - myConflicts.putValue(expression, classUnavailableMessage); - } - else { - final PsiClass methodContainingClass = myMethod.getContainingClass(); - LOG.assertTrue(methodContainingClass != null); - if (!PsiTreeUtil.isAncestor(myMethod, refClass, false)) { - PsiElement parent = refClass; - while ((parent = parent.getParent()) instanceof PsiClass) { - if (!PsiUtil.isAccessible((PsiClass)parent, myMethod, null)) { - break; - } - } - if (!(parent instanceof PsiFile)) { - myConflicts.putValue(expression, classUnavailableMessage); + PsiJavaCodeReferenceElement reference = expression.getClassOrAnonymousClassReference(); + if (reference != null && reference.resolve() instanceof PsiClass refClass) { + String classUnavailableMessage = "Parameter initializer depends on " + + RefactoringUIUtil.getDescription(refClass, true) + + " which is not available inside method and cannot be inlined"; + if (!PsiUtil.isAccessible(refClass, myMethod, null)) { + myConflicts.putValue(expression, classUnavailableMessage); + } + else { + PsiClass methodContainingClass = myMethod.getContainingClass(); + LOG.assertTrue(methodContainingClass != null); + if (!PsiTreeUtil.isAncestor(myMethod, refClass, false)) { + PsiElement parent = refClass; + while ((parent = parent.getParent()) instanceof PsiClass psiClass) { + if (!PsiUtil.isAccessible(psiClass, myMethod, null)) { + break; } } + if (!(parent instanceof PsiFile)) { + myConflicts.putValue(expression, classUnavailableMessage); + } } } } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java index 4195113bc..75d2b1a7f 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java @@ -33,7 +33,6 @@ import com.intellij.java.language.psi.util.TypeConversionUtil; import consulo.annotation.access.RequiredReadAction; import consulo.ide.impl.idea.refactoring.util.DocCommentPolicy; -import consulo.ide.impl.idea.util.ArrayUtilRt; import consulo.language.editor.refactoring.util.CommonRefactoringUtil; import consulo.language.psi.PsiElement; import consulo.language.psi.PsiReference; @@ -45,8 +44,9 @@ import consulo.ui.annotation.RequiredUIAccess; import consulo.usage.UsageInfo; import consulo.usage.UsageViewDescriptor; +import consulo.util.collection.ArrayUtil; import consulo.util.collection.MultiMap; -import consulo.util.lang.ref.Ref; +import consulo.util.lang.ref.SimpleReference; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; @@ -68,18 +68,17 @@ public InlineSuperClassRefactoringProcessor( PsiClass currentInheritor, PsiClass superClass, int policy, - final PsiClass... targetClasses + PsiClass... targetClasses ) { super(project); myCurrentInheritor = currentInheritor; mySuperClass = superClass; myPolicy = policy; myTargetClasses = currentInheritor != null ? new PsiClass[]{currentInheritor} : targetClasses; - MemberInfoStorage memberInfoStorage = new MemberInfoStorage(mySuperClass, new MemberInfo.Filter() { - public boolean includeMember(PsiMember element) { - return !(element instanceof PsiClass) || PsiTreeUtil.isAncestor(mySuperClass, element, true); - } - }); + MemberInfoStorage memberInfoStorage = new MemberInfoStorage( + mySuperClass, + element -> !(element instanceof PsiClass psiClass && !PsiTreeUtil.isAncestor(mySuperClass, psiClass, true)) + ); List members = memberInfoStorage.getClassMemberInfos(mySuperClass); for (MemberInfo member : members) { member.setChecked(true); @@ -88,97 +87,79 @@ public boolean includeMember(PsiMember element) { } @Nonnull - protected UsageViewDescriptor createUsageViewDescriptor(final UsageInfo[] usages) { + @Override + protected UsageViewDescriptor createUsageViewDescriptor(@Nonnull UsageInfo[] usages) { return new InlineSuperClassUsageViewDescriptor(mySuperClass); } + @Override @RequiredReadAction - protected void findUsages(@Nonnull final List usages) { - final JavaPsiFacade facade = JavaPsiFacade.getInstance(myProject); - final PsiElementFactory elementFactory = facade.getElementFactory(); - final PsiResolveHelper resolveHelper = facade.getResolveHelper(); + protected void findUsages(@Nonnull List usages) { + JavaPsiFacade facade = JavaPsiFacade.getInstance(myProject); + PsiElementFactory elementFactory = facade.getElementFactory(); + PsiResolveHelper resolveHelper = facade.getResolveHelper(); ReferencesSearch.search(mySuperClass).forEach(reference -> { - final PsiElement element = reference.getElement(); - if (element instanceof PsiJavaCodeReferenceElement) { + PsiElement element = reference.getElement(); + if (element instanceof PsiJavaCodeReferenceElement codeRef) { if (myCurrentInheritor != null) { - final PsiElement parent = element.getParent(); - if (parent instanceof PsiReferenceList) { - final PsiElement pparent = parent.getParent(); - if (pparent instanceof PsiClass) { - final PsiClass inheritor = (PsiClass)pparent; - if (parent.equals(inheritor.getExtendsList()) || parent.equals(inheritor.getImplementsList())) { - if (myCurrentInheritor.equals(inheritor)) { - usages.add(new ReplaceExtendsListUsageInfo( - (PsiJavaCodeReferenceElement)element, - mySuperClass, - inheritor - )); - } - } - } + if (element.getParent() instanceof PsiReferenceList refList + && refList.getParent() instanceof PsiClass inheritor + && (refList.equals(inheritor.getExtendsList()) || refList.equals(inheritor.getImplementsList())) + && myCurrentInheritor.equals(inheritor)) { + usages.add(new ReplaceExtendsListUsageInfo(codeRef, mySuperClass, inheritor)); } return true; } - final PsiImportStaticStatement staticImportStatement = PsiTreeUtil.getParentOfType(element, PsiImportStaticStatement.class); + PsiImportStaticStatement staticImportStatement = PsiTreeUtil.getParentOfType(element, PsiImportStaticStatement.class); if (staticImportStatement != null) { usages.add(new ReplaceStaticImportUsageInfo(staticImportStatement, myTargetClasses)); } else { - final PsiImportStatement importStatement = PsiTreeUtil.getParentOfType(element, PsiImportStatement.class); + PsiImportStatement importStatement = PsiTreeUtil.getParentOfType(element, PsiImportStatement.class); if (importStatement != null) { usages.add(new RemoveImportUsageInfo(importStatement)); } + else if (element.getParent() instanceof PsiReferenceList refList) { + if (refList.getParent() instanceof PsiClass inheritor + && (refList.equals(inheritor.getExtendsList()) || refList.equals(inheritor.getImplementsList()))) { + usages.add(new ReplaceExtendsListUsageInfo( + (PsiJavaCodeReferenceElement)element, + mySuperClass, + inheritor + )); + } + } else { - final PsiElement parent = element.getParent(); - if (parent instanceof PsiReferenceList) { - final PsiElement pparent = parent.getParent(); - if (pparent instanceof PsiClass) { - final PsiClass inheritor = (PsiClass)pparent; - if (parent.equals(inheritor.getExtendsList()) || parent.equals(inheritor.getImplementsList())) { - usages.add(new ReplaceExtendsListUsageInfo( - (PsiJavaCodeReferenceElement)element, - mySuperClass, - inheritor - )); - } - } + PsiClass targetClass = myTargetClasses[0]; + PsiClassType targetClassType = elementFactory.createType( + targetClass, + TypeConversionUtil.getSuperClassSubstitutor(mySuperClass, targetClass, PsiSubstitutor.EMPTY) + ); + + if (element.getParent() instanceof PsiTypeElement typeElem) { + PsiType superClassType = typeElem.getType(); + PsiSubstitutor subst = getSuperClassSubstitutor(superClassType, targetClassType, resolveHelper, targetClass); + usages.add(new ReplaceWithSubtypeUsageInfo( + typeElem, + elementFactory.createType(targetClass, subst), + myTargetClasses + )); } - else { - final PsiClass targetClass = myTargetClasses[0]; - final PsiClassType targetClassType = elementFactory.createType( + else if (element.getParent() instanceof PsiNewExpression newExpr) { + PsiClassType newType = elementFactory.createType( targetClass, - TypeConversionUtil.getSuperClassSubstitutor(mySuperClass, targetClass, PsiSubstitutor.EMPTY) + getSuperClassSubstitutor( + newExpr.getType(), + targetClassType, + resolveHelper, + targetClass + ) ); - - if (parent instanceof PsiTypeElement) { - final PsiType superClassType = ((PsiTypeElement)parent).getType(); - PsiSubstitutor subst = - getSuperClassSubstitutor(superClassType, targetClassType, resolveHelper, targetClass); - usages.add(new ReplaceWithSubtypeUsageInfo( - ((PsiTypeElement)parent), - elementFactory.createType(targetClass, subst), - myTargetClasses - )); - } - else if (parent instanceof PsiNewExpression) { - final PsiClassType newType = elementFactory.createType( - targetClass, - getSuperClassSubstitutor( - ((PsiNewExpression)parent).getType(), - targetClassType, - resolveHelper, - targetClass - ) - ); - usages.add(new ReplaceConstructorUsageInfo(((PsiNewExpression)parent), newType, myTargetClasses)); - } - else if (parent instanceof PsiJavaCodeReferenceElement) { - usages.add(new ReplaceReferenceUsageInfo( - ((PsiJavaCodeReferenceElement)parent).getQualifier(), - myTargetClasses - )); - } + usages.add(new ReplaceConstructorUsageInfo(newExpr, newType, myTargetClasses)); + } + else if (element.getParent() instanceof PsiJavaCodeReferenceElement parentCodeRef) { + usages.add(new ReplaceReferenceUsageInfo(parentCodeRef.getQualifier(), myTargetClasses)); } } } @@ -187,43 +168,35 @@ else if (parent instanceof PsiJavaCodeReferenceElement) { }); for (PsiClass targetClass : myTargetClasses) { for (MemberInfo memberInfo : myMemberInfos) { - final PsiMember member = memberInfo.getMember(); + PsiMember member = memberInfo.getMember(); for (PsiReference reference : ReferencesSearch.search(member, member.getUseScope(), true)) { - final PsiElement element = reference.getElement(); - if (element instanceof PsiReferenceExpression && - ((PsiReferenceExpression)element).getQualifierExpression() instanceof PsiSuperExpression && - PsiTreeUtil.isAncestor(targetClass, element, false)) { - usages.add(new RemoveQualifierUsageInfo((PsiReferenceExpression)element)); + if (reference.getElement() instanceof PsiReferenceExpression refExpr + && refExpr.getQualifierExpression() instanceof PsiSuperExpression + && PsiTreeUtil.isAncestor(targetClass, refExpr, false)) { + usages.add(new RemoveQualifierUsageInfo(refExpr)); } } } - final PsiMethod[] superConstructors = mySuperClass.getConstructors(); + PsiMethod[] superConstructors = mySuperClass.getConstructors(); for (PsiMethod constructor : targetClass.getConstructors()) { - final PsiCodeBlock constrBody = constructor.getBody(); + PsiCodeBlock constrBody = constructor.getBody(); LOG.assertTrue(constrBody != null); - final PsiStatement[] statements = constrBody.getStatements(); - if (statements.length > 0) { - final PsiStatement firstConstrStatement = statements[0]; - if (firstConstrStatement instanceof PsiExpressionStatement) { - final PsiExpression expression = ((PsiExpressionStatement)firstConstrStatement).getExpression(); - if (expression instanceof PsiMethodCallExpression) { - final PsiReferenceExpression methodExpression = ((PsiMethodCallExpression)expression).getMethodExpression(); - if (methodExpression.getText().equals(PsiKeyword.SUPER)) { - final PsiMethod superConstructor = ((PsiMethodCallExpression)expression).resolveMethod(); - if (superConstructor != null && superConstructor.getBody() != null) { - usages.add(new InlineSuperCallUsageInfo((PsiMethodCallExpression)expression)); - continue; - } - } - } + PsiStatement[] statements = constrBody.getStatements(); + if (statements.length > 0 && statements[0] instanceof PsiExpressionStatement exprStmt + && exprStmt.getExpression() instanceof PsiMethodCallExpression methodCall + && methodCall.getMethodExpression().getText().equals(PsiKeyword.SUPER)) { + PsiMethod superConstructor = methodCall.resolveMethod(); + if (superConstructor != null && superConstructor.getBody() != null) { + usages.add(new InlineSuperCallUsageInfo(methodCall)); + continue; } } //insert implicit call to super for (PsiMethod superConstructor : superConstructors) { if (superConstructor.getParameterList().getParametersCount() == 0) { - final PsiExpression expression = + PsiExpression expression = JavaPsiFacade.getElementFactory(myProject).createExpressionFromText("super()", constructor); usages.add(new InlineSuperCallUsageInfo((PsiMethodCallExpression)expression, constrBody)); } @@ -243,32 +216,28 @@ else if (parent instanceof PsiJavaCodeReferenceElement) { } @Override - protected boolean preprocessUsages(final Ref refUsages) { - final MultiMap conflicts = new MultiMap<>(); - final PushDownConflicts pushDownConflicts = new PushDownConflicts(mySuperClass, myMemberInfos); + @RequiredUIAccess + protected boolean preprocessUsages(@Nonnull SimpleReference refUsages) { + MultiMap conflicts = new MultiMap<>(); + PushDownConflicts pushDownConflicts = new PushDownConflicts(mySuperClass, myMemberInfos); for (PsiClass targetClass : myTargetClasses) { for (MemberInfo info : myMemberInfos) { - final PsiMember member = info.getMember(); + PsiMember member = info.getMember(); pushDownConflicts.checkMemberPlacementInTargetClassConflict(targetClass, member); } //todo check accessibility conflicts } - final MultiMap conflictsMap = pushDownConflicts.getConflicts(); + MultiMap conflictsMap = pushDownConflicts.getConflicts(); for (PsiElement element : conflictsMap.keySet()) { conflicts.put(element, conflictsMap.get(element)); } if (myCurrentInheritor != null) { ReferencesSearch.search(myCurrentInheritor).forEach(reference -> { - final PsiElement element = reference.getElement(); - if (element != null) { - final PsiElement parent = element.getParent(); - if (parent instanceof PsiNewExpression) { - final PsiClass aClass = PsiUtil.resolveClassInType(getPlaceExpectedType(parent)); - if (aClass == mySuperClass) { - conflicts.putValue(parent, "Instance of target type is passed to a place where super class is expected."); - return false; - } - } + PsiElement element = reference.getElement(); + if (element != null && element.getParent() instanceof PsiNewExpression newExpr + && PsiUtil.resolveClassInType(getPlaceExpectedType(newExpr)) == mySuperClass) { + conflicts.putValue(newExpr, "Instance of target type is passed to a place where super class is expected."); + return false; } return true; }); @@ -281,15 +250,13 @@ protected boolean preprocessUsages(final Ref refUsages) { private static PsiType getPlaceExpectedType(PsiElement parent) { PsiType type = PsiTypesUtil.getExpectedTypeByParent(parent); if (type == null) { - final PsiElement arg = PsiUtil.skipParenthesizedExprUp(parent); - final PsiElement gParent = arg.getParent(); - if (gParent instanceof PsiExpressionList) { - int i = ArrayUtilRt.find(((PsiExpressionList)gParent).getExpressions(), arg); - final PsiElement pParent = gParent.getParent(); - if (pParent instanceof PsiCallExpression) { - final PsiMethod method = ((PsiCallExpression)pParent).resolveMethod(); + PsiElement arg = PsiUtil.skipParenthesizedExprUp(parent); + if (arg.getParent() instanceof PsiExpressionList exprList) { + int i = ArrayUtil.find(exprList.getExpressions(), arg); + if (exprList.getParent() instanceof PsiCallExpression callExpr) { + PsiMethod method = callExpr.resolveMethod(); if (method != null) { - final PsiParameter[] parameters = method.getParameterList().getParameters(); + PsiParameter[] parameters = method.getParameterList().getParameters(); if (i >= parameters.length) { if (method.isVarArgs()) { return ((PsiEllipsisType)parameters[parameters.length - 1].getType()).getComponentType(); @@ -305,10 +272,13 @@ private static PsiType getPlaceExpectedType(PsiElement parent) { return type; } - protected void performRefactoring(final UsageInfo[] usages) { + @Override + @RequiredUIAccess + protected void performRefactoring(@Nonnull UsageInfo[] usages) { new PushDownProcessor(mySuperClass.getProject(), myMemberInfos, mySuperClass, new DocCommentPolicy(myPolicy)) { //push down conflicts are already collected @Override + @RequiredUIAccess protected boolean showConflicts(@Nonnull MultiMap conflicts, UsageInfo[] usages) { return true; } @@ -355,19 +325,20 @@ protected void performRefactoring(@Nonnull UsageInfo[] pushDownUsages) { } private void replaceInnerTypeUsages() { - final JavaPsiFacade facade = JavaPsiFacade.getInstance(myProject); - final PsiElementFactory elementFactory = facade.getElementFactory(); - final PsiResolveHelper resolveHelper = facade.getResolveHelper(); - final Map replacementMap = new HashMap<>(); - for (final PsiClass targetClass : myTargetClasses) { - final PsiSubstitutor superClassSubstitutor = + JavaPsiFacade facade = JavaPsiFacade.getInstance(myProject); + PsiElementFactory elementFactory = facade.getElementFactory(); + PsiResolveHelper resolveHelper = facade.getResolveHelper(); + Map replacementMap = new HashMap<>(); + for (PsiClass targetClass : myTargetClasses) { + PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(mySuperClass, targetClass, PsiSubstitutor.EMPTY); - final PsiClassType targetClassType = elementFactory.createType(targetClass, superClassSubstitutor); + PsiClassType targetClassType = elementFactory.createType(targetClass, superClassSubstitutor); targetClass.accept(new JavaRecursiveElementWalkingVisitor() { @Override - public void visitTypeElement(@Nonnull final PsiTypeElement typeElement) { + @RequiredReadAction + public void visitTypeElement(@Nonnull PsiTypeElement typeElement) { super.visitTypeElement(typeElement); - final PsiType superClassType = typeElement.getType(); + PsiType superClassType = typeElement.getType(); if (PsiUtil.resolveClassInType(superClassType) == mySuperClass) { PsiSubstitutor subst = getSuperClassSubstitutor(superClassType, targetClassType, resolveHelper, targetClass); replacementMap.put( @@ -379,9 +350,9 @@ public void visitTypeElement(@Nonnull final PsiTypeElement typeElement) { @Override @RequiredReadAction - public void visitNewExpression(@Nonnull final PsiNewExpression expression) { + public void visitNewExpression(@Nonnull PsiNewExpression expression) { super.visitNewExpression(expression); - final PsiType superClassType = expression.getType(); + PsiType superClassType = expression.getType(); if (PsiUtil.resolveClassInType(superClassType) == mySuperClass) { PsiSubstitutor subst = getSuperClassSubstitutor(superClassType, targetClassType, resolveHelper, targetClass); try { @@ -403,7 +374,7 @@ public void visitNewExpression(@Nonnull final PsiNewExpression expression) { } try { for (Map.Entry elementEntry : replacementMap.entrySet()) { - final PsiElement element = elementEntry.getKey().getElement(); + PsiElement element = elementEntry.getKey().getElement(); if (element != null) { element.replace(elementEntry.getValue()); } @@ -416,9 +387,9 @@ public void visitNewExpression(@Nonnull final PsiNewExpression expression) { @RequiredReadAction private static PsiSubstitutor getSuperClassSubstitutor( - final PsiType superClassType, - final PsiClassType targetClassType, - final PsiResolveHelper resolveHelper, + PsiType superClassType, + PsiClassType targetClassType, + PsiResolveHelper resolveHelper, PsiClass targetClass ) { PsiSubstitutor subst = PsiSubstitutor.EMPTY; @@ -437,6 +408,8 @@ private static PsiSubstitutor getSuperClassSubstitutor( return subst; } + @Nonnull + @Override protected String getCommandName() { return InlineSuperClassRefactoringHandler.REFACTORING_NAME; } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java index e74ae1b15..441294e91 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java @@ -52,7 +52,7 @@ import consulo.util.collection.ArrayUtil; import consulo.util.collection.MultiMap; 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; @@ -86,8 +86,10 @@ public IntroduceParameterObjectProcessor( String packageName, MoveDestination moveDestination, PsiMethod method, - VariableData[] parameters, boolean keepMethodAsDelegate, final boolean useExistingClass, - final boolean createInnerClass, + VariableData[] parameters, + boolean keepMethodAsDelegate, + boolean useExistingClass, + boolean createInnerClass, String newVisibility, boolean generateAccessors ) { @@ -105,26 +107,26 @@ public IntroduceParameterObjectProcessor( for (VariableData parameter : parameters) { this.parameters.add(new ParameterChunk(parameter)); } - final PsiParameterList parameterList = method.getParameterList(); - final PsiParameter[] methodParams = parameterList.getParameters(); + PsiParameterList parameterList = method.getParameterList(); + PsiParameter[] methodParams = parameterList.getParameters(); paramsToMerge = new int[parameters.length]; for (int p = 0; p < parameters.length; p++) { VariableData parameter = parameters[p]; for (int i = 0; i < methodParams.length; i++) { - final PsiParameter methodParam = methodParams[i]; + PsiParameter methodParam = methodParams[i]; if (parameter.variable.equals(methodParam)) { paramsToMerge[p] = i; break; } } } - final Set typeParamSet = new HashSet<>(); - final PsiTypeVisitor typeParametersVisitor = new PsiTypeVisitor<>() { + Set typeParamSet = new HashSet<>(); + PsiTypeVisitor typeParametersVisitor = new PsiTypeVisitor<>() { @Override public Object visitClassType(PsiClassType classType) { - final PsiClass referent = classType.resolve(); - if (referent instanceof PsiTypeParameter) { - typeParamSet.add((PsiTypeParameter)referent); + PsiClass referent = classType.resolve(); + if (referent instanceof PsiTypeParameter typeParameter) { + typeParamSet.add(typeParameter); } return super.visitClassType(classType); } @@ -134,8 +136,8 @@ public Object visitClassType(PsiClassType classType) { } typeParams = new ArrayList<>(typeParamSet); - final String qualifiedName = StringUtil.getQualifiedName(packageName, className); - final GlobalSearchScope scope = GlobalSearchScope.allScope(myProject); + String qualifiedName = StringUtil.getQualifiedName(packageName, className); + GlobalSearchScope scope = GlobalSearchScope.allScope(myProject); existingClass = JavaPsiFacade.getInstance(myProject).findClass(qualifiedName, scope); } @@ -147,7 +149,7 @@ protected UsageViewDescriptor createUsageViewDescriptor(@Nonnull UsageInfo[] usa @Override @RequiredUIAccess - protected boolean preprocessUsages(@Nonnull final Ref refUsages) { + protected boolean preprocessUsages(@Nonnull SimpleReference refUsages) { MultiMap conflicts = new MultiMap<>(); if (myUseExistingClass) { if (existingClass == null) { @@ -183,8 +185,8 @@ protected boolean preprocessUsages(@Nonnull final Ref refUsages) { } } for (UsageInfo usageInfo : refUsages.get()) { - if (usageInfo instanceof FixableUsageInfo) { - final String conflictMessage = ((FixableUsageInfo)usageInfo).getConflictMessage(); + if (usageInfo instanceof FixableUsageInfo fixableUsageInfo) { + String conflictMessage = fixableUsageInfo.getConflictMessage(); if (conflictMessage != null) { conflicts.putValue(usageInfo.getElement(), conflictMessage); } @@ -211,7 +213,7 @@ public void findUsages(@Nonnull List usages) { )); } - final PsiMethod[] overridingMethods = OverridingMethodsSearch.search(method, true).toArray(PsiMethod.EMPTY_ARRAY); + PsiMethod[] overridingMethods = OverridingMethodsSearch.search(method, true).toArray(PsiMethod.EMPTY_ARRAY); for (PsiMethod siblingMethod : overridingMethods) { findUsagesForMethod(siblingMethod, usages, false); } @@ -228,9 +230,9 @@ public void findUsages(@Nonnull List usages) { @RequiredReadAction private void findUsagesForMethod(PsiMethod overridingMethod, List usages, boolean changeSignature) { - final PsiCodeBlock body = overridingMethod.getBody(); - final String baseParameterName = StringUtil.decapitalize(className); - final String fixedParamName = body != null + PsiCodeBlock body = overridingMethod.getBody(); + String baseParameterName = StringUtil.decapitalize(className); + String fixedParamName = body != null ? JavaCodeStyleManager.getInstance(myProject).suggestUniqueVariableName(baseParameterName, body.getLBrace(), true) : JavaCodeStyleManager.getInstance(myProject).propertyNameToVariableName(baseParameterName, VariableKind.PARAMETER); @@ -246,16 +248,16 @@ private void findUsagesForMethod(PsiMethod overridingMethod, List values = visitor.getParameterUsages(); + Set values = visitor.getParameterUsages(); for (PsiReferenceExpression paramUsage : values) { - final PsiParameter parameter = (PsiParameter)paramUsage.resolve(); + PsiParameter parameter = (PsiParameter)paramUsage.resolve(); assert parameter != null; - final PsiMethod containingMethod = (PsiMethod)parameter.getDeclarationScope(); - final int index = containingMethod.getParameterList().getParameterIndex(parameter); - final PsiParameter replacedParameter = method.getParameterList().getParameters()[index]; - final ParameterChunk parameterChunk = ParameterChunk.getChunkByParameter(parameter, parameters); + PsiMethod containingMethod = (PsiMethod)parameter.getDeclarationScope(); + int index = containingMethod.getParameterList().getParameterIndex(parameter); + PsiParameter replacedParameter = method.getParameterList().getParameters()[index]; + ParameterChunk parameterChunk = ParameterChunk.getChunkByParameter(parameter, parameters); String getter = parameterChunk != null ? parameterChunk.getter : null; if (getter == null) { @@ -286,14 +288,14 @@ else if (RefactoringUtil.isAssignmentLHS(paramUsage)) { @Override @RequiredReadAction - protected void performRefactoring(UsageInfo[] usageInfos) { - final PsiClass psiClass = buildClass(); + protected void performRefactoring(@Nonnull UsageInfo[] usageInfos) { + PsiClass psiClass = buildClass(); if (psiClass != null) { fixJavadocForConstructor(psiClass); super.performRefactoring(usageInfos); if (!myUseExistingClass) { for (PsiReference reference : ReferencesSearch.search(method)) { - final PsiElement place = reference.getElement(); + PsiElement place = reference.getElement(); VisibilityUtil.escalateVisibility(psiClass, place); for (PsiMethod constructor : psiClass.getConstructors()) { VisibilityUtil.escalateVisibility(constructor, place); @@ -308,46 +310,46 @@ private PsiClass buildClass() { if (existingClass != null) { return existingClass; } - final ParameterObjectBuilder beanClassBuilder = new ParameterObjectBuilder(); + ParameterObjectBuilder beanClassBuilder = new ParameterObjectBuilder(); beanClassBuilder.setVisibility(myCreateInnerClass ? PsiModifier.PRIVATE : PsiModifier.PUBLIC); beanClassBuilder.setProject(myProject); beanClassBuilder.setTypeArguments(typeParams); beanClassBuilder.setClassName(className); beanClassBuilder.setPackageName(packageName); for (ParameterChunk parameterChunk : parameters) { - final VariableData parameter = parameterChunk.parameter; - final boolean setterRequired = paramsNeedingSetters.contains(parameter.variable); + VariableData parameter = parameterChunk.parameter; + boolean setterRequired = paramsNeedingSetters.contains(parameter.variable); beanClassBuilder.addField((PsiParameter)parameter.variable, parameter.name, parameter.type, setterRequired); } - final String classString = beanClassBuilder.buildBeanClass(); + String classString = beanClassBuilder.buildBeanClass(); try { - final PsiFileFactory factory = PsiFileFactory.getInstance(method.getProject()); - final PsiJavaFile newFile = (PsiJavaFile)factory.createFileFromText(className + ".java", JavaFileType.INSTANCE, classString); + PsiFileFactory factory = PsiFileFactory.getInstance(method.getProject()); + PsiJavaFile newFile = (PsiJavaFile)factory.createFileFromText(className + ".java", JavaFileType.INSTANCE, classString); if (myCreateInnerClass) { - final PsiClass containingClass = method.getContainingClass(); - final PsiClass[] classes = newFile.getClasses(); + PsiClass containingClass = method.getContainingClass(); + PsiClass[] classes = newFile.getClasses(); assert classes.length > 0 : classString; - final PsiClass innerClass = (PsiClass)containingClass.add(classes[0]); + PsiClass innerClass = (PsiClass)containingClass.add(classes[0]); PsiUtil.setModifierProperty(innerClass, PsiModifier.STATIC, true); return (PsiClass)JavaCodeStyleManager.getInstance(newFile.getProject()).shortenClassReferences(innerClass); } else { - final PsiFile containingFile = method.getContainingFile(); - final PsiDirectory containingDirectory = containingFile.getContainingDirectory(); - final PsiDirectory directory; + PsiFile containingFile = method.getContainingFile(); + PsiDirectory containingDirectory = containingFile.getContainingDirectory(); + PsiDirectory directory; if (myMoveDestination != null) { directory = myMoveDestination.getTargetDirectory(containingDirectory); } else { - final Module module = ModuleUtil.findModuleForPsiElement(containingFile); + Module module = ModuleUtil.findModuleForPsiElement(containingFile); directory = PackageUtil.findOrCreateDirectoryForPackage(module, packageName, containingDirectory, true, true); } if (directory != null) { - final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(method.getManager().getProject()); - final PsiElement shortenedFile = JavaCodeStyleManager.getInstance(newFile.getProject()).shortenClassReferences(newFile); - final PsiElement reformattedFile = codeStyleManager.reformat(shortenedFile); + CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(method.getManager().getProject()); + PsiElement shortenedFile = JavaCodeStyleManager.getInstance(newFile.getProject()).shortenClassReferences(newFile); + PsiElement reformattedFile = codeStyleManager.reformat(shortenedFile); return ((PsiJavaFile)directory.add(reformattedFile)).getClasses()[0]; } } @@ -360,17 +362,17 @@ private PsiClass buildClass() { @RequiredReadAction private void fixJavadocForConstructor(PsiClass psiClass) { - final PsiDocComment docComment = method.getDocComment(); + PsiDocComment docComment = method.getDocComment(); if (docComment != null) { - final List mergedTags = new ArrayList<>(); - final PsiDocTag[] paramTags = docComment.findTagsByName("param"); + List mergedTags = new ArrayList<>(); + PsiDocTag[] paramTags = docComment.findTagsByName("param"); for (PsiDocTag paramTag : paramTags) { - final PsiElement[] dataElements = paramTag.getDataElements(); + PsiElement[] dataElements = paramTag.getDataElements(); if (dataElements.length > 0) { if (dataElements[0] instanceof PsiDocParamRef docParamRef) { - final PsiReference reference = docParamRef.getReference(); + PsiReference reference = docParamRef.getReference(); if (reference != null && reference.resolve() instanceof PsiParameter parameter) { - final int parameterIndex = method.getParameterList().getParameterIndex(parameter); + int parameterIndex = method.getParameterList().getParameterIndex(parameter); if (ArrayUtil.find(paramsToMerge, parameterIndex) < 0) { continue; } @@ -406,7 +408,7 @@ else if (!myUseExistingClass) { @Override @RequiredReadAction protected String getCommandName() { - final PsiClass containingClass = method.getContainingClass(); + PsiClass containingClass = method.getContainingClass(); return JavaRefactoringLocalize.introducedParameterClassCommandName(className, containingClass.getName(), method.getName()).get(); } @@ -416,8 +418,8 @@ private static class ParamUsageVisitor extends JavaRecursiveElementVisitor { ParamUsageVisitor(PsiMethod method, int[] paramIndicesToMerge) { super(); - final PsiParameterList paramList = method.getParameterList(); - final PsiParameter[] parameters = paramList.getParameters(); + PsiParameterList paramList = method.getParameterList(); + PsiParameter[] parameters = paramList.getParameters(); for (int i : paramIndicesToMerge) { paramsToMerge.add(parameters[i]); } @@ -427,7 +429,7 @@ private static class ParamUsageVisitor extends JavaRecursiveElementVisitor { @RequiredReadAction public void visitReferenceExpression(PsiReferenceExpression expression) { super.visitReferenceExpression(expression); - final PsiElement referent = expression.resolve(); + PsiElement referent = expression.resolve(); if (referent instanceof PsiParameter parameter && paramsToMerge.contains(parameter)) { parameterUsages.add(expression); } @@ -441,8 +443,8 @@ public Set getParameterUsages() { @Nullable private static PsiMethod existingClassIsCompatible(PsiClass aClass, List params) { if (params.size() == 1) { - final ParameterChunk parameterChunk = params.get(0); - final PsiType paramType = parameterChunk.parameter.type; + ParameterChunk parameterChunk = params.get(0); + PsiType paramType = parameterChunk.parameter.type; if (TypeConversionUtil.isPrimitiveWrapper(aClass.getQualifiedName())) { parameterChunk.setField(aClass.findFieldByName("value", false)); parameterChunk.setGetter(paramType.getCanonicalText() + "Value"); @@ -453,7 +455,7 @@ private static PsiMethod existingClassIsCompatible(PsiClass aClass, List params) { - final PsiParameterList parameterList = constructor.getParameterList(); - final PsiParameter[] constructorParams = parameterList.getParameters(); + PsiParameterList parameterList = constructor.getParameterList(); + PsiParameter[] constructorParams = parameterList.getParameters(); if (constructorParams.length != params.size()) { return false; } @@ -543,7 +545,7 @@ public static ParameterChunk getChunkByParameter(PsiParameter param, List myToInvert = new HashMap(); + private final Map myToInvert = new HashMap<>(); private final SmartPointerManager mySmartPointerManager; - public InvertBooleanProcessor(final PsiNamedElement namedElement, final String newName) { + public InvertBooleanProcessor(PsiNamedElement namedElement, String newName) { super(namedElement.getProject()); myElement = namedElement; myNewName = newName; - final Project project = namedElement.getProject(); + Project project = namedElement.getProject(); myRenameProcessor = new RenameProcessor(project, namedElement, newName, false, false); mySmartPointerManager = SmartPointerManager.getInstance(project); } @Override @Nonnull - protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { + protected UsageViewDescriptor createUsageViewDescriptor(@Nonnull UsageInfo[] usages) { return new InvertBooleanUsageViewDescriptor(myElement); } @Override - protected boolean preprocessUsages(Ref refUsages) { + @RequiredUIAccess + protected boolean preprocessUsages(@Nonnull SimpleReference refUsages) { if (myRenameProcessor.preprocessUsages(refUsages)) { prepareSuccessful(); return true; @@ -79,90 +75,89 @@ protected boolean preprocessUsages(Ref refUsages) { return false; } - @Override @Nonnull + @Override + @RequiredReadAction protected UsageInfo[] findUsages() { - final List toInvert = new ArrayList(); + List toInvert = new ArrayList<>(); addRefsToInvert(toInvert, myElement); if (myElement instanceof PsiMethod) { - final Collection overriders = OverridingMethodsSearch.search((PsiMethod)myElement).findAll(); + Collection overriders = OverridingMethodsSearch.search((PsiMethod)myElement).findAll(); for (PsiMethod overrider : overriders) { myRenameProcessor.addElement(overrider, myNewName); } - Collection allMethods = new HashSet(overriders); + Collection allMethods = new HashSet<>(overriders); allMethods.add((PsiMethod)myElement); for (PsiMethod method : allMethods) { method.accept(new JavaRecursiveElementWalkingVisitor() { @Override - public void visitReturnStatement(PsiReturnStatement statement) { - final PsiExpression returnValue = statement.getReturnValue(); + public void visitReturnStatement(@Nonnull PsiReturnStatement statement) { + PsiExpression returnValue = statement.getReturnValue(); if (returnValue != null && PsiType.BOOLEAN.equals(returnValue.getType())) { toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(returnValue)); } } @Override - public void visitClass(PsiClass aClass) { + public void visitClass(@Nonnull PsiClass aClass) { } }); } } - else if (myElement instanceof PsiParameter && ((PsiParameter)myElement).getDeclarationScope() instanceof PsiMethod) { - final PsiMethod method = (PsiMethod)((PsiParameter)myElement).getDeclarationScope(); - int index = method.getParameterList().getParameterIndex((PsiParameter)myElement); + else if (myElement instanceof PsiParameter parameter && parameter.getDeclarationScope() instanceof PsiMethod) { + PsiMethod method = (PsiMethod)parameter.getDeclarationScope(); + int index = method.getParameterList().getParameterIndex(parameter); LOG.assertTrue(index >= 0); - final Query methodQuery = MethodReferencesSearch.search(method); - final Collection methodRefs = methodQuery.findAll(); + Query methodQuery = MethodReferencesSearch.search(method); + Collection methodRefs = methodQuery.findAll(); for (PsiReference ref : methodRefs) { PsiElement parent = ref.getElement().getParent(); if (parent instanceof PsiAnonymousClass) { parent = parent.getParent(); } - if (parent instanceof PsiCall) { - final PsiCall call = (PsiCall)parent; - final PsiReferenceExpression methodExpression = call instanceof PsiMethodCallExpression ? - ((PsiMethodCallExpression)call).getMethodExpression() : - null; - final PsiExpressionList argumentList = call.getArgumentList(); + if (parent instanceof PsiCall call) { + PsiReferenceExpression methodExpression = call instanceof PsiMethodCallExpression methodCall + ? methodCall.getMethodExpression() + : null; + PsiExpressionList argumentList = call.getArgumentList(); if (argumentList != null) { - final PsiExpression[] args = argumentList.getExpressions(); - if (index < args.length) { - if (methodExpression == null || methodExpression.getQualifier() == null - || !"super".equals(methodExpression.getQualifierExpression().getText())) { - toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(args[index])); - } + PsiExpression[] args = argumentList.getExpressions(); + if (index < args.length + && (methodExpression == null || methodExpression.getQualifier() == null + || !"super".equals(methodExpression.getQualifierExpression().getText()))) { + toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(args[index])); } } } } - final Collection overriders = OverridingMethodsSearch.search(method).findAll(); + Collection overriders = OverridingMethodsSearch.search(method).findAll(); for (PsiMethod overrider : overriders) { - final PsiParameter overriderParameter = overrider.getParameterList().getParameters()[index]; + PsiParameter overriderParameter = overrider.getParameterList().getParameters()[index]; myRenameProcessor.addElement(overriderParameter, myNewName); addRefsToInvert(toInvert, overriderParameter); } } - final UsageInfo[] renameUsages = myRenameProcessor.findUsages(); + UsageInfo[] renameUsages = myRenameProcessor.findUsages(); - final SmartPsiElementPointer[] usagesToInvert = toInvert.toArray(new SmartPsiElementPointer[toInvert.size()]); + SmartPsiElementPointer[] usagesToInvert = toInvert.toArray(new SmartPsiElementPointer[toInvert.size()]); //merge rename and invert usages - Map expressionsToUsages = new HashMap(); - List result = new ArrayList(); + Map expressionsToUsages = new HashMap<>(); + List result = new ArrayList<>(); for (UsageInfo renameUsage : renameUsages) { expressionsToUsages.put(renameUsage.getElement(), renameUsage); result.add(renameUsage); } for (SmartPsiElementPointer pointer : usagesToInvert) { - final PsiExpression expression = (PsiExpression)pointer.getElement(); + PsiExpression expression = (PsiExpression)pointer.getElement(); if (!expressionsToUsages.containsKey(expression)) { - final UsageInfo usageInfo = new UsageInfo(expression); + UsageInfo usageInfo = new UsageInfo(expression); expressionsToUsages.put(expression, usageInfo); result.add(usageInfo); //fake UsageInfo myToInvert.put(usageInfo, pointer); @@ -175,29 +170,25 @@ else if (myElement instanceof PsiParameter && ((PsiParameter)myElement).getDecla return result.toArray(new UsageInfo[result.size()]); } - private void addRefsToInvert(final List toInvert, final PsiNamedElement namedElement) { - final Query query = namedElement instanceof PsiMethod ? - MethodReferencesSearch.search((PsiMethod)namedElement) : - ReferencesSearch.search(namedElement); - final Collection refs = query.findAll(); + @RequiredReadAction + private void addRefsToInvert(List toInvert, PsiNamedElement namedElement) { + Query query = namedElement instanceof PsiMethod method + ? MethodReferencesSearch.search(method) + : ReferencesSearch.search(namedElement); + Collection refs = query.findAll(); for (PsiReference ref : refs) { - final PsiElement element = ref.getElement(); - if (element instanceof PsiReferenceExpression) { - final PsiReferenceExpression refExpr = (PsiReferenceExpression)element; - PsiElement parent = refExpr.getParent(); - if (parent instanceof PsiAssignmentExpression && refExpr.equals(((PsiAssignmentExpression)parent).getLExpression())) { - toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(((PsiAssignmentExpression)parent).getRExpression())); + PsiElement element = ref.getElement(); + if (element instanceof PsiReferenceExpression refExpr) { + if (refExpr.getParent() instanceof PsiAssignmentExpression assignment && refExpr.equals(assignment.getLExpression())) { + toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(assignment.getRExpression())); } else { - if (namedElement instanceof PsiParameter) { //filter usages in super method calls - if (refExpr.getParent().getParent() instanceof PsiMethodCallExpression) { - final PsiReferenceExpression methodExpression = - ((PsiMethodCallExpression)refExpr.getParent().getParent()).getMethodExpression(); - if (methodExpression.getQualifier() != null && "super".equals(methodExpression.getQualifierExpression() - .getText())) { - continue; - } + if (namedElement instanceof PsiParameter + && refExpr.getParent().getParent() instanceof PsiMethodCallExpression methodCall) { + PsiReferenceExpression methodExpr = methodCall.getMethodExpression(); + if (methodExpr.getQualifier() != null && "super".equals(methodExpr.getQualifierExpression().getText())) { + continue; } } @@ -206,8 +197,8 @@ private void addRefsToInvert(final List toInvert, final } } - if (namedElement instanceof PsiVariable) { - final PsiExpression initializer = ((PsiVariable)namedElement).getInitializer(); + if (namedElement instanceof PsiVariable variable) { + PsiExpression initializer = variable.getInitializer(); if (initializer != null) { toInvert.add(mySmartPointerManager.createSmartPsiElementPointer(initializer)); } @@ -221,7 +212,7 @@ protected void refreshElements(PsiElement[] elements) { } private static UsageInfo[] extractUsagesForElement(PsiElement element, UsageInfo[] usages) { - final ArrayList extractedUsages = new ArrayList(usages.length); + ArrayList extractedUsages = new ArrayList<>(usages.length); for (UsageInfo usage : usages) { if (usage instanceof MoveRenameUsageInfo) { MoveRenameUsageInfo usageInfo = (MoveRenameUsageInfo)usage; @@ -233,10 +224,10 @@ private static UsageInfo[] extractUsagesForElement(PsiElement element, UsageInfo return extractedUsages.toArray(new UsageInfo[extractedUsages.size()]); } - @Override - protected void performRefactoring(UsageInfo[] usages) { - for (final PsiElement element : myRenameProcessor.getElements()) { + @RequiredReadAction + protected void performRefactoring(@Nonnull UsageInfo[] usages) { + for (PsiElement element : myRenameProcessor.getElements()) { try { RenameUtil.doRename( element, @@ -246,26 +237,26 @@ protected void performRefactoring(UsageInfo[] usages) { null ); } - catch (final IncorrectOperationException e) { + catch (IncorrectOperationException e) { RenameUtil.showErrorMessage(e, element, myProject); return; } } - for (UsageInfo usage : usages) { - final SmartPsiElementPointer pointerToInvert = myToInvert.get(usage); + SmartPsiElementPointer pointerToInvert = myToInvert.get(usage); if (pointerToInvert != null) { PsiExpression expression = (PsiExpression)pointerToInvert.getElement(); LOG.assertTrue(expression != null); - if (expression.getParent() instanceof PsiMethodCallExpression) { - expression = (PsiExpression)expression.getParent(); + if (expression.getParent() instanceof PsiMethodCallExpression methodCall) { + expression = methodCall; } try { - while (expression.getParent() instanceof PsiPrefixExpression && - ((PsiPrefixExpression)expression.getParent()).getOperationTokenType() == JavaTokenType.EXCL) { - expression = (PsiExpression)expression.getParent(); + while (expression.getParent() instanceof PsiPrefixExpression prefixExpr + && prefixExpr.getOperationTokenType() == JavaTokenType.EXCL) { + expression = prefixExpr; } + if (!(expression.getParent() instanceof PsiExpressionStatement)) { expression.replace(CodeInsightServicesUtil.invertCondition(expression)); } @@ -277,6 +268,7 @@ protected void performRefactoring(UsageInfo[] usages) { } } + @Nonnull @Override protected String getCommandName() { return InvertBooleanHandler.REFACTORING_NAME; diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/migration/MigrationProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/migration/MigrationProcessor.java index d2601fa41..4d5f8891e 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/migration/MigrationProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/migration/MigrationProcessor.java @@ -18,11 +18,11 @@ import com.intellij.java.impl.psi.impl.migration.PsiMigrationManager; import com.intellij.java.language.psi.PsiMigration; import com.intellij.java.language.psi.codeStyle.JavaCodeStyleManager; -import consulo.application.ApplicationManager; +import consulo.annotation.access.RequiredReadAction; +import consulo.application.Application; import consulo.application.WriteAction; import consulo.content.scope.SearchScope; import consulo.language.editor.refactoring.BaseRefactoringProcessor; -import consulo.language.editor.refactoring.RefactoringBundle; import consulo.language.editor.refactoring.localize.RefactoringLocalize; import consulo.language.psi.PsiElement; import consulo.language.psi.SmartPsiElementPointer; @@ -36,8 +36,7 @@ import consulo.usage.UsageViewDescriptor; import consulo.util.lang.Comparing; import consulo.util.lang.StringUtil; -import consulo.util.lang.ref.Ref; - +import consulo.util.lang.ref.SimpleReference; import jakarta.annotation.Nonnull; import java.util.ArrayList; @@ -47,7 +46,6 @@ */ public class MigrationProcessor extends BaseRefactoringProcessor { private final MigrationMap myMigrationMap; - private static final String REFACTORING_NAME = RefactoringBundle.message("migration.title"); private PsiMigration myPsiMigration; private final SearchScope mySearchScope; private ArrayList> myRefsToShorten; @@ -70,12 +68,12 @@ protected UsageViewDescriptor createUsageViewDescriptor(@Nonnull UsageInfo[] usa } private PsiMigration startMigration(Project project) { - final PsiMigration migration = PsiMigrationManager.getInstance(project).startMigration(); + PsiMigration migration = PsiMigrationManager.getInstance(project).startMigration(); findOrCreateEntries(project, migration); return migration; } - private void findOrCreateEntries(Project project, final PsiMigration migration) { + private void findOrCreateEntries(Project project, PsiMigration migration) { for (int i = 0; i < myMigrationMap.getEntryCount(); i++) { MigrationMapEntry entry = myMigrationMap.getEntryAt(i); if (entry.getType() == MigrationMapEntry.PACKAGE) { @@ -92,8 +90,9 @@ protected void refreshElements(@Nonnull PsiElement[] elements) { myPsiMigration = startMigration(myProject); } - @Override @Nonnull + @Override + @RequiredReadAction protected UsageInfo[] findUsages() { ArrayList usagesVector = new ArrayList<>(); try { @@ -116,9 +115,11 @@ protected UsageInfo[] findUsages() { } } finally { - //invalidating resolve caches without write action could lead to situations when somebody with read action resolves reference and gets ResolveResult - //then here, in another read actions, all caches are invalidated but those resolve result is used without additional checks inside that read action - but it's already invalid - ApplicationManager.getApplication().invokeLater(() -> WriteAction.run(this::finishFindMigration), myProject.getDisposed()); + // Invalidating resolve caches without write action could lead to situations + // when somebody with read action resolves reference and gets ResolveResult. + // Then here, in another read actions, all caches are invalidated but those resolve result + // is used without additional checks inside that read action - but it's already invalid + Application.get().invokeLater(() -> WriteAction.run(this::finishFindMigration), myProject.getDisposed()); } return usagesVector.toArray(UsageInfo.EMPTY_ARRAY); } @@ -132,9 +133,13 @@ private void finishFindMigration() { @Override @RequiredUIAccess - protected boolean preprocessUsages(@Nonnull Ref refUsages) { + protected boolean preprocessUsages(@Nonnull SimpleReference refUsages) { if (refUsages.get().length == 0) { - Messages.showInfoMessage(myProject, RefactoringLocalize.migrationNoUsagesFoundInTheProject().get(), REFACTORING_NAME); + Messages.showInfoMessage( + myProject, + RefactoringLocalize.migrationNoUsagesFoundInTheProject().get(), + RefactoringLocalize.migrationTitle().get() + ); return false; } setPreviewUsages(true); @@ -144,7 +149,7 @@ protected boolean preprocessUsages(@Nonnull Ref refUsages) { @Override protected void performRefactoring(@Nonnull UsageInfo[] usages) { finishFindMigration(); - final PsiMigration psiMigration = PsiMigrationManager.getInstance(myProject).startMigration(); + PsiMigration psiMigration = PsiMigrationManager.getInstance(myProject).startMigration(); LocalHistoryAction a = LocalHistory.getInstance().startAction(getCommandName()); myRefsToShorten = new ArrayList<>(); @@ -176,6 +181,7 @@ protected void performRefactoring(@Nonnull UsageInfo[] usages) { } @Override + @RequiredReadAction protected void performPsiSpoilingRefactoring() { JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(myProject); for (SmartPsiElementPointer pointer : myRefsToShorten) { @@ -189,12 +195,13 @@ protected void performPsiSpoilingRefactoring() { @Override @Nonnull protected String getCommandName() { - return REFACTORING_NAME; + return RefactoringLocalize.migrationTitle().get(); } static class MigrationUsageInfo extends UsageInfo { MigrationMapEntry mapEntry; + @RequiredReadAction MigrationUsageInfo(UsageInfo info, MigrationMapEntry mapEntry) { super(info.getElement(), info.getRangeInElement().getStartOffset(), info.getRangeInElement().getEndOffset()); this.mapEntry = mapEntry; diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java index d6b9b3429..192c28952 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesProcessor.java @@ -39,13 +39,14 @@ import consulo.platform.base.localize.CommonLocalize; import consulo.project.DumbService; import consulo.project.Project; +import consulo.ui.annotation.RequiredUIAccess; import consulo.ui.ex.awt.Messages; import consulo.usage.NonCodeUsageInfo; import consulo.usage.UsageInfo; import consulo.usage.UsageViewDescriptor; import consulo.usage.UsageViewUtil; import consulo.util.collection.MultiMap; -import consulo.util.lang.ref.Ref; +import consulo.util.lang.ref.SimpleReference; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; @@ -72,9 +73,9 @@ public MoveDirectoryWithClassesProcessor( ) { super(project); if (targetDirectory != null) { - final List dirs = new ArrayList<>(Arrays.asList(directories)); + List dirs = new ArrayList<>(Arrays.asList(directories)); for (Iterator iterator = dirs.iterator(); iterator.hasNext(); ) { - final PsiDirectory directory = iterator.next(); + PsiDirectory directory = iterator.next(); if (targetDirectory.equals(directory.getParentDirectory()) || targetDirectory.equals(directory)) { iterator.remove(); } @@ -94,9 +95,9 @@ public MoveDirectoryWithClassesProcessor( @Nonnull @Override - protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { + protected UsageViewDescriptor createUsageViewDescriptor(@Nonnull UsageInfo[] usages) { PsiElement[] elements = new PsiElement[myFilesToMove.size()]; - final PsiFile[] classes = PsiUtilCore.toPsiFileArray(myFilesToMove.keySet()); + PsiFile[] classes = PsiUtilCore.toPsiFileArray(myFilesToMove.keySet()); System.arraycopy(classes, 0, elements, 0, classes.length); return new MoveMultipleElementsViewDescriptor(elements, getTargetName()); } @@ -108,7 +109,7 @@ protected String getTargetName() { @Nonnull @Override public UsageInfo[] findUsages() { - final List usages = new ArrayList<>(); + List usages = new ArrayList<>(); for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) { helper.findUsages(myFilesToMove.keySet(), myDirectories, usages, mySearchInComments, mySearchInNonJavaFiles, myProject); } @@ -116,8 +117,9 @@ public UsageInfo[] findUsages() { } @Override - protected boolean preprocessUsages(Ref refUsages) { - final MultiMap conflicts = new MultiMap<>(); + @RequiredUIAccess + protected boolean preprocessUsages(@Nonnull SimpleReference refUsages) { + MultiMap conflicts = new MultiMap<>(); for (PsiFile psiFile : myFilesToMove.keySet()) { try { myFilesToMove.get(psiFile).checkMove(psiFile); @@ -133,11 +135,12 @@ protected boolean preprocessUsages(Ref refUsages) { } @Override - protected void refreshElements(PsiElement[] elements) { + protected void refreshElements(@Nonnull PsiElement[] elements) { } @Override - public void performRefactoring(UsageInfo[] usages) { + @RequiredUIAccess + public void performRefactoring(@Nonnull UsageInfo[] usages) { //try to create all directories beforehand try { //top level directories should be created even if they are empty @@ -155,14 +158,14 @@ public void performRefactoring(UsageInfo[] usages) { return; } try { - final List movedFiles = new ArrayList<>(); - final Map oldToNewElementsMapping = new HashMap<>(); + List movedFiles = new ArrayList<>(); + Map oldToNewElementsMapping = new HashMap<>(); for (PsiFile psiFile : myFilesToMove.keySet()) { for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) { helper.beforeMove(psiFile); } - final RefactoringElementListener listener = getTransaction().getElementListener(psiFile); - final PsiDirectory moveDestination = myFilesToMove.get(psiFile).getTargetDirectory(); + RefactoringElementListener listener = getTransaction().getElementListener(psiFile); + PsiDirectory moveDestination = myFilesToMove.get(psiFile).getTargetDirectory(); for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) { boolean processed = helper.move(psiFile, moveDestination, oldToNewElementsMapping, movedFiles, listener); @@ -222,10 +225,10 @@ private static void collectFiles2Move( PsiDirectory rootDirectory, @Nonnull TargetDirectoryWrapper targetDirectory ) { - final PsiElement[] children = directory.getChildren(); - final String relativePath = VfsUtilCore.getRelativePath(directory.getVirtualFile(), rootDirectory.getVirtualFile(), '/'); + PsiElement[] children = directory.getChildren(); + String relativePath = VfsUtilCore.getRelativePath(directory.getVirtualFile(), rootDirectory.getVirtualFile(), '/'); - final TargetDirectoryWrapper newTargetDirectory = relativePath.isEmpty() + TargetDirectoryWrapper newTargetDirectory = relativePath.isEmpty() ? targetDirectory : targetDirectory.findOrCreateChild(relativePath); for (PsiElement child : children) { @@ -238,6 +241,7 @@ else if (child instanceof PsiDirectory psiDirectory) { } } + @Nonnull @Override protected String getCommandName() { return RefactoringLocalize.movingDirectoriesCommand().get(); @@ -270,7 +274,7 @@ public TargetDirectoryWrapper(PsiDirectory parentDirectory, String relativePath) public PsiDirectory findOrCreateTargetDirectory() throws IncorrectOperationException { if (myTargetDirectory == null) { - final PsiDirectory root = myParentDirectory.findOrCreateTargetDirectory(); + PsiDirectory root = myParentDirectory.findOrCreateTargetDirectory(); myTargetDirectory = root.findSubdirectory(myRelativePath); if (myTargetDirectory == null) { @@ -287,7 +291,7 @@ public PsiDirectory getTargetDirectory() { public TargetDirectoryWrapper findOrCreateChild(String relativePath) { if (myTargetDirectory != null) { - final PsiDirectory psiDirectory = myTargetDirectory.findSubdirectory(relativePath); + PsiDirectory psiDirectory = myTargetDirectory.findSubdirectory(relativePath); if (psiDirectory != null) { return new TargetDirectoryWrapper(psiDirectory); } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/removemiddleman/RemoveMiddlemanProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/removemiddleman/RemoveMiddlemanProcessor.java index 82d0370cc..19ef41093 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/removemiddleman/RemoveMiddlemanProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/removemiddleman/RemoveMiddlemanProcessor.java @@ -21,7 +21,10 @@ import com.intellij.java.impl.refactoring.util.FixableUsageInfo; import com.intellij.java.impl.refactoring.util.FixableUsagesRefactoringProcessor; import com.intellij.java.impl.refactoring.util.classMembers.MemberInfo; -import com.intellij.java.language.psi.*; +import com.intellij.java.language.psi.PsiClass; +import com.intellij.java.language.psi.PsiField; +import com.intellij.java.language.psi.PsiMethod; +import com.intellij.java.language.psi.PsiMethodCallExpression; import com.intellij.java.language.psi.util.PropertyUtil; import consulo.annotation.access.RequiredReadAction; import consulo.java.localize.JavaRefactoringLocalize; @@ -35,7 +38,7 @@ import consulo.usage.UsageInfo; import consulo.usage.UsageViewDescriptor; import consulo.util.collection.MultiMap; -import consulo.util.lang.ref.Ref; +import consulo.util.lang.ref.SimpleReference; import jakarta.annotation.Nonnull; import java.util.List; @@ -52,8 +55,8 @@ public RemoveMiddlemanProcessor(PsiField field, List memberInfos) { super(field.getProject()); this.field = field; containingClass = field.getContainingClass(); - final String propertyName = PropertyUtil.suggestPropertyName(field); - final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC); + String propertyName = PropertyUtil.suggestPropertyName(field); + boolean isStatic = field.isStatic(); getter = PropertyUtil.findPropertyGetter(containingClass, propertyName, isStatic, false); myDelegateMethodInfos = memberInfos; } @@ -67,14 +70,14 @@ protected UsageViewDescriptor createUsageViewDescriptor(@Nonnull UsageInfo[] usa @Override @RequiredReadAction public void findUsages(@Nonnull List usages) { - for (final MemberInfo memberInfo : myDelegateMethodInfos) { + for (MemberInfo memberInfo : myDelegateMethodInfos) { if (!memberInfo.isChecked()) { continue; } - final PsiMethod method = (PsiMethod)memberInfo.getMember(); - final String getterName = PropertyUtil.suggestGetterName(field); - final int[] paramPermutation = DelegationUtils.getParameterPermutation(method); - final PsiMethod delegatedMethod = DelegationUtils.getDelegatedMethod(method); + PsiMethod method = (PsiMethod)memberInfo.getMember(); + String getterName = PropertyUtil.suggestGetterName(field); + int[] paramPermutation = DelegationUtils.getParameterPermutation(method); + PsiMethod delegatedMethod = DelegationUtils.getDelegatedMethod(method); LOG.assertTrue(!DelegationUtils.isAbstract(method)); processUsagesForMethod(memberInfo.isToAbstract(), method, paramPermutation, getterName, delegatedMethod, usages); } @@ -82,8 +85,8 @@ public void findUsages(@Nonnull List usages) { @Override @RequiredUIAccess - protected boolean preprocessUsages(@Nonnull final Ref refUsages) { - final MultiMap conflicts = new MultiMap<>(); + protected boolean preprocessUsages(@Nonnull SimpleReference refUsages) { + MultiMap conflicts = new MultiMap<>(); for (MemberInfo memberInfo : myDelegateMethodInfos) { if (memberInfo.isChecked() && memberInfo.isToAbstract() && memberInfo.getMember() instanceof PsiMethod method && method.findDeepestSuperMethods().length > 0) { @@ -100,7 +103,7 @@ protected boolean preprocessUsages(@Nonnull final Ref refUsages) { @RequiredReadAction private void processUsagesForMethod( - final boolean deleteMethodHierarchy, + boolean deleteMethodHierarchy, PsiMethod method, int[] paramPermutation, String getterName, @@ -128,7 +131,7 @@ private void processUsagesForMethod( } @Override - protected void performRefactoring(UsageInfo[] usageInfos) { + protected void performRefactoring(@Nonnull UsageInfo[] usageInfos) { if (getter != null) { try { if (containingClass.findMethodBySignature(getter, false) == null) { diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderProcessor.java index 65b0c766c..bc392d2b5 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/replaceConstructorWithBuilder/ReplaceConstructorWithBuilderProcessor.java @@ -15,13 +15,13 @@ */ package com.intellij.java.impl.refactoring.replaceConstructorWithBuilder; +import com.intellij.java.impl.codeInsight.PackageUtil; import com.intellij.java.impl.refactoring.MoveDestination; import com.intellij.java.impl.refactoring.replaceConstructorWithBuilder.usageInfo.ReplaceConstructorWithSettersChainInfo; import com.intellij.java.impl.refactoring.util.FixableUsageInfo; import com.intellij.java.impl.refactoring.util.FixableUsagesRefactoringProcessor; import com.intellij.java.impl.refactoring.util.RefactoringUtil; import com.intellij.java.language.impl.JavaFileType; -import com.intellij.java.impl.codeInsight.PackageUtil; import com.intellij.java.language.psi.PsiElementFactory; import com.intellij.java.language.psi.*; import com.intellij.java.language.psi.codeStyle.JavaCodeStyleManager; @@ -30,6 +30,7 @@ import com.intellij.java.language.psi.util.PsiUtil; import com.intellij.java.language.psi.util.TypeConversionUtil; import com.intellij.java.language.util.VisibilityUtil; +import consulo.annotation.access.RequiredReadAction; import consulo.ide.impl.idea.openapi.module.ModuleUtil; import consulo.language.codeStyle.CodeStyleManager; import consulo.language.psi.*; @@ -39,14 +40,14 @@ import consulo.language.util.IncorrectOperationException; import consulo.module.Module; import consulo.project.Project; +import consulo.ui.annotation.RequiredUIAccess; import consulo.usage.UsageInfo; import consulo.usage.UsageViewDescriptor; import consulo.util.collection.MultiMap; import consulo.util.lang.Comparing; 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 java.util.Collections; @@ -55,7 +56,7 @@ /** * @author anna - * @since 04-Sep-2008 + * @since 2008-09-04 */ public class ReplaceConstructorWithBuilderProcessor extends FixableUsagesRefactoringProcessor { public static final String REFACTORING_NAME = "Replace Constructor with Builder"; @@ -88,10 +89,13 @@ public ReplaceConstructorWithBuilderProcessor( } @Nonnull - protected UsageViewDescriptor createUsageViewDescriptor(final UsageInfo[] usages) { + @Override + protected UsageViewDescriptor createUsageViewDescriptor(@Nonnull final UsageInfo[] usages) { return new ReplaceConstructorWithBuilderViewDescriptor(); } + @Override + @RequiredReadAction protected void findUsages(@Nonnull final List usages) { final String builderQualifiedName = StringUtil.getQualifiedName(myPackageName, myClassName); final PsiClass builderClass = @@ -113,6 +117,7 @@ protected void findUsages(@Nonnull final List usages) { } @Nullable + @RequiredReadAction private PsiClass createBuilderClass() { final PsiClass psiClass = myConstructors[0].getContainingClass(); assert psiClass != null; @@ -149,15 +154,15 @@ private PsiClass createBuilderClass() { } @Override - protected void performRefactoring(UsageInfo[] usageInfos) { - + @RequiredReadAction + protected void performRefactoring(@Nonnull UsageInfo[] usageInfos) { final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(myProject); final PsiClass builderClass = myCreateNewBuilderClass ? createBuilderClass() : psiFacade.findClass( - StringUtil.getQualifiedName(myPackageName, myClassName), - GlobalSearchScope.projectScope(myProject) - ); + StringUtil.getQualifiedName(myPackageName, myClassName), + GlobalSearchScope.projectScope(myProject) + ); if (builderClass == null) { return; } @@ -248,7 +253,7 @@ private void fixSetterReturnType(PsiClass builderClass, PsiField field, PsiMetho private PsiMethod createMethodSignature(String createMethodName) { JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(myProject); - final StringBuffer buf = new StringBuffer(); + final StringBuilder buf = new StringBuilder(); final PsiMethod constructor = getWorkingConstructor(); for (PsiParameter parameter : constructor.getParameterList().getParameters()) { final String pureParamName = styleManager.variableNameToPropertyName(parameter.getName(), VariableKind.PARAMETER); @@ -257,16 +262,12 @@ private PsiMethod createMethodSignature(String createMethodName) { } buf.append(myParametersMap.get(pureParamName).getFieldName()); } - return myElementFactory.createMethodFromText("public " + - constructor.getName() + - " " + - createMethodName + - "(){\n return new " + - constructor.getName() + - "(" + - buf.toString() + - ")" + - ";\n}", constructor); + return myElementFactory.createMethodFromText( + "public " + constructor.getName() + " " + createMethodName + "(){\n" + + " return new " + constructor.getName() + "(" + buf.toString() + ");\n" + + "}", + constructor + ); } private PsiMethod getWorkingConstructor() { @@ -307,13 +308,7 @@ else if (!isChained(commonConstructor, chainedConstructor)) { } private static boolean isChained(PsiMethod first, PsiMethod last) { - if (first == null) { - return false; - } - if (first == last) { - return true; - } - return isChained(RefactoringUtil.getChainedConstructor(first), last); + return first != null && (first == last || isChained(RefactoringUtil.getChainedConstructor(first), last)); } private String createMethodName() { @@ -322,8 +317,9 @@ private String createMethodName() { @Override - protected boolean preprocessUsages(Ref refUsages) { - final MultiMap conflicts = new MultiMap(); + @RequiredUIAccess + protected boolean preprocessUsages(@Nonnull SimpleReference refUsages) { + final MultiMap conflicts = new MultiMap<>(); final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(myProject); final PsiClass builderClass = psiFacade.findClass(StringUtil.getQualifiedName(myPackageName, myClassName), GlobalSearchScope.projectScope(myProject)); @@ -348,6 +344,7 @@ else if (myCreateNewBuilderClass) { return showConflicts(conflicts, refUsages.get()); } + @Override protected String getCommandName() { return REFACTORING_NAME; } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/TypeMigrationProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/TypeMigrationProcessor.java index 5b7acd0b5..1855c39a9 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/TypeMigrationProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/typeMigration/TypeMigrationProcessor.java @@ -21,7 +21,8 @@ import com.intellij.java.impl.refactoring.util.RefactoringUtil; import com.intellij.java.language.psi.*; import com.intellij.java.language.psi.codeStyle.JavaCodeStyleManager; -import consulo.application.ApplicationManager; +import consulo.annotation.access.RequiredReadAction; +import consulo.application.Application; import consulo.codeEditor.Editor; import consulo.language.editor.refactoring.BaseRefactoringProcessor; import consulo.language.psi.*; @@ -29,6 +30,7 @@ import consulo.project.Project; import consulo.project.ui.wm.ToolWindowId; import consulo.project.ui.wm.ToolWindowManager; +import consulo.ui.annotation.RequiredUIAccess; import consulo.ui.ex.content.Content; import consulo.usage.UsageInfo; import consulo.usage.UsageViewContentManager; @@ -37,7 +39,7 @@ import consulo.util.collection.SmartList; import consulo.util.lang.StringUtil; import consulo.util.lang.function.Functions; -import consulo.util.lang.ref.Ref; +import consulo.util.lang.ref.SimpleReference; import jakarta.annotation.Nonnull; import java.util.*; @@ -56,11 +58,11 @@ public class TypeMigrationProcessor extends BaseRefactoringProcessor { private TypeMigrationLabeler myLabeler; public TypeMigrationProcessor( - final Project project, - final PsiElement[] roots, - final Function rootTypes, - final TypeMigrationRules rules, - final boolean allowDependentRoots + Project project, + PsiElement[] roots, + Function rootTypes, + TypeMigrationRules rules, + boolean allowDependentRoots ) { super(project); myRoots = roots; @@ -69,23 +71,25 @@ public TypeMigrationProcessor( myAllowDependentRoots = allowDependentRoots; } + @RequiredUIAccess public static void runHighlightingTypeMigration( - final Project project, - final Editor editor, - final TypeMigrationRules rules, - final PsiElement root, - final PsiType migrationType + Project project, + Editor editor, + TypeMigrationRules rules, + PsiElement root, + PsiType migrationType ) { runHighlightingTypeMigration(project, editor, rules, root, migrationType, false, true); } + @RequiredUIAccess public static void runHighlightingTypeMigration( - final Project project, - final Editor editor, - final TypeMigrationRules rules, - final PsiElement root, - final PsiType migrationType, - final boolean optimizeImports, + Project project, + Editor editor, + TypeMigrationRules rules, + PsiElement root, + PsiType migrationType, + boolean optimizeImports, boolean allowDependentRoots ) { runHighlightingTypeMigration( @@ -99,36 +103,35 @@ public static void runHighlightingTypeMigration( ); } - + @RequiredUIAccess public static void runHighlightingTypeMigration( - final Project project, - final Editor editor, - final TypeMigrationRules rules, - final PsiElement[] roots, - final Function migrationTypeFunction, - final boolean optimizeImports, + Project project, + Editor editor, + TypeMigrationRules rules, + PsiElement[] roots, + Function migrationTypeFunction, + boolean optimizeImports, boolean allowDependentRoots ) { - final Set containingFiles = ContainerUtil.map2Set(roots, PsiElement::getContainingFile); - final TypeMigrationProcessor processor = + Set containingFiles = ContainerUtil.map2Set(roots, PsiElement::getContainingFile); + TypeMigrationProcessor processor = new TypeMigrationProcessor(project, roots, migrationTypeFunction, rules, allowDependentRoots) { @Override - public void performRefactoring(@Nonnull final UsageInfo[] usages) { + public void performRefactoring(@Nonnull UsageInfo[] usages) { super.performRefactoring(usages); if (editor != null) { - ApplicationManager.getApplication().invokeLater(() -> - { - final List result = new ArrayList<>(); + Application.get().invokeLater(() -> { + List result = new ArrayList<>(); for (UsageInfo usage : usages) { - final PsiElement element = usage.getElement(); + PsiElement element = usage.getElement(); if (element == null || !containingFiles.contains(element.getContainingFile())) { continue; } - if (element instanceof PsiMethod) { - result.add(((PsiMethod)element).getReturnTypeElement()); + if (element instanceof PsiMethod method) { + result.add(method.getReturnTypeElement()); } - else if (element instanceof PsiVariable) { - result.add(((PsiVariable)element).getTypeElement()); + else if (element instanceof PsiVariable variable) { + result.add(variable.getTypeElement()); } else { result.add(element); @@ -138,10 +141,10 @@ else if (element instanceof PsiVariable) { }); } if (optimizeImports) { - final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(myProject); - final Set affectedFiles = new HashSet<>(); + JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(myProject); + Set affectedFiles = new HashSet<>(); for (UsageInfo usage : usages) { - final PsiFile usageFile = usage.getFile(); + PsiFile usageFile = usage.getFile(); if (usageFile != null) { affectedFiles.add(usageFile); } @@ -164,9 +167,10 @@ protected UsageViewDescriptor createUsageViewDescriptor(@Nonnull UsageInfo[] usa } @Override - protected boolean preprocessUsages(@Nonnull Ref refUsages) { + @RequiredUIAccess + protected boolean preprocessUsages(@Nonnull SimpleReference refUsages) { if (hasFailedConversions()) { - if (ApplicationManager.getApplication().isUnitTestMode()) { + if (Application.get().isUnitTestMode()) { if (ourSkipFailedConversionInTestMode) { prepareSuccessful(); return true; @@ -175,7 +179,7 @@ protected boolean preprocessUsages(@Nonnull Ref refUsages) { } FailedConversionsDialog dialog = new FailedConversionsDialog(myLabeler.getFailedConversionsReport(), myProject); if (!dialog.showAndGet()) { - final int exitCode = dialog.getExitCode(); + int exitCode = dialog.getExitCode(); prepareSuccessful(); if (exitCode == FailedConversionsDialog.VIEW_USAGES_EXIT_CODE) { previewRefactoring(refUsages.get()); @@ -192,7 +196,8 @@ public boolean hasFailedConversions() { } @Override - protected void previewRefactoring(@Nonnull final UsageInfo[] usages) { + @RequiredUIAccess + protected void previewRefactoring(@Nonnull UsageInfo[] usages) { MigrationPanel panel = new MigrationPanel(myRoots, myLabeler, myProject, isPreviewUsages()); String name; if (myRoots.length == 1) { @@ -203,12 +208,12 @@ protected void previewRefactoring(@Nonnull final UsageInfo[] usages) { name = "Migrate Type of " + text + " from \'" + fromType + "\' to \'" + toType + "\'"; } else { - final int rootsInPresentationCount = + int rootsInPresentationCount = myRoots.length > MAX_ROOT_IN_PREVIEW_PRESENTATION ? MAX_ROOT_IN_PREVIEW_PRESENTATION : myRoots.length; String[] rootsPresentation = new String[rootsInPresentationCount]; for (int i = 0; i < rootsInPresentationCount; i++) { - final PsiElement root = myRoots[i]; - rootsPresentation[i] = root instanceof PsiNamedElement ? ((PsiNamedElement)root).getName() : root.getText(); + PsiElement root = myRoots[i]; + rootsPresentation[i] = root instanceof PsiNamedElement namedElement ? namedElement.getName() : root.getText(); } rootsPresentation = StringUtil.surround(rootsPresentation, "\'", "\'"); name = "Migrate Type of " + StringUtil.join(rootsPresentation, ", "); @@ -221,28 +226,28 @@ protected void previewRefactoring(@Nonnull final UsageInfo[] usages) { ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.FIND).activate(null); } + @RequiredReadAction public static String getPresentation(PsiElement element) { - String text; - if (element instanceof PsiField) { - text = "field \'" + ((PsiField)element).getName() + "\'"; + if (element instanceof PsiField field) { + return "field \'" + field.getName() + "\'"; } - else if (element instanceof PsiParameter) { - text = "parameter \'" + ((PsiParameter)element).getName() + "\'"; + else if (element instanceof PsiParameter parameter) { + return "parameter \'" + parameter.getName() + "\'"; } - else if (element instanceof PsiLocalVariable) { - text = "variable \'" + ((PsiLocalVariable)element).getName() + "\'"; + else if (element instanceof PsiLocalVariable localVar) { + return "variable \'" + localVar.getName() + "\'"; } - else if (element instanceof PsiMethod) { - text = "method \'" + ((PsiMethod)element).getName() + "\' return"; + else if (element instanceof PsiMethod method) { + return "method \'" + method.getName() + "\' return"; } else { - text = element.getText(); + return element.getText(); } - return text; } @Nonnull @Override + @RequiredUIAccess public UsageInfo[] findUsages() { myLabeler = new TypeMigrationLabeler(myRules, myRootTypes, myAllowDependentRoots ? null : myRoots, myProject); @@ -267,17 +272,18 @@ public void performRefactoring(@Nonnull UsageInfo[] usages) { } public static void change(UsageInfo[] usages, TypeMigrationLabeler labeler, Project project) { - final List> newExpressionsToCheckDiamonds = new SmartList<>(); - final TypeMigrationLabeler.MigrationProducer producer = labeler.createMigratorFor(usages); + List> newExpressionsToCheckDiamonds = new SmartList<>(); + TypeMigrationLabeler.MigrationProducer producer = labeler.createMigratorFor(usages); - final SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(project); + SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(project); List nonCodeUsages = new ArrayList<>(); for (UsageInfo usage : usages) { if (((TypeMigrationUsageInfo)usage).isExcluded()) { continue; } - final PsiElement element = usage.getElement(); - if (element instanceof PsiVariable || element instanceof PsiMember || element instanceof PsiExpression || element instanceof PsiReferenceParameterList) { + PsiElement element = usage.getElement(); + if (element instanceof PsiVariable || element instanceof PsiMember + || element instanceof PsiExpression || element instanceof PsiReferenceParameterList) { producer.change( (TypeMigrationUsageInfo)usage, expression -> newExpressionsToCheckDiamonds.add(smartPointerManager.createSmartPsiElementPointer(expression)) @@ -289,21 +295,21 @@ public static void change(UsageInfo[] usages, TypeMigrationLabeler labeler, Proj } for (SmartPsiElementPointer newExpressionPointer : newExpressionsToCheckDiamonds) { - final PsiNewExpression newExpression = newExpressionPointer.getElement(); + PsiNewExpression newExpression = newExpressionPointer.getElement(); if (newExpression != null) { labeler.postProcessNewExpression(newExpression); } } for (UsageInfo usageInfo : nonCodeUsages) { - final PsiElement element = usageInfo.getElement(); + PsiElement element = usageInfo.getElement(); if (element != null) { - final PsiReference reference = element.getReference(); + PsiReference reference = element.getReference(); if (reference != null) { - final Object target = producer.getConversion(usageInfo); - if (target instanceof PsiMember) { + Object target = producer.getConversion(usageInfo); + if (target instanceof PsiMember member) { try { - reference.bindToElement((PsiElement)target); + reference.bindToElement(member); } catch (IncorrectOperationException ignored) { } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/util/FixableUsagesRefactoringProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/util/FixableUsagesRefactoringProcessor.java index 146c4d848..3fa91c9be 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/util/FixableUsagesRefactoringProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/util/FixableUsagesRefactoringProcessor.java @@ -15,17 +15,16 @@ */ package com.intellij.java.impl.refactoring.util; -import consulo.project.Project; -import consulo.util.lang.ref.Ref; -import consulo.language.psi.PsiElement; +import com.intellij.xml.util.XmlUtil; import consulo.language.editor.refactoring.BaseRefactoringProcessor; import consulo.language.editor.refactoring.util.CommonRefactoringUtil; -import consulo.usage.UsageInfo; +import consulo.language.psi.PsiElement; import consulo.language.util.IncorrectOperationException; -import consulo.util.collection.MultiMap; -import com.intellij.xml.util.XmlUtil; import consulo.logging.Logger; - +import consulo.project.Project; +import consulo.usage.UsageInfo; +import consulo.util.collection.MultiMap; +import consulo.util.lang.ref.SimpleReference; import jakarta.annotation.Nonnull; import java.util.ArrayList; @@ -39,7 +38,8 @@ protected FixableUsagesRefactoringProcessor(Project project) { super(project); } - protected void performRefactoring(UsageInfo[] usageInfos) { + @Override + protected void performRefactoring(@Nonnull UsageInfo[] usageInfos) { CommonRefactoringUtil.sortDepthFirstRightLeftOrder(usageInfos); for (UsageInfo usageInfo : usageInfos) { if (usageInfo instanceof FixableUsageInfo) { @@ -54,8 +54,9 @@ protected void performRefactoring(UsageInfo[] usageInfos) { } @Nonnull + @Override protected final UsageInfo[] findUsages() { - final List usages = Collections.synchronizedList(new ArrayList()); + List usages = Collections.synchronizedList(new ArrayList()); findUsages(usages); final int numUsages = usages.size(); final FixableUsageInfo[] usageArray = usages.toArray(new FixableUsageInfo[numUsages]); @@ -64,9 +65,9 @@ protected final UsageInfo[] findUsages() { protected abstract void findUsages(@Nonnull List usages); - protected static void checkConflicts(final Ref refUsages, final MultiMap conflicts) { + protected static void checkConflicts(SimpleReference refUsages, MultiMap conflicts) { for (UsageInfo info : refUsages.get()) { - final String conflict = ((FixableUsageInfo)info).getConflictMessage(); + String conflict = ((FixableUsageInfo)info).getConflictMessage(); if (conflict != null) { conflicts.putValue(info.getElement(), XmlUtil.escape(conflict)); } diff --git a/plugin/src/main/java/com/intellij/java/impl/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java b/plugin/src/main/java/com/intellij/java/impl/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java index 37f0f3478..ca977c1e7 100644 --- a/plugin/src/main/java/com/intellij/java/impl/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java +++ b/plugin/src/main/java/com/intellij/java/impl/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java @@ -49,7 +49,7 @@ import consulo.util.collection.MultiMap; import consulo.util.lang.Comparing; import consulo.util.lang.StringUtil; -import consulo.util.lang.ref.Ref; +import consulo.util.lang.ref.SimpleReference; import jakarta.annotation.Nonnull; import java.io.IOException; @@ -75,9 +75,11 @@ public class WrapReturnValueProcessor extends FixableUsagesRefactoringProcessor public WrapReturnValueProcessor( String className, String packageName, - MoveDestination moveDestination, PsiMethod method, + MoveDestination moveDestination, + PsiMethod method, boolean useExistingClass, - final boolean createInnerClass, PsiField delegateField + boolean createInnerClass, + PsiField delegateField ) { super(method.getProject()); myMoveDestination = moveDestination; @@ -89,9 +91,9 @@ public WrapReturnValueProcessor( myQualifiedName = StringUtil.getQualifiedName(packageName, className); this.myUseExistingClass = useExistingClass; - final Set typeParamSet = new HashSet<>(); - final TypeParametersVisitor visitor = new TypeParametersVisitor(typeParamSet); - final PsiTypeElement returnTypeElement = method.getReturnTypeElement(); + Set typeParamSet = new HashSet<>(); + TypeParametersVisitor visitor = new TypeParametersVisitor(typeParamSet); + PsiTypeElement returnTypeElement = method.getReturnTypeElement(); assert returnTypeElement != null; returnTypeElement.accept(visitor); typeParams = new ArrayList<>(typeParamSet); @@ -104,17 +106,17 @@ public WrapReturnValueProcessor( } private String calculateUnwrapMethodName() { - final PsiClass existingClass = + PsiClass existingClass = JavaPsiFacade.getInstance(myProject).findClass(myQualifiedName, GlobalSearchScope.allScope(myProject)); if (existingClass != null) { if (TypeConversionUtil.isPrimitiveWrapper(myQualifiedName)) { - final PsiPrimitiveType unboxedType = + PsiPrimitiveType unboxedType = PsiPrimitiveType.getUnboxedType(JavaPsiFacade.getInstance(myProject).getElementFactory().createType(existingClass)); assert unboxedType != null; return unboxedType.getCanonicalText() + "Value()"; } - final PsiMethod getter = PropertyUtil.findGetterForField(myDelegateField); + PsiMethod getter = PropertyUtil.findGetterForField(myDelegateField); return getter != null ? getter.getName() : ""; } return ""; @@ -138,20 +140,20 @@ public void findUsages(@Nonnull List usages) { @RequiredReadAction private void findUsagesForMethod(PsiMethod psiMethod, List usages) { for (PsiReference reference : ReferencesSearch.search(psiMethod, psiMethod.getUseScope())) { - final PsiElement referenceElement = reference.getElement(); - final PsiElement parent = referenceElement.getParent(); - if (parent instanceof PsiCallExpression) { - usages.add(new UnwrapCall((PsiCallExpression)parent, unwrapMethodName)); + PsiElement referenceElement = reference.getElement(); + PsiElement parent = referenceElement.getParent(); + if (parent instanceof PsiCallExpression callExpr) { + usages.add(new UnwrapCall(callExpr, unwrapMethodName)); } } - final String returnType = calculateReturnTypeString(); + String returnType = calculateReturnTypeString(); usages.add(new ChangeReturnType(psiMethod, returnType)); psiMethod.accept(new ReturnSearchVisitor(usages, returnType, psiMethod)); } private String calculateReturnTypeString() { - final String qualifiedName = StringUtil.getQualifiedName(packageName, className); - final StringBuilder returnTypeBuffer = new StringBuilder(qualifiedName); + String qualifiedName = StringUtil.getQualifiedName(packageName, className); + StringBuilder returnTypeBuffer = new StringBuilder(qualifiedName); if (!typeParams.isEmpty()) { returnTypeBuffer.append('<'); returnTypeBuffer.append(StringUtil.join( @@ -170,9 +172,9 @@ private String calculateReturnTypeString() { @Override @RequiredUIAccess - protected boolean preprocessUsages(@Nonnull final Ref refUsages) { + protected boolean preprocessUsages(@Nonnull SimpleReference refUsages) { MultiMap conflicts = new MultiMap<>(); - final PsiClass existingClass = + PsiClass existingClass = JavaPsiFacade.getInstance(myProject).findClass(myQualifiedName, GlobalSearchScope.allScope(myProject)); if (myUseExistingClass) { if (existingClass == null) { @@ -180,9 +182,9 @@ protected boolean preprocessUsages(@Nonnull final Ref refUsages) { } else { boolean foundConstructor = false; - final Set returnTypes = new HashSet<>(); + Set returnTypes = new HashSet<>(); returnTypes.add(method.getReturnType()); - final PsiCodeBlock methodBody = method.getBody(); + PsiCodeBlock methodBody = method.getBody(); if (methodBody != null) { methodBody.accept(new JavaRecursiveElementWalkingVisitor() { @Override @@ -199,21 +201,21 @@ public void visitReturnStatement(@Nonnull PsiReturnStatement statement) { }); } - final PsiMethod[] constructors = existingClass.getConstructors(); + PsiMethod[] constructors = existingClass.getConstructors(); constr: for (PsiMethod constructor : constructors) { - final PsiParameter[] parameters = constructor.getParameterList().getParameters(); + PsiParameter[] parameters = constructor.getParameterList().getParameters(); if (parameters.length == 1) { - final PsiParameter parameter = parameters[0]; - final PsiType parameterType = parameter.getType(); + PsiParameter parameter = parameters[0]; + PsiType parameterType = parameter.getType(); for (PsiType returnType : returnTypes) { if (!TypeConversionUtil.isAssignable(parameterType, returnType)) { continue constr; } } - final PsiCodeBlock body = constructor.getBody(); + PsiCodeBlock body = constructor.getBody(); LOG.assertTrue(body != null); - final boolean[] found = new boolean[1]; + boolean[] found = new boolean[1]; body.accept(new JavaRecursiveElementWalkingVisitor() { @Override @RequiredReadAction @@ -263,7 +265,7 @@ public void visitAssignmentExpression(@Nonnull PsiAssignmentExpression expressio @Override @RequiredReadAction - protected void performRefactoring(UsageInfo[] usageInfos) { + protected void performRefactoring(@Nonnull UsageInfo[] usageInfos) { if (!myUseExistingClass && !buildClass()) { return; } @@ -272,18 +274,18 @@ protected void performRefactoring(UsageInfo[] usageInfos) { @RequiredReadAction private boolean buildClass() { - final PsiManager manager = method.getManager(); - final Project project = method.getProject(); - final ReturnValueBeanBuilder beanClassBuilder = new ReturnValueBeanBuilder(); + PsiManager manager = method.getManager(); + Project project = method.getProject(); + ReturnValueBeanBuilder beanClassBuilder = new ReturnValueBeanBuilder(); beanClassBuilder.setCodeStyleSettings(project); beanClassBuilder.setTypeArguments(typeParams); beanClassBuilder.setClassName(className); beanClassBuilder.setPackageName(packageName); - beanClassBuilder.setStatic(myCreateInnerClass && method.hasModifierProperty(PsiModifier.STATIC)); - final PsiType returnType = method.getReturnType(); + beanClassBuilder.setStatic(myCreateInnerClass && method.isStatic()); + PsiType returnType = method.getReturnType(); beanClassBuilder.setValueType(returnType); - final String classString; + String classString; try { classString = beanClassBuilder.buildBeanClass(); } @@ -293,30 +295,30 @@ private boolean buildClass() { } try { - final PsiFileFactory factory = PsiFileFactory.getInstance(project); - final PsiJavaFile psiFile = (PsiJavaFile)factory.createFileFromText(className + ".java", JavaFileType.INSTANCE, classString); - final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(manager.getProject()); + PsiFileFactory factory = PsiFileFactory.getInstance(project); + PsiJavaFile psiFile = (PsiJavaFile)factory.createFileFromText(className + ".java", JavaFileType.INSTANCE, classString); + CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(manager.getProject()); if (myCreateInnerClass) { - final PsiClass containingClass = method.getContainingClass(); - final PsiElement innerClass = containingClass.add(psiFile.getClasses()[0]); + PsiClass containingClass = method.getContainingClass(); + PsiElement innerClass = containingClass.add(psiFile.getClasses()[0]); JavaCodeStyleManager.getInstance(project).shortenClassReferences(innerClass); } else { - final PsiFile containingFile = method.getContainingFile(); + PsiFile containingFile = method.getContainingFile(); - final PsiDirectory containingDirectory = containingFile.getContainingDirectory(); - final PsiDirectory directory; + PsiDirectory containingDirectory = containingFile.getContainingDirectory(); + PsiDirectory directory; if (myMoveDestination != null) { directory = myMoveDestination.getTargetDirectory(containingDirectory); } else { - final Module module = ModuleUtil.findModuleForPsiElement(containingFile); + Module module = ModuleUtil.findModuleForPsiElement(containingFile); directory = PackageUtil.findOrCreateDirectoryForPackage(module, packageName, containingDirectory, true, true); } if (directory != null) { - final PsiElement shortenedFile = JavaCodeStyleManager.getInstance(project).shortenClassReferences(psiFile); - final PsiElement reformattedFile = codeStyleManager.reformat(shortenedFile); + PsiElement shortenedFile = JavaCodeStyleManager.getInstance(project).shortenClassReferences(psiFile); + PsiElement reformattedFile = codeStyleManager.reformat(shortenedFile); directory.add(reformattedFile); } else { @@ -335,7 +337,7 @@ private boolean buildClass() { @Override @RequiredReadAction protected String getCommandName() { - final PsiClass containingClass = method.getContainingClass(); + PsiClass containingClass = method.getContainingClass(); return JavaRefactoringLocalize.wrappedReturnCommandName(className, containingClass.getName(), '.', method.getName()).get(); } @@ -344,7 +346,7 @@ private class ReturnSearchVisitor extends JavaRecursiveElementWalkingVisitor { private final String type; private final PsiMethod myMethod; - ReturnSearchVisitor(List usages, String type, final PsiMethod psiMethod) { + ReturnSearchVisitor(List usages, String type, PsiMethod psiMethod) { super(); this.usages = usages; this.type = type; @@ -363,15 +365,15 @@ public void visitReturnStatement(@Nonnull PsiReturnStatement statement) { return; } - final PsiExpression returnValue = statement.getReturnValue(); + PsiExpression returnValue = statement.getReturnValue(); if (myUseExistingClass && returnValue instanceof PsiMethodCallExpression call) { if (call.getArgumentList().getExpressions().length == 0) { - final PsiReferenceExpression callMethodExpression = call.getMethodExpression(); - final String methodName = callMethodExpression.getReferenceName(); + PsiReferenceExpression callMethodExpression = call.getMethodExpression(); + String methodName = callMethodExpression.getReferenceName(); if (Comparing.strEqual(unwrapMethodName, methodName)) { - final PsiExpression qualifier = callMethodExpression.getQualifierExpression(); + PsiExpression qualifier = callMethodExpression.getQualifierExpression(); if (qualifier != null) { - final PsiType qualifierType = qualifier.getType(); + PsiType qualifierType = qualifier.getType(); if (qualifierType != null && qualifierType.getCanonicalText().equals(myQualifiedName)) { usages.add(new ReturnWrappedValue(statement)); return; diff --git a/plugin/src/main/java/consulo/java/impl/refactoring/changeSignature/ChangeSignatureUsageProcessorEx.java b/plugin/src/main/java/consulo/java/impl/refactoring/changeSignature/ChangeSignatureUsageProcessorEx.java index 5fdfc0981..3ecf9a533 100644 --- a/plugin/src/main/java/consulo/java/impl/refactoring/changeSignature/ChangeSignatureUsageProcessorEx.java +++ b/plugin/src/main/java/consulo/java/impl/refactoring/changeSignature/ChangeSignatureUsageProcessorEx.java @@ -21,12 +21,12 @@ import consulo.language.editor.refactoring.changeSignature.ChangeInfo; import consulo.language.editor.refactoring.changeSignature.ChangeSignatureUsageProcessor; import consulo.usage.UsageInfo; +import consulo.util.lang.ref.SimpleReference; /** * @author VISTALL - * @since 26.06.14 + * @since 2014-06-26 */ -public interface ChangeSignatureUsageProcessorEx extends ChangeSignatureUsageProcessor -{ - boolean setupDefaultValues(ChangeInfo changeInfo, Ref refUsages, Project project); +public interface ChangeSignatureUsageProcessorEx extends ChangeSignatureUsageProcessor { + boolean setupDefaultValues(ChangeInfo changeInfo, SimpleReference refUsages, Project project); }