mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-08 15:09:39 +07:00
migration: ensure migrated refs are shortened (IDEA-163298)
This commit is contained in:
@@ -22,17 +22,19 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiMigration;
|
||||
import com.intellij.psi.SmartPsiElementPointer;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.impl.migration.PsiMigrationManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.refactoring.BaseRefactoringProcessor;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.RefactoringHelper;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.usageView.UsageViewDescriptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -48,6 +50,7 @@ public class MigrationProcessor extends BaseRefactoringProcessor {
|
||||
private static final String REFACTORING_NAME = RefactoringBundle.message("migration.title");
|
||||
private PsiMigration myPsiMigration;
|
||||
private final GlobalSearchScope mySearchScope;
|
||||
private ArrayList<SmartPsiElementPointer<PsiElement>> myRefsToShorten;
|
||||
|
||||
public MigrationProcessor(Project project, MigrationMap migrationMap) {
|
||||
this(project, migrationMap, GlobalSearchScope.projectScope(project));
|
||||
@@ -142,21 +145,22 @@ public class MigrationProcessor extends BaseRefactoringProcessor {
|
||||
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);
|
||||
if (entry.getType() == MigrationMapEntry.PACKAGE) {
|
||||
MigrationUtil.doPackageMigration(myProject, psiMigration, entry.getNewName(), usages);
|
||||
}
|
||||
if (entry.getType() == MigrationMapEntry.CLASS) {
|
||||
MigrationUtil.doClassMigration(myProject, psiMigration, entry.getNewName(), usages);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
for(RefactoringHelper helper: Extensions.getExtensions(RefactoringHelper.EP_NAME)) {
|
||||
Object preparedData = helper.prepareOperation(usages);
|
||||
//noinspection unchecked
|
||||
helper.performOperation(myProject, preparedData);
|
||||
if (!sameShortNames) {
|
||||
myRefsToShorten.clear();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
@@ -166,6 +170,17 @@ public class MigrationProcessor extends BaseRefactoringProcessor {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void performPsiSpoilingRefactoring() {
|
||||
JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(myProject);
|
||||
for (SmartPsiElementPointer<PsiElement> pointer : myRefsToShorten) {
|
||||
PsiElement element = pointer.getElement();
|
||||
if (element != null) {
|
||||
styleManager.shortenClassReferences(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected String getCommandName() {
|
||||
return REFACTORING_NAME;
|
||||
}
|
||||
|
||||
@@ -38,56 +38,29 @@ public class MigrationUtil {
|
||||
public static UsageInfo[] findPackageUsages(Project project, PsiMigration migration, String qName, GlobalSearchScope searchScope) {
|
||||
PsiPackage aPackage = findOrCreatePackage(project, migration, qName);
|
||||
|
||||
return findRefs(project, aPackage, searchScope);
|
||||
return findRefs(aPackage, searchScope);
|
||||
}
|
||||
|
||||
public static void doPackageMigration(Project project, PsiMigration migration, String newQName, UsageInfo[] usages) {
|
||||
try {
|
||||
PsiPackage aPackage = findOrCreatePackage(project, migration, newQName);
|
||||
|
||||
// rename all references
|
||||
for (UsageInfo usage : usages) {
|
||||
if (usage instanceof MigrationProcessor.MigrationUsageInfo) {
|
||||
final MigrationProcessor.MigrationUsageInfo usageInfo = (MigrationProcessor.MigrationUsageInfo)usage;
|
||||
if (Comparing.equal(newQName, usageInfo.mapEntry.getNewName())) {
|
||||
PsiElement element = usage.getElement();
|
||||
if (element == null || !element.isValid()) continue;
|
||||
if (element instanceof PsiJavaCodeReferenceElement) {
|
||||
((PsiJavaCodeReferenceElement)element).bindToElement(aPackage);
|
||||
}
|
||||
else {
|
||||
bindNonJavaReference(aPackage, element, usage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
// should not happen!
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void bindNonJavaReference(PsiElement bindTo, PsiElement element, UsageInfo usage) {
|
||||
private static PsiElement bindNonJavaReference(PsiElement bindTo, PsiElement element, UsageInfo usage) {
|
||||
final TextRange range = usage.getRangeInElement();
|
||||
for (PsiReference reference : element.getReferences()) {
|
||||
if (reference instanceof JavaClassReference) {
|
||||
final JavaClassReference classReference = (JavaClassReference)reference;
|
||||
if (classReference.getRangeInElement().equals(range)) {
|
||||
classReference.bindToElement(bindTo);
|
||||
break;
|
||||
return classReference.bindToElement(bindTo);
|
||||
}
|
||||
}
|
||||
}
|
||||
return bindTo;
|
||||
}
|
||||
|
||||
public static UsageInfo[] findClassUsages(Project project, PsiMigration migration, String qName, GlobalSearchScope searchScope) {
|
||||
PsiClass aClass = findOrCreateClass(project, migration, qName);
|
||||
|
||||
return findRefs(project, aClass, searchScope);
|
||||
return findRefs(aClass, searchScope);
|
||||
}
|
||||
|
||||
private static UsageInfo[] findRefs(final Project project, final PsiElement aClass, GlobalSearchScope searchScope) {
|
||||
private static UsageInfo[] findRefs(final PsiElement aClass, GlobalSearchScope searchScope) {
|
||||
final ArrayList<UsageInfo> results = new ArrayList<>();
|
||||
for (PsiReference usage : ReferencesSearch.search(aClass, searchScope, false)) {
|
||||
results.add(new UsageInfo(usage));
|
||||
@@ -96,10 +69,9 @@ public class MigrationUtil {
|
||||
return results.toArray(new UsageInfo[results.size()]);
|
||||
}
|
||||
|
||||
public static void doClassMigration(Project project, PsiMigration migration, String newQName, UsageInfo[] usages) {
|
||||
static void doMigration(PsiElement elementToBind, String newQName, UsageInfo[] usages, ArrayList<SmartPsiElementPointer<PsiElement>> refsToShorten) {
|
||||
try {
|
||||
PsiClass aClass = findOrCreateClass(project, migration, newQName);
|
||||
|
||||
SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(elementToBind.getProject());
|
||||
// rename all references
|
||||
for (UsageInfo usage : usages) {
|
||||
if (usage instanceof MigrationProcessor.MigrationUsageInfo) {
|
||||
@@ -107,15 +79,17 @@ public class MigrationUtil {
|
||||
if (Comparing.equal(newQName, usageInfo.mapEntry.getNewName())) {
|
||||
PsiElement element = usage.getElement();
|
||||
if (element == null || !element.isValid()) continue;
|
||||
PsiElement psiElement;
|
||||
if (element instanceof PsiJavaCodeReferenceElement) {
|
||||
final PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)element;
|
||||
referenceElement.bindToElement(aClass);
|
||||
psiElement = ((PsiJavaCodeReferenceElement)element).bindToElement(elementToBind);
|
||||
}
|
||||
else {
|
||||
bindNonJavaReference(aClass, element, usage);
|
||||
psiElement = bindNonJavaReference(elementToBind, element, usage);
|
||||
}
|
||||
if (psiElement != null) {
|
||||
refsToShorten.add(smartPointerManager.createSmartPsiElementPointer(psiElement));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import aaa.*;
|
||||
import bbb.Test;
|
||||
|
||||
public class C {
|
||||
@Test
|
||||
void foo(){}
|
||||
|
||||
@Test
|
||||
void bar(){}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import bbb.Test;
|
||||
public class C1 {
|
||||
@Test
|
||||
void foo(){}
|
||||
|
||||
@Test
|
||||
void bar(){}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import aaa.*;
|
||||
public class C {
|
||||
@Test
|
||||
void foo(){}
|
||||
|
||||
@Test
|
||||
void bar(){}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import aaa.Test;
|
||||
public class C1 {
|
||||
@Test
|
||||
void foo(){}
|
||||
|
||||
@Test
|
||||
void bar(){}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,10 +15,9 @@
|
||||
*/
|
||||
package com.intellij.refactoring.migration;
|
||||
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.refactoring.MultiFileTestCase;
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.refactoring.MultiFileTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -37,6 +36,12 @@ public class MigrationTest extends MultiFileTestCase {
|
||||
})));
|
||||
}
|
||||
|
||||
public void testSameShortNameClass() throws Exception {
|
||||
doTest(createAction(new MigrationMap(new MigrationMapEntry[]{
|
||||
new MigrationMapEntry("aaa.Test", "bbb.Test", MigrationMapEntry.CLASS, false)
|
||||
})));
|
||||
}
|
||||
|
||||
public void testPackage() throws Exception {
|
||||
doTest(createAction(new MigrationMap(new MigrationMapEntry[]{
|
||||
new MigrationMapEntry("qqq", "java.lang", MigrationMapEntry.PACKAGE, true)
|
||||
|
||||
Reference in New Issue
Block a user